diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.ini b/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.ini index 713c3e39..abcc3af2 100644 --- a/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.ini +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.ini @@ -4,7 +4,7 @@ CNCTYPE=SOAP_GOMBA PING_MS_TIMEOUT=500 MinDeltaSec=5 -DIS_EXE_TASK=TRUE +DIS_EXE_TASK=FALSE DIS_STATE_CH=FALSE [MACHINE] @@ -55,10 +55,8 @@ BLINK_FILT=0 ;BLINK_FILT=28 [OPTPAR] -AUTO_CHANGE_ODL=false -CHANGE_ODL_MODE=TIME -CHANGE_ODL_HOURS=24 -CHANGE_ODL_IDLE_MIN=5 +AUTO_CHANGE_ODL=TRUE +CHANGE_ODL_MODE=DAILY PZCOUNT_MODE=GOMBA DISABLE_PZCOUNT=TRUE ENABLE_SEND_PZC_BLOCK=TRUE diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index d2353efd..3b777385 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -399,6 +399,8 @@ VersGen.cs + + diff --git a/IOB-WIN-NEXT/Iob/BaseObj.cs b/IOB-WIN-NEXT/Iob/BaseObj.cs new file mode 100644 index 00000000..84b92141 --- /dev/null +++ b/IOB-WIN-NEXT/Iob/BaseObj.cs @@ -0,0 +1,909 @@ +using IOB_UT_NEXT; +using NLog; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.NetworkInformation; +using System.Threading; + +namespace IOB_WIN_NEXT.Iob +{ + /// + /// Classe di base per IOB + /// + public class BaseObj + { + #region Public Fields + + /// + /// valore booleano di check se sia stato AVVIATO l'adapter (Running) + /// + public bool adpRunning = false; + + /// + /// valore booleano di check se l'adapter STIA SALVANDO + /// + public bool adpSaving = false; + + /// + /// valore booleano (richiesta di riavvio automatico) + /// + public bool adpTryRestart; + + /// + /// Struttura allarmi mappati + /// + public List alarmMaps = new List(); + + /// + /// Conf adapter corrente + /// + public IobConfiguration cIobConf; + + /// + /// Conteggio ATTUALE ore macchina IN LAVORO + /// + public double contOreMaccLav; + + /// + /// Conteggio ATTUALE ore macchina ON + /// + public double contOreMaccOn; + + /// + /// contatore x simulazione valori input + /// + public int countSim = 0; + + /// + /// ODL attualmente sulla macchina + /// + public Int32 currIdxODL = 0; + + /// + /// Modo corrente (da classe ENUM) + /// + public CNC_MODE currMode; + + /// + /// ODL corrente caricato sulla macchina (stringa, da chiamata MP/IO) + /// + public string currODL = ""; + + /// + /// Indica se sia richiesto campionamento memoria PERIODICO + /// + public bool doSampleMemory; + + /// + /// Indica se si debba leggere e fare DUMP delle aree di memoria (1 volta solo all'avvio x debug...) + /// + public bool doStartMemDump; + + /// + /// Data/ora ultimo avvio adapter + /// + public DateTime dtAvvioAdp = DateTime.Now; + + /// + /// Data/ora ultimo spegnimento adapter + /// + public DateTime dtStopAdp = DateTime.Now; + + /// + /// Indicazione VETO check status IOB x evitare loop troppo stretti... + /// + public DateTime dtVetoCheckIOB = DateTime.Now.AddDays(-1); + + /// + /// Indicazione VETO check sync ricette x evitare loop troppo stretti... + /// + public DateTime dtVetoCheckSyncRecipe = DateTime.Now.AddHours(-1); + + /// + /// Abilitazione lettura PrgName + /// + public bool enablePrgName = true; + + /// + /// Abilitazione invio pezzi "in blocco" per recupero contapezzi + /// + public bool enableSendPzCountBlock = false; + + /// + /// Determina se sia encessario convertire valori little/big endian (SIEMENS=true, OSAI=FALSE) + /// + public bool hasBigEndian = false; + + /// + /// dataOra ultima verifica CNC disconnesso... + /// + public DateTime lastDisconnCheck; + + /// + /// Data/ora ultima volta che IOB è stato dichiarato online + /// + public DateTime lastIobOnline = DateTime.Now.AddHours(-1); + + /// + /// dataOra ultimo log periodico... + /// + public DateTime lastPeriodicLog; + + /// + /// dataOra ultimo PING inviato verso il PLC... + /// + public DateTime lastPING = DateTime.Now.AddHours(-1); + + /// + /// DataOra ultima lettura da PLC + /// + public DateTime lastReadPLC; + + /// + /// ULtimo valore inviato (in caso di disconnessione lo reinvia x garantire watchdog...) + /// + public string lastSignInVal = ""; + + /// + /// DateTime Ultimo valore simulazione generato + /// + public DateTime lastSim; + + /// + /// dataOra ultimo segnale inviato al SERVER... + /// + public DateTime lastWatchDog; + + /// + /// dataOra ultimo segnale inviato a macchina/PLC... + /// + public DateTime lastWatchDogPLC = DateTime.Now; + + /// + /// Massimo numero di px da inviare in blocco + /// + public int maxSendPzCountBlock = 10; + + /// + /// Struttura memoria PLC x lettura/scrittura da JSON file + /// + public plcMemMapExt memMap; + + /// + /// Minimo numero di px da inviare in blocco + /// + public int minSendPzCountBlock = 5; + + /// + /// Variabile booleana che indica se sia necessario fare refresh del contapezzi + /// + public bool needRefreshPzCount = true; + + /// + /// Dizionario di persistenza per i valori da salvare da/su file + /// + public Dictionary persistenceLayer; + + /// + /// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing + /// "monoblocco" semplificato"= + /// + public bool procIotMem = false; + + /// + /// Coda valori ALLARMI ove gestiti... + /// + public DataQueue QueueAlarm = new DataQueue("000", "QueueAlarm", false); + + //public ConcurrentQueue QueueAlarm = new ConcurrentQueue(); + + /// + /// Oggetto della coda degli elementi letti di tipo FluxLog (e non ancora trasmessi) + /// + public DataQueue QueueFLog = new DataQueue("000", "QueueFLog", false); + + //public ConcurrentQueue QueueFLog = new ConcurrentQueue(); + + /// + /// Oggetto della coda degli elementi letti (e non ancora trasmessi) + /// + public DataQueue QueueIN = new DataQueue("000", "QueueIN", false); + + //public ConcurrentQueue QueueIN = new ConcurrentQueue(); + + /// + /// Coda valori MESSAGGI/EVENTI (da non sottocampionare come samples)... + /// + public DataQueue QueueMessages = new DataQueue("000", "QueueMessages", false); + + //public ConcurrentQueue QueueMessages = new ConcurrentQueue(); + + /// + /// 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 ConcurrentQueue QueueRawTransf = new ConcurrentQueue(); + + /// + /// Coda valori LOG UTENTE (da non sottocampionare come samples)... + /// + public DataQueue QueueULog = new DataQueue("000", "QueueULog", false); + + //public ConcurrentQueue QueueULog = new ConcurrentQueue(); + + /// + /// alias booleano false = R + /// + public bool R = false; + + /// + /// 32 byte input base (es strobe, 8 word da 32 bit di flags...) + /// + public byte[] RawInput = new byte[32]; + + /// + /// 32 byte output base (es ack, 8 word da 32 bit di flags...) + /// + public byte[] RawOutput = new byte[32]; + + /// + /// Oggetto connessione REDIS + /// + public RedisIobCache redisMan; + + /// + /// Oggetto cronometro x campionamento durate chiamate + /// + public Stopwatch stopwatch = 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) + /// + public DateTime vetoDataRead = DateTime.Now; + + /// + /// Imposta veto SYNC dati (es per DB 2 DB a 10 sec) + /// + public DateTime vetoDataSync = DateTime.Now; + + /// + /// Imposta veto chiamata split (durante chiamata, per 60 sec) + /// + public DateTime vetoSplit = DateTime.Now.AddMinutes(1); + + /// + /// alias booleano true = W + /// + public bool W = true; + + #endregion Public Fields + + #region Public Properties + + /// + /// Verifica se sia in modalità DEMO avanzata (campionamento da set di valori ammessi...) + /// + public static bool DemoInSample + { + get + { + return baseUtils.CRB("DemoInSample"); + } + } + + /// + /// Verifica se sia in modalità DEMO x dati OUTPUT + /// + public static bool DemoOut + { + get + { + return utils.CRB("DemoOut"); + } + } + + /// + /// Indicazione VETO PING a server sino alla data-ora indicata + /// + public static DateTime dtVetoPing + { + get + { + return utils.dtVetoPing; + } + set + { + utils.dtVetoPing = value; + } + } + + /// + /// Indicazione VETO accodamento valori INGRESSI/EVENTI sino alla data-ora indicata + /// + public static DateTime dtVetoQueueIN + { + get + { + return utils.dtVetoQueueIN; + } + set + { + utils.dtVetoQueueIN = value; + } + } + + /// + /// Indicazione VETO invio a server sino alla data-ora indicata + /// + public static DateTime dtVetoSend + { + get + { + return utils.dtVetoSend; + } + set + { + utils.dtVetoSend = value; + } + } + + /// + /// Verifica se sia abilitato test lettura blocchi memoria all'avvio + /// + public static bool EnableTest + { + get + { + return baseUtils.CRB("enableTest"); + } + } + + /// + /// stato Online/Offline del server MP IO (su REDIS) + /// + public static bool MPOnline + { + get + { + return utils.MPIO_Online; + } + set + { + utils.MPIO_Online = value; + } + } + + #endregion Public Properties + + #region Public Methods + + /// + /// Effettua chiamata URL e restituisce risultato + /// + /// + /// invio in modalità async (NON GARANTITO ordine...) + /// + public static string callUrl(string URL, bool doAsync) + { + string answ = ""; + // Chiamata ASINCRONA + if (doAsync) + { + //Task resp = utils.callUrlAsync(URL); + //answ = resp.Result; + answ = utils.callUrlAsync(URL); + if (urlRandWait > 0) + { + Random rnd = new Random(); + Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); + } + } + // chiamata SOLO NORMALE SINCRONA... + else + { + answ = utils.callUrl(URL); + if (urlRandWait > 0) + { + Random rnd = new Random(); + Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); + } + } + return answ; + } + + /// + /// Effettua chiamata URL e restituisce risultato + /// + /// + /// + /// invio in modalità async (NON GARANTITO ordine...) + /// + public static string callUrlWithPayload(string URL, string payload, bool doAsync) + { + string answ = ""; + // Chiamata ASINCRONA + if (doAsync) + { + answ = utils.callUrlAsync(URL, payload); + if (urlRandWait > 0) + { + Random rnd = new Random(); + Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); + } + } + // chiamata SOLO NORMALE SINCRONA... + else + { + answ = utils.callUrl(URL, payload); + if (urlRandWait > 0) + { + Random rnd = new Random(); + Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); + } + } + return answ; + } + + /// + /// processa dataLayer e se necessario salva/mostra + /// + public static void checkSavePersDataLayer() + { + } + + public static string GetMACAddress() + { + NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); + String sMacAddress = string.Empty; + foreach (NetworkInterface adapter in nics) + { + if (string.IsNullOrEmpty(sMacAddress))// only return MAC Address from first card + { + IPInterfaceProperties properties = adapter.GetIPProperties(); + //sMacAddress = adapter.GetPhysicalAddress().ToString(); + sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray()); + } + } + return sMacAddress; + } + + public static void resetDebugConsole() + { + } + + /// + /// Reset dei webclients + /// + public static void resetWebClients() + { + utils.resetWebClients(); + } + + #endregion Public Methods + + #region Protected Fields + + /// + /// wrapper di log + /// + protected static Logger lg; + + /// + /// Valore di attesa (random) dopo ogni invio x evitare congestione send... + /// + protected static int urlRandWait = 0; + + /// + /// Ultimo LOG registrazione avvio (x ridurre log notturni...) + /// + protected DateTime lastLogStartup = DateTime.Today.AddHours(-1); + + /// + /// Form chiamante + /// + protected AdapterForm parentForm; + + /// + /// Veto per registrazione completa log di startup (minuti) + /// + protected int vetoLogStartupDuration = 60; + + #endregion Protected Fields + + #region Protected Properties + + /// + /// Dizionario condizioni di veto log x ogni tipo di messaggio (periodo differente secondo livello) + /// + protected Dictionary VetoLog { get; set; } = new Dictionary(); + + /// + /// Dizionario conteggio numero volte che si fa veto log x ogni tipo di messaggio + /// + protected Dictionary VetoLogCount { get; set; } = new Dictionary(); + + #endregion Protected Properties + + #region Protected Methods + + /// + /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgDebug(string message, bool sendToForm = true) + { + bool doVeto = checkLogVeto(20, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Debug(message); + if (sendToForm) + { + sendToLogWatch("DEBUG", message); + } + } + } + + /// + /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgDebug(string message, params object[] args) + { + bool doVeto = checkLogVeto(20, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Debug(message, args); + sendToLogWatch("DEBUG", message, args); + } + } + + /// + /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgError(string message, bool sendToForm = true) + { + bool doVeto = checkLogVeto(2, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Error(message); + if (sendToForm) + { + sendToLogWatch("ERROR", message); + } + } + } + + /// + /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgError(string message, params object[] args) + { + bool doVeto = checkLogVeto(2, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Error(message, args); + sendToLogWatch("ERROR", message, args); + } + } + + /// + /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + /// + protected void lgError(Exception exception, string message, params object[] args) + { + bool doVeto = checkLogVeto(2, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Error(exception, message, args); + sendToLogWatch("ERROR", message, exception, args); + } + } + + /// + /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgFatal(string message, bool sendToForm = true) + { + bool doVeto = checkLogVeto(1, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Fatal(message); + if (sendToForm) + { + sendToLogWatch("FATAL", message); + } + } + } + + /// + /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgFatal(string message, params object[] args) + { + bool doVeto = checkLogVeto(1, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Fatal(message, args); + sendToLogWatch("FATAL", message, args); + } + } + + /// + /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + /// + protected void lgFatal(Exception exception, string message, params object[] args) + { + bool doVeto = checkLogVeto(1, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Fatal(exception, message, args); + sendToLogWatch("FATAL", message, exception, args); + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgInfo(string message, bool sendToForm = true) + { + bool doVeto = checkLogVeto(30, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Info(message); + if (sendToForm) + { + sendToLogWatch("INFO", message); + } + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgInfo(string message, params object[] args) + { + bool doVeto = checkLogVeto(30, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Info(message, args); + sendToLogWatch("INFO", message, args); + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgInfoStartup(string message, bool sendToForm = true) + { + bool doVeto = checkLogVeto(30, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + DateTime adesso = DateTime.Now; + if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration) + { + lg.Info(message); + // se supera di 5 minutis cadenza -_> reimposto veto... + if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration + 5) + { + lastLogStartup = adesso; + } + } + if (sendToForm) + { + sendToLogWatch("INFO", message); + } + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgInfoStartup(string message, params object[] args) + { + bool doVeto = checkLogVeto(30, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + DateTime adesso = DateTime.Now; + if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration) + { + lg.Info(message, args); + // se supera di 5 minutis cadenza -_> reimposto veto... + if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration + 5) + { + lastLogStartup = adesso; + } + } + sendToLogWatch("INFO", message, args); + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + protected void lgTrace(string message, bool sendToForm = true) + { + bool doVeto = checkLogVeto(60, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Trace(message); + if (sendToForm) + { + sendToLogWatch("TRACE", message); + } + } + } + + /// + /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... + /// + /// + /// + protected void lgTrace(string message, params object[] args) + { + bool doVeto = checkLogVeto(60, ref message); + // se non ho veto --> loggo + if (!doVeto) + { + lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; + lg.Trace(message, args); + sendToLogWatch("TRACE", message, args); + } + } + + /// + /// Invia messaggio a logWatcher + /// + /// + /// + protected void sendToLogWatch(string messType, string message) + { + newDisplayData currDispData = new newDisplayData(); + currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | {messType} | {message}"; + parentForm.updateFormDisplay(currDispData); + } + + /// + /// Invia messaggio a logWatcher + /// + /// + /// + /// + protected void sendToLogWatch(string messType, string message, params object[] args) + { + try + { + string expString = string.Format(message, args); + newDisplayData currDispData = new newDisplayData(); + currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | {messType} | {expString}"; + parentForm.updateFormDisplay(currDispData); + } + catch + { } + } + + /// + /// Invia messaggio a logWatcher + /// + /// + /// + /// + /// + protected void sendToLogWatch(string messType, string message, Exception exception, params object[] args) + { + try + { + string expString = string.Format(message, args); + newDisplayData currDispData = new newDisplayData(); + currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | {messType} | {expString}{Environment.NewLine}{exception}"; + parentForm.updateFormDisplay(currDispData); + } + catch + { } + } + + #endregion Protected Methods + + #region Private Methods + + /// + /// Verifica se ci sia veto log attivo e gestisce casistiche + /// + /// + /// + /// + private bool checkLogVeto(int vetoSec, ref string message) + { + //verifico SE si debba fare log, altrimenti metto in coda... + bool doVeto = true; + DateTime adesso = DateTime.Now; + if (VetoLog.ContainsKey(message)) + { + // conteggio num veto a +1... + if (VetoLogCount.ContainsKey(message)) + { + VetoLogCount[message]++; + } + else + { + VetoLogCount.Add(message, 1); + } + // controllo scadenza, quando superata soglia aggiorno messaggio con {n} x {messaggio} + if (adesso.Subtract(VetoLog[message]).TotalSeconds > vetoSec) + { + doVeto = false; + string newMessage = $"{VetoLogCount[message]} x {message}"; + VetoLog.Remove(message); + VetoLogCount.Remove(message); + message = newMessage; + } + } + else + { + // primo --> loggo + doVeto = false; + VetoLog.Add(message, adesso.AddSeconds(vetoSec)); + VetoLogCount.Add(message, 0); + } + // restituisco esito! + return doVeto; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/Iob/Generic.cs b/IOB-WIN-NEXT/Iob/Generic.cs index 2cc7498c..676862aa 100644 --- a/IOB-WIN-NEXT/Iob/Generic.cs +++ b/IOB-WIN-NEXT/Iob/Generic.cs @@ -7,9 +7,7 @@ using Newtonsoft.Json.Linq; using NLog; using System; using System.Collections; -using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -19,7 +17,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using System.Windows.Shell; using System.Xml.Serialization; using static IOB_UT_NEXT.CustomObj; using static IOB_UT_NEXT.DataModel.Fimat; @@ -27,274 +24,8 @@ using static MapoSDK.WharehouseData; namespace IOB_WIN_NEXT.Iob { - public class Generic + public class Generic : BaseObj { - #region Public Fields - - /// - /// valore booleano di check se sia stato AVVIATO l'adapter (Running) - /// - public bool adpRunning = false; - - /// - /// valore booleano di check se l'adapter STIA SALVANDO - /// - public bool adpSaving = false; - - /// - /// valore booleano (richiesta di riavvio automatico) - /// - public bool adpTryRestart; - - /// - /// Struttura allarmi mappati - /// - public List alarmMaps = new List(); - - /// - /// Conf adapter corrente - /// - public IobConfiguration cIobConf; - - /// - /// Conteggio ATTUALE ore macchina IN LAVORO - /// - public double contOreMaccLav; - - /// - /// Conteggio ATTUALE ore macchina ON - /// - public double contOreMaccOn; - - /// - /// contatore x simulazione valori input - /// - public int countSim = 0; - - /// - /// ODL attualmente sulla macchina - /// - public Int32 currIdxODL = 0; - - /// - /// Modo corrente (da classe ENUM) - /// - public CNC_MODE currMode; - - /// - /// ODL corrente caricato sulla macchina (stringa, da chiamata MP/IO) - /// - public string currODL = ""; - - /// - /// Indica se sia richiesto campionamento memoria PERIODICO - /// - public bool doSampleMemory; - - /// - /// Indica se si debba leggere e fare DUMP delle aree di memoria (1 volta solo all'avvio x debug...) - /// - public bool doStartMemDump; - - /// - /// Data/ora ultimo avvio adapter - /// - public DateTime dtAvvioAdp = DateTime.Now; - - /// - /// Data/ora ultimo spegnimento adapter - /// - public DateTime dtStopAdp = DateTime.Now; - - /// - /// Indicazione VETO check status IOB x evitare loop troppo stretti... - /// - public DateTime dtVetoCheckIOB = DateTime.Now.AddDays(-1); - /// - /// Indicazione VETO check sync ricette x evitare loop troppo stretti... - /// - public DateTime dtVetoCheckSyncRecipe = DateTime.Now.AddHours(-1); - - /// - /// Abilitazione lettura PrgName - /// - public bool enablePrgName = true; - - /// - /// Abilitazione invio pezzi "in blocco" per recupero contapezzi - /// - public bool enableSendPzCountBlock = false; - - /// - /// Determina se sia encessario convertire valori little/big endian (SIEMENS=true, OSAI=FALSE) - /// - public bool hasBigEndian = false; - - /// - /// dataOra ultima verifica CNC disconnesso... - /// - public DateTime lastDisconnCheck; - - /// - /// Data/ora ultima volta che IOB è stato dichiarato online - /// - public DateTime lastIobOnline = DateTime.Now.AddHours(-1); - - /// - /// dataOra ultimo log periodico... - /// - public DateTime lastPeriodicLog; - - /// - /// dataOra ultimo PING inviato verso il PLC... - /// - public DateTime lastPING = DateTime.Now.AddHours(-1); - - /// - /// DataOra ultima lettura da PLC - /// - public DateTime lastReadPLC; - - /// - /// ULtimo valore inviato (in caso di disconnessione lo reinvia x garantire watchdog...) - /// - public string lastSignInVal = ""; - - /// - /// DateTime Ultimo valore simulazione generato - /// - public DateTime lastSim; - - /// - /// dataOra ultimo segnale inviato al SERVER... - /// - public DateTime lastWatchDog; - - /// - /// dataOra ultimo segnale inviato a macchina/PLC... - /// - public DateTime lastWatchDogPLC = DateTime.Now; - - /// - /// Massimo numero di px da inviare in blocco - /// - public int maxSendPzCountBlock = 10; - - /// - /// Struttura memoria PLC x lettura/scrittura da JSON file - /// - public plcMemMapExt memMap; - - /// - /// Minimo numero di px da inviare in blocco - /// - public int minSendPzCountBlock = 5; - - /// - /// Variabile booleana che indica se sia necessario fare refresh del contapezzi - /// - public bool needRefreshPzCount = true; - - /// - /// Dizionario di persistenza per i valori da salvare da/su file - /// - public Dictionary persistenceLayer; - - /// - /// Determina se utilizzare blocchi di memoria IOT contigui (e quindi processing - /// "monoblocco" semplificato"= - /// - public bool procIotMem = false; - - /// - /// Coda valori ALLARMI ove gestiti... - /// - public DataQueue QueueAlarm = new DataQueue("000", "QueueAlarm", false); - //public ConcurrentQueue QueueAlarm = new ConcurrentQueue(); - - /// - /// Oggetto della coda degli elementi letti di tipo FluxLog (e non ancora trasmessi) - /// - public DataQueue QueueFLog = new DataQueue("000", "QueueFLog", false); - //public ConcurrentQueue QueueFLog = new ConcurrentQueue(); - - /// - /// Oggetto della coda degli elementi letti (e non ancora trasmessi) - /// - public DataQueue QueueIN = new DataQueue("000", "QueueIN", false); - //public ConcurrentQueue QueueIN = new ConcurrentQueue(); - - /// - /// Coda valori MESSAGGI/EVENTI (da non sottocampionare come samples)... - /// - public DataQueue QueueMessages = new DataQueue("000", "QueueMessages", false); - //public ConcurrentQueue QueueMessages = new ConcurrentQueue(); - - /// - /// 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 ConcurrentQueue QueueRawTransf = new ConcurrentQueue(); - - /// - /// Coda valori LOG UTENTE (da non sottocampionare come samples)... - /// - public DataQueue QueueULog = new DataQueue("000", "QueueULog", false); - //public ConcurrentQueue QueueULog = new ConcurrentQueue(); - - /// - /// alias booleano false = R - /// - public bool R = false; - - /// - /// 32 byte input base (es strobe, 8 word da 32 bit di flags...) - /// - public byte[] RawInput = new byte[32]; - - /// - /// 32 byte output base (es ack, 8 word da 32 bit di flags...) - /// - public byte[] RawOutput = new byte[32]; - - /// - /// Oggetto connessione REDIS - /// - public RedisIobCache redisMan; - - /// - /// Oggetto cronometro x campionamento durate chiamate - /// - public Stopwatch stopwatch = 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) - /// - public DateTime vetoDataRead = DateTime.Now; - - /// - /// Imposta veto SYNC dati (es per DB 2 DB a 10 sec) - /// - public DateTime vetoDataSync = DateTime.Now; - - /// - /// Imposta veto chiamata split (durante chiamata, per 60 sec) - /// - public DateTime vetoSplit = DateTime.Now.AddMinutes(1); - - /// - /// alias booleano true = W - /// - public bool W = true; - - #endregion Public Fields - #region Public Constructors /// @@ -329,6 +60,10 @@ namespace IOB_WIN_NEXT.Iob lgInfo("Avvio preliminare AdapterGeneric"); lastLogStartup = DateTime.Now; + // setup currProdData & last prod data + currProdData = redisMan.redGetHashDict(rKeyCurrProdData); + lastProdData = redisMan.redGetHashDict(rKeyCurrProdData); + // aggiungo altri defaults setDefaults(true); @@ -362,117 +97,6 @@ namespace IOB_WIN_NEXT.Iob #region Public Properties - /// - /// Verifica se sia in modalità DEMO avanzata (campionamento da set di valori ammessi...) - /// - public static bool DemoInSample - { - get - { - return baseUtils.CRB("DemoInSample"); - } - } - - /// - /// Verifica se sia in modalità DEMO x dati OUTPUT - /// - public static bool DemoOut - { - get - { - return utils.CRB("DemoOut"); - } - } - - /// - /// Indicazione VETO PING a server sino alla data-ora indicata - /// - public static DateTime dtVetoPing - { - get - { - return utils.dtVetoPing; - } - set - { - utils.dtVetoPing = value; - } - } - - /// - /// Indicazione VETO accodamento valori INGRESSI/EVENTI sino alla data-ora indicata - /// - public static DateTime dtVetoQueueIN - { - get - { - return utils.dtVetoQueueIN; - } - set - { - utils.dtVetoQueueIN = value; - } - } - - protected bool queueInEnabCurr - { - get => qInEnabCurr; - set - { - qInEnabCurr = value; - lgInfo($"SET queueInEnabCurr: {value} | {DateTime.Now:HHmmss}"); - } - } - private bool qInEnabCurr { get; set; } = false; - /// - /// Verifica veto coda QueueIN ed aggiorna abilitazione su variabile - /// - protected void checkVetoQueueIn() - { - queueInEnabCurr = dtVetoQueueIN < DateTime.Now; - } - - /// - /// Indicazione VETO invio a server sino alla data-ora indicata - /// - public static DateTime dtVetoSend - { - get - { - return utils.dtVetoSend; - } - set - { - utils.dtVetoSend = value; - } - } - - /// - /// Verifica se sia abilitato test lettura blocchi memoria all'avvio - /// - public static bool EnableTest - { - get - { - return baseUtils.CRB("enableTest"); - } - } - - /// - /// stato Online/Offline del server MP IO (su REDIS) - /// - public static bool MPOnline - { - get - { - return utils.MPIO_Online; - } - set - { - utils.MPIO_Online = value; - } - } - /// /// Verifica se il server sia ALIVE (tramite PING) /// @@ -1496,108 +1120,6 @@ namespace IOB_WIN_NEXT.Iob #region Public Methods - /// - /// Effettua chiamata URL e restituisce risultato - /// - /// - /// invio in modalità async (NON GARANTITO ordine...) - /// - public static string callUrl(string URL, bool doAsync) - { - string answ = ""; - // Chiamata ASINCRONA - if (doAsync) - { - //Task resp = utils.callUrlAsync(URL); - //answ = resp.Result; - answ = utils.callUrlAsync(URL); - if (urlRandWait > 0) - { - Random rnd = new Random(); - Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); - } - } - // chiamata SOLO NORMALE SINCRONA... - else - { - answ = utils.callUrl(URL); - if (urlRandWait > 0) - { - Random rnd = new Random(); - Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); - } - } - return answ; - } - - /// - /// Effettua chiamata URL e restituisce risultato - /// - /// - /// - /// invio in modalità async (NON GARANTITO ordine...) - /// - public static string callUrlWithPayload(string URL, string payload, bool doAsync) - { - string answ = ""; - // Chiamata ASINCRONA - if (doAsync) - { - answ = utils.callUrlAsync(URL, payload); - if (urlRandWait > 0) - { - Random rnd = new Random(); - Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); - } - } - // chiamata SOLO NORMALE SINCRONA... - else - { - answ = utils.callUrl(URL, payload); - if (urlRandWait > 0) - { - Random rnd = new Random(); - Thread.Sleep(rnd.Next(urlRandWait / 10, urlRandWait)); - } - } - return answ; - } - - /// - /// processa dataLayer e se necessario salva/mostra - /// - public static void checkSavePersDataLayer() - { - } - - public static string GetMACAddress() - { - NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); - String sMacAddress = string.Empty; - foreach (NetworkInterface adapter in nics) - { - if (string.IsNullOrEmpty(sMacAddress))// only return MAC Address from first card - { - IPInterfaceProperties properties = adapter.GetIPProperties(); - //sMacAddress = adapter.GetPhysicalAddress().ToString(); - sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray()); - } - } - return sMacAddress; - } - - public static void resetDebugConsole() - { - } - - /// - /// Reset dei webclients - /// - public static void resetWebClients() - { - utils.resetWebClients(); - } - /// /// Accumula in coda i valori ALARM e logga... /// @@ -2148,8 +1670,6 @@ namespace IOB_WIN_NEXT.Iob return valTransl; } - - /// /// effettua recupero dati ed invio valori modificati... /// @@ -3545,15 +3065,7 @@ namespace IOB_WIN_NEXT.Iob /// public void saveProdData(KeyValuePair item) { - // imposto i valori... - if (currProdData.ContainsKey(item.Key)) - { - currProdData[item.Key] = item.Value; - } - else - { - currProdData.Add(item.Key, item.Value); - } + upsertKey(item.Key, item.Value); } /// @@ -4194,6 +3706,8 @@ namespace IOB_WIN_NEXT.Iob { currProdData.Add(chiave, valore); } + // salvo in redis... + redisMan.redSaveHashDict(rKeyCurrProdData, currProdData); } /// @@ -4312,16 +3826,6 @@ namespace IOB_WIN_NEXT.Iob #region Protected Fields - /// - /// wrapper di log - /// - protected static Logger lg; - - /// - /// Valore di attesa (random) dopo ogni invio x evitare congestione send... - /// - protected static int urlRandWait = 0; - protected bool _connOk = false; /// @@ -4419,11 +3923,6 @@ namespace IOB_WIN_NEXT.Iob /// protected int[] i_counters; - /// - /// Durata in secondi del divieto accodamento segnali IN alla fase di startup - /// - protected int vetoQueueIn = 1; - /// /// Indica impianto IN SETUP (fino a quando SMETTE di esserlo...) /// @@ -4434,11 +3933,6 @@ namespace IOB_WIN_NEXT.Iob /// protected DateTime lastConnectTry; - /// - /// Ultimo LOG registrazione avvio (x ridurre log notturni...) - /// - protected DateTime lastLogStartup = DateTime.Today.AddHours(-1); - /// /// Dizionario ULTIMI valori impostati x produzione /// @@ -4509,11 +4003,6 @@ namespace IOB_WIN_NEXT.Iob /// protected int numErroriCheck = 0; - /// - /// Form chiamante - /// - protected AdapterForm parentForm; - /// /// Timeout x ping al server /// @@ -4541,9 +4030,9 @@ namespace IOB_WIN_NEXT.Iob protected Dictionary VarArray = new Dictionary(); /// - /// Veto per registrazione completa log di startup (minuti) + /// Durata in secondi del divieto accodamento segnali IN alla fase di startup /// - protected int vetoLogStartupDuration = 60; + protected int vetoQueueIn = 1; /// /// Periodo wathdog di default (2 sec se non specificato) @@ -4647,7 +4136,7 @@ namespace IOB_WIN_NEXT.Iob protected int maxPingRetry { get; set; } = 5; /// - /// Coda massima ammessa per FLog (se <=0 disattivata...) + /// Coda massima ammessa per FLog (se <=0 disattivata...) /// protected int maxQueueFLog { get; set; } = utils.CRI("maxQueueFLog"); @@ -4778,6 +4267,16 @@ namespace IOB_WIN_NEXT.Iob } } + protected bool queueInEnabCurr + { + get => qInEnabCurr; + set + { + qInEnabCurr = value; + lgInfo($"SET queueInEnabCurr: {value} | {DateTime.Now:HHmmss}"); + } + } + /// /// Definizioni x replace in file ricette /// @@ -4834,16 +4333,6 @@ namespace IOB_WIN_NEXT.Iob } } - /// - /// Dizionario condizioni di veto log x ogni tipo di messaggio (periodo differente secondo livello) - /// - protected Dictionary VetoLog { get; set; } = new Dictionary(); - - /// - /// Dizionario conteggio numero volte che si fa veto log x ogni tipo di messaggio - /// - protected Dictionary VetoLogCount { get; set; } = new Dictionary(); - /// /// Secondi standard x veto check status e log /// @@ -4853,6 +4342,22 @@ namespace IOB_WIN_NEXT.Iob #region Protected Methods + /// + /// Recupera valore da dizionario CurrProdData o restituisce val default + /// + /// Chiave richiesta + /// Valore di default + /// + protected string getCurrProdData(string key, string defVal) + { + string answ = ""; + if (currProdData.ContainsKey(key)) + { + answ = string.IsNullOrEmpty(currProdData[key]) ? defVal : currProdData[key]; + } + return answ; + } + /// /// Decodifica file MAP (caso .bit) /// @@ -4956,6 +4461,14 @@ namespace IOB_WIN_NEXT.Iob { } } + /// + /// Verifica veto coda QueueIN ed aggiorna abilitazione su variabile + /// + protected void checkVetoQueueIn() + { + queueInEnabCurr = dtVetoQueueIN < DateTime.Now; + } + /// /// Restituisce stato allarmi in formato byte[] /// @@ -5415,277 +4928,6 @@ namespace IOB_WIN_NEXT.Iob return answ; } - /// - /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - protected void lgDebug(string message, bool sendToForm = true) - { - bool doVeto = checkLogVeto(20, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Debug(message); - if (sendToForm) - { - sendToLogWatch("DEBUG", message); - } - } - } - - /// - /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgDebug(string message, params object[] args) - { - bool doVeto = checkLogVeto(20, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Debug(message, args); - sendToLogWatch("DEBUG", message, args); - } - } - - /// - /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - protected void lgError(string message, bool sendToForm = true) - { - bool doVeto = checkLogVeto(2, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Error(message); - if (sendToForm) - { - sendToLogWatch("ERROR", message); - } - } - } - - /// - /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgError(string message, params object[] args) - { - bool doVeto = checkLogVeto(2, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Error(message, args); - sendToLogWatch("ERROR", message, args); - } - } - - /// - /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - /// - protected void lgError(Exception exception, string message, params object[] args) - { - bool doVeto = checkLogVeto(2, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Error(exception, message, args); - sendToLogWatch("ERROR", message, exception, args); - } - } - - /// - /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - protected void lgFatal(string message, bool sendToForm = true) - { - bool doVeto = checkLogVeto(1, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Fatal(message); - if (sendToForm) - { - sendToLogWatch("FATAL", message); - } - } - } - - /// - /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgFatal(string message, params object[] args) - { - bool doVeto = checkLogVeto(1, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Fatal(message, args); - sendToLogWatch("FATAL", message, args); - } - } - - /// - /// Effettua logging FATAL corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - /// - protected void lgFatal(Exception exception, string message, params object[] args) - { - bool doVeto = checkLogVeto(1, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Fatal(exception, message, args); - sendToLogWatch("FATAL", message, exception, args); - } - } - - /// - /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - protected void lgInfo(string message, bool sendToForm = true) - { - bool doVeto = checkLogVeto(30, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Info(message); - if (sendToForm) - { - sendToLogWatch("INFO", message); - } - } - } - - /// - /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgInfo(string message, params object[] args) - { - bool doVeto = checkLogVeto(30, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Info(message, args); - sendToLogWatch("INFO", message, args); - } - } - - /// - /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgInfoStartup(string message, bool sendToForm = true) - { - bool doVeto = checkLogVeto(30, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - DateTime adesso = DateTime.Now; - if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration) - { - lg.Info(message); - // se supera di 5 minutis cadenza -_> reimposto veto... - if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration + 5) - { - lastLogStartup = adesso; - } - } - if (sendToForm) - { - sendToLogWatch("INFO", message); - } - } - } - - /// - /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgInfoStartup(string message, params object[] args) - { - bool doVeto = checkLogVeto(30, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - DateTime adesso = DateTime.Now; - if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration) - { - lg.Info(message, args); - // se supera di 5 minutis cadenza -_> reimposto veto... - if (adesso.Subtract(lastLogStartup).TotalMinutes > vetoLogStartupDuration + 5) - { - lastLogStartup = adesso; - } - } - sendToLogWatch("INFO", message, args); - } - } - - /// - /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - protected void lgTrace(string message, bool sendToForm = true) - { - bool doVeto = checkLogVeto(60, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Trace(message); - if (sendToForm) - { - sendToLogWatch("TRACE", message); - } - } - } - - /// - /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... - /// - /// - /// - protected void lgTrace(string message, params object[] args) - { - bool doVeto = checkLogVeto(60, ref message); - // se non ho veto --> loggo - if (!doVeto) - { - lg.Factory.Configuration.Variables["codIOB"] = cIobConf.codIOB; - lg.Trace(message, args); - sendToLogWatch("TRACE", message, args); - } - } - /// /// Legge il file di conf di una MAP di informazioni da gestire con lettura set memoria /// @@ -6006,11 +5248,6 @@ namespace IOB_WIN_NEXT.Iob return answ; } - /// - /// Cerca di recuperare i file generati dall'impianto in merito al processing degli ordini - /// - /// - /// /// Processa le richieste di scrittura memoria /// @@ -6042,7 +5279,7 @@ namespace IOB_WIN_NEXT.Iob // sistemo valori item.value = item.reqValue; lgInfo($"Richiesta update parametro {item.uid} | actVal = {item.value} | reqVal = {item.reqValue}"); - item.reqValue = ""; + //item.reqValue = ""; // salvo in lista da ritrasmettere updatedPar.Add(item); } @@ -6071,6 +5308,10 @@ namespace IOB_WIN_NEXT.Iob return answ; } + /// + /// Cerca di recuperare i file generati dall'impianto in merito al processing degli ordini + /// + /// /// /// Processing di dati "OtherInfo" da implementare caso x caso (qui riportato caso FIMAT ricette...) /// @@ -6133,6 +5374,28 @@ namespace IOB_WIN_NEXT.Iob return answ; } + protected virtual bool processRecipeFileRet() + { + bool answ = false; + // test file import da conf... se hasRecipe=true --> modalità Tenditalia/FIMAT... + if (hasRecipe) + { + // recupera i NUOVI file e li sposta in folder locale temp + string remoPath = Path.Combine(pathList["path-locBase"], pathList["path-05-remExe"]); + string archBasePath = Path.Combine(pathList["path-locBase"], pathList["path-03-Recv"]); + string tempPath = Path.Combine(archBasePath, "TEMP"); + baseUtils.checkDir(tempPath); + bool okRetrieve = RecipeTaskDoneRetrieve(remoPath, tempPath); + + // ora cerca nella folder locale e processa i files... + bool okCheck = RecipeDoCheckFileProc(tempPath, archBasePath); + + // verifica se sia da creare/inviare il record settimanale di consumo (dopo la mezzanotte del lunedì inizio settimana) + bool okSent = RecipeDoProcCons(); + } + return answ; + } + /// /// Sync archivio ricette (Macchina <--> MES) /// @@ -6156,28 +5419,6 @@ namespace IOB_WIN_NEXT.Iob return answ; } - protected virtual bool processRecipeFileRet() - { - bool answ = false; - // test file import da conf... se hasRecipe=true --> modalità Tenditalia/FIMAT... - if (hasRecipe) - { - // recupera i NUOVI file e li sposta in folder locale temp - string remoPath = Path.Combine(pathList["path-locBase"], pathList["path-05-remExe"]); - string archBasePath = Path.Combine(pathList["path-locBase"], pathList["path-03-Recv"]); - string tempPath = Path.Combine(archBasePath, "TEMP"); - baseUtils.checkDir(tempPath); - bool okRetrieve = RecipeTaskDoneRetrieve(remoPath, tempPath); - - // ora cerca nella folder locale e processa i files... - bool okCheck = RecipeDoCheckFileProc(tempPath, archBasePath); - - // verifica se sia da creare/inviare il record settimanale di consumo (dopo la mezzanotte del lunedì inizio settimana) - bool okSent = RecipeDoProcCons(); - } - return answ; - } - protected void raiseRefresh(newDisplayData currDispData) { if (currDispData != null) @@ -6306,7 +5547,7 @@ namespace IOB_WIN_NEXT.Iob var okHashDict = redisMan.redSaveHashDict(fullKey, redHashWeek); #if false // manda a MP-IO update delle settimane processate (+ azioni) - Dictionary currStats = redisMan.redGetHashDict(fullKey); + Dictionary currStats = redisMan.redGetHashDict(fullKey); #endif // invio ANCHE in MP-IO l'update delle info... string remUrl = urlSetHashDict; @@ -6725,57 +5966,6 @@ namespace IOB_WIN_NEXT.Iob sendOptVal(paramName, paramValueInt.ToString()); } - /// - /// Invia messaggio a logWatcher - /// - /// - /// - protected void sendToLogWatch(string messType, string message) - { - newDisplayData currDispData = new newDisplayData(); - currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | {messType} | {message}"; - parentForm.updateFormDisplay(currDispData); - } - - /// - /// Invia messaggio a logWatcher - /// - /// - /// - /// - protected void sendToLogWatch(string messType, string message, params object[] args) - { - try - { - string expString = string.Format(message, args); - newDisplayData currDispData = new newDisplayData(); - currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | {messType} | {expString}"; - parentForm.updateFormDisplay(currDispData); - } - catch - { } - } - - /// - /// Invia messaggio a logWatcher - /// - /// - /// - /// - /// - protected void sendToLogWatch(string messType, string message, Exception exception, params object[] args) - { - try - { - string expString = string.Format(message, args); - newDisplayData currDispData = new newDisplayData(); - currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | {messType} | {expString}{Environment.NewLine}{exception}"; - parentForm.updateFormDisplay(currDispData); - } - catch - { } - } - /// /// Invia messaggio a logWatcher /// @@ -7124,6 +6314,7 @@ namespace IOB_WIN_NEXT.Iob lgInfo($"Eseguito tryClosePODL per {idxPODL} | url: {fullUrl} | esito: {fatto}"); return fatto; } + /// /// Effettua chiamata MP-IO per tentare chiusura PODL --> ODL specifico /// @@ -7252,6 +6443,7 @@ namespace IOB_WIN_NEXT.Iob { } return fatto; } + /// /// Effettua chiamata MP-IO per tentare setup del PODL indicato con indicazioni estese (confirm pezzi, dtEvento, dtCorrente) /// @@ -7389,6 +6581,16 @@ namespace IOB_WIN_NEXT.Iob } } + private bool qInEnabCurr { get; set; } = false; + + /// + /// Redis key del dizionari valori currProdData persistiti + /// + private string rKeyCurrProdData + { + get => redisMan.redHash($"IOB:Status:{cIobConf.codIOB}:CurrProdData"); + } + /// /// test ping all'indirizzo impostato nei parametri /// @@ -7554,49 +6756,6 @@ namespace IOB_WIN_NEXT.Iob } } - /// - /// Verifica se ci sia veto log attivo e gestisce casistiche - /// - /// - /// - /// - private bool checkLogVeto(int vetoSec, ref string message) - { - //verifico SE si debba fare log, altrimenti metto in coda... - bool doVeto = true; - DateTime adesso = DateTime.Now; - if (VetoLog.ContainsKey(message)) - { - // conteggio num veto a +1... - if (VetoLogCount.ContainsKey(message)) - { - VetoLogCount[message]++; - } - else - { - VetoLogCount.Add(message, 1); - } - // controllo scadenza, quando superata soglia aggiorno messaggio con {n} x {messaggio} - if (adesso.Subtract(VetoLog[message]).TotalSeconds > vetoSec) - { - doVeto = false; - string newMessage = $"{VetoLogCount[message]} x {message}"; - VetoLog.Remove(message); - VetoLogCount.Remove(message); - message = newMessage; - } - } - else - { - // primo --> loggo - doVeto = false; - VetoLog.Add(message, adesso.AddSeconds(vetoSec)); - VetoLogCount.Add(message, 0); - } - // restituisco esito! - return doVeto; - } - /// /// Verifica e se necessario comprime directory log... /// @@ -8085,6 +7244,7 @@ namespace IOB_WIN_NEXT.Iob case "fixwidth": fatto = DataExport.SaveFixedWidth(ListConsSum, $"{reportPath}.txt", currConf.fieldLength, currConf.fieldLPad, currConf.fieldNDec); break; + case "csv": default: fatto = DataExport.SaveToCsv(ListConsSum, $"{reportPath}.csv", addHeader); @@ -8220,7 +7380,7 @@ namespace IOB_WIN_NEXT.Iob lastPeriodicLog = DateTime.Now; // fix parametri generali... enablePrgName = true; - // valore standard divieto accodamento segnali IN + // valore standard divieto accodamento segnali IN string VETO_QUEUE_IN = getOptPar("VETO_QUEUE_IN"); if (!string.IsNullOrEmpty(VETO_QUEUE_IN)) { @@ -8571,44 +7731,4 @@ namespace IOB_WIN_NEXT.Iob #endregion Private Methods } - - /// - /// Evento per incapsulare dati x refresh pagina - /// - public class iobRefreshedEventArgs : EventArgs - { - #region Public Constructors - - /// - /// salvataggio obj - /// - /// - public iobRefreshedEventArgs(newDisplayData newObject) - { - _newDisplayData = newObject; - } - - #endregion Public Constructors - - #region Public Properties - - /// - /// Proprietà lettura displayData aggiornato - /// - public newDisplayData DisplayDataObject - { - get { return _newDisplayData; } - } - - #endregion Public Properties - - #region Private Fields - - /// - /// classe obj privata - /// - private readonly newDisplayData _newDisplayData; - - #endregion Private Fields - } } \ No newline at end of file diff --git a/IOB-WIN-NEXT/Iob/iobRefreshedEventArgs.cs b/IOB-WIN-NEXT/Iob/iobRefreshedEventArgs.cs new file mode 100644 index 00000000..b9fa89eb --- /dev/null +++ b/IOB-WIN-NEXT/Iob/iobRefreshedEventArgs.cs @@ -0,0 +1,45 @@ +using IOB_UT_NEXT; +using System; + +namespace IOB_WIN_NEXT.Iob +{ + /// + /// Evento per incapsulare dati x refresh pagina + /// + public class iobRefreshedEventArgs : EventArgs + { + #region Public Constructors + + /// + /// salvataggio obj + /// + /// + public iobRefreshedEventArgs(newDisplayData newObject) + { + _newDisplayData = newObject; + } + + #endregion Public Constructors + + #region Public Properties + + /// + /// Proprietà lettura displayData aggiornato + /// + public newDisplayData DisplayDataObject + { + get { return _newDisplayData; } + } + + #endregion Public Properties + + #region Private Fields + + /// + /// classe obj privata + /// + private readonly newDisplayData _newDisplayData; + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobSoap/Gomba.cs b/IOB-WIN-NEXT/IobSoap/Gomba.cs index 6acc9109..00b0146c 100644 --- a/IOB-WIN-NEXT/IobSoap/Gomba.cs +++ b/IOB-WIN-NEXT/IobSoap/Gomba.cs @@ -1,5 +1,4 @@ - -using EgwProxy.Gomba.GombaServ; +using EgwProxy.Gomba.GombaServ; using IOB_UT_NEXT; using MapoSDK; using Newtonsoft.Json; @@ -8,12 +7,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.NetworkInformation; -using static IOB_UT_NEXT.CustomObj; namespace IOB_WIN_NEXT.IobSoap { /// - /// Adapter specializzato per ICOEL e le chiamate tramite WS Soap al Sizer, con libreria EgwProxy.Icoel + /// Adapter specializzato per GOMA e le chiamate tramite WS Soap alla bilancia, libreria EgwProxy.Gomba /// public class Gomba : Iob.Generic { @@ -31,84 +29,8 @@ namespace IOB_WIN_NEXT.IobSoap lastPING = DateTime.Now.AddHours(-1); } - /// - /// Proxy per connessione al SOAP webservice GOMBA - /// - protected EgwProxy.Gomba.GombaServ.lwpServiceClient gombaConn; - - /// - /// Data inizio periodo dati Bilancia: - /// - al boot impostato a -6 mesi - /// - dopo lettura impostato a data ultimi 5 record - /// - private string dataFrom - { - get => dtStartLive.ToString("dd/MM/yyyy"); - } - - private DateTime dtStartLive { get; set; } = DateTime.Today.AddMonths(-6); - - /// - /// Data fine periodo dati Bilancia: oggi + 1gg - /// - private string dataTo - { - get => DateTime.Today.AddDays(1).ToString("dd/MM/yyyy"); - } - /// - /// Elenco pesate attuali - /// - private List listPesateCurr { get; set; } = new List(); - - private string redKeyPesate { get; set; } = ""; - - /// - /// Elenco lettura pesate precedenti - /// - private List listPesatePrev { get; set; } = new List(); - - /// - /// Gestione archivio serializzato delle pesate già processate - /// - private List listPesateArch - { - get - { - List answ = new List(); - string rawData = redisMan.getRSV(redKeyPesate); - if (!string.IsNullOrEmpty(rawData)) - { - try - { - answ = JsonConvert.DeserializeObject>(rawData); - lgInfo($"Rilettura status listPesateArch: trovati {answ.Count} record"); - } - catch (Exception exc) - { - lgError($"Errore in deserializzazione listPesateArch{Environment.NewLine}{exc}"); - answ = new List(); - } - } - return answ; - } - set - { - string rawVal = JsonConvert.SerializeObject(value); - redisMan.setRSV(redKeyPesate, rawVal); - lgInfo($"Salvataggio status listPesateArch | {value.Count} record"); - } - } - - #endregion Public Constructors - - public enum gombaTaskType - { - reqIN, - reqOUT, - } - #region Public Methods /// @@ -182,7 +104,6 @@ namespace IOB_WIN_NEXT.IobSoap { lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!"); } - } return taskDone; @@ -256,38 +177,6 @@ namespace IOB_WIN_NEXT.IobSoap lastReadPLC = DateTime.Now; return outVal; } - /// - /// Formatta record completo pesata - /// - /// record completo pesate Gomba - /// Indica se deve formattare i dati tipo IN (true) o OUT (false) - /// - private static string formatPesata(gestWeightOut rec, bool isIN) - { - string currVal = ""; - if (isIN) - { - currVal = $"{rec.dateIn:yyyy-MM-dd HH:mm:ss} | {rec.weightIn} kg"; - } - else - { - currVal = $"{rec.dateOut:yyyy-MM-dd HH:mm:ss} | {rec.weightOut} kg"; - } - currVal += formatCode(rec.cod1); - currVal += formatCode(rec.cod2); - currVal += formatCode(rec.cod3); - currVal += formatCode(rec.cod4); - currVal += formatCode(rec.cod5); - currVal += formatCode(rec.cod6); - return currVal; - } - - private static string formatCode(string currCode) - { - string code = string.IsNullOrEmpty(currCode) ? "-" : currCode; - return $" | {code}"; - } - /// /// Effettua lettura semafori principale Parametri da @@ -429,11 +318,14 @@ namespace IOB_WIN_NEXT.IobSoap #endregion Public Methods - #region Protected Properties + #region Protected Fields + /// + /// Proxy per connessione al SOAP webservice GOMBA + /// + protected EgwProxy.Gomba.GombaServ.lwpServiceClient gombaConn; - - #endregion Protected Properties + #endregion Protected Fields #region Protected Methods @@ -446,7 +338,7 @@ namespace IOB_WIN_NEXT.IobSoap foreach (var item in updatedPar) { // salvo i valori di setup x prox pesata... - upsertKey(item.uid, item.reqValue); + upsertKey(item.uid, item.value); bool fatto = false; // se è richiesta pesata IN/OUT --> mando chiamata if (item.uid == "reqIN") @@ -457,6 +349,11 @@ namespace IOB_WIN_NEXT.IobSoap { fatto = reqWeight(false); } + else if (item.uid == "RM" || item.uid.StartsWith("Cod")) + { + // comunque segno fatto x altri casi + fatto = true; + } // se fatto --> aggiorno! if (fatto) { @@ -467,6 +364,7 @@ namespace IOB_WIN_NEXT.IobSoap } } } + /// /// Esegue richiesta PESO /// @@ -481,16 +379,20 @@ namespace IOB_WIN_NEXT.IobSoap sw.Start(); // preparo parametri string tipoRic = reqIN ? "IN" : "OUT"; - string rm = string.IsNullOrEmpty(currProdData["RM"]) ? $"{DateTime.Now:yyyyMMdd-HHmmss}" : currProdData["RM"]; - string Cod1 = string.IsNullOrEmpty(currProdData["Cod1"]) ? "" : currProdData["Cod1"]; - string Cod2 = string.IsNullOrEmpty(currProdData["Cod2"]) ? "" : currProdData["Cod2"]; - string Cod3 = string.IsNullOrEmpty(currProdData["Cod3"]) ? "" : currProdData["Cod3"]; - string Cod4 = string.IsNullOrEmpty(currProdData["Cod4"]) ? "" : currProdData["Cod4"]; - string Cod5 = string.IsNullOrEmpty(currProdData["Cod5"]) ? "" : currProdData["Cod5"]; - string Cod6 = string.IsNullOrEmpty(currProdData["Cod6"]) ? "" : currProdData["Cod6"]; + string rm = getCurrProdData("RM", $"{DateTime.Now:yyyyMMdd-HHmmss}");// string.IsNullOrEmpty(currProdData["RM"]) ? $"{DateTime.Now:yyyyMMdd-HHmmss}" : currProdData["RM"]; + string Cod1 = getCurrProdData("Cod1", ""); //string.IsNullOrEmpty(currProdData["Cod1"]) ? "" : currProdData["Cod1"]; + string Cod2 = getCurrProdData("Cod2", ""); //string.IsNullOrEmpty(currProdData["Cod2"]) ? "" : currProdData["Cod2"]; + string Cod3 = getCurrProdData("Cod3", ""); //string.IsNullOrEmpty(currProdData["Cod3"]) ? "" : currProdData["Cod3"]; + string Cod4 = getCurrProdData("Cod4", ""); //string.IsNullOrEmpty(currProdData["Cod4"]) ? "" : currProdData["Cod4"]; + string Cod5 = getCurrProdData("Cod5", ""); //string.IsNullOrEmpty(currProdData["Cod5"]) ? "" : currProdData["Cod5"]; + string Cod6 = getCurrProdData("Cod6", ""); //string.IsNullOrEmpty(currProdData["Cod6"]) ? "" : currProdData["Cod6"]; // faccio chiamata var answ = gombaConn.memWeight(tipoRic, rm, Cod1, Cod2, Cod3, Cod4, Cod5, Cod6); fatto = answ.feedback == "C"; + if(!fatto) + { + lgError($"reqWeight | Errore in richiesta peso GOMBA | {answ.feedback} | {answ.notes}"); + } sw.Stop(); lgInfo($"SOAP: effettuata chiamata reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}"); } @@ -503,8 +405,107 @@ namespace IOB_WIN_NEXT.IobSoap #endregion Protected Methods + #region Private Properties + + /// + /// Data inizio periodo dati Bilancia: + /// - al boot impostato a -6 mesi + /// - dopo lettura impostato a data ultimi 5 record + /// + private string dataFrom + { + get => dtStartLive.ToString("dd/MM/yyyy"); + } + + /// + /// Data fine periodo dati Bilancia: oggi + 1gg + /// + private string dataTo + { + get => DateTime.Today.AddDays(1).ToString("dd/MM/yyyy"); + } + + private DateTime dtStartLive { get; set; } = DateTime.Today.AddMonths(-6); + + /// + /// Gestione archivio serializzato delle pesate già processate + /// + private List listPesateArch + { + get + { + List answ = new List(); + string rawData = redisMan.getRSV(redKeyPesate); + if (!string.IsNullOrEmpty(rawData)) + { + try + { + answ = JsonConvert.DeserializeObject>(rawData); + lgInfo($"Rilettura status listPesateArch: trovati {answ.Count} record"); + } + catch (Exception exc) + { + lgError($"Errore in deserializzazione listPesateArch{Environment.NewLine}{exc}"); + answ = new List(); + } + } + return answ; + } + set + { + string rawVal = JsonConvert.SerializeObject(value); + redisMan.setRSV(redKeyPesate, rawVal); + lgInfo($"Salvataggio status listPesateArch | {value.Count} record"); + } + } + + /// + /// Elenco pesate attuali + /// + private List listPesateCurr { get; set; } = new List(); + + /// + /// Elenco lettura pesate precedenti + /// + private List listPesatePrev { get; set; } = new List(); + + private string redKeyPesate { get; set; } = ""; + + #endregion Private Properties + #region Private Methods + private static string formatCode(string currCode) + { + string code = string.IsNullOrEmpty(currCode) ? "-" : currCode; + return $" | {code}"; + } + + /// + /// Formatta record completo pesata + /// + /// record completo pesate Gomba + /// Indica se deve formattare i dati tipo IN (true) o OUT (false) + /// + private static string formatPesata(gestWeightOut rec, bool isIN) + { + string currVal = ""; + if (isIN) + { + currVal = $"{rec.dateIn:yyyy-MM-dd HH:mm:ss} | {rec.weightIn} kg"; + } + else + { + currVal = $"{rec.dateOut:yyyy-MM-dd HH:mm:ss} | {rec.weightOut} kg"; + } + currVal += formatCode(rec.cod1); + currVal += formatCode(rec.cod2); + currVal += formatCode(rec.cod3); + currVal += formatCode(rec.cod4); + currVal += formatCode(rec.cod5); + currVal += formatCode(rec.cod6); + return currVal; + } #endregion Private Methods }