From 036fb4f3e003d637ca7b5bdccb6a9da3cbedeebb Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 15 Nov 2023 11:24:25 +0100 Subject: [PATCH] FluxLog: - Aggiunta gestione veto e deduplica - test su SIM - da verificare su altri adapter (es giacovelli) --- IOB-WIN-NEXT/DATA/CONF/SIMUL_01.json | 3 + IOB-WIN-NEXT/Iob/Generic.cs | 86 +++++++++++++++++++++++++- IOB-WIN-NEXT/Iob/Simula.cs | 36 ++++++++--- IOB-WIN-NEXT/IobModbusTCP/ModbusTCP.cs | 24 ------- 4 files changed, 114 insertions(+), 35 deletions(-) diff --git a/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.json b/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.json index 1421c1e1..56873ca0 100644 --- a/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.json +++ b/IOB-WIN-NEXT/DATA/CONF/SIMUL_01.json @@ -96,6 +96,9 @@ } }, "optKVP": { + "fluxLogReduce": true, + "fluxLogRedDeadBand": 1.5, + "fluxLogResendPeriod": 5, "hasRecipe": true, "maxPodlQty": 530, "useLocalRecipe": true, diff --git a/IOB-WIN-NEXT/Iob/Generic.cs b/IOB-WIN-NEXT/Iob/Generic.cs index 94320adc..462e5edf 100644 --- a/IOB-WIN-NEXT/Iob/Generic.cs +++ b/IOB-WIN-NEXT/Iob/Generic.cs @@ -3165,6 +3165,50 @@ namespace IOB_WIN_NEXT.Iob bool scaduto = stackVal_TSVC(chiave, valore); // recupero VC valore = getVal_TSVC(chiave, scaduto); + + // 2023.11.15: gestione deduplica (opzionale) fluxlog... in caso invalida scaduto... + if (fluxLogReduce && scaduto) + { + /*------------------------------- + * logica processing: + * - confronto con valore precedente (se non c'è allora registro questo) + * - se variato OLTRE deadband --> nulla cambia + * - se NON variato x deadband --> accodo SOLO SE scaduto tempo resend + * ------------------------------ */ + DateTime adesso = DateTime.Now; + // cerco tra i veto... + if (fluxLogReduceVeto.ContainsKey(chiave)) + { + // per prima cosa verifico che sia ancora valido il veto... + if (adesso < fluxLogReduceVeto[chiave]) + { + // verifico valore precedente + deadband x decidere se sia davvero scaduto + if (fluxLogReduceLast.ContainsKey(chiave)) + { + scaduto = Math.Abs(fluxLogReduceLast[chiave] - valore) > fluxLogRedDeadBand; + } + } + // altrimenti creo un nuovo veto lasciando inalterata la scadenza... + else + { + fluxLogReduceVeto[chiave] = adesso.AddMinutes(fluxLogResendPeriod); + } + } + // se non ci fosse metto veto con periodo std... + else + { + fluxLogReduceVeto.Add(chiave, adesso.AddMinutes(fluxLogResendPeriod)); + if (fluxLogReduceLast.ContainsKey(chiave)) + { + fluxLogReduceLast[chiave] = valore; + } + else + { + fluxLogReduceLast.Add(chiave, valore); + } + } + + } if (scaduto) { // limite a 3 digit x valore float @@ -3197,6 +3241,12 @@ namespace IOB_WIN_NEXT.Iob { maxVetoSeconds = TSVC_Data[chiave].Period; } + // se ho attivo il veto invio fluxLogReduce metto periodo a minuti indicati... + if (fluxLogReduce) + { + maxVetoSeconds = fluxLogResendPeriod * 60; + } + // verifico se sia scaduto OVVERO variato rispetto a prima oppure oltre tempo bool scaduto = !LastTSSSend.ContainsKey(chiave) || (LastTSSSend[chiave].AddSeconds(maxVetoSeconds) < adesso); bool cambiato = !LastTSS.ContainsKey(chiave) || !LastTSS[chiave].Equals(valore); @@ -4017,6 +4067,32 @@ namespace IOB_WIN_NEXT.Iob /// protected bool hasRecipe = false; + /// + /// Determina se sia gestita riduzione dati FluxLog + /// + protected bool fluxLogReduce = false; + /// + /// DeadBand x riduzione dati FluxLog (se 0 non gestita) + /// + protected double fluxLogRedDeadBand = 0; + /// + /// Finestra in minuti x invio dati FluxLog quando invariati + /// + protected int fluxLogResendPeriod = 60; + + /// + /// Dizionario dei veto send x ogni variabile quando non variata + /// + protected Dictionary fluxLogReduceVeto = new Dictionary(); + /// + /// Dizionario dei valori FluxLog ultimi verificati x veto + /// + protected Dictionary fluxLogReduceLast = new Dictionary(); + /// + /// Dizionario dei valori FluxLog ultimi tipo STRING verificati x veto + /// + protected Dictionary fluxLogReduceLastString = new Dictionary(); + /// /// Array dei contatori x segnali blinking /// @@ -5271,7 +5347,7 @@ namespace IOB_WIN_NEXT.Iob // gestione completa PODL string sEnabelPodlManFull = getOptPar("EnabelPodlManFull"); - if(!string.IsNullOrEmpty(sEnabelPodlManFull)) + if (!string.IsNullOrEmpty(sEnabelPodlManFull)) { bool.TryParse(sEnabelPodlManFull, out EnabelPodlManFull); } @@ -6552,6 +6628,14 @@ namespace IOB_WIN_NEXT.Iob // per prima cosa inizializzo lista PODL inviati POdlSentList = POdlSentFileArch; + // verifico se sia attiva gestione riduzione FluxLog... + if (!string.IsNullOrEmpty(getOptJsonKVP("fluxLogReduce"))) + { + bool.TryParse(getOptJsonKVP("fluxLogReduce"), out fluxLogReduce); + double.TryParse(getOptJsonKVP("fluxLogRedDeadBand"), NumberStyles.Any, CultureInfo.InvariantCulture, out fluxLogRedDeadBand); + int.TryParse(getOptJsonKVP("fluxLogResendPeriod"), out fluxLogResendPeriod); + } + // check modalità ricetta attiva bool.TryParse(getOptJsonKVP("hasRecipe"), out hasRecipe); diff --git a/IOB-WIN-NEXT/Iob/Simula.cs b/IOB-WIN-NEXT/Iob/Simula.cs index 0e79e6d0..5ba6750f 100644 --- a/IOB-WIN-NEXT/Iob/Simula.cs +++ b/IOB-WIN-NEXT/Iob/Simula.cs @@ -325,6 +325,7 @@ namespace IOB_WIN_NEXT.Iob /// public override Dictionary getDynData() { + bool useLUT = true; // valore non presente in vers default... se gestito fare override Dictionary outVal = new Dictionary(); // verificare periodo SIM parametri... se passato li invio altrimenti NO... FIX a 20 sec @@ -350,14 +351,14 @@ namespace IOB_WIN_NEXT.Iob if (item.Value.name == "SIM_LEVEL") { // verifico last value - float lastVal = 0; - float.TryParse(item.Value.value, out lastVal); + double lastVal = 0; + double.TryParse(item.Value.value, out lastVal); if (lastVal == 0) { - lastVal = item.Value.maxVal - (float)item.Value.factor; + lastVal = item.Value.maxVal - (double)item.Value.factor; } // decremento casuale... - float newVal = lastVal - ((float)item.Value.factor * rnd.Next(40, 120) / 100); + double newVal = lastVal - ((double)item.Value.factor * rnd.Next(40, 120) / 100); // se inferiore a minimo --> massimo! if (newVal < item.Value.minVal) { @@ -365,22 +366,37 @@ namespace IOB_WIN_NEXT.Iob } // salvo il suo VALUE... item.Value.value = $"{newVal}"; - outVal.Add(item.Key, $"{newVal}"); + if (useLUT) + { + saveValue(ref outVal, newVal, item.Key); + } + else + { + outVal.Add(item.Key, $"{newVal}"); + } } - // altrimenti siulazione random walk... + // altrimenti simulazione random walk... else { + double randVal = 0; if (item.Value.factor == 1) { // uso factor come valore MAX ammesso - int randVal = rnd.Next(item.Value.minVal, item.Value.maxVal); - outVal.Add(item.Key, randVal.ToString()); + randVal = rnd.Next(item.Value.minVal, item.Value.maxVal); } else { // uso factor come fattore di divisione x simulare decimali - float randVal = ((float)rnd.Next(item.Value.minVal, item.Value.maxVal)) / (float)item.Value.factor; - outVal.Add(item.Key, randVal.ToString()); + randVal = ((float)rnd.Next(item.Value.minVal, item.Value.maxVal)) / (float)item.Value.factor; + } + // verifico uso LUT + if (useLUT) + { + saveValue(ref outVal, randVal, item.Key); + } + else + { + outVal.Add(item.Key, $"{randVal}"); } } } diff --git a/IOB-WIN-NEXT/IobModbusTCP/ModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP/ModbusTCP.cs index bea62379..a11dcb0d 100644 --- a/IOB-WIN-NEXT/IobModbusTCP/ModbusTCP.cs +++ b/IOB-WIN-NEXT/IobModbusTCP/ModbusTCP.cs @@ -458,30 +458,6 @@ namespace IOB_WIN_NEXT.IobModbusTCP } } - /// - /// Effettua salvataggio in LUT del valore ricevuto (double) - /// - /// - /// - /// - /// - public override void saveValue(ref Dictionary outVal, double valore, string chiave) - { - //check obj preliminare - if (outVal == null) - { - outVal = new Dictionary(); - } - bool scaduto = stackVal_TSVC(chiave, valore); - // recupero VC - valore = getVal_TSVC(chiave, scaduto); - if (scaduto) - { - outVal.Add(chiave, $"{valore:N3}"); - } - LastTSVC[chiave] = valore; - } - /// /// Override connessione ///