continuo fix
This commit is contained in:
+475
-32
@@ -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
|
||||
/// </summary>
|
||||
public DataQueue QueueRawTransf;// = new DataQueue("000", "QueueRawTransf", false);
|
||||
public DataQueue QueueRawTransf;
|
||||
|
||||
/// <summary>
|
||||
/// Coda delle richieste dal server (Task2Exe)
|
||||
/// </summary>
|
||||
public DataQueue QueueSrvReq;
|
||||
|
||||
// = new DataQueue("000", "QueueRawTransf", false);
|
||||
/// <summary>
|
||||
/// Coda delle risposte al server (Task2Exe)
|
||||
/// </summary>
|
||||
@@ -253,13 +260,14 @@ namespace IOB_UT_NEXT.Iob
|
||||
/// <summary>
|
||||
/// Coda valori LOG UTENTE (da non sottocampionare come samples)...
|
||||
/// </summary>
|
||||
public DataQueue QueueULog;// = new DataQueue("000", "QueueULog", false);
|
||||
public DataQueue QueueULog;
|
||||
|
||||
/// <summary>
|
||||
/// alias booleano false = R
|
||||
/// </summary>
|
||||
public bool R = false;
|
||||
|
||||
// = new DataQueue("000", "QueueULog", false);
|
||||
/// <summary>
|
||||
/// 32 byte input base (es strobe, 8 word da 32 bit di flags...)
|
||||
/// </summary>
|
||||
@@ -280,11 +288,6 @@ namespace IOB_UT_NEXT.Iob
|
||||
/// </summary>
|
||||
public Stopwatch sw = new Stopwatch();
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto gestione TempiCiclo e contapezzi
|
||||
/// </summary>
|
||||
public TCMan tcMan = new TCMan(0.5, 1.3, 5);
|
||||
|
||||
/// <summary>
|
||||
/// Imposta veto lettura dati (es per DB a 2 sec)
|
||||
/// </summary>
|
||||
@@ -402,49 +405,407 @@ namespace IOB_UT_NEXT.Iob
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette
|
||||
/// </summary>
|
||||
protected static int numErroriCheck = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Valore di attesa (random) dopo ogni invio x evitare congestione send...
|
||||
/// </summary>
|
||||
protected static int urlRandWait = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Stato connessione con macchina gestita
|
||||
/// </summary>
|
||||
protected bool _connOk = false;
|
||||
|
||||
/// <summary>
|
||||
/// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
|
||||
/// </summary>
|
||||
protected bool adpCommAct;
|
||||
|
||||
/// <summary>
|
||||
/// porta x adapter (x restart)
|
||||
/// </summary>
|
||||
protected int adpPortNum;
|
||||
|
||||
/// <summary>
|
||||
/// DataOra ultimo avvio adapter x watchdog
|
||||
/// </summary>
|
||||
protected DateTime adpStartRun;
|
||||
|
||||
/// <summary>
|
||||
/// Vettore 32 BIT valori in ingresso al filtro
|
||||
/// </summary>
|
||||
protected int B_input;
|
||||
|
||||
/// <summary>
|
||||
/// Vettore 32 BIT valori in uscita dal filtro
|
||||
/// </summary>
|
||||
protected int B_output;
|
||||
|
||||
/// <summary>
|
||||
/// Vettore 32 BIT valori precedenti
|
||||
/// </summary>
|
||||
protected int B_previous = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Cod grupo IOB x creazione PODL al volo
|
||||
/// </summary>
|
||||
protected string CodGruppoIob = "ND-00";
|
||||
|
||||
/// <summary>
|
||||
/// Num errori check alive
|
||||
/// </summary>
|
||||
protected int currAliveErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario valori impostati x produzione
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> currProdData = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// num corrente errori read PLC
|
||||
/// </summary>
|
||||
protected int currReadErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// num errori send
|
||||
/// </summary>
|
||||
protected int currSendErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo di attesa in minuti x lettura contapezzi standard (da .ini / OptPar)
|
||||
/// </summary>
|
||||
protected double delayMinReadPzCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Fattore di demoltiplicazione dei DynData x ridurre campionamento
|
||||
/// </summary>
|
||||
protected int demFactDynData = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Disabilitazione gestione ODL (lettura e gestione)
|
||||
/// </summary>
|
||||
protected bool disableOdl = false;
|
||||
|
||||
/// <summary>
|
||||
/// Boolean x indicare contapezzi disabilitato forzatamente da IOB
|
||||
/// </summary>
|
||||
protected bool disablePzCountByIob = false;
|
||||
|
||||
/// <summary>
|
||||
/// Veto x esecuzione task AutoDossier
|
||||
/// </summary>
|
||||
protected DateTime dtVetoAutoDossier = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Veto x lettura contapezzi (in caso di autoODL con attesa reset ad esempio...)
|
||||
/// </summary>
|
||||
protected DateTime dtVetoReadPzCount = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// DataOra x veto all'invio dataItem
|
||||
/// </summary>
|
||||
protected DateTime dtVetoSenDataItem = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Veto x esecuzione Task2Exe troppo frequenti
|
||||
/// </summary>
|
||||
protected DateTime dtVetoTask2Exe = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab
|
||||
/// </summary>
|
||||
protected bool EnabelPodlManFull = false;
|
||||
|
||||
/// <summary>
|
||||
/// Abilita riscrittura memoria se trova differenze lettura/richiesti
|
||||
/// </summary>
|
||||
protected bool ENABLE_MEM_REWRITE = true;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione restart (da opt par...)
|
||||
/// </summary>
|
||||
protected bool enableCliRestart = false;
|
||||
|
||||
/// <summary>
|
||||
/// Boolean x indicare contapezzi abilitato a livello di conf applicazione
|
||||
/// </summary>
|
||||
protected bool enablePzCountByApp = true;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione invio dataitem
|
||||
/// </summary>
|
||||
protected bool enableSendDataItem = true;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione gestione slow data
|
||||
/// </summary>
|
||||
protected bool enableSlowData = false;
|
||||
|
||||
//protected static Logger lg = LogManager.GetCurrentClassLogger();
|
||||
/// <summary>
|
||||
/// Abilitazione invio conf macchine
|
||||
/// </summary>
|
||||
protected bool enabSendMachineConf = true;
|
||||
|
||||
/// <summary>
|
||||
/// dizionario (opzionale) xz decodifica file da importare
|
||||
/// </summary>
|
||||
protected Dictionary<string, int> FileDecod = new Dictionary<string, int>();
|
||||
|
||||
/// <summary>
|
||||
/// DeadBand x riduzione dati FluxLog (se 0 non gestita)
|
||||
/// </summary>
|
||||
protected double fluxLogRedDeadBand = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determina se sia gestita riduzione dati FluxLog
|
||||
/// </summary>
|
||||
protected bool fluxLogReduce = false;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei valori FluxLog ultimi verificati x veto
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> fluxLogReduceLast = new Dictionary<string, double>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> fluxLogReduceLastString = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei veto send x ogni variabile quando non variata
|
||||
/// </summary>
|
||||
protected Dictionary<string, DateTime> fluxLogReduceVeto = new Dictionary<string, DateTime>();
|
||||
|
||||
/// <summary>
|
||||
/// Finestra in minuti x invio dati FluxLog quando invariati
|
||||
/// </summary>
|
||||
protected int fluxLogResendPeriod = 60;
|
||||
|
||||
/// <summary>
|
||||
/// indica che è richiesto forzatamente reset contapezzi
|
||||
/// </summary>
|
||||
protected bool forcePzReset = false;
|
||||
|
||||
/// <summary>
|
||||
/// indica che è richiesto forzatamente reset contapezzi
|
||||
/// </summary>
|
||||
protected DateTime forcePzResetUntil = DateTime.Now.AddMinutes(-1);
|
||||
|
||||
/// <summary>
|
||||
/// DEADBAND globale se impostata (es x gestire variazioni minime valori FluxLog da inviare...)
|
||||
/// </summary>
|
||||
protected float GLOBAL_DBAND = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determina se siano gestite le ricette
|
||||
/// </summary>
|
||||
protected bool hasRecipe = false;
|
||||
|
||||
/// <summary>
|
||||
/// Array dei contatori x segnali blinking
|
||||
/// </summary>
|
||||
protected int[] i_counters;
|
||||
|
||||
/// <summary>
|
||||
/// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
|
||||
/// </summary>
|
||||
protected bool inSetup = false;
|
||||
|
||||
/// <summary>
|
||||
/// ultimo tentativo connessione...
|
||||
/// </summary>
|
||||
protected DateTime lastConnectTry;
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo LOG registrazione avvio (x ridurre log notturni...)
|
||||
/// </summary>
|
||||
protected DateTime lastLogStartup = DateTime.Today.AddHours(-1);
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ULTIMI valori impostati x produzione
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> lastProdData = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo invio contapezzi (x invio delayed)
|
||||
/// </summary>
|
||||
protected DateTime lastPzCountSend;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (string) delle TSS
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> LastTSS = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (string) delle TSS
|
||||
/// </summary>
|
||||
protected Dictionary<string, DateTime> LastTSSSend = new Dictionary<string, DateTime>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (double) delle TSVC
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> LastTSVC = new Dictionary<string, double>();
|
||||
|
||||
/// <summary>
|
||||
/// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
|
||||
/// </summary>
|
||||
protected DateTime lastWarnODL;
|
||||
|
||||
/// <summary>
|
||||
/// ultima data-ora invio parametri write x ribadire status
|
||||
/// </summary>
|
||||
protected DateTime lastWriteParamsUpsert = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Separatore linea (tipicamente x commenti)
|
||||
/// </summary>
|
||||
protected string lineSep = "--------------------------";
|
||||
|
||||
/// <summary>
|
||||
/// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT)
|
||||
/// </summary>
|
||||
protected List<objItem> list2Write = new List<objItem>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco delle eventuali condizioni di veto conditions attive
|
||||
/// </summary>
|
||||
protected List<string> ListVetoCond = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Num massimo di errori in funzionalità check alive
|
||||
/// </summary>
|
||||
protected int maxAliveErrors = utils.CRI("maxAliveErrors");
|
||||
|
||||
/// <summary>
|
||||
/// Soglia massima errori prima della disconnessione automatica in check
|
||||
/// </summary>
|
||||
protected int maxErroriCheck = utils.CRI("maxErroriCheck");
|
||||
|
||||
/// <summary>
|
||||
/// Quantità massima per singola ricetta (per determinare num ricette da inviare)
|
||||
/// </summary>
|
||||
protected int maxQtyPerFile = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Dimensione coda di ping x valutazione
|
||||
/// </summary>
|
||||
protected int maxQueuePing = 11;
|
||||
|
||||
/// <summary>
|
||||
/// Num massimo di errori di rete read (dal PLC)
|
||||
/// </summary>
|
||||
protected int maxReadErrors = utils.CRI("maxReadErrors");
|
||||
|
||||
/// <summary>
|
||||
/// Periodo massimo (in sec) per letture dati in mancanza di eventi di aggiornamento
|
||||
/// </summary>
|
||||
protected int MaxSecReload = 120;
|
||||
|
||||
/// <summary>
|
||||
/// Num massimodi errori di rete send al server
|
||||
/// </summary>
|
||||
protected int maxSendErrors = utils.CRI("maxSendErrors");
|
||||
|
||||
/// <summary>
|
||||
/// Numero massimo di tentativi x test ping preliminare
|
||||
/// </summary>
|
||||
protected int maxTryPing = 1;
|
||||
|
||||
protected string mem2trace = "";
|
||||
|
||||
/// <summary>
|
||||
/// Tempo minimo ammissibile di risposta (es x errori ModBus che risponde troppo in fretta) in millisec
|
||||
/// </summary>
|
||||
protected int minRespTimeMs = 5;
|
||||
|
||||
protected int minVetoSendDataItem = 60;
|
||||
|
||||
/// <summary>
|
||||
/// indica se serva refresh parametri e quindi PLC...
|
||||
/// </summary>
|
||||
protected bool needRefresh = true;
|
||||
|
||||
/// <summary>
|
||||
/// Indica se usare la parte numerica di un articolo come codice INT
|
||||
/// </summary>
|
||||
protected bool numArtCharTrim = false;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout x ping al server
|
||||
/// </summary>
|
||||
protected int pingServerMsTimeout = utils.CRI("PingMsTimeout");
|
||||
|
||||
/// <summary>
|
||||
/// DataOra avvio Programma x check avvio
|
||||
/// </summary>
|
||||
protected DateTime prgStarted = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Ritardo minimo x invio contapezzi
|
||||
/// </summary>
|
||||
protected int pzCountDelay = 2500;
|
||||
|
||||
/// <summary>
|
||||
/// Indica se resettare allarmi all'avvio e inviare il reset appena parte adapter
|
||||
/// </summary>
|
||||
protected bool resetAlarmOnStart = false;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo di campionamento x refresh info
|
||||
/// </summary>
|
||||
protected int samplePeriod = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// MsSample Period base x campionamenti tpo OCP-UA
|
||||
/// </summary>
|
||||
protected int samplePeriodBase = 600;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
|
||||
/// </summary>
|
||||
protected Dictionary<string, VCData> TSVC_Data = new Dictionary<string, VCData>();
|
||||
|
||||
/// <summary>
|
||||
/// Indica se usare archivio locale ricette vs scarico http/REST
|
||||
/// </summary>
|
||||
protected bool useLocalRecipe = true;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a
|
||||
/// scadenza periodo...)
|
||||
/// </summary>
|
||||
protected Dictionary<string, EVData> VarArray = new Dictionary<string, EVData>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei divieti di invio x ogni counter gestito
|
||||
/// </summary>
|
||||
protected Dictionary<string, DateTime> VetoCounterSend = new Dictionary<string, DateTime>();
|
||||
|
||||
/// <summary>
|
||||
/// Veto per registrazione completa log di startup (minuti)
|
||||
/// </summary>
|
||||
protected int vetoLogStartupDuration = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Durata in secondi del divieto accodamento segnali IN alla fase di startup
|
||||
/// </summary>
|
||||
protected int vetoQueueIn = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo di veto prima di invio nuova conferma dei valori write correnti, default ogni 5 min
|
||||
/// </summary>
|
||||
protected double vetoSendWriteUpsert = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo wathdog di default (2 sec se non specificato)
|
||||
/// </summary>
|
||||
protected int watchDogPeriod = 2;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
@@ -463,6 +824,88 @@ namespace IOB_UT_NEXT.Iob
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Decodifica file MAP (caso <paramref name="ByteNum" />.bit)
|
||||
/// </summary>
|
||||
/// <param name="linea"></param>
|
||||
/// <param name="separator"></param>
|
||||
/// <param name="ByteNum">indirizzo Byte: indirizzo di partenza memoria</param>
|
||||
/// <param name="memSize">dimensione singolo slot in byte</param>
|
||||
/// <param name="BitNum">indirizzo bit: numero riga x calcolo indice bit</param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodifica file MAP generico
|
||||
/// </summary>
|
||||
/// <param name="linea"></param>
|
||||
/// <param name="separator"></param>
|
||||
/// <param name="memPre"></param>
|
||||
/// <param name="baseAddr"></param>
|
||||
/// <param name="memSize"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifica se ci sia veto log attivo e gestisce casistiche
|
||||
/// </summary>
|
||||
@@ -560,6 +1003,21 @@ namespace IOB_UT_NEXT.Iob
|
||||
/// </summary>
|
||||
protected string GetWeekStatsKey() => redisMan.redHash($"IOB:Status:{IOBConfFull.General.FilenameIOB}:WeekStats");
|
||||
|
||||
/// <summary>
|
||||
/// Deserializza una stringa JSON in un oggetto.
|
||||
/// </summary>
|
||||
protected T JsonDeserialize<T>(string json) => DataSerializer.Deserialize<T>(json);
|
||||
|
||||
/// <summary>
|
||||
/// Serializza un oggetto in formato JSON.
|
||||
/// </summary>
|
||||
protected string JsonSerialize<T>(T obj) => DataSerializer.Serialize(obj);
|
||||
|
||||
/// <summary>
|
||||
/// Serializza un oggetto in formato JSON con opzioni serializzazione.
|
||||
/// </summary>
|
||||
protected string JsonSerialize<T>(T obj, Formatting reqFormat) => DataSerializer.Serialize(obj, reqFormat);
|
||||
|
||||
/// <summary>
|
||||
/// Imposta un valore nel hash dello stato dell'IOB.
|
||||
/// </summary>
|
||||
@@ -590,36 +1048,17 @@ namespace IOB_UT_NEXT.Iob
|
||||
QueueULog = new DataQueue(codIob, "QueueULog", false, redisMan);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Protected Serialization Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Serializza un oggetto in formato JSON.
|
||||
/// Deserializza una stringa XML in un oggetto.
|
||||
/// </summary>
|
||||
protected string JsonSerialize<T>(T obj) => IOB_UT_NEXT.Services.Data.DataSerializer.Serialize(obj);
|
||||
|
||||
/// <summary>
|
||||
/// Serializza un oggetto in formato JSON con opzioni serializzazione.
|
||||
/// </summary>
|
||||
protected string JsonSerialize<T>(T obj, Formatting reqFormat) => IOB_UT_NEXT.Services.Data.DataSerializer.Serialize(obj, reqFormat);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializza una stringa JSON in un oggetto.
|
||||
/// </summary>
|
||||
protected T JsonDeserialize<T>(string json) => IOB_UT_NEXT.Services.Data.DataSerializer.Deserialize<T>(json);
|
||||
protected T XmlDeserialize<T>(string xml) => XmlDataSerializer.Deserialize<T>(xml);
|
||||
|
||||
/// <summary>
|
||||
/// Serializza un oggetto in formato XML.
|
||||
/// </summary>
|
||||
protected string XmlSerialize<T>(T obj) => IOB_UT_NEXT.Services.Data.XmlDataSerializer.Serialize(obj);
|
||||
protected string XmlSerialize<T>(T obj) => XmlDataSerializer.Serialize(obj);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializza una stringa XML in un oggetto.
|
||||
/// </summary>
|
||||
protected T XmlDeserialize<T>(string xml) => IOB_UT_NEXT.Services.Data.XmlDataSerializer.Deserialize<T>(xml);
|
||||
|
||||
#endregion Protected Serialization Helpers
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
@@ -628,7 +1067,11 @@ namespace IOB_UT_NEXT.Iob
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
||||
@@ -57,6 +57,14 @@ namespace IOB_UT_NEXT.Services.Machine
|
||||
set => _tcMan.pzCountPLC = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione allarme in caso di TC superiore a soglia
|
||||
/// </summary>
|
||||
public bool AlarmDelayTC
|
||||
{
|
||||
get => _tcMan.alarmDelayTC;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Legge un valore dalla memoria condivisa (MemMap) ricevuta dal PLC.
|
||||
/// </summary>
|
||||
|
||||
+18
-471
@@ -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
|
||||
/// <summary>
|
||||
/// Valore medio del TC rilevato x verifica derive sul delta variazione contapezzi
|
||||
/// </summary>
|
||||
public double plcAvgTc => tcMan.avgTC > 0 ? tcMan.avgTC : 1;
|
||||
|
||||
/// <summary>
|
||||
/// DataOra dell'ultima lettura variabile contapezzi da CNC
|
||||
/// </summary>
|
||||
public DateTime plcLastPzRead => tcMan.lastObservedData;
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Contapezzi attuale
|
||||
/// </summary>
|
||||
@@ -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
|
||||
|
||||
/// <summary>
|
||||
/// Variabile numero errori vari (in lettura) --> se supera soglia maxErroriCheck --> disconnette
|
||||
/// </summary>
|
||||
protected static int numErroriCheck = 0;
|
||||
|
||||
protected bool _connOk = false;
|
||||
|
||||
/// <summary>
|
||||
/// valore booleano di check se sia in fase di COMUNICAZIONE ATTIVA con il PLC/NC
|
||||
/// </summary>
|
||||
protected bool adpCommAct;
|
||||
|
||||
/// <summary>
|
||||
/// porta x adapter (x restart)
|
||||
/// </summary>
|
||||
protected int adpPortNum;
|
||||
|
||||
/// <summary>
|
||||
/// DataOra ultimo avvio adapter x watchdog
|
||||
/// </summary>
|
||||
protected DateTime adpStartRun;
|
||||
|
||||
/// <summary>
|
||||
/// Vettore 32 BIT valori in ingresso al filtro
|
||||
/// </summary>
|
||||
protected int B_input;
|
||||
|
||||
/// <summary>
|
||||
/// Vettore 32 BIT valori in uscita dal filtro
|
||||
/// </summary>
|
||||
protected int B_output;
|
||||
|
||||
/// <summary>
|
||||
/// Vettore 32 BIT valori precedenti
|
||||
/// </summary>
|
||||
protected int B_previous = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Cod grupo IOB x creazione PODL al volo
|
||||
/// </summary>
|
||||
protected string CodGruppoIob = "ND-00";
|
||||
|
||||
/// <summary>
|
||||
/// Num errori check alive
|
||||
/// </summary>
|
||||
protected int currAliveErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario valori impostati x produzione
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> currProdData = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// num corrente errori read PLC
|
||||
/// </summary>
|
||||
protected int currReadErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// num errori send
|
||||
/// </summary>
|
||||
protected int currSendErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Tempo di attesa in minuti x lettura contapezzi standard (da .ini / OptPar)
|
||||
/// </summary>
|
||||
protected double delayMinReadPzCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Fattore di demoltiplicazione dei DynData x ridurre campionamento
|
||||
/// </summary>
|
||||
protected int demFactDynData = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Boolean x indicare contapezzi disabilitato forzatamente da IOB
|
||||
/// </summary>
|
||||
protected bool disablePzCountByIob = false;
|
||||
|
||||
/// <summary>
|
||||
/// Veto x esecuzione task AutoDossier
|
||||
/// </summary>
|
||||
protected DateTime dtVetoAutoDossier = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Veto x esecuzione Task2Exe troppo frequenti
|
||||
/// </summary>
|
||||
protected DateTime dtVetoTask2Exe = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Veto x lettura contapezzi (in caso di autoODL con attesa reset ad esempio...)
|
||||
/// </summary>
|
||||
protected DateTime dtVetoReadPzCount = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Determina se sia prevista gestione PODL (creazione/avvio/chiusura) come Soitaab
|
||||
/// </summary>
|
||||
protected bool EnabelPodlManFull = false;
|
||||
|
||||
/// <summary>
|
||||
/// Abilita riscrittura memoria se trova differenze lettura/richiesti
|
||||
/// </summary>
|
||||
protected bool ENABLE_MEM_REWRITE = true;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione restart (da opt par...)
|
||||
/// </summary>
|
||||
protected bool enableCliRestart = false;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione invio dataitem
|
||||
/// </summary>
|
||||
protected bool enableSendDataItem = true;
|
||||
protected int minVetoSendDataItem = 60;
|
||||
/// <summary>
|
||||
/// DataOra x veto all'invio dataItem
|
||||
/// </summary>
|
||||
protected DateTime dtVetoSenDataItem = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Boolean x indicare contapezzi abilitato a livello di conf applicazione
|
||||
/// </summary>
|
||||
protected bool enablePzCountByApp = true;
|
||||
|
||||
/// <summary>
|
||||
/// Abilitazione gestione slow data
|
||||
/// </summary>
|
||||
protected bool enableSlowData = false;
|
||||
|
||||
/// <summary>
|
||||
/// dizionario (opzionale) xz decodifica file da importare
|
||||
/// </summary>
|
||||
protected Dictionary<string, int> FileDecod = new Dictionary<string, int>();
|
||||
|
||||
/// <summary>
|
||||
/// DeadBand x riduzione dati FluxLog (se 0 non gestita)
|
||||
/// </summary>
|
||||
protected double fluxLogRedDeadBand = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determina se sia gestita riduzione dati FluxLog
|
||||
/// </summary>
|
||||
protected bool fluxLogReduce = false;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei valori FluxLog ultimi verificati x veto
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> fluxLogReduceLast = new Dictionary<string, double>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> fluxLogReduceLastString = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei veto send x ogni variabile quando non variata
|
||||
/// </summary>
|
||||
protected Dictionary<string, DateTime> fluxLogReduceVeto = new Dictionary<string, DateTime>();
|
||||
|
||||
/// <summary>
|
||||
/// Finestra in minuti x invio dati FluxLog quando invariati
|
||||
/// </summary>
|
||||
protected int fluxLogResendPeriod = 60;
|
||||
|
||||
/// <summary>
|
||||
/// indica che è richiesto forzatamente reset contapezzi
|
||||
/// </summary>
|
||||
protected bool forcePzReset = false;
|
||||
|
||||
/// <summary>
|
||||
/// indica che è richiesto forzatamente reset contapezzi
|
||||
/// </summary>
|
||||
protected DateTime forcePzResetUntil = DateTime.Now.AddMinutes(-1);
|
||||
|
||||
/// <summary>
|
||||
/// DEADBAND globale se impostata (es x gestire variazioni minime valori FluxLog da inviare...)
|
||||
/// </summary>
|
||||
protected float GLOBAL_DBAND = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determina se siano gestite le ricette
|
||||
/// </summary>
|
||||
protected bool hasRecipe = false;
|
||||
|
||||
/// <summary>
|
||||
/// Array dei contatori x segnali blinking
|
||||
/// </summary>
|
||||
protected int[] i_counters;
|
||||
|
||||
/// <summary>
|
||||
/// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...)
|
||||
/// </summary>
|
||||
protected bool inSetup = false;
|
||||
|
||||
/// <summary>
|
||||
/// ultimo tentativo connessione...
|
||||
/// </summary>
|
||||
protected DateTime lastConnectTry;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ULTIMI valori impostati x produzione
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> lastProdData = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Ultimo invio contapezzi (x invio delayed)
|
||||
/// </summary>
|
||||
protected DateTime lastPzCountSend;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (string) delle TSS
|
||||
/// </summary>
|
||||
protected Dictionary<string, string> LastTSS = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (string) delle TSS
|
||||
/// </summary>
|
||||
protected Dictionary<string, DateTime> LastTSSSend = new Dictionary<string, DateTime>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario ultimi valori (double) delle TSVC
|
||||
/// </summary>
|
||||
protected Dictionary<string, double> LastTSVC = new Dictionary<string, double>();
|
||||
|
||||
/// <summary>
|
||||
/// Ultima registrazione warning x ODL mancante (x scrivere solo ogni 15 secondi)
|
||||
/// </summary>
|
||||
protected DateTime lastWarnODL;
|
||||
|
||||
/// <summary>
|
||||
/// ultima data-ora invio parametri write x ribadire status
|
||||
/// </summary>
|
||||
protected DateTime lastWriteParamsUpsert = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Separatore linea (tipicamente x commenti)
|
||||
/// </summary>
|
||||
protected string lineSep = "--------------------------";
|
||||
|
||||
/// <summary>
|
||||
/// Elenco parametri calcolati da inviare alla macchina (es ricetta con traduzione, RAMA/TFT)
|
||||
/// </summary>
|
||||
protected List<objItem> list2Write = new List<objItem>();
|
||||
|
||||
/// <summary>
|
||||
/// Elenco delle eventuali condizioni di veto conditions attive
|
||||
/// </summary>
|
||||
protected List<string> ListVetoCond = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Num massimo di errori in funzionalità check alive
|
||||
/// </summary>
|
||||
protected int maxAliveErrors = utils.CRI("maxAliveErrors");
|
||||
|
||||
/// <summary>
|
||||
/// Soglia massima errori prima della disconnessione automatica in check
|
||||
/// </summary>
|
||||
protected int maxErroriCheck = utils.CRI("maxErroriCheck");
|
||||
|
||||
/// <summary>
|
||||
/// Quantità massima per singola ricetta (per determinare num ricette da inviare)
|
||||
/// </summary>
|
||||
protected int maxQtyPerFile = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Num massimo di errori di rete read (dal PLC)
|
||||
/// </summary>
|
||||
protected int maxReadErrors = utils.CRI("maxReadErrors");
|
||||
|
||||
/// <summary>
|
||||
/// Periodo massimo (in sec) per letture dati in mancanza di eventi di aggiornamento
|
||||
/// </summary>
|
||||
protected int MaxSecReload = 120;
|
||||
|
||||
/// <summary>
|
||||
/// Num massimodi errori di rete send al server
|
||||
/// </summary>
|
||||
protected int maxSendErrors = utils.CRI("maxSendErrors");
|
||||
|
||||
/// <summary>
|
||||
/// Numero massimo di tentativi x test ping preliminare
|
||||
/// </summary>
|
||||
protected int maxTryPing = 1;
|
||||
|
||||
protected string mem2trace = "";
|
||||
|
||||
/// <summary>
|
||||
/// indica se serva refresh parametri e quindi PLC...
|
||||
/// </summary>
|
||||
protected bool needRefresh = true;
|
||||
|
||||
/// <summary>
|
||||
/// Indica se usare la parte numerica di un articolo come codice INT
|
||||
/// </summary>
|
||||
protected bool numArtCharTrim = false;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout x ping al server
|
||||
/// </summary>
|
||||
protected int pingServerMsTimeout = utils.CRI("PingMsTimeout");
|
||||
|
||||
/// <summary>
|
||||
/// DataOra avvio Programma x check avvio
|
||||
/// </summary>
|
||||
protected DateTime prgStarted = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Ritardo minimo x invio contapezzi
|
||||
/// </summary>
|
||||
protected int pzCountDelay = 2500;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo di campionamento x refresh info
|
||||
/// </summary>
|
||||
protected int samplePeriod = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// MsSample Period base x campionamenti tpo OCP-UA
|
||||
/// </summary>
|
||||
protected int samplePeriodBase = 600;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario di VC da trattare come TimeSeries (con conf decodificata + processing successivo...)
|
||||
/// </summary>
|
||||
protected Dictionary<string, VCData> TSVC_Data = new Dictionary<string, VCData>();
|
||||
|
||||
/// <summary>
|
||||
/// Indica se usare archivio locale ricette vs scarico http/REST
|
||||
/// </summary>
|
||||
protected bool useLocalRecipe = true;
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario di VARIABILI da trattare come eventi (da inviare quando cambiano oppure a
|
||||
/// scadenza periodo...)
|
||||
/// </summary>
|
||||
protected Dictionary<string, EVData> VarArray = new Dictionary<string, EVData>();
|
||||
|
||||
/// <summary>
|
||||
/// Dizionario dei divieti di invio x ogni counter gestito
|
||||
/// </summary>
|
||||
protected Dictionary<string, DateTime> VetoCounterSend = new Dictionary<string, DateTime>();
|
||||
|
||||
/// <summary>
|
||||
/// Durata in secondi del divieto accodamento segnali IN alla fase di startup
|
||||
/// </summary>
|
||||
protected int vetoQueueIn = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo di veto prima di invio nuova conferma dei valori write correnti, default ogni 5 min
|
||||
/// </summary>
|
||||
protected double vetoSendWriteUpsert = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Periodo wathdog di default (2 sec se non specificato)
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Decodifica file MAP (caso <paramref name="ByteNum" />.bit)
|
||||
/// </summary>
|
||||
/// <param name="linea"></param>
|
||||
/// <param name="separator"></param>
|
||||
/// <param name="ByteNum">indirizzo Byte: indirizzo di partenza memoria</param>
|
||||
/// <param name="memSize">dimensione singolo slot in byte</param>
|
||||
/// <param name="BitNum">indirizzo bit: numero riga x calcolo indice bit</param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decodifica file MAP generico
|
||||
/// </summary>
|
||||
/// <param name="linea"></param>
|
||||
/// <param name="separator"></param>
|
||||
/// <param name="memPre"></param>
|
||||
/// <param name="baseAddr"></param>
|
||||
/// <param name="memSize"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto logger della classe
|
||||
|
||||
+22
-28
@@ -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<string> alarmMessages = new List<string>();
|
||||
|
||||
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<List<AnagArticoli>>(rawListArt);
|
||||
okArt = listaArt.Count > 0;
|
||||
listaArt = JsonDeserialize<List<AnagArticoli>>(rawListArt);
|
||||
okArt = listaArt.Count > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -1776,8 +1770,8 @@ namespace IOB_WIN_FORM.Iob
|
||||
{
|
||||
try
|
||||
{
|
||||
listaDoss = JsonDeserialize<List<DossiersModel>>(rawListDOSS);
|
||||
okDoss = listaDoss.Count > 0;
|
||||
listaDoss = JsonDeserialize<List<DossiersModel>>(rawListDOSS);
|
||||
okDoss = listaDoss.Count > 0;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@@ -1792,8 +1786,8 @@ namespace IOB_WIN_FORM.Iob
|
||||
{
|
||||
try
|
||||
{
|
||||
listaPODL = JsonDeserialize<List<PODLModel>>(rawListPODL);
|
||||
okPodl = listaPODL.Count > 0;
|
||||
listaPODL = JsonDeserialize<List<PODLModel>>(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<DossierFluxLogDTO>(selDoss.Valore);
|
||||
DossierFluxLogDTO resultSet = JsonDeserialize<DossierFluxLogDTO>(selDoss.Valore);
|
||||
List<FluxLog> listFluxLog = resultSet.ODL;
|
||||
|
||||
// preparo elenco parametri da inviare...
|
||||
@@ -2167,7 +2161,7 @@ namespace IOB_WIN_FORM.Iob
|
||||
/// <param name="dataItems"></param>
|
||||
private void sendDataItemsList(List<machDataItem> dataItems)
|
||||
{
|
||||
string rawData = JsonSerialize(dataItems);
|
||||
string rawData = JsonSerialize(dataItems);
|
||||
HttpService.CallUrlPost($"{urlSaveDataItems}", rawData);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user