diff --git a/MP.Data/Controllers/MpIocController.cs b/MP.Data/Controllers/MpIocController.cs
index 4a9cf45a..76753997 100644
--- a/MP.Data/Controllers/MpIocController.cs
+++ b/MP.Data/Controllers/MpIocController.cs
@@ -372,6 +372,60 @@ namespace MP.Data.Controllers
return await dbCtx.SaveChangesAsync() > 0;
}
+
+
+ ///
+ /// Aggiunta record MicroStato + EventList
+ ///
+ ///
+ ///
+ ///
+ public async Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv)
+ {
+ // eseguo in transazione...
+ await using var dbCtx = new MoonProContext(_configuration);
+ await using var tx = await dbCtx.Database.BeginTransactionAsync();
+
+ try
+ {
+ // inizio con record microstato...
+ var actRec = await dbCtx
+ .DbSetMicroStatoMacc
+ .FindAsync(newRecMsm.IdxMacchina);
+ //.SingleOrDefaultAsync();
+ if (actRec == null)
+ {
+ dbCtx.DbSetMicroStatoMacc.Add(newRecMsm);
+ }
+ else
+ {
+ actRec.IdxMicroStato = newRecMsm.IdxMicroStato;
+ actRec.InizioStato = newRecMsm.InizioStato;
+ actRec.Value = newRecMsm.Value;
+
+ // Update() allega l'entità e segna tutti i campi come Modified
+ dbCtx.DbSetMicroStatoMacc.Update(actRec);
+#if false
+ dbCtx.Entry(actRec).State = EntityState.Modified;
+#endif
+ }
+
+ // ora record EVList
+ dbCtx.DbSetEvList.Add(newRecEv);
+
+ // EF Core 8 raggruppa automaticamente INSERT/UPDATE in un batch
+ var rowsAffected = await dbCtx.SaveChangesAsync();
+ await tx.CommitAsync();
+
+ return rowsAffected > 0;
+ }
+ catch
+ {
+ await tx.RollbackAsync();
+ throw;
+ }
+ }
+
///
/// Chiamata x stored recupero FluxLog x macchina (first)
///
diff --git a/MP.IOC/Controllers/BenchController.cs b/MP.IOC/Controllers/BenchController.cs
index e8b5d3c8..357ee5cb 100644
--- a/MP.IOC/Controllers/BenchController.cs
+++ b/MP.IOC/Controllers/BenchController.cs
@@ -131,7 +131,7 @@ namespace MP.IOC.Controllers
}
// recupero singolo valore (stringa) x chiave
- outVal = DService.ValoreSMI(idxFamIn, idxMicroStato, valIOB);
+ outVal = await DService.ValoreSmiAsync(idxFamIn, idxMicroStato, valIOB);
// mostro output
answ += $"idxFamIN: {idxFamIn} | idxMS: {idxMicroStato} | valIOB: {valIOB} | out: {outVal}";
}
diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs
index ee1733c8..d41e1cff 100644
--- a/MP.IOC/Data/MpDataService.cs
+++ b/MP.IOC/Data/MpDataService.cs
@@ -156,9 +156,9 @@ namespace MP.IOC.Data
try
{
Dictionary savedTask = mSavedTaskMacchina(idxMacchina);
- // cerco valore saved
+ // cerco valOut saved
string savedVal = savedTask[taskKey.ToString()];
- // se ho un valore != "" --> rimetto in coda di invio...
+ // se ho un valOut != "" --> rimetto in coda di invio...
if (!string.IsNullOrEmpty(savedVal) && (savedVal != taskVal))
{
// leggo tName attuali...
@@ -342,8 +342,8 @@ namespace MP.IOC.Data
/// Idx macchina
/// area memoria
/// indice memoria
- /// valore status
- /// valore decodificato
+ /// valOut status
+ /// valOut decodificato
///
public async Task AlarmInsertAsync(DateTime dtRif, string idxMacchina, string memAddress, int memIndex, int statusVal, string valDecoded)
{
@@ -449,7 +449,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = Utils.redisArtByDossier;
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -497,7 +497,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisArtList}:Last:{idxMacc}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -535,7 +535,7 @@ namespace MP.IOC.Data
string readType = "DB";
string sKey = string.IsNullOrEmpty(searchVal) ? "***" : searchVal;
string currKey = $"{Utils.redisArtList}:{azienda}:{sKey}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -947,7 +947,7 @@ namespace MP.IOC.Data
/// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE
///
/// idx macchina
- /// valore ingresso
+ /// valOut ingresso
/// data-ora evento (server)
/// sequenza dati inviati
/// dati macchina in cache (opzionale, se null fa lookup)
@@ -960,8 +960,11 @@ namespace MP.IOC.Data
// processing
inputComandoMapo answ = new inputComandoMapo();
- // verifico se esista la macchina altrimenti la creo... REDIS compliant
- await verificaIdxMacchinaAsync(idxMacchina);
+ // SE no trovassi verifico se esista la macchina altrimenti la creo... REDIS compliant
+ if (!datiMacc.ContainsKey(idxMacchina))
+ {
+ await verificaIdxMacchinaAsync(idxMacchina);
+ }
// continuo processing...
string CodArticolo = datiMacc["CodArticolo"];
@@ -980,34 +983,31 @@ namespace MP.IOC.Data
int next_idxMS = 0;
try
{
- valINT = int.Parse(valore, System.Globalization.NumberStyles.HexNumber);
- try
+ valINT = int.Parse(valore, NumberStyles.HexNumber);
+ int idxFamIn = Convert.ToInt32(datiMacc["IdxFamIn"]);
+ int idxMicroStato = Convert.ToInt32(datiMacc["IdxMicroStato"]);
+ int valIOB = Convert.ToInt32(valINT);
+ next_idxMS = idxMicroStato;
+#if false
+ // verifico esistenza tab SMI...
+ var fiHASH = Utils.GetHashSMI(idxFamIn);
+ bool trovato = await RedisKeyPresentAsync(fiHASH);
+ if (!trovato)
{
- int idxFamIn = Convert.ToInt32(datiMacc["IdxFamIn"]);
- int idxMicroStato = Convert.ToInt32(datiMacc["IdxMicroStato"]);
- int valIOB = Convert.ToInt32(valINT);
- next_idxMS = idxMicroStato;
- // verifico esistenza tab SMI...
- var fiHASH = Utils.GetHashSMI(idxFamIn);
- bool trovato = await RedisKeyPresentAsync(fiHASH);
- if (!trovato)
- {
- // ricarico tabella (salvando in redis x ricerca successiva)!
- KeyValuePair[] valori = await StateMachInByKeyAsync(idxFamIn);
- }
- string todoSMI = "";
- // recupero singolo valore (stringa) x chiave
- todoSMI = valoreSMI(idxFamIn, idxMicroStato, valIOB);
- // solo se ho trovato un risultato nella tab SMI della famiglia macchina...
- if (todoSMI != "")
- {
- // splitto e salvo valori OUT...
- string[] valori = todoSMI.Split('_');
- idxTipoEv = Convert.ToInt32(valori[0]);
- next_idxMS = Convert.ToInt32(valori[1]);
- }
+ // ricarico tabella (salvando in redis x ricerca successiva)!
+ KeyValuePair[] valori = await StateMachInByKeyAsync(idxFamIn);
+ }
+#endif
+ // recupero singolo valOut (stringa) x chiave
+ string todoSMI = await ValoreSmiAsync(idxFamIn, idxMicroStato, valIOB);
+ // solo se ho trovato un risultato nella tab SMI della famiglia macchina...
+ if (!string.IsNullOrEmpty(todoSMI) && todoSMI.Contains("_"))
+ {
+ // splitto e salvo valori OUT...
+ string[] valori = todoSMI.Split('_');
+ idxTipoEv = Convert.ToInt32(valori[0]);
+ next_idxMS = Convert.ToInt32(valori[1]);
}
- catch { }
}
catch (Exception exc)
{
@@ -1015,38 +1015,35 @@ namespace MP.IOC.Data
}
// effettuo update vari SU DB!!!
- MicroStatoMacchinaModel newRec = new MicroStatoMacchinaModel()
+ MicroStatoMacchinaModel newRecMsm = new MicroStatoMacchinaModel()
{
IdxMacchina = idxMacchina,
IdxMicroStato = next_idxMS,
InizioStato = dtEve,
Value = valore
};
- await IocDbController.MicroStatoMacchinaUpsertAsync(newRec);
if (idxTipoEv > 0)
{
- try
+ // preparo record
+ string valEsteso = string.Format("[{0}] {1}", contatore.PadLeft(3, '0'), valore);
+ // creo evento
+ EventListModel newRecEv = new EventListModel()
{
- // preparo record
- string valEsteso = string.Format("[{0}] {1}", contatore.PadLeft(3, '0'), valore);
- // creo evento
- EventListModel newRecEv = new EventListModel()
- {
- CodArticolo = CodArticolo,
- IdxMacchina = idxMacchina,
- IdxTipo = idxTipoEv,
- InizioStato = dtEve,
- MatrOpr = 0,
- pallet = "-",
- Value = valEsteso
- };
- // salva e processa
- answ = await scriviRigaEventoAsync(newRecEv);
- }
- catch (Exception exc)
- {
- Log.Error($"[ChkMiSt_8a] - Eccezione:{Environment.NewLine}{exc}");
- }
+ CodArticolo = CodArticolo,
+ IdxMacchina = idxMacchina,
+ IdxTipo = idxTipoEv,
+ InizioStato = dtEve,
+ MatrOpr = 0,
+ pallet = "-",
+ Value = valEsteso
+ };
+ // salva e processa evento + microstato
+ answ = await scriviRigaEventoAsync(newRecMsm, newRecEv);
+ }
+ else
+ {
+ // solo microstato
+ await IocDbController.MicroStatoMacchinaUpsertAsync(newRecMsm);
}
return answ;
}
@@ -1112,7 +1109,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisBaseAddr}:TabDatiMacchine:ALL";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1141,7 +1138,7 @@ namespace MP.IOC.Data
List result = new();
string tag = string.IsNullOrEmpty(codArt) ? "ALL" : codArt;
string currKey = $"{Utils.redisDecNumArtKey}:{tag}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
@@ -1234,7 +1231,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtStart:yyyyMMddHHmm}:{DtEnd:yyyyMMddHHmm}:{MaxRec}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
@@ -1293,7 +1290,7 @@ namespace MP.IOC.Data
}
///
- /// Update valore dossier
+ /// Update valOut dossier
///
///
///
@@ -1325,7 +1322,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisAnagGruppi}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1443,7 +1440,7 @@ namespace MP.IOC.Data
DateTime dtEnd = dtFrom;
// max 10 dossier alla volta (se non configurato diversamente)
int maxAdd = 1;
- string confVal = await tryGetConfig("IO_numDossMaxCreate");
+ string confVal = await tryGetConfigAsync("IO_numDossMaxCreate");
if (!string.IsNullOrEmpty(confVal))
{
int.TryParse(confVal, out maxAdd);
@@ -1536,7 +1533,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisFluxLogFilt}:{IdxMacchina}:{CodFlux}:{MaxRec}:{DtMax:yyyyMMddHHmm}:{DtMin:yyyyMMddHHmm}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1550,7 +1547,7 @@ namespace MP.IOC.Data
rawData = JsonConvert.SerializeObject(result);
if (string.IsNullOrEmpty(canCacheParametri))
{
- canCacheParametri = await tryGetConfig("SPEC_ParametriEnableRedisCache");
+ canCacheParametri = await tryGetConfigAsync("SPEC_ParametriEnableRedisCache");
}
if (canCacheParametri != "false")
{
@@ -1568,7 +1565,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza
+ /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza
/// ODL NO invio/gestione ODL)
///
///
@@ -1577,7 +1574,7 @@ namespace MP.IOC.Data
{
string result = "";
string currKey = $"{Utils.redisOdlCurrByMac}:{idxMacchina}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1594,7 +1591,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza
+ /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza
/// ODL NO invio/gestione ODL)
///
///
@@ -1620,7 +1617,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore dell'ultimo ODL
+ /// Restituisce il valOut dell'ultimo ODL
///
///
///
@@ -1628,7 +1625,7 @@ namespace MP.IOC.Data
{
ODLExpModel result = new ODLExpModel();
string currKey = $"{Utils.redisOdlLastByMac}:{idxMacchina}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1720,7 +1717,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore booleano se la macchina sia abilitata all'input
+ /// Restituisce il valOut booleano se la macchina sia abilitata all'input
///
///
///
@@ -1740,7 +1737,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore booleano se la macchina sia master
+ /// Restituisce il valOut booleano se la macchina sia master
///
///
///
@@ -1765,7 +1762,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore booleano se la macchina sia abilitata all'inserimento COMPLETO nel
+ /// Restituisce il valOut booleano se la macchina sia abilitata all'inserimento COMPLETO nel
/// Signal Log
///
///
@@ -1807,7 +1804,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisGiacenzaList}:{IdxOdl}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1865,7 +1862,7 @@ namespace MP.IOC.Data
{
List? result = new List();
string currKey = $"{Utils.redisBaseAddr}:M2STab";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
@@ -1908,7 +1905,7 @@ namespace MP.IOC.Data
string readType = "DB";
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
string currKey = $"{Utils.redisMacList}:{keyGrp}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1944,7 +1941,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisMacRecipePath}:{idxMacchina}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -1979,7 +1976,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisMacRecipeConf}:{idxMacchina}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2015,7 +2012,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2151,11 +2148,11 @@ namespace MP.IOC.Data
Log.Info($"upsertCurrObjItems | idxMacchina: {idxMacchina} | {innovations.Count} innovations");
// leggo i valori attuali...
List actValues = await MachineParamListAsync(idxMacchina);
- // per ogni valore passatomi faccio insert o update rispetto elenco valori correnti
+ // per ogni valOut passatomi faccio insert o update rispetto elenco valori correnti
// in REDIS
foreach (var item in actValues)
{
- // cerco nelle innovazioni SE CI SIA il valore...
+ // cerco nelle innovazioni SE CI SIA il valOut...
var trovato = innovations.Find(obj => obj.uid == item.uid);
// se non trovato nelle innovazioni...
if (trovato == null)
@@ -2391,7 +2388,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = Utils.redisOdlByBatch;
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2474,7 +2471,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisOdlList}:Current:{IdxMacchina}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
@@ -2521,7 +2518,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisOdlCurrByMac}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2586,7 +2583,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2622,7 +2619,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisFluxByMac}:{IdxMacchina}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2688,7 +2685,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisPOdlByPOdl}:{idxPODL}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2768,7 +2765,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2818,7 +2815,7 @@ namespace MP.IOC.Data
stopWatch.Start();
string readType = "DB";
string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
- // cerco in redis dato valore sel macchina...
+ // cerco in redis dato valOut sel macchina...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
@@ -2881,7 +2878,7 @@ namespace MP.IOC.Data
if (string.IsNullOrEmpty(idxMacchina) || string.IsNullOrEmpty(valore))
{
- string errore = "processFluxLog | Errore: parametri macchina/valore vuoti";
+ string errore = "processFluxLog | Errore: parametri macchina/valOut vuoti";
Log.Error(errore);
answ = errore;
}
@@ -2896,7 +2893,7 @@ namespace MP.IOC.Data
Cnt = contatore
};
await IocDbController.FluxLogInsertAsync(newRec);
- // 2022.06.06 salvo su redis il valore ULTIMO del flux x recupero rapido ultimo valore
+ // 2022.06.06 salvo su redis il valOut ULTIMO del flux x recupero rapido ultimo valOut
var currKey = Utils.RedKeyLastFLog(idxMacchina, flux, MpIoNS);
// 10 min cache max...
await redisDb.StringSetAsync(currKey, valore, TimeSpan.FromMinutes(10));
@@ -2907,6 +2904,89 @@ namespace MP.IOC.Data
return answ;
}
+ ///
+ /// Validazione preliminare valori input
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private bool ValidateinputParams(string idxMacchina, string valore, string dtEve, string dtCurr)
+ {
+ bool isValid = false;
+ // preparo stringa valori correnti
+ string currVals = $"idxMacchina: {idxMacchina} | valOut: {valore} | dtEve: {dtEve} | dtCurr:{dtCurr}";
+ if (dtEve == null || dtCurr == null)
+ {
+ Log.Warn($"procInput: null found | {currVals}");
+ }
+ else if (dtEve.Length < 17 || dtCurr.Length < 17)
+ {
+ Log.Info($"procInput: invalid data | {currVals}");
+ }
+ else if (string.IsNullOrEmpty(idxMacchina))
+ {
+ Log.Info($"procInput: missing IdxMacchina | {currVals}");
+ }
+ else if (string.IsNullOrEmpty(valore))
+ {
+ Log.Info($"procInput: missing valOut | {currVals}");
+ }
+ else
+ {
+ isValid = true;
+ }
+ return isValid;
+ }
+
+ ///
+ /// Calcola dataora evento da info dt ricevute
+ ///
+ ///
+ ///
+ ///
+ private DateTime ParseEventTime(string dtEve, string dtCurr)
+ {
+ DateTime dataOraEvento = DateTime.Now;
+
+ // fix formato dataora in ingresso
+ string stdEve = dtFormStd(dtEve);
+ string stdCurr = dtFormStd(dtCurr);
+
+ // 2. Se le stringhe normalizzate coincidono, skip dei calcoli
+ if (stdEve != stdCurr)
+ {
+ // 3. Parsing sicuro
+ if (DateTime.TryParseExact(stdEve, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtEvento) &&
+ DateTime.TryParseExact(stdCurr, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtCorrente))
+ {
+ TimeSpan diff = dtCorrente - dtEvento;
+ double ms = Math.Abs(diff.TotalMilliseconds);
+
+ // 4. Classificazione delta con switch expression (più leggibile e performante)
+ string deltaClass = ms switch
+ {
+ <= 10 => "0-10 ms",
+ <= 100 => "10-100 ms",
+ <= 1000 => "100-1000 ms",
+ <= 10000 => "1-10 sec",
+ _ => "> 10 sec"
+ };
+
+ Log.Debug($"Correzione delta {deltaClass}");
+
+ // 5. Correzione data/ora server: sottrao lo scarto calcolato
+ dataOraEvento = dataOraEvento.Subtract(diff);
+ }
+ else
+ {
+ Log.Error($"Errore parsing date: {stdEve} | {stdCurr}");
+ }
+ }
+ return dataOraEvento;
+ }
+
///
/// Processa input da IOB eventualmente registrando i segnali inviati
///
@@ -2919,118 +2999,55 @@ namespace MP.IOC.Data
public async Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore)
{
string answ = "";
- // 2018.10.26 controllo dtEve e dtCurr
- if (dtEve == null || dtCurr == null)
+ if (ValidateinputParams(idxMacchina, valore, dtEve, dtCurr))
{
- Log.Warn(string.Format("procInput: valori nulli date: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr));
- }
- else if (dtEve.Length < 17 || dtCurr.Length < 17)
- {
- Log.Info(string.Format("procInput: valori data non corretti: idxMacchina: {0} | valore: {1} | dtEve: {2} | dtCurr:{3}", idxMacchina, valore, dtEve, dtCurr));
- }
- else
- {
- DateTime dataOraEvento = DateTime.Now;
+ DateTime dataOraEvento = ParseEventTime(dtEve, dtCurr);
- // fix formato dataora in ingresso
- string stdEve = dtFormStd(dtEve);
- string stdCurr = dtFormStd(dtCurr);
-
- // 2. Se le stringhe normalizzate coincidono, skip dei calcoli
- if (stdEve != stdCurr)
+ // se abilitato registro evento sul DB
+ if (await IobSLogEnabAsync(idxMacchina))
{
- // 3. Parsing sicuro
- if (DateTime.TryParseExact(stdEve, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtEvento) &&
- DateTime.TryParseExact(stdCurr, dtFormat, ciProvider, DateTimeStyles.None, out DateTime dtCorrente))
+ int cntVal = 0;
+ int.TryParse(contatore, out cntVal);
+ await saveSigLogAsync(idxMacchina, valore, dataOraEvento, cntVal);
+ }
+ // continuo col resto
+ try
+ {
+ // 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....
+ if (isMulti(idxMacchina, datiMacc))
{
- TimeSpan diff = dtCorrente - dtEvento;
- double ms = Math.Abs(diff.TotalMilliseconds);
-
- // 4. Classificazione delta con switch expression (più leggibile e performante)
- string deltaClass = ms switch
+ // inizio preprocessing
+ string newVal = "";
+ // processo OGNI macchina a stati dell'impianto... (KEY:IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn)
+ foreach (var item in await mTabMSMIAsync(idxMacchina))
{
- <= 10 => "0-10 ms",
- <= 100 => "10-100 ms",
- <= 1000 => "100-1000 ms",
- <= 10000 => "1-10 sec",
- _ => "> 10 sec"
- };
-
- Log.Debug($"Correzione delta {deltaClass}");
-
- // 5. Correzione data/ora server: sottrao lo scarto calcolato
- dataOraEvento = dataOraEvento.Subtract(diff);
+ newVal = preProcInput(item.Key, valore, datiMacc);
+ // ora processo e salvo il valOut del microstato...
+ // INTERNAMENTE gestisce i casi DB/REDIS secondo necessità
+ await CheckMicroStatoAsync(item.Key, newVal, dataOraEvento, contatore, datiMacc);
+ }
}
else
{
- Log.Error($"Errore parsing date: {stdEve} | {stdCurr}");
+ // ora processo e salvo il valOut del microstato... INTERNAMENTE
+ // gestisce i casi DB/REDIS secondo necessità
+ await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore, datiMacc);
}
+ // forzo RESET dati macchina...
+ await ResetDatiMacchinaAsync(idxMacchina);
+ // registro in risposta che è andato tutto bene...
+ answ = "OK";
}
- // inizio processing vero e proprio INPUT...
- if (string.IsNullOrEmpty(idxMacchina))
+ catch (Exception exc)
{
- string errore = "Errore: missing IdxMacchina";
- Log.Warn(errore);
+ string errore = $"Errore: {Environment.NewLine}{exc}";
+ Log.Error(errore);
answ = errore;
}
- else
- {
- if (string.IsNullOrEmpty(valore))
- {
- string errore = "Errore: missing valore";
- Log.Warn(errore);
- answ = errore;
- }
- else
- {
- // se abilitato registro evento sul DB
- if (await IobSLogEnabAsync(idxMacchina))
- {
- int cntVal = 0;
- int.TryParse(contatore, out cntVal);
- await saveSigLogAsync(idxMacchina, valore, dataOraEvento, cntVal);
- }
- // continuo col resto
- try
- {
- // 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, datiMacc))
- {
- // inizio preprocessing
- string newVal = "";
- // processo OGNI macchina a stati dell'impianto... (KEY:IdxMacchina / IdxMacchina#qualcosa, Val = IdxFamIn)
- foreach (var item in await mTabMSMIAsync(idxMacchina))
- {
- 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, datiMacc);
- }
- }
- else
- {
- // ora processo e salvo il valore del microstato... INTERNAMENTE
- // gestisce i casi DB/REDIS secondo necessità
- await CheckMicroStatoAsync(idxMacchina, valore, dataOraEvento, contatore, datiMacc);
- }
- // forzo RESET dati macchina...
- await ResetDatiMacchinaAsync(idxMacchina);
- // registro in risposta che è andato tutto bene...
- answ = "OK";
- }
- catch (Exception exc)
- {
- string errore = $"Errore: {Environment.NewLine}{exc}";
- Log.Error(errore);
- answ = errore;
- }
- }
- }
}
return answ;
}
@@ -3040,7 +3057,7 @@ namespace MP.IOC.Data
///
/// Macchina
/// Flusso: DI/RC/RC
- /// valore = note/valString
+ /// valOut = note/valString
/// data evento
/// data corrente
/// contatore invio
@@ -3386,9 +3403,9 @@ namespace MP.IOC.Data
return result;
}
- public string RedisGetHashField(RedisKey key, string hashField)
+ public async Task RedisGetHashFieldAsync(RedisKey key, string hashField)
{
- return redisDb.HashGet(key, hashField).ToString();
+ return await redisDb.HashGetAsync(key, hashField);
}
public bool RedisKeyPresent(RedisKey key)
@@ -3456,7 +3473,7 @@ namespace MP.IOC.Data
doClean = true;
}
- string confVal = await tryGetConfig("IO_NumReboot2Keep");
+ string confVal = await tryGetConfigAsync("IO_NumReboot2Keep");
int num2keep = int.TryParse(confVal, out int n) ? n : 5;
// insert del record + pulizia
bool fatto = await IocDbController.RemRebootLogAddAndCleanAsync(newRec, doClean, num2keep);
@@ -3591,7 +3608,7 @@ namespace MP.IOC.Data
i++;
}
// verifico il timeout (default 60 sec...)
- var sTOutSmi = await tryGetConfig("TmOut.MSMI");
+ var sTOutSmi = await tryGetConfigAsync("TmOut.MSMI");
int tOut = 60;
int.TryParse(sTOutSmi, out tOut);
tOut = tOut <= 60 ? 60 : tOut;
@@ -3822,7 +3839,7 @@ namespace MP.IOC.Data
/// salva il segnale di "microstato" (segnale) ASYNC
///
/// idx macchina
- /// valore ingresso
+ /// valOut ingresso
/// data-ora evento (server)
/// contatore sequenza dati inviati
///
@@ -3847,16 +3864,14 @@ namespace MP.IOC.Data
///
public async Task ScriviKeepAliveAsync(string IdxMacchina, DateTime oraMacchina)
{
- string nomeVar = string.Format("KeepAlive:{0}", IdxMacchina);
// cerco se ho keep alive in redis,
- DateTime adesso = DateTime.Now;
- var currKey = Utils.RedKeyHash(nomeVar);
+ var currKey = Utils.RedKeyHash($"KeepAlive:{IdxMacchina}");
bool keyPresent = await RedisKeyPresentAsync(currKey);
// se NON presente salvo in REDIS con TTL 10 sec e sul DB...
if (!keyPresent)
{
- await redisDb.StringSetAsync(currKey, adesso.ToString("s"), TimeSpan.FromSeconds(20));
- Log.Trace($"Scrittura keep alive! IdxMacchina: {IdxMacchina}");
+ DateTime adesso = DateTime.Now;
+ await redisDb.StringSetAsync(currKey, adesso.ToString("s"), TimeSpan.FromSeconds(30));
// effettuo scrittura sul DB
await IocDbController.KeepAliveUpsertAsync(IdxMacchina, DateTime.Now, oraMacchina);
}
@@ -3906,7 +3921,7 @@ namespace MP.IOC.Data
{
// hard coded dimensione vettore DatiMacchine
KeyValuePair[] answ = new KeyValuePair[1];
- // iniziualizzo con un valore... 0/0
+ // iniziualizzo con un valOut... 0/0
answ[0] = new KeyValuePair("0", "0");
// ORA recupero da memoria redis...
try
@@ -3936,9 +3951,9 @@ namespace MP.IOC.Data
}
///
- /// restituisce il valore da REDIS associato al tag richeisto
+ /// restituisce il valOut da REDIS associato al tag richeisto
///
- /// Chiave in cui cercare il valore
+ /// Chiave in cui cercare il valOut
///
public string TagConfGetKey(string redKey)
{
@@ -4005,7 +4020,7 @@ namespace MP.IOC.Data
fluxLogList.Add(editFL);
}
- // serializzo nuovamente valore
+ // serializzo nuovamente valOut
DossierFluxLogDTO? result = new DossierFluxLogDTO();
var ODLflux = result.ODL.ToList();
foreach (var item in fluxLogList)
@@ -4038,10 +4053,10 @@ namespace MP.IOC.Data
Log.Info($"upsertCurrObjItems | idxMacchina: {idxMacchina} | {innovations.Count} innovations");
// leggo i valori attuali...
List actValues = MachineParamList(idxMacchina);
- // per ogni valore passatomi faccio insert o update rispetto elenco valori correnti in REDIS
+ // per ogni valOut passatomi faccio insert o update rispetto elenco valori correnti in REDIS
foreach (var item in actValues)
{
- // cerco nelle innovazioni SE CI SIA il valore...
+ // cerco nelle innovazioni SE CI SIA il valOut...
var trovato = innovations.Find(obj => obj.uid == item.uid);
// se non trovato nelle innovazioni...
if (trovato == null)
@@ -4074,11 +4089,23 @@ namespace MP.IOC.Data
///
///
///
- public string ValoreSMI(int idxFamIn, int idxMicroStato, int valoreIn)
+ public async Task ValoreSmiAsync(int idxFamIn, int idxMicroStato, int valoreIn)
{
+ string valOut = "";
var currHash = Utils.GetHashSMI(idxFamIn);
string field = $"{idxMicroStato}_{valoreIn}";
- return RedisGetHashField(currHash, field);
+ var searchVal = await RedisGetHashFieldAsync(currHash, field);
+ if (!searchVal.HasValue)
+ {
+ // ricarico tabella (salvando in redis x ricerca successiva)!
+ var valori = await StateMachInByKeyAsync(idxFamIn);
+ if (valori.Any(x => x.Key == field))
+ {
+ searchVal = valori.FirstOrDefault(x => x.Key == field).Value;
+ }
+ }
+ valOut = $"{searchVal}";
+ return valOut;
}
///
@@ -4378,7 +4405,7 @@ namespace MP.IOC.Data
}
///
- /// Helper standardizzazione valore dataora ricevuto da IOB remoti
+ /// Helper standardizzazione valOut dataora ricevuto da IOB remoti
///
///
///
@@ -4467,7 +4494,7 @@ namespace MP.IOC.Data
}
///
- /// Restituisce il valore booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI)
+ /// Restituisce il valOut booleano se la macchina sia di tipo MULTI (con più state machine x INGRESSI)
/// usando dati macchina in cache per evitare lookup ridondanti
///
///
@@ -4543,7 +4570,7 @@ namespace MP.IOC.Data
}
///
- /// Calcola l'effettivo valore da passare alla macchina a stati INGRESSI usando dati macchina in cache
+ /// Calcola l'effettivo valOut da passare alla macchina a stati INGRESSI usando dati macchina in cache
///
///
///
@@ -4568,7 +4595,7 @@ namespace MP.IOC.Data
// non usato (x ora)
int.TryParse(datiMacc.ContainsKey("NumBit") ? datiMacc["NumBit"] : "0", out NumBit);
- // recupero valore
+ // recupero valOut
valINT = int.Parse(valore, NumberStyles.HexNumber);
// filtro
newValInt = MP.Core.Utils.bMaskInt(valINT, BitFilt);
@@ -4626,7 +4653,8 @@ namespace MP.IOC.Data
double numSecCache = redisLongTimeCache;
// converto in formato dizionario...
if (dbResult != null)
- { // salvo 1:1 i valori... STATO
+ {
+ // salvo 1:1 i valori... STATO
result.Add("IdxMicroStato", $"{dbResult.IdxMicroStato}");
result.Add("IdxStato", $"{dbResult.IdxStato}");
result.Add("CodArticolo", $"{dbResult.CodArticolo}");
@@ -4653,9 +4681,14 @@ namespace MP.IOC.Data
result.Add("IdxFamMacc", $"{dbResult.IdxFamiglia}");
result.Add("simplePallet", $"{dbResult.SimplePallet}");
result.Add("palletChange", $"{dbResult.PalletChange}");
- // durata cache in secondi dal valore insEnabled...
+ // durata cache in secondi dal valOut insEnabled...
//double numSecCache = ((result["insEnabled"].ToLower() == "true") ? redisShortTimeCache : redisLongTimeCache);
numSecCache = dbResult.InsEnabled ? redisShortTimeCache : redisLongTimeCache;
+ }
+ else
+ {
+
+
}
// dati master/slave
string isMaster = (await ListMasterAsync()).Contains(idxMacc) ? "1" : "0";
@@ -4708,8 +4741,8 @@ namespace MP.IOC.Data
i++;
}
// verifico il timeout (default 60 sec...)
- var sTOutSmi = tryGetConfig("TmOut.SMI").Result;
- int tOut = 60;
+ int tOut = 300;
+ var sTOutSmi = await tryGetConfigAsync("TmOut.SMI");
if (!string.IsNullOrEmpty(sTOutSmi))
{
int.TryParse(sTOutSmi, out tOut);
@@ -4773,6 +4806,35 @@ namespace MP.IOC.Data
return answ;
}
+ ///
+ /// Scrive una riga evento + una riga microstato insieme, ed effettua verifica necessità cambio stato
+ ///
+ /// Record MicroStatoMacchina
+ /// record EventList
+ ///
+ private async Task scriviRigaEventoAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv)
+ {
+ bool inserito = false;
+ try
+ {
+ // inserisco evento
+ inserito = await IocDbController.EvListMicroStatoInsertAsync(newRecMsm, newRecEv);
+ // faccio controllo per eventuale cambio stato da tab transizioni...
+ await CheckCambiaStatoBatchAsync(tipoInputEvento.hw, newRecEv.IdxMacchina, newRecEv.InizioStato ?? DateTime.Now, newRecEv.IdxTipo, newRecEv.CodArticolo, newRecEv.Value, newRecEv.MatrOpr, newRecEv.pallet);
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in scriviRigaEvento | IdxMacchina {newRecEv.IdxMacchina} | IdxTipo {newRecEv.IdxTipo} | codArticolo {newRecEv.CodArticolo} | Value {newRecEv.Value} | MatrOpr {newRecEv.MatrOpr} | Pallet {newRecEv.pallet} | dTime {newRecEv.InizioStato}{Environment.NewLine}{exc}");
+ }
+ // formatto output
+ inputComandoMapo answ = new inputComandoMapo();
+ answ.outValue = inserito.ToString();
+ answ.needStatusRefresh = true;
+ return answ;
+ }
+
+
+
///
/// Scrive una riga di evento manuale (barcode) nel db + check cambio stato DiarioDiBordo
///
@@ -4833,11 +4895,11 @@ namespace MP.IOC.Data
}
///
- /// Restituisce valore della stringa (SE disponibile)
+ /// Restituisce valOut della stringa (SE disponibile)
///
///
///
- private async Task tryGetConfig(string keyName)
+ private async Task tryGetConfigAsync(string keyName)
{
string answ = "";
// preselezione valori
@@ -4850,8 +4912,9 @@ namespace MP.IOC.Data
return answ;
}
+#if false
///
- /// Restituisce il valore SPECIFICATO per la state machine ingressi
+ /// Restituisce il valOut SPECIFICATO per la state machine ingressi
/// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE)
///
///
@@ -4862,8 +4925,9 @@ namespace MP.IOC.Data
{
var currHash = Utils.GetHashSMI(idxFamIn);
string field = string.Format("{0}_{1}", idxMicroStato, valoreIn);
- return RedisGetHashField(currHash, field);
- }
+ return RedisGetHashFieldAsync(currHash, field);
+ }
+#endif
///
/// cerca codice in anagrafica macchine ed eventualmente inserisce nuova macchina