Files
Mapo-IOB-WIN/IOB-WIN-NEXT/IobSiemensFape.cs
T
2021-12-02 11:19:37 +01:00

292 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace IOB_WIN_NEXT
{
public class IobSiemensFape : IobSiemens
{
/* --------------------------------------------------------------------------------
* Controlli SIEMENS FAPE (es punzonatrice Tecnomeccanica di LVF)
* - basasto su SIEMENS
* - S7 vers 1200
* - abilitata 1 area in lettura DB15 ed 1 in scrittura DB16 (NON la usano)
* - x poter funzionare --> protezione: meccanismi di collegamento / consenti put/get
* - lettura/scrittura primi 48 byte (240 max x le due DB)
*
* LETTURA seguenti byte:
* - B0, WORD, Stato Macchina Generale
* - B2, WORD, Posizione sequenza contatore
* - B4, WORD, contatore cicli eseguiti per lubrifica
* - B40, DWORD, contapezzi azzerabile da operatore
* - B44, DWORD, contapezzi ASSOLUTO
*
* -------------------------------------------------------------------------------- */
#region Public Constructors
/// <summary>
/// Classe base con i metodi x Siemens
/// </summary>
/// <param name="caller"></param>
/// <param name="adpConf"></param>
public IobSiemensFape(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
// dovebbe fare init della classe base, VERIFICARE...
lgInfo("NEW IOB SIEMENS versione FAPE");
}
#endregion Public Constructors
#region Public Enums
/// <summary>
/// Posizione sequenza ciclo standard punzonatrice
/// </summary>
public enum posizioneSequenza
{
CICLO_AUTOMATICO_FERMO = 0,
CONTROLLO_MODO_OPERATIVO = 5,
MODO_ATTIVO_CON_ROBOT = 8,
SBLOCCAGGIO_PEZZO = 10,
APERTURA_PORTELLO_ROBOT = 11,
CONSENSO_ACCESSO_AL_ROBOT = 12,
CARICO_ROBOT_IN_CORSO = 14,
CARICO_ROBOT_CONCLUSO = 16,
CHIUSURA_PORTELLO_ROBOT = 18,
VERIFICA_POSIZIONE_CARRI = 20,
BLOCCAGGIO_PEZZO = 22,
ATTESA_CARRO_A_DESTRA = 24,
DISCESA_RAPIDO_BROCCIATURA = 25,
CICLO_DI_BROCCIATURA = 26,
RITORNO_BROCCIATRICE = 28,
COMANDO_CARRO_A_SINISTRA = 30,
CICLO_DI_ALESATURA = 32,
RITORNO_CARRO_ALESATURA = 34,
COMANDO_CARRO_A_DESTRA = 36,
INCREMENTO_CONTAPEZZI = 38,
CONTROLLO_TIME_OUT_CICLO = 40,
RILANCIO_CICLO_F42 = 42,
ATTESA_FINE_CICLO = 45
}
/// <summary>
/// Enum degli stati macchina (B0)
/// </summary>
public enum statoMacchina
{
COMUNICAZIONE_ASSENTE = 0,
EMERGENZA_INSERITA = 1,
AVARIA_ARIA = 2,
AVARIA_PRESSIONE_OLIO = 3,
AVARIA_LIVELLO_OLIO = 4,
AVARIA_TEMPERATURA_OLIO = 5,
AVARIA_MOTORE_POMPA_IDRAULICA = 6,
AVARIA_MOTORE_RAFFREDDO_IDRAULICA = 7,
AVARIA_SINCRONISMO_PORTE = 8,
AVARIA_LIBERA = 9,
ATTIVAZIONE_IN_CORSO = 10,
MODO_MANUALE_ATTREZZAGGIO = 11,
MODO_AUTOMATICO_LOCALE = 12,
MODO_AUTOMATICO_ROBOT = 13,
CICLO_IN_CORSO = 14,
LIBERO = 15
}
#endregion Public Enums
#region Protected Methods
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
protected override void decodeToBaseBitmap()
{
// init a zero...
B_input = 0;
// FAPE: leggo i primi 2 WORD x decodifica stato e posizione...
ushort valStatus = S7.Net.Types.Word.FromByteArray(RawInput.Skip(0).Take(2).ToArray());
ushort valPosit = S7.Net.Types.Word.FromByteArray(RawInput.Skip(2).Take(2).ToArray());
statoMacchina _stMacch = ((statoMacchina)valStatus);
posizioneSequenza _posSeq = ((posizioneSequenza)valPosit);
/* -----------------------------------------------------
* bitmap MAPO
* B0: POWER_ON
* B1: RUN
* B2: pzCount
* B3: allarme
* B4: manuale
* B5: emergenza
----------------------------------------------------- */
// bit 0 (poweron) imposto a 1 SE connected...
B_input = currPLC.IsConnected ? 1 : 0;
// controllo stato macchina x impostare altri bit...
switch (_stMacch)
{
case statoMacchina.EMERGENZA_INSERITA:
B_input += (1 << 5);
break;
case statoMacchina.AVARIA_ARIA:
case statoMacchina.AVARIA_PRESSIONE_OLIO:
case statoMacchina.AVARIA_LIVELLO_OLIO:
case statoMacchina.AVARIA_TEMPERATURA_OLIO:
B_input += (1 << 3);
B_input += (1 << 6);
break;
case statoMacchina.AVARIA_MOTORE_POMPA_IDRAULICA:
case statoMacchina.AVARIA_MOTORE_RAFFREDDO_IDRAULICA:
case statoMacchina.COMUNICAZIONE_ASSENTE:
case statoMacchina.AVARIA_SINCRONISMO_PORTE:
case statoMacchina.AVARIA_LIBERA:
case statoMacchina.ATTIVAZIONE_IN_CORSO:
B_input += (1 << 3);
break;
case statoMacchina.MODO_MANUALE_ATTREZZAGGIO:
B_input += (1 << 4);
break;
case statoMacchina.CICLO_IN_CORSO:
B_input += (1 << 1);
break;
case statoMacchina.MODO_AUTOMATICO_LOCALE:
case statoMacchina.MODO_AUTOMATICO_ROBOT:
B_input += (1 << 7);
break;
case statoMacchina.LIBERO:
default:
break;
}
// procedo SOLO SE è enabled IOB
if (IobOnline)
{
try
{
currODL = utils.callUrl(urlGetCurrODL);
// solo SE HO un ODL...
if (string.IsNullOrWhiteSpace(currODL) || currODL == "0")
{
if (periodicLog)
{
lgInfo(string.Format("SiemensFape | Lettura ODL andata a vuoto: currODL: {0}", currODL));
}
}
else
{
// se variato o scaduto timeout log...
if (periodicLog || (currIdxODL.ToString() != currODL))
{
lgInfo(string.Format("SiemensFape | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL));
}
// provo a salvare nuovo ODL
int.TryParse(currODL, out currIdxODL);
}
}
catch (Exception exc)
{
if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15)
{
lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL);
lastWarnODL = DateTime.Now;
}
}
}
else
{
// imposto currODL a vuoto!
currODL = "";
if (periodicLog)
{
lgInfo($"Fanuc | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto");
}
}
if (!string.IsNullOrWhiteSpace(currODL) && currODL != "0")
{
// ora processo il contapezzi...
// controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture
if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
{
// se sono differenti MOSTRO...
if (contapezziPLC != contapezziIOB)
{
// registro contapezzi
lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB {contapezziIOB}");
}
// verifico se variato contapezzi... e se passato ritardo minimo...
if (contapezziPLC > contapezziIOB)
{
// salvo nuovo contapezzi (incremento di 1...) + richiesta refresh conteggio
contapezziIOB++;
needRefreshPzCount = true;
// salvo in semaforo!
B_input += (1 << 2);
// registro contapezzi
lgInfo($"contapezziPLC SIEMENS: {contapezziPLC} | contapezziIOB {contapezziIOB}");
}
// invio a server contapezzi (aggiornato)
string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString());
// verifica se tutto OK
if (retVal != contapezziIOB.ToString())
{
// errore salvataggio contapezzi
lgInfo($"Errore salvataggio Contapezzi SIEMENS: contapezziPLC {contapezziPLC} | contapezziIOB {contapezziIOB} | risposta: {retVal}");
// rileggo il counter pezzi da server
pzCntReload(true);
}
// resetto timer...
lastPzCountSend = DateTime.Now;
}
}
else
{
if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
{
lgInfo($"Attenzione: mancanza ODL non procedo con gestione contapezzi. contapezziPLC SIEMENS {contapezziPLC} | contapezziIOB {contapezziIOB}");
// resetto timer...
lastPzCountSend = DateTime.Now;
}
}
// log opzionale!
if (verboseLog)
{
lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
/// Recupero dati override in formato dictionary
/// </summary>
/// <returns></returns>
public override Dictionary<string, string> getDynData()
{
Dictionary<string, string> outVal = new Dictionary<string, string>();
ushort valStatus = S7.Net.Types.Word.FromByteArray(RawInput.Skip(0).Take(2).ToArray());
ushort valPosit = S7.Net.Types.Word.FromByteArray(RawInput.Skip(2).Take(2).ToArray());
outVal.Add("CURR_STATO", ((statoMacchina)valStatus).ToString());
outVal.Add("CURR_POSIT", ((posizioneSequenza)valPosit).ToString());
return outVal;
}
/// <summary>
/// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
/// </summary>
public override void processOverride()
{
}
#endregion Public Methods
}
}