using EgwProxy.Icoel; using IOB_UT_NEXT; using IOB_UT_NEXT.Config; using IOB_UT_NEXT.Objects; using IOB_UT_NEXT.Services.Files; using MapoSDK; using System; using System.Collections.Generic; using System.Diagnostics; using System.Net.NetworkInformation; namespace IOB_WIN_SQL.IobSql { /// /// Adapter specializzato per ICOEL e le chiamate tramite DB per i dati /// - accettazione lotti prodotto (frontiera / entrata ciliegie) /// - export (totale per prodotti) /// - tracciabilità (confezioni /// public class IcoelDb : Iob.GenericNext { #region Public Constructors /// /// Costruttore dell'IOB Icoel DB /// /// Form chiamante /// Configurazione (legacy) /// Configurazione (v 4.x) public IcoelDb(AdapterFormNext caller, IobConfTree IobConfFull) : base(caller, IobConfFull) { /* -------------------------------------- * todo's * -------------------------------------- * - init obj comunicazione da conf e nuget * - lanciare sync e verifica stato sync */ string SyncStateServer = getOptPar("SyncStateServer"); string SyncStateDb = getOptPar("SyncStateDb"); string SyncStateUser = getOptPar("SyncStateUser"); string SyncStatePwd = getOptPar("SyncStatePwd"); string SyncStateCTout = getOptPar("SyncStateCTout"); string connSyncState = $"data source={SyncStateServer};initial catalog={SyncStateDb};persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT"; // gestione command timeout da https://erikej.github.io/sqlclient/2020/10/26/sqlclient-commandtimeout-preview.html if (!string.IsNullOrEmpty(SyncStateCTout)) { connSyncState = $"{connSyncState};Command Timeout={SyncStateCTout}"; } // eccezione: NON TROVA EntityFramework 6.0.0 o successivo... why?!? dbProxy = new DbProxy(connSyncState); DtHelp.lastPING = DateTime.Now.AddHours(-1); } #endregion Public Constructors #region Public Methods /// /// Implementazione custom esecuzione task specifici /// /// /// public override Dictionary executeTasks(Dictionary task2exe, string codTav) { // unico task ammissibile: fare un SYNC forzato... Dictionary taskDone = new Dictionary(); if (task2exe != null) { // controllo se memMap != null... if (memMap != null) { bool taskOk = false; string taskVal = ""; // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4 foreach (var item in task2exe) { taskOk = false; taskVal = ""; // converto richiesta in enum... taskType tName = taskType.nihil; Enum.TryParse(item.Key, out tName); // controllo sulla KEY... switch (tName) { case taskType.syncDbData: lgInfo($"executeTasks --> syncDbData"); // effettua sync refreshElencoStati(); break; default: taskVal = $"IobIcoelDb | taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; lgInfo($"IobIcoelDb | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); break; } } } } DtHelp.lastReadPLC = DateTime.Now; return taskDone; } /// /// Recupero dati dinamici... /// public override Dictionary getDynData() { // valore non presente in vers default... se gestito fare override Dictionary outVal = new Dictionary(); // recupero da DB locale stato sync attuale var elencoSyncStateCurr = dbProxy.DataController.SyncStateGetAll(); foreach (var item in elencoSyncStateCurr) { saveValue(ref outVal, $"{item.TableName}_NumRec", item.NumRec); saveValue(ref outVal, $"{item.TableName}_NumRecIn", item.NumRecIn); saveValue(ref outVal, $"{item.TableName}_LastIdx", item.LastIdx); saveValue(ref outVal, $"{item.TableName}_LastIdxIn", item.LastIdxIn); } // aggiungo anche i campi currData var currData = dbProxy.DataController.CurrDataGetAll(); foreach (var item in currData) { saveValue(ref outVal, item.Topic, (double)item.CurrVal); } DtHelp.lastReadPLC = DateTime.Now; return outVal; } /// /// Effettua processing CUSTOM x Icoel: /// - recupera elenco batch delle 2 linee /// - invia al sistema /// public override void processCustomTaskLF() { lgInfo($"Richiesto processCustomTaskLF"); // effettua sync refreshElencoStati(); DtHelp.lastReadPLC = DateTime.Now; } /// /// Effettua lettura semafori principale Parametri da /// aggiornare x display in form /// public override void readSemafori(ref newDisplayData currDispData) { if (connectionOk) { B_input = 1; currDispData.semIn = Semaforo.SV; if (dbProxy != null && elencoSyncState != null && elencoSyncState.Count > 0) { B_input += (1 << 1); } // accodo NON emergenza B_input += (1 << 7); } else { B_input = 0; currDispData.semIn = Semaforo.SR; } } /// /// Override connessione /// public override void tryConnect() { if (!connectionOk) { // controllo che il ping sia stato tentato almeno pingTestSec fa... if (DateTime.Now.Subtract(DtHelp.lastPING).TotalSeconds > utils.CRI("pingTestSec")) { if (verboseLog || periodicLog) { lgInfo("IcoelSoap: ConnKO - tryConnect"); } // in primis salvo data ping... DtHelp.lastPING = DateTime.Now; // se passa il ping faccio il resto... if (testPingMachine == IPStatus.Success) { string szStatusConnection = ""; try { // ora provo connessione... parentForm.commPlcActive = true; if (dbProxy != null) { elencoSyncState = dbProxy.DataController.SyncStateDoImportAll(); if (elencoSyncState != null && elencoSyncState.Count > 0) { parentForm.commPlcActive = false; connectionOk = true; } } // refresh stato connessione!!! if (connectionOk) { queueInEnabCurr = true; if (adpRunning) { lgInfo("Connessione OK"); DtHelp.lastReadPLC = DateTime.Now; } } else { lgError("Impossibile procedere, connessione mancante..."); } } catch (Exception exc) { lgFatal($"Errore nella connessione all'adapter IcoelSoap: {szStatusConnection}{Environment.NewLine}{exc}"); connectionOk = false; lgInfo($"Eccezione in TryConnect, Adapter IcoelSoap NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); } } else { // loggo no risposta ping ... connectionOk = false; if (verboseLog || periodicLog) { lgInfo($"Attenzione: IcoelSoap controllo PING fallito per IP {IOBConfFull.Device.Connect.PingIpAddr}"); } } } } else { needRefresh = true; } } public override void tryDisconnect() { // registro solo che è disconnesso connectionOk = false; queueInEnabCurr = false; } #endregion Public Methods #region Protected Properties protected EgwProxy.Icoel.DbProxy dbProxy { get; set; } = null; /// /// Stato di sync delle tab gestite /// protected List elencoSyncState { get; set; } = new List(); #endregion Protected Properties #region Private Methods private void refreshElencoStati() { Stopwatch sw = new Stopwatch(); sw.Start(); elencoSyncState = dbProxy.DataController.SyncStateDoImportAll(); sw.Stop(); DtHelp.lastReadPLC = DateTime.Now; lgInfo($"DB: esecuzione task dbProxy.DataController.SyncStateGetAll() in {sw.ElapsedMilliseconds} ms"); if (elencoSyncState != null) { foreach (var item in elencoSyncState) { lgTrace($"TAB: {item.TableName} | IdxIN / IdxLocal {item.LastIdxIn} / {item.LastIdx} | NumIn / NumLocal {item.NumRecIn} / {item.NumRec}"); } } } #endregion Private Methods } }