From e71de2c52f832ecaa32cd1bda554bbabdc7383e9 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 18 Apr 2023 09:06:44 +0200 Subject: [PATCH] Aggiunta conf test soitaab preliminare --- IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.ini | 83 ++++ IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.json | 29 ++ IOB-WIN-NEXT/IOB-WIN-NEXT.csproj | 6 + IOB-WIN-NEXT/IobSqlServLantek.cs | 466 ++++++++++++++++++--- 4 files changed, 529 insertions(+), 55 deletions(-) create mode 100644 IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.ini create mode 100644 IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.json diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.ini b/IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.ini new file mode 100644 index 00000000..5e53eea6 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.ini @@ -0,0 +1,83 @@ +;Configurazione IOB-WIN +[IOB] +;Accesso gestione sync DB x sync SOITAAB/LANTEK --> MoonPro_IOB_ISF --> Chiamate REST +CNCTYPE=SQLSERVER_LANTEK +PING_MS_TIMEOUT=500 +MinDeltaSec=5 + +[MACHINE] +VENDOR=SOITAAB +MODEL=Ossitaglio xxx / sw LANTEK + +[CNC] +IP=127.0.0.1 +PORT=1443 +GETPRGNAME=false + +[SERVER] +MPIP=http://192.168.0.110 +MPURL=/MP/IO +CMDBASE=/IOB/input/ +CMDFLOG=/IOB/flog/ +CMDALIVE=/IOB +CMDENABLED=/IOB/enabled/ +CMDADV1=?valore= +CMDREBO=/sendReboot.aspx?idxMacchina= +CMDRAWTRANSF=/IOB/rawTransfJson/ + +[MEMORY] +ADDR_READ=DB9999.DBB0 +ADDR_WRITE=DB9999.DBB0 +SIZE_READ=0 +SIZE_WRITE=0 +;BIT0=CONN +;BIT1=DB60.DBB1 +;BIT2=PZCOUNT.STD.DB700.DBW22 +;BIT3=DB60.DBB3 +;BIT4=DB60.DBB4 + + +[BLINK] +;MAX_COUNTER_BLINK = 30 +MAX_COUNTER_BLINK = 15 +;bit0 = 0 +;bit1 = 0 +;bit2 = 1 +;bit3 = 1 +;bit4 = 1 +;bit5 = 0 +;bit6 = 0 +;bit7 = 0 +BLINK_FILT=0 +;BLINK_FILT=28 + +[OPTPAR] +AUTO_CHANGE_ODL=false +CHANGE_ODL_MODE=TIME +CHANGE_ODL_HOURS=24 +CHANGE_ODL_IDLE_MIN=5 +PZCOUNT_MODE=PAMA +DISABLE_PZCOUNT=FALSE +ENABLE_SEND_PZC_BLOCK=TRUE +MIN_SEND_PZC_BLOCK=0 +MAX_SEND_PZC_BLOCK=100 +ENABLE_DYN_DATA=TRUE +FORCE_DYN_DATA=TRUE +DEM_FACT_DYN_DATA=5 +ENABLE_DATA_FILTER=TRUE +ENABLE_CLI_RESTART=TRUE +SyncStateServer=308SERVER60\LANTEK +SyncStateDb=MoonPro_IOB_ISF_LANTEK +SyncStateUser=steamware +SyncStatePwd=viadante16 +SyncStateCTout= +VetoReadSec=2 + +; clock base (da 10ms) +timerIntMs=20 + +; conf parametri memoria READ/WRITE +PARAM_CONF=IMI_SOITAAB_01.json + +[BRANCH] +NAME=master \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.json b/IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.json new file mode 100644 index 00000000..898e2595 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_SOITAAB_01.json @@ -0,0 +1,29 @@ +{ + "mMapWrite": { + + }, + "mMapRead": { + //"TotMerceProcTonn": { + // "name": "TotMerceProcTonn", + // "description": "Totale merce processata oggi su impianto (Tonn)", + // "memAddr": "TotMerceProcTonn", + // "tipoMem": "Real", + // "index": 0, + // "size": 0, + // "func": "MAX", + // "period": 60, + // "factor": 1 + //}, + //"TotMerceCaricTonn": { + // "name": "TotMerceCaricTonn", + // "description": "Totale merce caricata oggi su impianto (Tonn)", + // "memAddr": "TotMerceCaricTonn", + // "tipoMem": "Real", + // "index": 0, + // "size": 0, + // "func": "MAX", + // "period": 60, + // "factor": 1 + //} + } +} diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index a9241d49..411f8262 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -321,6 +321,12 @@ + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/IOB-WIN-NEXT/IobSqlServLantek.cs b/IOB-WIN-NEXT/IobSqlServLantek.cs index 7e81a6b0..ffe80351 100644 --- a/IOB-WIN-NEXT/IobSqlServLantek.cs +++ b/IOB-WIN-NEXT/IobSqlServLantek.cs @@ -1,16 +1,21 @@ -using EgwProxy.Icoel; +using EgwProxy.SqlDb.Controllers; +using EgwProxy.SqlDb.DbModels; using IOB_UT_NEXT; using MapoSDK; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Net.NetworkInformation; +using static IOB_UT_NEXT.CustomObj; namespace IOB_WIN_NEXT { /// /// Adapter specializzato per LANTEK e le chiamate tramite DB per i dati - /// ....TBD + /// - PODL (ordini MES --> MACCHINA) + /// - ProdLog (da FasiDaLantek) /// public class IobSqlServLantek : IobGeneric @@ -18,34 +23,38 @@ namespace IOB_WIN_NEXT #region Public Constructors /// - /// Costruttore dell'IOB Icoel DB + /// Costruttore dell'IOB DB LANTEK /// /// AdapterForm chiamante /// Configurazione IOB per avvio public IobSqlServLantek(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { - /* -------------------------------------- - * todo's - * -------------------------------------- - * - init obj comunicazione da conf e nuget - * - lanciare sync e verifica stato sync - */ - + string SyncStateServ = getOptPar("SyncStateServer"); string SyncStateDb = getOptPar("SyncStateDb"); string SyncStateUser = getOptPar("SyncStateUser"); string SyncStatePwd = getOptPar("SyncStatePwd"); string SyncStateCTout = getOptPar("SyncStateCTout"); + string VetoReadSec = getOptPar("VetoReadSec"); + string VetoSyncSec = getOptPar("VetoSyncSec"); - string connSyncState = $"data source={SyncStateDb};initial catalog=MoonPro_ISF;persist security info=True;user id={SyncStateUser};password={SyncStatePwd};MultipleActiveResultSets=True;App=IOB-WIN-NEXT"; + string connSyncState = $"data source={SyncStateServ};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}"; } + if (!string.IsNullOrEmpty(VetoReadSec)) + { + int.TryParse(VetoReadSec, out vetoReadDbSec); + } + if (!string.IsNullOrEmpty(VetoSyncSec)) + { + int.TryParse(VetoSyncSec, out VetoSyncDbSec); + } // eccezione: NON TROVA EntityFramework 6.0.0 o successivo... why?!? - dbProxy = new DbProxy(connSyncState); + dbProxy = new DbController(connSyncState); lastPING = DateTime.Now.AddHours(-1); } @@ -61,6 +70,7 @@ namespace IOB_WIN_NEXT /// public override Dictionary executeTasks(Dictionary task2exe) { + DateTime adesso = DateTime.Now; // unico task ammissibile: fare un SYNC forzato... Dictionary taskDone = new Dictionary(); if (task2exe != null) @@ -81,10 +91,86 @@ namespace IOB_WIN_NEXT // controllo sulla KEY... switch (tName) { + case taskType.setComm: case taskType.syncDbData: - lgInfo($"executeTasks --> syncDbData"); - // effettua sync - refreshElencoStati(); + lgInfo($"executeTasks --> {tName}"); + // per prima cosa recupero elenco PODL attivi x la macchina + List listaPODL = new List(); + bool okPodl = false; + var rawListPODL = callUrl(urlGetCurrPODL, false); + if (!string.IsNullOrEmpty(rawListPODL)) + { + try + { + listaPODL = JsonConvert.DeserializeObject>(rawListPODL); + okPodl = listaPODL.Count > 0; + } + catch (Exception exc) + { + lg.Error($"Errore: chiamata elenco PODL ha restituito errore{Environment.NewLine}{exc}"); + } + } + else + { + lg.Error($"Errore: chiamata elenco PODL ({urlGetCurrPODL}) ha restituito valore vuoto"); + } + if (okPodl) + { + //mando elenco PODL... + List CurrPodlReq = listaPODL + .Select(x => new MesPODLReqModel() + { + Attivabile = x.Attivabile, + CodArticolo = x.CodArticolo, + CodCli = x.CodCli, + CodGruppo = x.CodGruppo, + DueDate = x.DueDate ?? DateTime.Now, + IdxMacchina = x.IdxMacchina, + IdxODL = x.IdxOdl, + IdxPromessa = x.IdxPromessa, + InsertDate = x.InsertDate, + KeyBCode = x.KeyBCode, + KeyRichiesta = x.KeyRichiesta, + Note = x.Note, + NumPezzi = x.NumPezzi, + Priorita = x.Priorita, + PzPallet = x.PzPallet, + TCAssegnato = x.Tcassegnato + }) + .ToList(); + // scrivo i record richiesti + bool fatto = dbProxy.MesPodlWriteReq(CurrPodlReq); + if (fatto) + { + taskVal = $"EXECUTED task: {item.Key} / {item.Value}"; + // registro evento chiamata scrittura in syncState... + string tabName = item.Key; + var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName); + // verifico x registrare azione + if (currSyncState == null) + { + currSyncState = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabName, + Note = "Init" + }; + } + else + { + var lastRec = CurrPodlReq.OrderBy(x => x.IdxPromessa).LastOrDefault(); + currSyncState.LastIdx = lastRec != null ? lastRec.IdxPromessa : -1; + currSyncState.Note = $"Esecuzione {tabName} per {CurrPodlReq.Count} rec | last code: {currSyncState.LastIdx}"; + currSyncState.LastUpdate = adesso; + } + // salvo sync... + dbProxy.SyncStateUpsert(currSyncState); + } + + // effettua sync scrivendo i dati in export (PODL) + execExportAll(); + } break; @@ -93,6 +179,8 @@ namespace IOB_WIN_NEXT lgInfo($"IobSqlServLantek | chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); break; } + // aggiungo task! + taskDone.Add(item.Key, taskVal); } } } @@ -105,39 +193,27 @@ namespace IOB_WIN_NEXT /// 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.NumRec, $"{item.TableName}_NumRec"); - saveValue(ref outVal, item.NumRecIn, $"{item.TableName}_NumRecIn"); - saveValue(ref outVal, item.LastIdx, $"{item.TableName}_LastIdx"); - saveValue(ref outVal, item.LastIdxIn, $"{item.TableName}_LastIdxIn"); - } + DateTime adesso = DateTime.Now; - // aggiungo anche i campi currData - var currData = dbProxy.DataController.CurrDataGetAll(); - foreach (var item in currData) - { - saveValue(ref outVal, (double)item.CurrVal, item.Topic); - } + // dizionario vuoto / faccio direttamente accodamento in FluxLog + Dictionary outVal = new Dictionary(); + + // processo ed accodo! + processFluxLogTable(adesso); lastReadPLC = DateTime.Now; return outVal; } /// - /// Effettua processing CUSTOM x Icoel: - /// - recupera elenco batch delle 2 linee - /// - invia al sistema + /// Effettua processing CUSTOM: + /// - esegue tutti gli import /// public override void processCustomTaskLF() { lgInfo($"Richiesto processCustomTaskLF"); // effettua sync - refreshElencoStati(); + execImportAll(); lastReadPLC = DateTime.Now; } @@ -147,18 +223,30 @@ namespace IOB_WIN_NEXT /// public override void readSemafori(ref newDisplayData currDispData) { + DateTime adesso = DateTime.Now; if (connectionOk) { - B_input = 1; - currDispData.semIn = Semaforo.SV; - - if (dbProxy != null && elencoSyncState != null && elencoSyncState.Count > 0) + // controllo veto checkDB + if (adesso > vetoDataRead) { - B_input += (1 << 1); - } + // predispongo prox veto... + vetoDataRead = adesso.AddSeconds(vetoReadDbSec); + if (adesso > vetoDataSync) + { + // effettua sync + execImportAll(); + vetoDataSync = adesso.AddSeconds(VetoSyncDbSec); + } - // accodo NON emergenza - B_input += (1 << 7); + // semaforo + currDispData.semIn = Semaforo.SV; + // recupero syncState + elencoSyncState = dbProxy.SyncStateGetAll(); + // verifico SignLog e processo + bool sentSignLog = processSignLogTable(adesso); + // verifico ProdData e processo + bool sentProdData = processProdDataTable(adesso); + } } else { @@ -179,7 +267,7 @@ namespace IOB_WIN_NEXT { if (verboseLog || periodicLog) { - lgInfo("IcoelSoap: ConnKO - tryConnect"); + lgInfo("SqlDb LANTEK: ConnKO - tryConnect"); } // in primis salvo data ping... lastPING = DateTime.Now; @@ -193,7 +281,7 @@ namespace IOB_WIN_NEXT parentForm.commPlcActive = true; if (dbProxy != null) { - elencoSyncState = dbProxy.DataController.SyncStateDoImportAll(); + elencoSyncState = dbProxy.SyncStateDoImportAll(); if (elencoSyncState != null && elencoSyncState.Count > 0) { @@ -217,9 +305,9 @@ namespace IOB_WIN_NEXT } catch (Exception exc) { - lgFatal($"Errore nella connessione all'adapter IcoelSoap: {szStatusConnection}{Environment.NewLine}{exc}"); + lgFatal($"Errore nella connessione all'adapter SqlDb LANTEK: {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"); + lgInfo($"Eccezione in TryConnect, Adapter SqlDb LANTEK NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione"); } } else @@ -228,7 +316,7 @@ namespace IOB_WIN_NEXT connectionOk = false; if (verboseLog || periodicLog) { - lgInfo($"Attenzione: IcoelSoap controllo PING fallito per IP {cIobConf.cncIpAddr}"); + lgInfo($"Attenzione: SqlDb LANTEK controllo PING fallito per IP {cIobConf.cncIpAddr}"); } } } @@ -247,37 +335,305 @@ namespace IOB_WIN_NEXT #endregion Public Methods + #region Protected Fields + + protected int vetoReadDbSec = 3; + + protected int VetoSyncDbSec = 20; + + #endregion Protected Fields + #region Protected Properties - protected EgwProxy.Icoel.DbProxy dbProxy { get; set; } = null; + protected DbController dbProxy { get; set; } = null; /// /// Stato di sync delle tab gestite /// - protected List elencoSyncState { get; set; } = new List(); + protected List elencoSyncState { get; set; } = new List(); #endregion Protected Properties #region Private Methods - private void refreshElencoStati() + /// + /// Esegue task EXPORT (MES PODL to MACHINE) + /// + private void execExportAll() { Stopwatch sw = new Stopwatch(); sw.Start(); - elencoSyncState = dbProxy.DataController.SyncStateDoImportAll(); + elencoSyncState = dbProxy.SyncStateDoExportAll(); + sw.Stop(); + DateTime adesso = DateTime.Now; + lastReadPLC = adesso; + lgInfo($"DB: esecuzione task dbProxy.SyncStateDoExportAll() in {sw.ElapsedMilliseconds} ms"); + + if (elencoSyncState != null) + { + // registro evento chiamata scrittura in syncState... + string tabName = "ExportAll"; + var currSyncState = elencoSyncState.FirstOrDefault(x => x.TableName == tabName); + // verifico x registrare azione + if (currSyncState == null) + { + currSyncState = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabName, + Note = "Init" + }; + } + else + { + // calcolo lastIDX valore da datetime + int valInt = -1; + var nowString = $"{adesso:HHmmss}"; + int.TryParse(nowString, out valInt); + currSyncState.LastIdx = valInt; + currSyncState.Note = $"Esecuzione {tabName} | DT code: {currSyncState.LastIdx}"; + currSyncState.LastUpdate = adesso; + } + // salvo sync... + dbProxy.SyncStateUpsert(currSyncState); + foreach (var item in elencoSyncState) + { + lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}"); + } + } + } + + /// + /// Esegue task IMPORT (MES PODL to MACHINE) + /// + private void execImportAll() + { + Stopwatch sw = new Stopwatch(); + sw.Start(); + elencoSyncState = dbProxy.SyncStateDoImportAll(); sw.Stop(); lastReadPLC = DateTime.Now; - lgInfo($"DB: esecuzione task dbProxy.DataController.SyncStateGetAll() in {sw.ElapsedMilliseconds} ms"); + lgInfo($"DB: esecuzione task dbProxy.SyncStateDoImportAll() 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}"); + lgTrace($"TAB {item.TableName} | LastIdx {item.LastIdx} | Note {item.Note} | Last Upd {item.LastUpdate}"); } } } + /// + /// Esegue processing + invio dati tab SignLog + /// + /// + /// + private bool processFluxLogTable(DateTime adesso) + { + bool fatto = false; + string tabNameIn = "FluxLog"; + string tabNameOut = "FluxLogToMes"; + // cerco info sui SignLog (ToMes e letti) + var currFluxLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); + // se nullo inizializzo + if (currFluxLogRead == null) + { + currFluxLogRead = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabNameIn, + Note = "Init" + }; + } + var currFluxLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); + // se nullo inizializzo + if (currFluxLogSent == null) + { + currFluxLogSent = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabNameOut, + Note = "Init" + }; + } + // verifica se ci siano dati da trasmettere (sui valori LastIdx) + if (currFluxLogRead.LastIdx > currFluxLogSent.LastIdx) + { + // recupero i dati dal DB... + var data2send = dbProxy.MachFluxLogGetNew(currFluxLogSent.LastIdx); + // se ho dati preparo invio + if (data2send != null && data2send.Count > 0) + { + string sVal = ""; + foreach (var fLog2send in data2send) + { + sVal = $"[DYNDATA] |{fLog2send.DtEvento:yyyy-MM-dd HH:mm:ss}|{fLog2send.CodFlux}|{fLog2send.Valore}"; + // chiamo accodamento con dataora corretta... + accodaFLog(sVal, qEncodeFLog(fLog2send.DtEvento, fLog2send.CodFlux, fLog2send.Valore)); + } + fatto = true; + } + + // aggiorno idx inviato... + currFluxLogSent.Note = $"Updated from {currFluxLogRead.LastIdx}"; + currFluxLogSent.LastUpdate = adesso; + currFluxLogSent.LastIdx = currFluxLogRead.LastIdx; + } + + // alla fine aggiorno i dati inviati! + dbProxy.SyncStateUpsert(currFluxLogSent); + + return fatto; + } + + /// + /// Esegue processing + invio dati tab ProdData + /// + /// + /// + private bool processProdDataTable(DateTime adesso) + { + bool fatto = false; + string tabNameIn = "ProdData"; + string tabNameOut = "ProdDataToMes"; + // cerco info sui SignLog (ToMes e letti) + var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); + // se nullo inizializzo + if (currSignLogRead == null) + { + currSignLogRead = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabNameIn, + Note = "Init" + }; + } + var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); + // se nullo inizializzo + if (currSignLogSent == null) + { + currSignLogSent = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabNameOut, + Note = "Init" + }; + } + // verifica se ci siano dati da trasmettere (sui valori LastIdx) + if (currSignLogRead.LastIdx > currSignLogSent.LastIdx) + { + // recupero i dati dal DB... + var data2send = dbProxy.MachProdDataGetNew(currSignLogSent.LastIdx); + // se ho dati preparo invio + if (data2send != null && data2send.Count > 0) + { + foreach (var sLog2send in data2send) + { + // se il record è apertura PODL chiamo apertura + + trySetupPODL(0); + + // se il record è chiusura PODL chiamo chiusura... DOPO aver cercato PODL --> ODL + tryClosePODL(0); + } + } + + // aggiorno idx inviato... + currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}"; + currSignLogSent.LastUpdate = adesso; + currSignLogSent.LastIdx = currSignLogRead.LastIdx; + fatto = true; + } + + // alla fine aggiorno i dati inviati! + dbProxy.SyncStateUpsert(currSignLogSent); + + return fatto; + } + + /// + /// Esegue processing + invio dati tab SignLog + /// + /// + /// + private bool processSignLogTable(DateTime adesso) + { + bool fatto = false; + string tabNameIn = "SignLog"; + string tabNameOut = "SignLogToMes"; + // cerco info sui SignLog (ToMes e letti) + var currSignLogRead = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameIn); + // se nullo inizializzo + if (currSignLogRead == null) + { + currSignLogRead = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabNameIn, + Note = "Init" + }; + } + var currSignLogSent = elencoSyncState.FirstOrDefault(x => x.TableName == tabNameOut); + // se nullo inizializzo + if (currSignLogSent == null) + { + currSignLogSent = new SyncStateModel() + { + LastIdx = 0, + LastUpdate = adesso, + TableName = tabNameOut, + Note = "Init" + }; + } + // verifica se ci siano dati da trasmettere (sui valori LastIdx) + if (currSignLogRead.LastIdx > currSignLogSent.LastIdx) + { + // recupero i dati dal DB... + var data2send = dbProxy.MachSigLogGetNew(currSignLogSent.LastIdx); + // se ho dati preparo invio + if (data2send != null && data2send.Count > 0) + { + foreach (var sLog2send in data2send) + { + string currVal = getEncodSigLog(sLog2send.DtEve, sLog2send.ValInt, counterSigIN); + // --> accodo (valore già formattato)! + QueueIN.Enqueue(currVal); + // loggo! + lgTrace(string.Format("[QUEUE-IN] {0}", currVal)); + counterSigIN++; + if (counterSigIN > 9999) + { + counterSigIN = 0; + } + } + } + + // aggiorno idx inviato... + currSignLogSent.Note = $"Updated from {currSignLogRead.LastIdx}"; + currSignLogSent.LastUpdate = adesso; + currSignLogSent.LastIdx = currSignLogRead.LastIdx; + var lastRec = data2send.LastOrDefault(); + if (lastRec != null) + { + // salvo in B_input ultimo valore letto... + B_input = lastRec.ValInt; + } + fatto = true; + } + + // alla fine aggiorno i dati inviati! + dbProxy.SyncStateUpsert(currSignLogSent); + + return fatto; + } + #endregion Private Methods } } \ No newline at end of file