diff --git a/IOB-UT-NEXT/Iob/BaseObj.cs b/IOB-UT-NEXT/Iob/BaseObj.cs
index 131bde02..38bfb956 100644
--- a/IOB-UT-NEXT/Iob/BaseObj.cs
+++ b/IOB-UT-NEXT/Iob/BaseObj.cs
@@ -1,16 +1,22 @@
using IOB_UT_NEXT.Config;
using IOB_UT_NEXT.Config.Mem;
+using IOB_UT_NEXT.Objects;
using IOB_UT_NEXT.Services.Cache;
using IOB_UT_NEXT.Services.Core;
using IOB_UT_NEXT.Services.Data;
using IOB_UT_NEXT.Services.Files;
+using MapoSDK;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Text.Json;
+using System.Text.Json.Serialization;
using static IOB_UT_NEXT.Config.BaseAlarmConf;
namespace IOB_UT_NEXT.Iob
@@ -238,13 +244,14 @@ namespace IOB_UT_NEXT.Iob
/// Oggetto della coda degli elementi di tipo RawTransf (e non ancora trasmessi)
/// NB: sono salvati serializzati come stringhe
///
- public DataQueue QueueRawTransf;// = new DataQueue("000", "QueueRawTransf", false);
+ public DataQueue QueueRawTransf;
///
/// Coda delle richieste dal server (Task2Exe)
///
public DataQueue QueueSrvReq;
+ // = new DataQueue("000", "QueueRawTransf", false);
///
/// Coda delle risposte al server (Task2Exe)
///
@@ -253,13 +260,14 @@ namespace IOB_UT_NEXT.Iob
///
/// Coda valori LOG UTENTE (da non sottocampionare come samples)...
///
- public DataQueue QueueULog;// = new DataQueue("000", "QueueULog", false);
+ public DataQueue QueueULog;
///
/// alias booleano false = R
///
public bool R = false;
+ // = new DataQueue("000", "QueueULog", false);
///
/// 32 byte input base (es strobe, 8 word da 32 bit di flags...)
///
@@ -280,11 +288,6 @@ namespace IOB_UT_NEXT.Iob
///
public Stopwatch sw = new Stopwatch();
- ///
- /// Oggetto gestione TempiCiclo e contapezzi
- ///
- public TCMan tcMan = new TCMan(0.5, 1.3, 5);
-
///
/// Imposta veto lettura dati (es per DB a 2 sec)
///
@@ -402,49 +405,407 @@ namespace IOB_UT_NEXT.Iob
#region Protected Fields
-
+ ///
+ /// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette
+ ///
+ protected static int numErroriCheck = 0;
///
/// Valore di attesa (random) dopo ogni invio x evitare congestione send...
///
protected static int urlRandWait = 0;
+ ///
+ /// Stato connessione con macchina gestita
+ ///
+ protected bool _connOk = false;
+
+ ///
+ /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
+ ///
+ protected bool adpCommAct;
+
+ ///
+ /// porta x adapter (x restart)
+ ///
+ protected int adpPortNum;
+
+ ///
+ /// DataOra ultimo avvio adapter x watchdog
+ ///
+ protected DateTime adpStartRun;
+
+ ///
+ /// Vettore 32 BIT valori in ingresso al filtro
+ ///
+ protected int B_input;
+
+ ///
+ /// Vettore 32 BIT valori in uscita dal filtro
+ ///
+ protected int B_output;
+
+ ///
+ /// Vettore 32 BIT valori precedenti
+ ///
+ protected int B_previous = -1;
+
+ ///
+ /// Cod grupo IOB x creazione PODL al volo
+ ///
+ protected string CodGruppoIob = "ND-00";
+
+ ///
+ /// Num errori check alive
+ ///
+ protected int currAliveErrors = 0;
+
+ ///
+ /// Dizionario valori impostati x produzione
+ ///
+ protected Dictionary currProdData = new Dictionary();
+
+ ///
+ /// num corrente errori read PLC
+ ///
+ protected int currReadErrors = 0;
+
+ ///
+ /// num errori send
+ ///
+ protected int currSendErrors = 0;
+
+ ///
+ /// Tempo di attesa in minuti x lettura contapezzi standard (da .ini / OptPar)
+ ///
+ protected double delayMinReadPzCount = 0;
+
+ ///
+ /// Fattore di demoltiplicazione dei DynData x ridurre campionamento
+ ///
+ protected int demFactDynData = 1;
+
///
/// Disabilitazione gestione ODL (lettura e gestione)
///
protected bool disableOdl = false;
+ ///
+ /// Boolean x indicare contapezzi disabilitato forzatamente da IOB
+ ///
+ protected bool disablePzCountByIob = false;
+
+ ///
+ /// Veto x esecuzione task AutoDossier
+ ///
+ protected DateTime dtVetoAutoDossier = DateTime.Now;
+
+ ///
+ /// Veto x lettura contapezzi (in caso di autoODL con attesa reset ad esempio...)
+ ///
+ protected DateTime dtVetoReadPzCount = DateTime.Now;
+
+ ///
+ /// DataOra x veto all'invio dataItem
+ ///
+ protected DateTime dtVetoSenDataItem = DateTime.Now;
+
+ ///
+ /// Veto x esecuzione Task2Exe troppo frequenti
+ ///
+ protected DateTime dtVetoTask2Exe = DateTime.Now;
+
+ ///
+ /// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab
+ ///
+ protected bool EnabelPodlManFull = false;
+
+ ///
+ /// Abilita riscrittura memoria se trova differenze lettura/richiesti
+ ///
+ protected bool ENABLE_MEM_REWRITE = true;
+
+ ///
+ /// Abilitazione restart (da opt par...)
+ ///
+ protected bool enableCliRestart = false;
+
+ ///
+ /// Boolean x indicare contapezzi abilitato a livello di conf applicazione
+ ///
+ protected bool enablePzCountByApp = true;
+
+ ///
+ /// Abilitazione invio dataitem
+ ///
+ protected bool enableSendDataItem = true;
+
+ ///
+ /// Abilitazione gestione slow data
+ ///
+ protected bool enableSlowData = false;
+
//protected static Logger lg = LogManager.GetCurrentClassLogger();
///
/// Abilitazione invio conf macchine
///
protected bool enabSendMachineConf = true;
+ ///
+ /// dizionario (opzionale) xz decodifica file da importare
+ ///
+ protected Dictionary FileDecod = new Dictionary();
+
+ ///
+ /// DeadBand x riduzione dati FluxLog (se 0 non gestita)
+ ///
+ protected double fluxLogRedDeadBand = 0;
+
+ ///
+ /// Determina se sia gestita riduzione dati FluxLog
+ ///
+ protected bool fluxLogReduce = false;
+
+ ///
+ /// Dizionario dei valori FluxLog ultimi verificati x veto
+ ///
+ protected Dictionary fluxLogReduceLast = new Dictionary();
+
+ ///
+ /// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto
+ ///
+ protected Dictionary fluxLogReduceLastString = new Dictionary();
+
+ ///
+ /// Dizionario dei veto send x ogni variabile quando non variata
+ ///
+ protected Dictionary fluxLogReduceVeto = new Dictionary();
+
+ ///
+ /// Finestra in minuti x invio dati FluxLog quando invariati
+ ///
+ protected int fluxLogResendPeriod = 60;
+
+ ///
+ /// indica che è richiesto forzatamente reset contapezzi
+ ///
+ protected bool forcePzReset = false;
+
+ ///
+ /// indica che è richiesto forzatamente reset contapezzi
+ ///
+ protected DateTime forcePzResetUntil = DateTime.Now.AddMinutes(-1);
+
+ ///
+ /// DEADBAND globale se impostata (es x gestire variazioni minime valori FluxLog da inviare...)
+ ///
+ protected float GLOBAL_DBAND = 0;
+
+ ///
+ /// Determina se siano gestite le ricette
+ ///
+ protected bool hasRecipe = false;
+
+ ///
+ /// Array dei contatori x segnali blinking
+ ///
+ protected int[] i_counters;
+
+ ///
+ /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
+ ///
+ protected bool inSetup = false;
+
+ ///
+ /// ultimo tentativo connessione...
+ ///
+ protected DateTime lastConnectTry;
+
///
/// Ultimo LOG registrazione avvio (x ridurre log notturni...)
///
protected DateTime lastLogStartup = DateTime.Today.AddHours(-1);
+ ///
+ /// Dizionario ULTIMI valori impostati x produzione
+ ///
+ protected Dictionary lastProdData = new Dictionary();
+
+ ///
+ /// Ultimo invio contapezzi (x invio delayed)
+ ///
+ protected DateTime lastPzCountSend;
+
+ ///
+ /// Dizionario ultimi valori (string) delle TSS
+ ///
+ protected Dictionary LastTSS = new Dictionary();
+
+ ///
+ /// Dizionario ultimi valori (string) delle TSS
+ ///
+ protected Dictionary LastTSSSend = new Dictionary();
+
+ ///
+ /// Dizionario ultimi valori (double) delle TSVC
+ ///
+ protected Dictionary LastTSVC = new Dictionary();
+
+ ///
+ /// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
+ ///
+ protected DateTime lastWarnODL;
+
+ ///
+ /// ultima data-ora invio parametri write x ribadire status
+ ///
+ protected DateTime lastWriteParamsUpsert = DateTime.Now;
+
+ ///
+ /// Separatore linea (tipicamente x commenti)
+ ///
+ protected string lineSep = "--------------------------";
+
+ ///
+ /// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT)
+ ///
+ protected List list2Write = new List();
+
+ ///
+ /// Elenco delle eventuali condizioni di veto conditions attive
+ ///
+ protected List ListVetoCond = new List();
+
+ ///
+ /// Num massimo di errori in funzionalità check alive
+ ///
+ protected int maxAliveErrors = utils.CRI("maxAliveErrors");
+
+ ///
+ /// Soglia massima errori prima della disconnessione automatica in check
+ ///
+ protected int maxErroriCheck = utils.CRI("maxErroriCheck");
+
+ ///
+ /// Quantità massima per singola ricetta (per determinare num ricette da inviare)
+ ///
+ protected int maxQtyPerFile = 0;
+
///
/// Dimensione coda di ping x valutazione
///
protected int maxQueuePing = 11;
+ ///
+ /// Num massimo di errori di rete read (dal PLC)
+ ///
+ protected int maxReadErrors = utils.CRI("maxReadErrors");
+
+ ///
+ /// Periodo massimo (in sec) per letture dati in mancanza di eventi di aggiornamento
+ ///
+ protected int MaxSecReload = 120;
+
+ ///
+ /// Num massimodi errori di rete send al server
+ ///
+ protected int maxSendErrors = utils.CRI("maxSendErrors");
+
+ ///
+ /// Numero massimo di tentativi x test ping preliminare
+ ///
+ protected int maxTryPing = 1;
+
+ protected string mem2trace = "";
+
///
/// Tempo minimo ammissibile di risposta (es x errori ModBus che risponde troppo in fretta) in millisec
///
protected int minRespTimeMs = 5;
+ protected int minVetoSendDataItem = 60;
+
+ ///
+ /// indica se serva refresh parametri e quindi PLC...
+ ///
+ protected bool needRefresh = true;
+
+ ///
+ /// Indica se usare la parte numerica di un articolo come codice INT
+ ///
+ protected bool numArtCharTrim = false;
+
+ ///
+ /// Timeout x ping al server
+ ///
+ protected int pingServerMsTimeout = utils.CRI("PingMsTimeout");
+
+ ///
+ /// DataOra avvio Programma x check avvio
+ ///
+ protected DateTime prgStarted = DateTime.Now;
+
+ ///
+ /// Ritardo minimo x invio contapezzi
+ ///
+ protected int pzCountDelay = 2500;
+
///
/// Indica se resettare allarmi all'avvio e inviare il reset appena parte adapter
///
protected bool resetAlarmOnStart = false;
+ ///
+ /// Periodo di campionamento x refresh info
+ ///
+ protected int samplePeriod = 1000;
+
+ ///
+ /// MsSample Period base x campionamenti tpo OCP-UA
+ ///
+ protected int samplePeriodBase = 600;
+
+ ///
+ /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
+ ///
+ protected Dictionary TSVC_Data = new Dictionary();
+
+ ///
+ /// Indica se usare archivio locale ricette vs scarico http/REST
+ ///
+ protected bool useLocalRecipe = true;
+
+ ///
+ /// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a
+ /// scadenza periodo...)
+ ///
+ protected Dictionary VarArray = new Dictionary();
+
+ ///
+ /// Dizionario dei divieti di invio x ogni counter gestito
+ ///
+ protected Dictionary VetoCounterSend = new Dictionary();
+
///
/// Veto per registrazione completa log di startup (minuti)
///
protected int vetoLogStartupDuration = 60;
+ ///
+ /// Durata in secondi del divieto accodamento segnali IN alla fase di startup
+ ///
+ protected int vetoQueueIn = 10;
+
+ ///
+ /// Periodo di veto prima di invio nuova conferma dei valori write correnti, default ogni 5 min
+ ///
+ protected double vetoSendWriteUpsert = 1;
+
+ ///
+ /// Periodo wathdog di default (2 sec se non specificato)
+ ///
+ protected int watchDogPeriod = 2;
+
#endregion Protected Fields
#region Protected Properties
@@ -463,6 +824,88 @@ namespace IOB_UT_NEXT.Iob
#region Protected Methods
+ ///
+ /// Decodifica file MAP (caso .bit)
+ ///
+ ///
+ ///
+ /// indirizzo Byte: indirizzo di partenza memoria
+ /// dimensione singolo slot in byte
+ /// indirizzo bit: numero riga x calcolo indice bit
+ ///
+ protected static otherData decodeBitData(string linea, char separator, int ByteNum, int memSize, int BitNum)
+ {
+ if (linea != null)
+ {
+ string[] valori = linea.Split(separator);
+ int shift = 0;
+ try
+ {
+ shift = Convert.ToInt32(valori[0]) - 1;
+ }
+ catch
+ { }
+ int resto = 0;
+ Math.DivRem(BitNum, 8, out resto);
+ string memAddr = string.Format("{0}.{1}", ByteNum + shift * memSize, resto);
+ return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ ///
+ /// Decodifica file MAP generico
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static otherData decodeOtherData(string linea, char separator, string memPre, int baseAddr, int memSize)
+ {
+ if (linea != null)
+ {
+ string[] valori = linea.Split(separator);
+ int shift = 0;
+ try
+ {
+ shift = Convert.ToInt32(valori[0]) - 1;
+ }
+ catch
+ { }
+ string memAddr = string.Format("{0}{1}", memPre, baseAddr + shift * memSize);
+ return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ protected static long GetObjectSize(object genObj, bool isSerializable)
+ {
+ long result = 0;
+ if (isSerializable)
+ {
+ using (var stream = new MemoryStream())
+ {
+ var formatter = new BinaryFormatter();
+ formatter.Serialize(stream, genObj);
+ result = stream.Length;
+ }
+ }
+ else
+ {
+ string rawVal = System.Text.Json.JsonSerializer.Serialize(genObj, options);
+ result = rawVal.Length;
+ }
+ return result;
+ }
+
///
/// Verifica se ci sia veto log attivo e gestisce casistiche
///
@@ -560,6 +1003,21 @@ namespace IOB_UT_NEXT.Iob
///
protected string GetWeekStatsKey() => redisMan.redHash($"IOB:Status:{IOBConfFull.General.FilenameIOB}:WeekStats");
+ ///
+ /// Deserializza una stringa JSON in un oggetto.
+ ///
+ protected T JsonDeserialize(string json) => DataSerializer.Deserialize(json);
+
+ ///
+ /// Serializza un oggetto in formato JSON.
+ ///
+ protected string JsonSerialize(T obj) => DataSerializer.Serialize(obj);
+
+ ///
+ /// Serializza un oggetto in formato JSON con opzioni serializzazione.
+ ///
+ protected string JsonSerialize(T obj, Formatting reqFormat) => DataSerializer.Serialize(obj, reqFormat);
+
///
/// Imposta un valore nel hash dello stato dell'IOB.
///
@@ -590,36 +1048,17 @@ namespace IOB_UT_NEXT.Iob
QueueULog = new DataQueue(codIob, "QueueULog", false, redisMan);
}
- #endregion Protected Methods
-
- #region Protected Serialization Helpers
-
///
- /// Serializza un oggetto in formato JSON.
+ /// Deserializza una stringa XML in un oggetto.
///
- protected string JsonSerialize(T obj) => IOB_UT_NEXT.Services.Data.DataSerializer.Serialize(obj);
-
- ///
- /// Serializza un oggetto in formato JSON con opzioni serializzazione.
- ///
- protected string JsonSerialize(T obj, Formatting reqFormat) => IOB_UT_NEXT.Services.Data.DataSerializer.Serialize(obj, reqFormat);
-
- ///
- /// Deserializza una stringa JSON in un oggetto.
- ///
- protected T JsonDeserialize(string json) => IOB_UT_NEXT.Services.Data.DataSerializer.Deserialize(json);
+ protected T XmlDeserialize(string xml) => XmlDataSerializer.Deserialize(xml);
///
/// Serializza un oggetto in formato XML.
///
- protected string XmlSerialize(T obj) => IOB_UT_NEXT.Services.Data.XmlDataSerializer.Serialize(obj);
+ protected string XmlSerialize(T obj) => XmlDataSerializer.Serialize(obj);
- ///
- /// Deserializza una stringa XML in un oggetto.
- ///
- protected T XmlDeserialize(string xml) => IOB_UT_NEXT.Services.Data.XmlDataSerializer.Deserialize(xml);
-
- #endregion Protected Serialization Helpers
+ #endregion Protected Methods
#region Private Fields
@@ -628,7 +1067,11 @@ namespace IOB_UT_NEXT.Iob
///
private static readonly Logger lg = LogManager.GetCurrentClassLogger();
- private static Random rnd = new Random();
+ private static readonly JsonSerializerOptions options = new JsonSerializerOptions
+ {
+ ReferenceHandler = ReferenceHandler.IgnoreCycles,
+ WriteIndented = false // Optional: set to true for pretty-printing
+ };
#endregion Private Fields
}
diff --git a/IOB-UT-NEXT/Iob/Services/Machine/MachineCommunicationService.cs b/IOB-UT-NEXT/Iob/Services/Machine/MachineCommunicationService.cs
index 5accac77..e04741d1 100644
--- a/IOB-UT-NEXT/Iob/Services/Machine/MachineCommunicationService.cs
+++ b/IOB-UT-NEXT/Iob/Services/Machine/MachineCommunicationService.cs
@@ -57,6 +57,14 @@ namespace IOB_UT_NEXT.Services.Machine
set => _tcMan.pzCountPLC = value;
}
+ ///
+ /// Abilitazione allarme in caso di TC superiore a soglia
+ ///
+ public bool AlarmDelayTC
+ {
+ get => _tcMan.alarmDelayTC;
+ }
+
///
/// Legge un valore dalla memoria condivisa (MemMap) ricevuta dal PLC.
///
diff --git a/IOB-WIN-FORM/Iob/Generic.cs b/IOB-WIN-FORM/Iob/Generic.cs
index a5a05a83..0a6ff827 100644
--- a/IOB-WIN-FORM/Iob/Generic.cs
+++ b/IOB-WIN-FORM/Iob/Generic.cs
@@ -41,13 +41,6 @@ namespace IOB_WIN_FORM.Iob
{
public partial class Generic : BaseObj
{
- #region Private Fields
-
- private CommunicationService commService;
- private MachineCommunicationService machineCommService;
-
- #endregion Private Fields
-
#region Public Fields
public int numPzReqOdl = 0;
@@ -73,6 +66,9 @@ namespace IOB_WIN_FORM.Iob
// init oggetto redis...
redisMan = new RedisIobCache(IobConfNew.MapoMes.IpAddr, IobConfNew.General.FilenameIOB, $"{IobConfNew.General.IobType}", IobConfNew.General.MinDeltaSec);
+ // init oggetto TCMan
+ var tcMan = new TCMan(IobConfNew.TCDataConf.Lambda, IobConfNew.TCDataConf.MaxDelayFactor, IobConfNew.TCDataConf.MaxIncrPz);
+
// init communication services
commService = new CommunicationService(IobConfNew, redisMan);
machineCommService = new MachineCommunicationService(IobConfNew, tcMan, memMap);
@@ -80,8 +76,6 @@ namespace IOB_WIN_FORM.Iob
// init code
SetupQueue();
- // initi oggetto TCMan
- tcMan = new TCMan(IobConfNew.TCDataConf.Lambda, IobConfNew.TCDataConf.MaxDelayFactor, IobConfNew.TCDataConf.MaxIncrPz);
lastConnectTry = DateTime.Now;
@@ -288,18 +282,6 @@ namespace IOB_WIN_FORM.Iob
}
}
-#if false
- ///
- /// Valore medio del TC rilevato x verifica derive sul delta variazione contapezzi
- ///
- public double plcAvgTc => tcMan.avgTC > 0 ? tcMan.avgTC : 1;
-
- ///
- /// DataOra dell'ultima lettura variabile contapezzi da CNC
- ///
- public DateTime plcLastPzRead => tcMan.lastObservedData;
-
-#endif
///
/// Contapezzi attuale
///
@@ -1129,14 +1111,14 @@ namespace IOB_WIN_FORM.Iob
case taskType.forceSetPzCount:
// recupero dati da memMap...
- if (machineCommService.WriteToMemMap(iKey, item.Value))
- {
- taskVal = $"SET task: {iKey} --> {item.Value} | mem: [Updated via MachineComm]";
- }
- else
- {
- taskVal = $"NO DATA MEM, SET task: {iKey} --> {item.Value}";
- }
+ if (machineCommService.WriteToMemMap(iKey, item.Value))
+ {
+ taskVal = $"SET task: {iKey} --> {item.Value} | mem: [Updated via MachineComm]";
+ }
+ else
+ {
+ taskVal = $"NO DATA MEM, SET task: {iKey} --> {item.Value}";
+ }
lgInfo($"Chiamata forceSetPzCount: taskVal: {taskVal}");
@@ -3834,362 +3816,11 @@ namespace IOB_WIN_FORM.Iob
}
#endregion Private Methods
+
#region Protected Fields
- ///
- /// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette
- ///
- protected static int numErroriCheck = 0;
-
- protected bool _connOk = false;
-
- ///
- /// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
- ///
- protected bool adpCommAct;
-
- ///
- /// porta x adapter (x restart)
- ///
- protected int adpPortNum;
-
- ///
- /// DataOra ultimo avvio adapter x watchdog
- ///
- protected DateTime adpStartRun;
-
- ///
- /// Vettore 32 BIT valori in ingresso al filtro
- ///
- protected int B_input;
-
- ///
- /// Vettore 32 BIT valori in uscita dal filtro
- ///
- protected int B_output;
-
- ///
- /// Vettore 32 BIT valori precedenti
- ///
- protected int B_previous = -1;
-
- ///
- /// Cod grupo IOB x creazione PODL al volo
- ///
- protected string CodGruppoIob = "ND-00";
-
- ///
- /// Num errori check alive
- ///
- protected int currAliveErrors = 0;
-
- ///
- /// Dizionario valori impostati x produzione
- ///
- protected Dictionary currProdData = new Dictionary();
-
- ///
- /// num corrente errori read PLC
- ///
- protected int currReadErrors = 0;
-
- ///
- /// num errori send
- ///
- protected int currSendErrors = 0;
-
- ///
- /// Tempo di attesa in minuti x lettura contapezzi standard (da .ini / OptPar)
- ///
- protected double delayMinReadPzCount = 0;
-
- ///
- /// Fattore di demoltiplicazione dei DynData x ridurre campionamento
- ///
- protected int demFactDynData = 1;
-
- ///
- /// Boolean x indicare contapezzi disabilitato forzatamente da IOB
- ///
- protected bool disablePzCountByIob = false;
-
- ///
- /// Veto x esecuzione task AutoDossier
- ///
- protected DateTime dtVetoAutoDossier = DateTime.Now;
-
- ///
- /// Veto x esecuzione Task2Exe troppo frequenti
- ///
- protected DateTime dtVetoTask2Exe = DateTime.Now;
-
- ///
- /// Veto x lettura contapezzi (in caso di autoODL con attesa reset ad esempio...)
- ///
- protected DateTime dtVetoReadPzCount = DateTime.Now;
-
- ///
- /// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab
- ///
- protected bool EnabelPodlManFull = false;
-
- ///
- /// Abilita riscrittura memoria se trova differenze lettura/richiesti
- ///
- protected bool ENABLE_MEM_REWRITE = true;
-
- ///
- /// Abilitazione restart (da opt par...)
- ///
- protected bool enableCliRestart = false;
-
- ///
- /// Abilitazione invio dataitem
- ///
- protected bool enableSendDataItem = true;
- protected int minVetoSendDataItem = 60;
- ///
- /// DataOra x veto all'invio dataItem
- ///
- protected DateTime dtVetoSenDataItem = DateTime.Now;
-
- ///
- /// Boolean x indicare contapezzi abilitato a livello di conf applicazione
- ///
- protected bool enablePzCountByApp = true;
-
- ///
- /// Abilitazione gestione slow data
- ///
- protected bool enableSlowData = false;
-
- ///
- /// dizionario (opzionale) xz decodifica file da importare
- ///
- protected Dictionary FileDecod = new Dictionary();
-
- ///
- /// DeadBand x riduzione dati FluxLog (se 0 non gestita)
- ///
- protected double fluxLogRedDeadBand = 0;
-
- ///
- /// Determina se sia gestita riduzione dati FluxLog
- ///
- protected bool fluxLogReduce = false;
-
- ///
- /// Dizionario dei valori FluxLog ultimi verificati x veto
- ///
- protected Dictionary fluxLogReduceLast = new Dictionary();
-
- ///
- /// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto
- ///
- protected Dictionary fluxLogReduceLastString = new Dictionary();
-
- ///
- /// Dizionario dei veto send x ogni variabile quando non variata
- ///
- protected Dictionary fluxLogReduceVeto = new Dictionary();
-
- ///
- /// Finestra in minuti x invio dati FluxLog quando invariati
- ///
- protected int fluxLogResendPeriod = 60;
-
- ///
- /// indica che è richiesto forzatamente reset contapezzi
- ///
- protected bool forcePzReset = false;
-
- ///
- /// indica che è richiesto forzatamente reset contapezzi
- ///
- protected DateTime forcePzResetUntil = DateTime.Now.AddMinutes(-1);
-
- ///
- /// DEADBAND globale se impostata (es x gestire variazioni minime valori FluxLog da inviare...)
- ///
- protected float GLOBAL_DBAND = 0;
-
- ///
- /// Determina se siano gestite le ricette
- ///
- protected bool hasRecipe = false;
-
- ///
- /// Array dei contatori x segnali blinking
- ///
- protected int[] i_counters;
-
- ///
- /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
- ///
- protected bool inSetup = false;
-
- ///
- /// ultimo tentativo connessione...
- ///
- protected DateTime lastConnectTry;
-
- ///
- /// Dizionario ULTIMI valori impostati x produzione
- ///
- protected Dictionary lastProdData = new Dictionary();
-
- ///
- /// Ultimo invio contapezzi (x invio delayed)
- ///
- protected DateTime lastPzCountSend;
-
- ///
- /// Dizionario ultimi valori (string) delle TSS
- ///
- protected Dictionary LastTSS = new Dictionary();
-
- ///
- /// Dizionario ultimi valori (string) delle TSS
- ///
- protected Dictionary LastTSSSend = new Dictionary();
-
- ///
- /// Dizionario ultimi valori (double) delle TSVC
- ///
- protected Dictionary LastTSVC = new Dictionary();
-
- ///
- /// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
- ///
- protected DateTime lastWarnODL;
-
- ///
- /// ultima data-ora invio parametri write x ribadire status
- ///
- protected DateTime lastWriteParamsUpsert = DateTime.Now;
-
- ///
- /// Separatore linea (tipicamente x commenti)
- ///
- protected string lineSep = "--------------------------";
-
- ///
- /// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT)
- ///
- protected List list2Write = new List();
-
- ///
- /// Elenco delle eventuali condizioni di veto conditions attive
- ///
- protected List ListVetoCond = new List();
-
- ///
- /// Num massimo di errori in funzionalità check alive
- ///
- protected int maxAliveErrors = utils.CRI("maxAliveErrors");
-
- ///
- /// Soglia massima errori prima della disconnessione automatica in check
- ///
- protected int maxErroriCheck = utils.CRI("maxErroriCheck");
-
- ///
- /// Quantità massima per singola ricetta (per determinare num ricette da inviare)
- ///
- protected int maxQtyPerFile = 0;
-
- ///
- /// Num massimo di errori di rete read (dal PLC)
- ///
- protected int maxReadErrors = utils.CRI("maxReadErrors");
-
- ///
- /// Periodo massimo (in sec) per letture dati in mancanza di eventi di aggiornamento
- ///
- protected int MaxSecReload = 120;
-
- ///
- /// Num massimodi errori di rete send al server
- ///
- protected int maxSendErrors = utils.CRI("maxSendErrors");
-
- ///
- /// Numero massimo di tentativi x test ping preliminare
- ///
- protected int maxTryPing = 1;
-
- protected string mem2trace = "";
-
- ///
- /// indica se serva refresh parametri e quindi PLC...
- ///
- protected bool needRefresh = true;
-
- ///
- /// Indica se usare la parte numerica di un articolo come codice INT
- ///
- protected bool numArtCharTrim = false;
-
- ///
- /// Timeout x ping al server
- ///
- protected int pingServerMsTimeout = utils.CRI("PingMsTimeout");
-
- ///
- /// DataOra avvio Programma x check avvio
- ///
- protected DateTime prgStarted = DateTime.Now;
-
- ///
- /// Ritardo minimo x invio contapezzi
- ///
- protected int pzCountDelay = 2500;
-
- ///
- /// Periodo di campionamento x refresh info
- ///
- protected int samplePeriod = 1000;
-
- ///
- /// MsSample Period base x campionamenti tpo OCP-UA
- ///
- protected int samplePeriodBase = 600;
-
- ///
- /// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
- ///
- protected Dictionary TSVC_Data = new Dictionary();
-
- ///
- /// Indica se usare archivio locale ricette vs scarico http/REST
- ///
- protected bool useLocalRecipe = true;
-
- ///
- /// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a
- /// scadenza periodo...)
- ///
- protected Dictionary VarArray = new Dictionary();
-
- ///
- /// Dizionario dei divieti di invio x ogni counter gestito
- ///
- protected Dictionary VetoCounterSend = new Dictionary();
-
- ///
- /// Durata in secondi del divieto accodamento segnali IN alla fase di startup
- ///
- protected int vetoQueueIn = 10;
-
- ///
- /// Periodo di veto prima di invio nuova conferma dei valori write correnti, default ogni 5 min
- ///
- protected double vetoSendWriteUpsert = 1;
-
- ///
- /// Periodo wathdog di default (2 sec se non specificato)
- ///
- protected int watchDogPeriod = 2;
+ protected CommunicationService commService;
+ protected MachineCommunicationService machineCommService;
#endregion Protected Fields
@@ -4938,87 +4569,7 @@ namespace IOB_WIN_FORM.Iob
#region Protected Methods
- ///
- /// Decodifica file MAP (caso .bit)
- ///
- ///
- ///
- /// indirizzo Byte: indirizzo di partenza memoria
- /// dimensione singolo slot in byte
- /// indirizzo bit: numero riga x calcolo indice bit
- ///
- protected static otherData decodeBitData(string linea, char separator, int ByteNum, int memSize, int BitNum)
- {
- if (linea != null)
- {
- string[] valori = linea.Split(separator);
- int shift = 0;
- try
- {
- shift = Convert.ToInt32(valori[0]) - 1;
- }
- catch
- { }
- int resto = 0;
- Math.DivRem(BitNum, 8, out resto);
- string memAddr = string.Format("{0}.{1}", ByteNum + shift * memSize, resto);
- return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
- }
- else
- {
- return null;
- }
- }
- ///
- /// Decodifica file MAP generico
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- protected static otherData decodeOtherData(string linea, char separator, string memPre, int baseAddr, int memSize)
- {
- if (linea != null)
- {
- string[] valori = linea.Split(separator);
- int shift = 0;
- try
- {
- shift = Convert.ToInt32(valori[0]) - 1;
- }
- catch
- { }
- string memAddr = string.Format("{0}{1}", memPre, baseAddr + shift * memSize);
- return new otherData(valori[0], memAddr, valori[1].Trim(), valori[2].Trim());
- }
- else
- {
- return null;
- }
- }
-
- protected static long GetObjectSize(object genObj, bool isSerializable)
- {
- long result = 0;
- if (isSerializable)
- {
- using (var stream = new MemoryStream())
- {
- var formatter = new BinaryFormatter();
- formatter.Serialize(stream, genObj);
- result = stream.Length;
- }
- }
- else
- {
- string rawVal = System.Text.Json.JsonSerializer.Serialize(genObj, options);
- result = rawVal.Length;
- }
- return result;
- }
///
/// Decodifica valore della coda IN nel formato sendEnab[0]=dtEve sendEnab[1]=valore sendEnab[2]=counter
@@ -6331,10 +5882,9 @@ namespace IOB_WIN_FORM.Iob
{
foreach (var item in writeList)
{
- // scrivo in memoria
- if (memMap.mMapWrite.ContainsKey(item.uid))
+ // scrivo in memoria tramite servizio
+ if (machineCommService.WriteToMemMap(item.uid, item.reqValue))
{
- memMap.mMapWrite[item.uid].value = item.reqValue;
currOut = $" | Parameter {item.uid} | {item.value} --> {item.reqValue}";
// sistemo valori
item.value = item.reqValue;
@@ -6344,6 +5894,7 @@ namespace IOB_WIN_FORM.Iob
// salvo in lista da ritrasmettere
updatedPar.Add(item);
}
+
else
{
currOut = $" | Error: parameter {item.uid} not found";
@@ -8473,11 +8024,7 @@ namespace IOB_WIN_FORM.Iob
#region Private Fields
- private static readonly JsonSerializerOptions options = new JsonSerializerOptions
- {
- ReferenceHandler = ReferenceHandler.IgnoreCycles,
- WriteIndented = false // Optional: set to true for pretty-printing
- };
+
///
/// Oggetto logger della classe
diff --git a/IOB-WIN-FORM/Iob/Simula.cs b/IOB-WIN-FORM/Iob/Simula.cs
index 0f70f550..f075c8c2 100644
--- a/IOB-WIN-FORM/Iob/Simula.cs
+++ b/IOB-WIN-FORM/Iob/Simula.cs
@@ -60,18 +60,13 @@ namespace IOB_WIN_FORM.Iob
#endregion Public Fields
- #region Private Fields for Dirty Check
- private int lastSentPzCount = -1;
- private DateTime lastBitmapDecodeTime = DateTime.MinValue;
- #endregion
-
#region Public Constructors
public Simula(AdapterForm caller, IobConfTree IobConfFull) : base(caller, IobConfFull)
{
// jitter di avvio per disallineare le istanze nella VM
Random startRnd = new Random();
- int startDelay = startRnd.Next(0, 5000);
+ int startDelay = startRnd.Next(0, 5000);
Thread.Sleep(startDelay);
// gestione invio ritardato contapezzi
@@ -95,13 +90,13 @@ namespace IOB_WIN_FORM.Iob
{
int basePeriod = 0;
int.TryParse(IOBConfFull.OptParGet("PER_BASE"), out basePeriod);
-
+
// Applicazione Jitter sui periodi per evitare sincronizzazione tra VM
Random rnd = new Random();
// Aggiungiamo un rumore del +/- 15% e un jitter extra
- double noiseFactor = 0.85 + (rnd.NextDouble() * 0.30);
+ double noiseFactor = 0.85 + (rnd.NextDouble() * 0.30);
periodoMSec = (int)(basePeriod * noiseFactor);
-
+
// Assicuriamo un minimo di jitter per evitare che periodi simili si allineino
periodoMSec += rnd.Next(1, 500);
}
@@ -157,12 +152,12 @@ namespace IOB_WIN_FORM.Iob
// carica conf
try
{
- // Invece di bloccare il costruttore con .GetAwaiter().GetResult(),
+ // Invece di bloccare il costruttore con .GetAwaiter().GetResult(),
// avviamo il carico in modo "fire-and-forget" controllato.
// Questo evita il context switch pesante durante l'inizializzazione.
_ = Task.Run(async () =>
{
- try
+ try
{
await Simula_Load(adesso);
}
@@ -973,10 +968,10 @@ namespace IOB_WIN_FORM.Iob
item.reqValue = "";
MemBlock = new byte[byteSize];
- serObj = JsonSerialize(item, Formatting.Indented);
- lgInfo($"Inizio processing plcWriteParams per {currMem.name} | valore richiesto {currMem.value}{Environment.NewLine}---------------UPDATED PARAM---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
- serObj = JsonSerialize(currMem, Formatting.Indented);
- lgInfo($"---------------MEMORY CONTENT---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
+ serObj = JsonSerialize(item, Formatting.Indented);
+ lgInfo($"Inizio processing plcWriteParams per {currMem.name} | valore richiesto {currMem.value}{Environment.NewLine}---------------UPDATED PARAM---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
+ serObj = JsonSerialize(currMem, Formatting.Indented);
+ lgInfo($"---------------MEMORY CONTENT---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
lgInfo($"---------------MemBlock data---------------{Environment.NewLine}{BitConverter.ToString(MemBlock)}{Environment.NewLine}--------------- END data ---------------");
// salvo
@@ -1002,12 +997,12 @@ namespace IOB_WIN_FORM.Iob
{
try
{
- // Eseguiamo il lavoro in un Task per non bloccare il thread chiamante,
+ // Eseguiamo il lavoro in un Task per non bloccare il thread chiamante,
// ma evitiamo il .GetAwaiter().GetResult() che causerebbe un blocco sincrono pesante.
// In un ambiente WinForms, questo permette al thread di polling di non restare in attesa attiva.
_ = Task.Run(async () =>
{
- try
+ try
{
// Esecuzione dei task sincroni esistenti
iobWriteLocalCSV();
@@ -1102,9 +1097,8 @@ namespace IOB_WIN_FORM.Iob
#region Private Fields
private List alarmMessages = new List();
-
private int currSimAlarmCode = 0;
-
+ private DateTime lastBitmapDecodeTime = DateTime.MinValue;
private Random rnd = new Random();
#endregion Private Fields
@@ -1475,7 +1469,7 @@ namespace IOB_WIN_FORM.Iob
}
}
}
- else if (bit5 != null && bit5.wait <= 0 || tcMan.alarmDelayTC)
+ else if (bit5 != null && bit5.wait <= 0 || machineCommService.AlarmDelayTC)
{
// segnalo BIT
B_input += (1 << 5);
@@ -1760,8 +1754,8 @@ namespace IOB_WIN_FORM.Iob
{
try
{
- listaArt = JsonDeserialize>(rawListArt);
- okArt = listaArt.Count > 0;
+ listaArt = JsonDeserialize>(rawListArt);
+ okArt = listaArt.Count > 0;
}
catch (Exception exc)
{
@@ -1776,8 +1770,8 @@ namespace IOB_WIN_FORM.Iob
{
try
{
- listaDoss = JsonDeserialize>(rawListDOSS);
- okDoss = listaDoss.Count > 0;
+ listaDoss = JsonDeserialize>(rawListDOSS);
+ okDoss = listaDoss.Count > 0;
}
catch (Exception exc)
{
@@ -1792,8 +1786,8 @@ namespace IOB_WIN_FORM.Iob
{
try
{
- listaPODL = JsonDeserialize>(rawListPODL);
- okPodl = listaPODL.Count > 0;
+ listaPODL = JsonDeserialize>(rawListPODL);
+ okPodl = listaPODL.Count > 0;
}
catch (Exception exc)
{
@@ -1828,7 +1822,7 @@ namespace IOB_WIN_FORM.Iob
if (selArt != null && selDoss != null)
{
// recupero il resultset dei valori FluxLog da caricare
- DossierFluxLogDTO resultSet = JsonDeserialize(selDoss.Valore);
+ DossierFluxLogDTO resultSet = JsonDeserialize(selDoss.Valore);
List listFluxLog = resultSet.ODL;
// preparo elenco parametri da inviare...
@@ -2167,7 +2161,7 @@ namespace IOB_WIN_FORM.Iob
///
private void sendDataItemsList(List dataItems)
{
- string rawData = JsonSerialize(dataItems);
+ string rawData = JsonSerialize(dataItems);
HttpService.CallUrlPost($"{urlSaveDataItems}", rawData);
}