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 } }