Files
Mapo-IOB-WIN/IOB-WIN-NEXT/IobSiemensLasco.cs
T
2022-03-16 09:49:07 +01:00

585 lines
30 KiB
C#

using IOB_UT_NEXT;
using MapoSDK;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace IOB_WIN_NEXT
{
/// <summary>
/// Controllo Siemens specifico x impianti Lasco (Pressa bilancere Valvital)
/// </summary>
public class IobSiemensLasco : IobSiemens
{
/* --------------------------------------------------------------------------------
* Controlli SIEMENS LASCO (Pressa principale in VALVITAL)
* - basasto su SIEMENS
* - S7 vers 1500
*
* STRUTTURA MEMORIA DB1001 READ: 68 byte lettura, DB1002 68 byte byte scrittura, vedere doc allegato
* F:\Drive condivisi\30_Clienti\Valvital\Comunicazione PLC\22 - LASCO Bilancere
*
* !!!RISCRIVERE!!!
* - parametri processo
* - DBD00: Watchdog INT SAET Alive ( 1-9999 )
*
* - DB60.DBD6: pressione camera filtrante (salvataggio del MAX ogni minuto) | var testVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(0).Take(4).ToArray());
* - DB60.DBD10: pressione linea utenze (salvataggio del MAX ogni minuto)
* - DB60.DBD14: temperatura acqua pulita (salvataggio del MAX ogni minuto)
*
* - BIT di stato
* - DBX2.1: READY TO RUN in AUTOMATICO
* - DBX2.3: Macchina in LAVORAZIONE
* - DBX2.4: WARNING Differenza tra Part Code MES - Saet (blu)
* - DBX2.5: se 1 --> LAMPADA ROSSA (allarmi almeno 1 attivo)
*
* PartCounter DINT 4.0 Conteggio Parziale di pezzi "OK" prodotti dalla macchina
* NumberCode String [12] 8.0 Valore numerico associato alla ricetta di produzione attualmente utilizzata dalla macchina
* NewCode INT 22.0 "1= Avvenuta ricezione del segnale ""richiesta nuovo ordine di produzione (NEW CODE)""
* ricevuto dal server,impostabile su 1 solo quando la macchina NON è in produzione attiva"
* Potenza utilizzata ST.1 REAL 24 Potenza utilizzata dalla stazione di riscaldo 1 [kW]
* Potenza utilizzata ST.2 REAL 28 Potenza utilizzata dalla stazione di riscaldo 2 [kW]
* Potenza utilizzata ST.3 REAL 32 Potenza utilizzata dalla stazione di riscaldo 3 [kW]
* Potenza utilizzata ST.4 REAL 36 Potenza utilizzata dalla stazione di riscaldo 4 [kW]
* Lettura Pirometro ST.1 REAL 40 Lettura Pirometro della stazione di riscaldo 1 [°C]
* Lettura Pirometro ST.2 REAL 44 Lettura Pirometro della stazione di riscaldo 2 [°C]
* Lettura Pirometro ST.3 REAL 48 Lettura Pirometro della stazione di riscaldo 3 [°C]
* Lettura Pirometro ST.4 REAL 52 Lettura Pirometro della stazione di riscaldo 4 [°C]
* Temperatura Acqua Raff Conv. ST.1 REAL 56 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 1 [°C]
* Temperatura Acqua Raff Conv. ST.2 REAL 60 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 2 [°C]
* Temperatura Acqua Raff Conv. ST.3 REAL 64 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 3 [°C]
* Temperatura Acqua Raff Conv. ST.4 REAL 68 Temperarura Acqua di Raffreddamento Convertitore Stazione di Riscaldo 4 [°C]
* Part_Status ST.1 INT 72 Stato Pezzo Stazione di Riscaldo 1 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Part_Status ST.2 INT 74 Stato Pezzo Stazione di Riscaldo 2 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Part_Status ST.3 INT 76 Stato Pezzo Stazione di Riscaldo 3 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Part_Status ST.4 INT 78 Stato Pezzo Stazione di Riscaldo 4 (0=Assente 1=Grezzo 10=OK 11=NOK)
* Reserve_12 REAL 80 Riserva
* Reserve_13 REAL 84 Riserva
* Reserve_14 REAL 88 Riserva
* -------------------------------------------------------------------------------- */
#region Protected Fields
protected int counterMes2Plc = 0;
protected int counterPlc2Mes = 0;
protected int counterPlc2MesWrote = 0;
protected DateTime lastPLCWatchDog;
protected bool useNewSend = false;
#endregion Protected Fields
#region Public Constructors
/// <summary>
/// Classe base con i metodi x Siemens
/// </summary>
/// <param name="caller"></param>
/// <param name="adpConf"></param>
public IobSiemensLasco(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
lgInfo("NEW IOB SIEMENS versione LASCO");
lastPLCWatchDog = DateTime.Now.AddMinutes(-1);
useNewSend = string.IsNullOrWhiteSpace(getOptPar("USE_NEW_EXE_TASK")) ? false : true;
// imposto i parametri speciali x calcolo...
var chiaviTSVC = findOptPar("TSVC");
if (chiaviTSVC.Count > 0)
{
lgInfo($"Trovate {chiaviTSVC.Count} chiavi TSVC");
string[] codVal;
VCData currConf;
int periodo = 0;
VC_func funz = VC_func.POINT;
// accodo nella conf...
foreach (var item in chiaviTSVC)
{
codVal = item.Value.Split(':');
Enum.TryParse(codVal[0], out funz);
int.TryParse(codVal[1], out periodo);
currConf = new VCData()
{
Funzione = funz,
Period = periodo,
DTStart = DateTime.Now.AddHours(-1),
dataArray = new List<double>()
};
TSVC_Data.Add(item.Key.Replace("TSVC_", ""), currConf);
}
// documento...
foreach (var item in TSVC_Data)
{
lgTrace($"TSVC: {item.Key} | periodo: {item.Value.Period} | funz: {item.Value.Funzione}");
// salvo i valori PREC...
LastTSVC.Add(item.Key, 0);
}
}
}
#endregion Public Constructors
#region Protected Methods
/// <summary>
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
/// </summary>
protected override void decodeToBaseBitmap()
{
// init a zero...
B_input = 0;
/* -----------------------------------------------------
* bitmap MAPO STANDARD
* B0: POWER_ON
* B1: RUN
* B2: pzCount
* B3: allarme
* B4: manuale
* B5: emergenza
*
*
* - BIT di stato
* - DBX0.0: RUN STATE
* - DBX0.1: CYCLE
* - DBX0.2: MANUAL MODE
* - DBX0.3: GENERAL ALARM
* - DBX0.4: ESTOP (1=OK, 0 = emergency)
* - DBX0.5: SAFETY DOORS
----------------------------------------------------- */
byte mainData = RawInput[0];
int byteSignals = 0;
// bit 0 (poweron) imposto a 1 SE connected...
if (currPLC.IsConnected)
{
byteSignals += (1 << 0);
}
if ((mainData & (1 << 0)) == 1)
{
byteSignals += (1 << 1);
}
// EMERGENZA
if ((mainData & (1 << 5)) == 1)
{
byteSignals += (1 << 5);
}
// ALLARME
if ((mainData & (1 << 3)) == 1)
{
byteSignals += (1 << 3);
}
// MANUALE ...
if ((mainData & (1 << 2)) == 1)
{
byteSignals += (1 << 4);
}
// salvo!
B_input = byteSignals;
// log opzionale!
if (verboseLog)
{
lgInfo(string.Format($"Trasformazione dati: RawInput:{RawInput[3]} --> B_input: {B_input}"));
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
/// Processo i task richiesti e li elimino dalla coda 1:1
/// </summary>
/// <param name="task2exe"></param>
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
{
// Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
Dictionary<string, string> taskDone = new Dictionary<string, string>();
bool taskOk = false;
string taskVal = "";
string memAddrWrite = "";
if (task2exe != null)
{
// inizio VUOTO
byte[] MemBlock = new byte[parametri.memSizeWrite];
// controllo su OPT_PAR se usare nuovo metodo exe task...
if (useNewSend)
{
// cerco task specifici
foreach (var item in task2exe)
{
taskOk = false;
taskVal = "";
// converto richiesta in enum...
taskType tName = taskType.nihil;
Enum.TryParse(item.Key, out tName);
// controllo sulla KEY
switch (tName)
{
case taskType.nihil:
case taskType.fixStopSetup:
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.setProg:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
case taskType.setArt:
case taskType.setComm:
case taskType.setPzComm:
saveProdData(item);
// verifico se posso aggiornare valori in memoria...
if (memMap != null && memMap.mMapWrite != null)
{
if (memMap.mMapWrite.ContainsKey(item.Key))
{
dataConf currMem = memMap.mMapWrite[item.Key];
string addr = currMem.memAddr;
taskVal = $"SET task: {item.Key} --> {item.Value} | mem: {currMem.memAddr} - {currMem.size} byte";
// salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
memMap.mMapWrite[item.Key].value = item.Value;
}
else
{
taskVal = $"NO DATA MEM, SET task: {item.Key} --> {item.Value}";
}
}
else
{
taskVal = $"NO MemMap found, SET task: {item.Key} --> {item.Value}";
}
int byteSize = 0;
// recupero dati da memMap... altrimenti NULLA
if (memMap.mMapWrite.ContainsKey(item.Key))
{
dataConf currMem = memMap.mMapWrite[item.Key];
byteSize = currMem.size;
memAddrWrite = currMem.memAddr;
MemBlock = new byte[byteSize];
if (currMem.tipoMem == plcDataType.String)
{
saveStringOnMemBlock(ref MemBlock, item.Key, 0, byteSize);
}
else if (currMem.tipoMem == plcDataType.DInt)
{
int valDInt = 0;
int.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt);
}
else if (currMem.tipoMem == plcDataType.Int)
{
short valDInt = 0;
short.TryParse(item.Value, out valDInt);
MemBlock = S7.Net.Types.Int.ToByteArray(valDInt);
}
}
taskVal = item.Value;
break;
case taskType.sendWatchDogMes2Plc:
// processo scrittura BIT su DB150.DBX4.0
MemBlock = new byte[1];
memAddrWrite = "DB1002.DBB0";
// compogo in byte... primo bit è setup/run, ultimo è watchdog
int valore = inSetup ? 1 : 0;
valore += (byte)(counterMes2Plc << 7);
MemBlock[0] = (byte)valore;
taskVal = $"VALUE DB1002.92 --> {valore} | counter interno {counterMes2Plc}";
break;
case taskType.setParameter:
// richiedo da URL i parametri WRITE da popolare
lgInfo("Chiamata processMemWriteRequests");
taskVal = processMemWriteRequests();
// se restituiscce "" faccio altra prova...
if (string.IsNullOrEmpty(taskVal))
{
// i parametri me li aspetto come stringa composta paramName|paramvalue
if (item.Value.Contains("|"))
{
string[] paramsJob = item.Value.Split('|');
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
}
else
{
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
}
}
break;
case taskType.startSetup:
// salvo che SONO IN SETUP!
inSetup = true;
break;
case taskType.stopSetup:
// salvo che SONO FUORI DAL SETUP!
inSetup = false;
break;
default:
taskVal = "SKIPPED | NO EXEC";
break;
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
// scrivo comunque!
taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
if (!taskOk)
{
lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
}
}
}
else
{
// cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
foreach (var item in task2exe)
{
taskOk = false;
taskVal = "";
// converto richiesta in enum...
taskType tName = taskType.nihil;
Enum.TryParse(item.Key, out tName);
// controllo sulla KEY
switch (tName)
{
case taskType.nihil:
case taskType.fixStopSetup:
case taskType.forceResetPzCount:
case taskType.forceSetPzCount:
case taskType.startSetup:
case taskType.stopSetup:
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
break;
case taskType.setArt:
case taskType.setComm:
case taskType.setProg:
saveProdData(item);
taskVal = item.Value;
break;
case taskType.sendWatchDogMes2Plc:
// compogo in byte... primo bit è setup/run, ultimo è watchdog
int valore = inSetup ? 1 : 0;
valore += (byte)(counterMes2Plc << 7);
MemBlock[0] = (byte)valore;
taskVal = $"VALUE DB1002.92 --> {counterMes2Plc}";
break;
case taskType.setParameter:
// richiedo da URL i parametri WRITE da popolare
lgInfo("Chiamata processMemWriteRequests");
taskVal = processMemWriteRequests();
// se restituiscce "" faccio altra prova...
if (string.IsNullOrEmpty(taskVal))
{
// i parametri me li aspetto come stringa composta paramName|paramvalue
if (item.Value.Contains("|"))
{
string[] paramsJob = item.Value.Split('|');
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
}
else
{
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
}
}
break;
default:
taskVal = "SKIPPED | NO EXEC";
break;
}
// aggiungo task!
taskDone.Add(item.Key, taskVal);
}
// controllo SE HO da scrivere articolo/commessa/programma
saveStringOnMemBlock(ref MemBlock, "setArt", 2, 22);
saveStringOnMemBlock(ref MemBlock, "setComm", 24, 22);
saveStringOnMemBlock(ref MemBlock, "setProg", 46, 22);
// scrivo comunque!
taskOk = S7WriteBB(ref MemBlock);
}
}
return taskDone;
}
/// <summary>
/// Recupero dati dinamici in formato dictionary
/// </summary>
/// <returns></returns>
public override Dictionary<string, string> getDynData()
{
Dictionary<string, string> outVal = new Dictionary<string, string>();
// processing
try
{
// le 3 posizioni sono in 1/10 mm x cui vanno divise x 10... x avere MM
double RamPosition = S7.Net.Types.Int.FromByteArray(RawInput.Skip(18).Take(2).ToArray()) / 10;
double LowerEjectorPosition = S7.Net.Types.Int.FromByteArray(RawInput.Skip(20).Take(2).ToArray()) / 10;
double UpperTool = S7.Net.Types.Int.FromByteArray(RawInput.Skip(22).Take(2).ToArray()) / 10;
// temp in °C
int TempMainMotorU = S7.Net.Types.Int.FromByteArray(RawInput.Skip(24).Take(2).ToArray());
int TempMainMotorV = S7.Net.Types.Int.FromByteArray(RawInput.Skip(26).Take(2).ToArray());
int TempMainMotorW = S7.Net.Types.Int.FromByteArray(RawInput.Skip(28).Take(2).ToArray());
int TempSpindleNut = S7.Net.Types.Int.FromByteArray(RawInput.Skip(30).Take(2).ToArray());
int TempMotoModule = S7.Net.Types.Int.FromByteArray(RawInput.Skip(32).Take(2).ToArray());
int TempOilCirculation = S7.Net.Types.Int.FromByteArray(RawInput.Skip(34).Take(2).ToArray());
int TempHydraulicUnit = S7.Net.Types.Int.FromByteArray(RawInput.Skip(36).Take(2).ToArray());
// press in BAR
int PressHydraulicPump = S7.Net.Types.Int.FromByteArray(RawInput.Skip(38).Take(2).ToArray());
int PressHydraulicAccumulator = S7.Net.Types.Int.FromByteArray(RawInput.Skip(40).Take(2).ToArray());
int PressCounterforceOil = S7.Net.Types.Int.FromByteArray(RawInput.Skip(42).Take(2).ToArray());
int PressCounterforceGas = S7.Net.Types.Int.FromByteArray(RawInput.Skip(44).Take(2).ToArray());
// forze in kN (10^3 Newton)
int ForcePressureActual = S7.Net.Types.DInt.FromByteArray(RawInput.Skip(46).Take(4).ToArray());
int ForceOnBushing = S7.Net.Types.Int.FromByteArray(RawInput.Skip(50).Take(2).ToArray());
if (utils.CRB("enableTSVC"))
{
bool[] scaduti = new bool[16];
// salvo in stack le VC rilevate
scaduti[0] = stackVal_TSVC("RamPosition", RamPosition);
scaduti[1] = stackVal_TSVC("LowerEjectorPosition", LowerEjectorPosition);
scaduti[2] = stackVal_TSVC("UpperTool", UpperTool);
scaduti[3] = stackVal_TSVC("TempMainMotorU", TempMainMotorU);
scaduti[4] = stackVal_TSVC("TempMainMotorV", TempMainMotorV);
scaduti[5] = stackVal_TSVC("TempMainMotorW", TempMainMotorW);
scaduti[6] = stackVal_TSVC("TempSpindleNut", TempSpindleNut);
scaduti[7] = stackVal_TSVC("TempMotoModule", TempMotoModule);
scaduti[8] = stackVal_TSVC("TempOilCirculation", TempOilCirculation);
scaduti[9] = stackVal_TSVC("TempHydraulicUnit", TempHydraulicUnit);
scaduti[10] = stackVal_TSVC("PressHydraulicPump", PressHydraulicPump);
scaduti[11] = stackVal_TSVC("PressHydraulicAccumulator", PressHydraulicAccumulator);
scaduti[12] = stackVal_TSVC("PressCounterforceOil", PressCounterforceOil);
scaduti[13] = stackVal_TSVC("PressCounterforceGas", PressCounterforceGas);
scaduti[14] = stackVal_TSVC("ForcePressureActual", ForcePressureActual);
scaduti[15] = stackVal_TSVC("ForceOnBushing", ForceOnBushing);
// verifico SE devo riportare dati VC
if (baseUtils.CountTrue(scaduti) > 0)
{
RamPosition = getVal_TSVC_int("RamPosition", scaduti[0]);
LowerEjectorPosition = getVal_TSVC_int("LowerEjectorPosition", scaduti[1]);
UpperTool = getVal_TSVC_int("UpperTool", scaduti[2]);
TempMainMotorU = getVal_TSVC_int("TempMainMotorU", scaduti[3]);
TempMainMotorV = getVal_TSVC_int("TempMainMotorV", scaduti[4]);
TempMainMotorW = getVal_TSVC_int("TempMainMotorW", scaduti[5]);
TempSpindleNut = getVal_TSVC_int("TempSpindleNut", scaduti[6]);
TempMotoModule = getVal_TSVC_int("TempMotoModule", scaduti[7]);
TempOilCirculation = getVal_TSVC_int("TempOilCirculation", scaduti[8]);
TempHydraulicUnit = getVal_TSVC_int("TempHydraulicUnit", scaduti[9]);
PressHydraulicPump = getVal_TSVC_int("PressHydraulicPump", scaduti[10]);
PressHydraulicAccumulator = getVal_TSVC_int("PressHydraulicAccumulator", scaduti[11]);
PressCounterforceOil = getVal_TSVC_int("PressCounterforceOil", scaduti[12]);
PressCounterforceGas = getVal_TSVC_int("PressCounterforceGas", scaduti[13]);
ForcePressureActual = getVal_TSVC_int("ForcePressureActual", scaduti[14]);
ForceOnBushing = getVal_TSVC_int("ForceOnBushing", scaduti[15]);
//outVal.Add("DYNDATA", $"RamPosition {RamPosition:N2} | TempMainMotorV {TempMainMotorV:N2} | TempOilCirculation {TempOilCirculation:N2} | PressCounterforceGas {PressCounterforceGas}");
outVal.Add("RamPosition", $"{RamPosition:N1}");
outVal.Add("LowerEjectorPosition", $"{LowerEjectorPosition:N1}");
outVal.Add("UpperTool", $"{UpperTool:N1}");
outVal.Add("TempMainMotorU", $"{TempMainMotorU}");
outVal.Add("TempMainMotorV", $"{TempMainMotorV}");
outVal.Add("TempMainMotorW", $"{TempMainMotorW}");
outVal.Add("TempSpindleNut", $"{TempSpindleNut}");
outVal.Add("TempMotoModule", $"{TempMotoModule}");
outVal.Add("TempOilCirculation", $"{TempOilCirculation}");
outVal.Add("TempHydraulicUnit", $"{TempHydraulicUnit}");
outVal.Add("PressHydraulicPump", $"{PressHydraulicPump}");
outVal.Add("PressHydraulicAccumulator", $"{PressHydraulicAccumulator}");
outVal.Add("PressCounterforceOil", $"{PressCounterforceOil}");
outVal.Add("PressCounterforceGas", $"{PressCounterforceGas}");
outVal.Add("ForcePressureActual", $"{ForcePressureActual}");
outVal.Add("ForceOnBushing", $"{ForceOnBushing}");
// salvo!
LastTSVC["RamPosition"] = RamPosition;
LastTSVC["LowerEjectorPosition"] = LowerEjectorPosition;
LastTSVC["UpperTool"] = UpperTool;
LastTSVC["TempMainMotorU"] = TempMainMotorU;
LastTSVC["TempMainMotorV"] = TempMainMotorV;
LastTSVC["TempMainMotorW"] = TempMainMotorW;
LastTSVC["TempSpindleNut"] = TempSpindleNut;
LastTSVC["TempMotoModule"] = TempMotoModule;
LastTSVC["TempOilCirculation"] = TempOilCirculation;
LastTSVC["TempHydraulicUnit"] = TempHydraulicUnit;
LastTSVC["PressHydraulicPump"] = PressHydraulicPump;
LastTSVC["PressHydraulicAccumulator"] = PressHydraulicAccumulator;
LastTSVC["PressCounterforceOil"] = PressCounterforceOil;
LastTSVC["PressCounterforceGas"] = PressCounterforceGas;
LastTSVC["ForcePressureActual"] = ForcePressureActual;
LastTSVC["ForceOnBushing"] = ForceOnBushing;
}
else
{
outVal.Add("DYNDATA", $"RamPosition {LastTSVC["RamPosition"]:N1} | ForcePressureActual {LastTSVC["ForcePressureActual"]} | ForceOnBushing {LastTSVC["ForceOnBushing"]}");
}
}
else
{
outVal.Add("DYNDATA", $"RamPosition {LastTSVC["RamPosition"]:N1} | ForcePressureActual {LastTSVC["ForcePressureActual"]} | ForceOnBushing {LastTSVC["ForceOnBushing"]}");
}
}
catch (Exception exc)
{
lgError(exc, "Errore in getDynData x Siemens Aprochim");
}
return outVal;
}
public override string getPrgName()
{
string answ = "";
try
{
string rawProdCode = S7.Net.Types.String.FromByteArray(RawInput.Skip(54).Take(12).ToArray());
// primi due char sono \f e \n avanzamento carta e nuova linea...
answ = Regex.Replace(rawProdCode, @"\t|\n|\r|\f", "");
}
catch (Exception exc)
{
lgError($"Errore in decodifica product code{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Effettua processing del recupero delle OVERRIDE (spindle, feedrate, rapid)
/// </summary>
public override void processOverride()
{
}
public override void processWhatchDog()
{
// scrive nel primo byte, ultimo bit, il watchdog, mentre scrive nel primo 1 = setup, 0 = run
// scrivo 1 volta al secondo il contatore incrementale su area apposita
DateTime adesso = DateTime.Now;
if (adesso.Subtract(lastPLCWatchDog).TotalSeconds > watchDogPeriod)
{
// incremento
counterMes2Plc++;
// se > 1 --> 0 (balla solo 0..1)
if (counterMes2Plc > 1) counterMes2Plc = 0;
// salvo su DB
Dictionary<string, string> task2exe = new Dictionary<string, string>();
Dictionary<string, string> taskDone = new Dictionary<string, string>();
task2exe.Add("sendWatchDogMes2Plc", counterMes2Plc.ToString());
taskDone = executeTasks(task2exe);
// salvo watchdog PLC
lastPLCWatchDog = adesso;
}
}
#endregion Public Methods
}
}