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