diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs
index 62e209a8..b4b77b69 100644
--- a/MP.IOC/Data/MpDataService.cs
+++ b/MP.IOC/Data/MpDataService.cs
@@ -1,4 +1,4 @@
-using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
using MP.Core.Conf;
using MP.Core.DTO;
using MP.Core.Objects;
@@ -561,11 +561,12 @@ namespace MP.IOC.Data
/// valore ingresso
/// data-ora evento (server)
/// sequenza dati inviati
+ /// dati macchina in cache (opzionale, se null fa lookup)
///
- public async Task CheckMicroStatoAsync(string idxMacchina, string valore, DateTime dtEve, string contatore)
+ public async Task CheckMicroStatoAsync(string idxMacchina, string valore, DateTime dtEve, string contatore, Dictionary? datiMaccCache = null)
{
// recupero SE IMPIEGATO REDIS i valori del Dictionary della macchina...
- Dictionary datiMacc = await mDatiMacchineAsync(idxMacchina);
+ Dictionary datiMacc = datiMaccCache ?? await mDatiMacchineAsync(idxMacchina);
// processing
inputComandoMapo answ = new inputComandoMapo();
@@ -2025,6 +2026,31 @@ namespace MP.IOC.Data
return answ;
}
+ ///
+ /// Restitusice elenco KVP (async) per evitare blocchi quando chiamato da metodi asincroni
+ ///
+ ///
+ ///
+ public async Task[]> mTabMSMIAsync(string idxMacchina)
+ {
+ KeyValuePair[] answ = new KeyValuePair[1];
+ answ[0] = new KeyValuePair("0", "0");
+ try
+ {
+ var currHash = Utils.RedKeyMsmi(idxMacchina);
+ answ = await RedisGetHashDictAsync(currHash);
+ if (answ == null || answ.Length == 0)
+ {
+ answ = await resetMSMIAsync(idxMacchina);
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in compilazione Tabella Multi State Machine Ingressi x Redis:{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
///
/// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
///
@@ -2714,26 +2740,28 @@ namespace MP.IOC.Data
{
// scrivo keep alive!!! (se necessario, altrimenti è in cache...)
await ScriviKeepAliveAsync(idxMacchina, DateTime.Now);
+ // Cache dati macchina per evitare lookup ridondanti
+ Dictionary datiMacc = await mDatiMacchineAsync(idxMacchina);
// verifico se sia una macchina MULTI ed in tal caso calcolo i
// SUB-systems e CHIAMERO' alla fine pure loro....
- if (isMulti(idxMacchina))
+ if (isMulti(idxMacchina, datiMacc))
{
// inizio preprocessing
string newVal = "";
// processo OGNI macchina a stati dell'impianto... (KEY:IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn)
- foreach (var item in mTabMSMI(idxMacchina))
+ foreach (var item in await mTabMSMIAsync(idxMacchina))
{
- newVal = preProcInput(item.Key, valore);
+ newVal = preProcInput(item.Key, valore, datiMacc);
// ora processo e salvo il valore del microstato...
// INTERNAMENTE gestisce i casi DB/REDIS secondo necessità
- await CheckMicroStatoAsync(item.Key, newVal, dataOraEvento, contatore);
+ await CheckMicroStatoAsync(item.Key, newVal, dataOraEvento, contatore, datiMacc);
}
}
else
{
// ora processo e salvo il valore del microstato... INTERNAMENTE
// gestisce i casi DB/REDIS secondo necessità
- await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore);
+ await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore, datiMacc);
}
// registro in risposta che è andato tutto bene...
answ = "OK";
@@ -3391,6 +3419,32 @@ namespace MP.IOC.Data
return answ;
}
+ ///
+ ///
+ public async Task[]> resetMSMIAsync(string idxMacchina)
+ {
+ var currHash = Utils.RedKeyMsmi(idxMacchina);
+ // recupero records
+ var tabMSMI = await IocDbController.VMSFDGetMultiByMaccAsync(idxMacchina);
+
+ KeyValuePair[] answ = new KeyValuePair[tabMSMI.Count];
+ // salvo tutti i valori StateMachineIngressi...
+ int i = 0;
+ foreach (var item in tabMSMI)
+ {
+ answ[i] = new KeyValuePair(item.IdxMacchina, item.IdxFamigliaIngresso.ToString());
+ i++;
+ }
+ // verifico il timeout (default 60 sec...)
+ var sTOutSmi = await tryGetConfig("TmOut.MSMI");
+ int tOut = 60;
+ int.TryParse(sTOutSmi, out tOut);
+ tOut = tOut <= 60 ? 60 : tOut;
+ // salvo in redis!
+ await RedisSetHashAsync(currHash, answ, tOut);
+ return answ;
+ }
+
///
/// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB
///
@@ -4340,6 +4394,27 @@ namespace MP.IOC.Data
return answ;
}
+ ///
+ /// Restituisce il valore booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI)
+ /// usando dati macchina in cache per evitare lookup ridondanti
+ ///
+ ///
+ ///
+ ///
+ private bool isMulti(string idxMacchina, Dictionary datiMacc)
+ {
+ bool answ = false;
+ try
+ {
+ answ = Convert.ToBoolean(datiMacc.ContainsKey("Multi") && datiMacc["Multi"] == "1");
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Eccezione in isMulti{Environment.NewLine}{exc}");
+ }
+ return answ;
+ }
+
private async Task POdlFlushCache()
{
bool answ = false;
@@ -4378,7 +4453,56 @@ namespace MP.IOC.Data
int.TryParse(mDatiMacchinaVal(idxMacchina, "BSR"), out BSR);
Boolean.TryParse(mDatiMacchinaVal(idxMacchina, "ExplodeBit"), out ExplodeBit);
int.TryParse(mDatiMacchinaVal(idxMacchina, "NumBit"), out NumBit); // non usato (x ora)
- // recupero valore
+ // recupero valore
+ valINT = int.Parse(valore, NumberStyles.HexNumber);
+ // filtro
+ newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt);
+ // effettuo eventuale BitShiftRight
+ if (BSR > 0)
+ {
+ newValInt = newValInt >> BSR;
+ }
+ // effettuo eventuale esplosione in BIT esclusivi
+ if (ExplodeBit)
+ {
+ newValInt = Convert.ToInt32(1 << newValInt);
+ }
+ // riconverto a STRING HEX!!!
+ newVal = newValInt.ToString("X");
+ }
+ catch
+ {
+ newVal = valore;
+ }
+
+ return newVal;
+ }
+
+ ///
+ /// Calcola l'effettivo valore da passare alla macchina a stati INGRESSI usando dati macchina in cache
+ ///
+ ///
+ ///
+ ///
+ ///
+ private string preProcInput(string idxMacchina, string valore, Dictionary datiMacc)
+ {
+ string newVal = "";
+ try
+ {
+ // variabili
+ int valINT = 0;
+ int BitFilt = 0;
+ int BSR = 0;
+ bool ExplodeBit = false;
+ int NumBit = 0;
+ int newValInt = 0;
+ // recupero parametri dalla cache...
+ int.TryParse(datiMacc.ContainsKey("BitFilt") ? datiMacc["BitFilt"] : "0", out BitFilt);
+ int.TryParse(datiMacc.ContainsKey("BSR") ? datiMacc["BSR"] : "0", out BSR);
+ Boolean.TryParse(datiMacc.ContainsKey("ExplodeBit") ? datiMacc["ExplodeBit"] : "false", out ExplodeBit);
+ int.TryParse(datiMacc.ContainsKey("NumBit") ? datiMacc["NumBit"] : "0", out NumBit); // non usato (x ora)
+ // recupero valore
valINT = int.Parse(valore, NumberStyles.HexNumber);
// filtro
newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt);