diff --git a/MP.IOC/Data/IMpDataService.cs b/MP.IOC/Data/IMpDataService.cs
new file mode 100644
index 00000000..3864402b
--- /dev/null
+++ b/MP.IOC/Data/IMpDataService.cs
@@ -0,0 +1,620 @@
+using MP.Core.DTO;
+using MP.Core.Objects;
+using MP.Data.DbModels;
+using MP.Data.DbModels.Anag;
+using MP.Data.MgModels;
+using StackExchange.Redis;
+using static MP.Core.Objects.Enums;
+
+namespace MP.IOC.Data
+{
+ public interface IMpDataService
+ {
+ #region Public Methods
+
+ ///
+ /// Verifica se sia da reinviare un taskName alla macchina dall'elenco di quelli salvati (in
+ /// modalit\u00e0 upsert) se non scaduti
+ ///
+ /// idx macchina
+ /// tipo task
+ /// valore task
+ /// true se il task \u00e8 stato reinviato
+ bool AddCheckTask4Machine(string idxMacchina, taskType taskKey, string taskVal);
+
+ ///
+ /// Aggiunge un parametro opzionale all'elenco dei saved task (in modalit\u00e0 upsert)
+ ///
+ /// idx macchina
+ /// chiave del parametro
+ /// valore del parametro
+ /// true se inserito
+ bool AddOptPar4Machine(string idxMacchina, string taskKey, string taskVal);
+
+ ///
+ /// Aggiunge un task all'elenco di quelli salvati (in modalit\u00e0 upsert)
+ ///
+ /// idx macchina
+ /// tipo task
+ /// valore task
+ /// true se inserito
+ bool AddTask4Machine(string idxMacchina, taskType taskKey, string taskVal);
+
+ ///
+ /// Aggiunge un set di task per macchina all'elenco di quelli salvati (in modalit\u00e0 upsert)
+ ///
+ /// idx macchina
+ /// Dizionario di task tipo-valore da salvare
+ /// true se completato
+ Task AddTask4MacListAsync(string idxMacchina, Dictionary taskDict);
+
+ ///
+ /// Inserimento record allarme su DB
+ ///
+ /// Data evento
+ /// Nome macchina
+ /// Indirizzo memoria PLC
+ /// Indice memoria
+ /// Stato valOut
+ /// Valore decodificato
+ /// true se inserito
+ Task AlarmInsertAsync(DateTime dtRif, string idxMacchina, string memAddress, int memIndex, int statusVal, string valDecoded);
+
+ ///
+ /// Restituisce l'anagrafica STATI per intero con cache Fusion
+ ///
+ /// Lista di modelli AnagStatiModel
+ Task> AnagStatiGetAllAsync();
+
+ ///
+ /// Restituisce i modelli di ultimo articolo per data macchina, con cache Fusion
+ ///
+ /// idx macchina
+ /// Lista di modelli AnagArticoliModel
+ Task> ArticoliGetLastByMaccAsync(string idxMacc);
+
+ ///
+ /// Effettua lo split dell'ODL corrente per la macchina, con eventuale conferma produzione e
+ /// gestione slave
+ ///
+ /// idx macchina
+ /// effettuare la conferma quantitativa
+ /// imposta la qty del prossimo ODL da quello che si chiude
+ /// matricola operatore
+ /// Step di arrotondamento quantit\u00e0
+ /// Chiave esterna da associare all'ODL
+ /// "OK" se successo, "KO" altrimenti
+ Task AutoStartOdlAsync(string idxMacchina, bool doConfirm, bool qtyFromLast, int matrOpr, int roundStep = 100, string keyRichiesta = "");
+
+ ///
+ /// Calcola la ricetta su MongoDB dato modello ricetta corrente
+ ///
+ /// Modello ricetta da calcolare
+ /// Risultato del calcolo ricetta
+ string CalcRecipe(RecipeModel currRecipe);
+
+ ///
+ /// Controlla se dal segnale di "microstato" deriva un evento da generare - modalit\u00e0 OFFLINE
+ ///
+ /// idx macchina
+ /// valore valOut ingresso
+ /// data-ora evento (server)
+ /// sequenza dati inviati
+ /// dati macchina in cache (opzionale, se null fa lookup)
+ /// Risultato del processing
+ Task CheckMicroStatoAsync(string idxMacchina, string valore, DateTime dtEve, string contatore, Dictionary? datiMaccCache = null);
+
+ ///
+ /// Restituisce l'elenco completo delle configurazioni da DB, con cache Fusion
+ ///
+ /// Lista di modelli ConfigModel
+ Task> ConfigGetAllAsync();
+
+ ///
+ /// Restituisce l'elenco delle decodifiche articoli filtrata per codice, con cache Fusion
+ ///
+ /// codice articolo (opzionale, se vuoto restituisce tutto)
+ /// Lista di modelli DecNumArticoliModel
+ Task> DecNumArtGetFiltAsync(string codArt = "");
+
+ ///
+ /// Restituisce le date dei dossier per una macchina, con cache Fusion
+ ///
+ /// idx macchina
+ /// Lista di modelli DossierModel
+ Task> DossierLastByMachAsync(string idxMacchina);
+
+ ///
+ /// Task completo per sistemazione dossier quotidiani mancanti
+ ///
+ /// idx macchina
+ /// "OK" se completato
+ Task FixDailyDossierAsync(string idxMacc);
+
+ ///
+ /// Restituisce il codice valOut dell'ODL corrente (con cache redis interna)
+ ///
+ /// idx macchina
+ /// codice valOut dell'ODL corrente
+ Task GetCurrOdlAsync(string idxMacchina);
+
+ ///
+ /// Restituisce il modello dell'ultimo ODL per macchina, con cache Fusion
+ ///
+ /// idx macchina
+ /// Modello ODLExpModel
+ Task GetLastOdlAsync(string idxMacchina);
+
+ ///
+ /// Effettua il calcolo della data-ora di riferimento per il server, correggendo il delta
+ /// tra orologio macchina e server
+ ///
+ /// data-oras dell'evento (macchina)
+ /// data-ora corrente (server)
+ /// Data-ora evento corretta
+ DateTime GetSrvDtEvent(string dtEve, string dtCurr);
+
+ ///
+ /// Restituisce se la macchina sia abilitata all'inserimento dati da IOB
+ ///
+ /// idx macchina
+ /// true se abilitato all'input
+ Task IobInsEnabAsync(string idxMacchina);
+
+ ///
+ /// Restituisce se la macchina sia abilitata come master di un impianto
+ ///
+ /// idx macchina
+ /// true se \u00e8 master
+ Task IobIsMasterAsync(string idxMacchina);
+
+ ///
+ /// Restituisce se la macchina sia abilitata all'inserimento nel Signal Log
+ ///
+ /// idx macchina
+ /// true se abilitato
+ Task IobSLogEnabAsync(string idxMacchina);
+
+ ///
+ /// Restituisce i valori ammessi per una tabella/colonna (con cache redis interna)
+ ///
+ /// nome tabella
+ /// nome campo
+ /// Lista di ListValuesModel
+ Task> ListValuesFilt(string tabName, string fieldName);
+
+ ///
+ /// Restituisce l'elenco completo delle relazioni macchine master-slave, con cache Fusion
+ ///
+ /// Lista di Macchine2SlaveModel
+ Task> Macchine2SlaveGetAllAsync();
+
+ ///
+ /// Restituisce le macchine filtrate per gruppo, con cache Fusion
+ ///
+ /// codice gruppo (o "*" per tutto)
+ /// Lista di MacchineModel
+ Task> MacchineGetFilt(string codGruppo);
+
+ ///
+ /// Restituisce il path delle ricette di una macchina, con cache Fusion
+ ///
+ /// idx macchina
+ /// Path delle ricette
+ Task MacchineRecipeArchive(string idxMacchina);
+
+ ///
+ /// Restituisce la lista parametri correnti (ObjItemDTO) della macchina da Redis
+ ///
+ /// idx macchina
+ /// Lista di ObjItemDTO
+ Task> MachineParamListAsync(string idxMacchina);
+
+ ///
+ /// Restituisce i parametri correnti della macchina che necessitano di write (writable + reqValue valorizzato)
+ ///
+ /// idx macchina
+ /// Lista di ObjItemDTO
+ Task> MachineParamListPendingWriteAsync(string idxMacchina);
+
+ ///
+ /// Imposta i parametri correnti (ObjItemDTO) nella cache Redis della macchina
+ ///
+ /// idx macchina
+ /// dati parametri da impostare
+ /// true se salvato
+ Task MachineParamListSetAsync(string idxMacchina, List currData);
+
+ ///
+ /// Effettua l'UPSERT degli elementi dei parametri macchina in Redis
+ ///
+ /// idx macchina
+ /// nuovi elementi da aggiungere/aggiornare
+ /// true se completato
+ Task MachineParamUpsertAsync(string idxMacchina, List innovations);
+
+ ///
+ /// Restituisce i campi DatiMacchine + StatoMacchine come dizionario (da Redis o DB)
+ ///
+ /// idx macchina
+ /// Dizionario KVP dei campi macchina
+ Task> mDatiMacchineAsync(string idxMacchina);
+
+ ///
+ /// Restituisce i parametri ottimizzati per la macchine (Redis hash sync)
+ ///
+ /// idx macchina
+ /// Dizionario KVP parametri
+ Dictionary mOptParMacchina(string idxMacchina);
+
+ ///
+ /// Restituisce i task salvati della macchina (Redis hash sync)
+ ///
+ /// idx macchina
+ /// Dizionario KVP dei task salvati
+ Dictionary mSavedTaskMacchina(string idxMacchina);
+
+ ///
+ /// Restituisce l'elenco dalla tabella MappaStatoExpl, con o senza cache
+ ///
+ /// se true forza lettura database senza cache
+ /// Lista di MappaStatoExplModel
+ Task> MseGetAllAsync(bool forceDb = false);
+
+ ///
+ /// Restituisce il dizionario KVP della tabella Multi State Machine Ingressi (da Redis)
+ ///
+ /// idx macchina
+ /// Array di KeyValuePair
+ Task[]> mTabMSMIAsync(string idxMacchina);
+
+ ///
+ /// Restituisce i task in esecuzione per la macchina (Redis hash sync)
+ ///
+ /// idx macchina
+ /// Dizionario KVP dei task
+ Dictionary mTaskMacchina(string idxMacchina);
+
+ ///
+ /// Restituisce i task in esecuzione per la macchina (Redis hash async)
+ ///
+ /// idx macchina
+ /// Dizionario KVP dei task
+ Task> mTaskMacchinaAsync(string idxMacchina);
+
+ ///
+ /// Generazione automatica ODL giornalieri per la macchina
+ ///
+ /// idx macchina
+ /// data di inizio generazione
+ /// data di fine generazione
+ /// codice articolo
+ /// true se generato con successo
+ Task OdlAutoDayGenAsync(string idxMacchina, DateTime dataInizio, DateTime dataFine, string codArticolo);
+
+ ///
+ /// Generazione automatica ODL giornalieri completa con tutti i parametri PO/TC
+ ///
+ /// idx macchina
+ /// data inizio
+ /// data fine
+ /// codice articolo
+ /// pezzi per PODL
+ /// pezzi per pallet
+ /// chiave richiesta
+ /// TC assegnato
+ /// codice gruppo
+ /// flag crea PODL
+ /// flag verifica TC
+ /// true se generato con successo
+ Task OdlAutoDayGenFullAsync(string idxMacchina, DateTime dataInizio, DateTime dataFine, string codArticolo, int? pzPODL, int? pzPallet, string? keyRichiesta, int? tcAssegnato, string? codGruppo, bool flgCreaPODL, bool flgCheckTC);
+
+ ///
+ /// Restituisce l'ODL corrente per macchina, con cache Fusion
+ ///
+ /// idx macchina
+ /// Modello ODLExpModel
+ Task OdlCurrByMaccAsync(string IdxMacchina);
+
+ ///
+ /// Restituisce il modello PODL dato il suo indice, con cache Fusion
+ ///
+ /// indice PODL
+ /// Modello PODLModel
+ Task POdlGetByKey(int idxPODL);
+
+ ///
+ /// Restituisce i PODL per macchina/articolo, con cache Fusion
+ ///
+ /// idx macchina
+ /// codice articolo
+ /// codice gruppo
+ /// solo PODL liberi
+ /// Lista di PODLExpModel
+ Task> POdlGetByMaccArtAsync(string idxMacchina, string codArticolo, string codGruppo, bool onlyFree);
+
+ ///
+ /// Processa la registrazione di un flusso (FL) da IOB
+ ///
+ /// idx macchina
+ /// codice flusso (es. Ingresso, Uscita)
+ /// valore valOut del flusso
+ /// data-ora dell'evento (macchina)
+ /// data-ora corrente (server)
+ /// contatore invio
+ /// se true disabilita la scrittura del keepalive
+ /// "OK" se completato
+ Task ProcessFluxLogAsync(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore, bool disabKA);
+
+ ///
+ /// Processa un input completo da IOB (verifica parametri, log segnali, processing microstato)
+ ///
+ /// idx macchina
+ /// valore valOut
+ /// data-ora evento (macchina)
+ /// data-ora corrente (server)
+ /// contatore
+ /// "OK" se completato, error message in caso contrario
+ Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore);
+
+ ///
+ /// Processa un UserLog registrato da IOB (DI=dichiarazioni, RC=controlli, RS=scarti)
+ ///
+ /// idx macchina
+ /// tipo flusso: DI (Dichiarazione), RC (Controllo), RS (Scarto)
+ /// valore/testo
+ /// data-ora evento
+ /// data-ora corrente
+ /// contatore invio dati
+ /// matricola operatore
+ /// causale scarto o tagCode
+ /// esitoOk (0/1) o quantit\u00e0 scarto
+ /// "OK" se completato
+ Task ProcessUserLogAsync(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore, int matrOpr, string label, int valNum);
+
+ ///
+ /// Restituisce il contapezzi salvato in Redis per la macchina
+ ///
+ /// idx macchina
+ /// Contatore pezzi (-1 se non trovato)
+ Task pzCounter(string idxMacchina);
+
+ ///
+ /// Restituisce il contapezzi come conteggio da TCRilevati (dal DB)
+ ///
+ /// idx macchina
+ /// Conteggio pezzi (-1 se non trovato)
+ Task PzCounterTcAsync(string idxMacchina);
+
+ ///
+ /// Ricerca la ricetta su MongoDB dato l'indice del PODL
+ ///
+ /// indice PODL di riferimento
+ /// Modello ricetta o null
+ Task RecipeGetByPODL(int idxPODL);
+
+ ///
+ /// Effettua il conteggio delle chiavi Redis che corrispondono a un pattern
+ ///
+ /// pattern di ricerca
+ /// Numero di chiavi trovate
+ int RedisCountKey(string keyPattern);
+
+ ///
+ /// Elimina una chiave dalla memoria Redis
+ ///
+ /// chiave da eliminare
+ /// true se eliminata
+ bool RedisDelKey(string keyVal);
+
+ ///
+ /// Elimina una chiave dalla memoria Redis (async)
+ ///
+ /// chiave da eliminare
+ /// true se eliminata
+ Task RedisDelKeyAsync(RedisKey keyVal);
+
+ ///
+ /// Esegue il flush di tutte le chiavi Redis che corrispondono a un pattern
+ ///
+ /// pattern di ricerca
+ /// true se completato
+ Task RedisFlushPatternAsync(RedisValue pattern);
+
+ ///
+ /// Leggo un hash Redis come array di KeyValuePair (sync)
+ ///
+ /// chiave Redis
+ /// Array di KeyValuePair
+ KeyValuePair[] RedisGetHash(RedisKey redKey);
+
+ ///
+ /// Leggo un hash Redis come array di KeyValuePair (async)
+ ///
+ /// chiave Redis
+ /// Array di KeyValuePair
+ Task[]> RedisGetHashAsync(RedisKey redKey);
+
+ ///
+ /// Leggo un hash Redis come dizionario (sync)
+ ///
+ /// chiave Redis
+ /// Dizionario KVP
+ Dictionary RedisGetHashDict(RedisKey hashKey);
+
+ ///
+ /// Leggo un hash Redis come dizionario (async)
+ ///
+ /// chiave Redis
+ /// Dizionario KVP
+ Task> RedisGetHashDictAsync(RedisKey hashKey);
+
+ ///
+ /// Leggo un singolo campo di un hash Redis (async)
+ ///
+ /// chiave Redis
+ /// nome campo hash
+ /// Valore del campo
+ Task RedisGetHashFieldAsync(RedisKey key, string hashField);
+
+ ///
+ /// Verifica se una chiave esista in Redis (sync)
+ ///
+ /// chiave Redis
+ /// true se la chiave esiste
+ bool RedisKeyPresent(RedisKey key);
+
+ ///
+ /// Verifica se una chiave esista in Redis (async)
+ ///
+ /// chiave Redis
+ /// true se la chiave esiste
+ Task RedisKeyPresentAsync(RedisKey key);
+
+ ///
+ /// Imposta un hash Redis con expiration opzionale (sync)
+ ///
+ /// chiave Redis
+ /// array di coppie chiave-valore da inserire
+ /// TTL in secondi (-1 = nessuna expiration)
+ void RedisSetHash(RedisKey redKey, KeyValuePair[] valori, double expireSeconds = -1.0);
+
+ ///
+ /// Imposta un hash Redis con expiration opzionale (async)
+ ///
+ /// chiave Redis
+ /// array di coppie chiave-valore da inserire
+ /// TTL in secondi (-1 = nessuna expiration)
+ Task RedisSetHashAsync(RedisKey redKey, KeyValuePair[] valori, double expireSeconds = -1.0);
+
+ ///
+ /// Imposta un hash Redis con expiration opzionale (sync) da dizionario
+ ///
+ /// chiave Redis
+ /// dizionario di coppie chiave-valore da inserire
+ /// TTL in secondi (-1 = nessuna expiration)
+ void RedisSetHashDict(RedisKey redKey, Dictionary valori, double expireSeconds = -1.0);
+
+ ///
+ /// Imposta un hash Redis con expiration opzionale (async) da dizionario
+ ///
+ /// chiave Redis
+ /// dizionario di coppie chiave-valore da inserire
+ /// TTL in secondi (-1 = nessuna expiration)
+ Task RedisSetHashDictAsync(RedisKey redKey, Dictionary valori, double expireSeconds = -1.0);
+
+ ///
+ /// Inserimento record RemoteRebootLog con eventuale pulizia dei record vecchi
+ ///
+ /// record da inserire
+ /// true se completato
+ Task RemRebootLogAddAsync(RemoteRebootLogModel newRec);
+
+ ///
+ /// Elimina un task da elenco Redis per l'impianto indicato
+ ///
+ /// idx macchina
+ /// nome task da eliminare
+ /// Dizionario KVP rimanente
+ Task> RemTask2ExeMacchinaAsync(string idxMacchina, taskType tName);
+
+ ///
+ /// Resetta la tabella Multi State Machine Ingressi per macchina rileggendola dal DB
+ ///
+ /// idx macchina
+ /// Array di KVP della State Machine Ingressi
+ Task[]> resetMSMIAsync(string idxMacchina);
+
+ ///
+ /// Registra la movimentazione di un carico pezzi su Redis
+ ///
+ /// idx macchina
+ /// quantit\u00e0 da registrare
+ /// "OK" se completato
+ Task saveCaricoPezzi(string idxMacchina, string qty);
+
+ ///
+ /// Salva un elenco di dati macchina in DB
+ ///
+ /// identificativo della serie dati
+ /// elenco di dati macchina da salvare
+ /// true se salvato
+ Task SaveDataItemsAsync(string id, List dataList);
+
+ ///
+ /// Salva i dati macchina-IOB (serializzazione JSON) su Redis
+ ///
+ /// idx macchina
+ /// dati JSON serializzati
+ /// true se salvato
+ Task SaveMachine2Iob(string idxMacchina, string serData);
+
+ ///
+ /// Salva la configurazione della macchina come dizionario su Redis
+ ///
+ /// idx macchina
+ /// dizionario di configurazione
+ /// true se salvato
+ Task SaveMachineIobConf(string idxMacchina, Dictionary currDict);
+
+ ///
+ /// Salva il segnale di "microstato" come record SignalLog su DB (async)
+ ///
+ /// idx macchina
+ /// valOut ingresso
+ /// data-ora evento (server)
+ /// contatore sequenza dati inviati
+ /// true se salvato
+ Task saveSigLogAsync(string idxMacchina, string valore, DateTime dtEve, int contatore);
+
+ ///
+ /// Scrive un evento di keepalive se non presente in Redis con TTL
+ ///
+ /// idx macchina
+ /// ora macchina
+ Task ScriviKeepAliveAsync(string IdxMacchina, DateTime oraMacchina);
+
+ ///
+ /// Salva la configurazione YAML completa dell'IOB su Redis
+ ///
+ /// idx macchina
+ /// configurazione YAML completa
+ /// true se salvata
+ Task SetIobConfYamlAsync(string idxMacchina, string iobConfFull);
+
+ ///
+ /// Salva la mappatura memoria PLC su Redis
+ ///
+ /// idx macchina
+ /// mappatura PLC da salvare
+ /// true se salvata
+ Task SetIobMemMap(string idxMacchina, PlcMemMapDto currMap);
+
+ ///
+ /// Restituisce la tabella key-value della State Machine Ingressi per famiglia,
+ /// rileggendola dal DB e salvandola in Redis
+ ///
+ /// idx famiglia ingressi
+ /// Array di KVP (currentMicroStato_nVal -> IdxTipoEv_nStato)
+ Task[]> StateMachInByKeyAsync(int idxFamIn);
+
+ ///
+ /// Effettua l'UPSERT degli oggetti corrente della macchina su Redis (legacy compatibilit\u00e0)
+ ///
+ /// idx macchina
+ /// dati da aggiornare/aggiungere
+ /// true se completato
+ Task UpsertCurrObjItemsAsync(string idxMacchina, List innovations);
+
+ ///
+ /// Restituisce il valore SPECIFICATO per la state machine ingressi in formato hash Redis
+ ///
+ /// idx famiglia ingressi
+ /// idx microstato
+ /// valore ingresso
+ /// valore (IdxFamIn_nValore) dalla tab SMI Redis
+ Task ValoreSmiAsync(int idxFamIn, int idxMicroStato, int valoreIn);
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs
index 603f52a0..ec12bc77 100644
--- a/MP.IOC/Data/MpDataService.cs
+++ b/MP.IOC/Data/MpDataService.cs
@@ -7,7 +7,10 @@ using MP.Data.Controllers;
using MP.Data.DbModels;
using MP.Data.DbModels.Anag;
using MP.Data.MgModels;
+using MP.Data.Repository.Anag;
+using MP.Data.Repository.IOC;
using MP.Data.Repository.Production;
+using MP.Data.Repository.System;
using MP.Data.Services.IOC;
using MP.Data.Services.Mtc;
using Newtonsoft.Json;
@@ -16,21 +19,14 @@ using StackExchange.Redis;
using System.Data;
using System.Diagnostics;
using System.Globalization;
-using MP.Data.Repository.IOC;
-using MP.Data.Repository.Anag;
-using MP.Data.Repository.System;
using ZiggyCreatures.Caching.Fusion;
using static MP.Core.Objects.Enums;
namespace MP.IOC.Data
{
- public class MpDataService
+ public class MpDataService : IMpDataService
{
#region Public Constructors
- private readonly IProductionRepository _productionRepository;
- private readonly IIocRepository _iocRepository;
- private readonly IAnagRepository _anagRepository;
- private readonly ISystemRepository _systemRepository;
public MpDataService(
IConfiguration configuration,
@@ -95,34 +91,24 @@ namespace MP.IOC.Data
mongoController = new MpMongoController(configuration);
Log.Info("MongoController INIT OK");
}
-
}
#endregion Public Constructors
#region Public Properties
- public static MpMongoController mongoController { get; set; } = null!;
public static MpIocController IocDbController { get; set; } = null!;
+ public static MpMongoController mongoController { get; set; } = null!;
public MessagePipe BroadastMsgPipe { get; set; } = null!;
- ///
- /// Dizionario dei tag configurati per IOB
- ///
+ ///
public Dictionary> currTagConf { get; set; } = new Dictionary>();
#endregion Public Properties
#region Public Methods
- ///
- /// Verifica se sia da reinviare un tName alla macchina dall'elenco di quelli salvati (in
- /// modalità upsert) se non scaduti
- ///
- ///
- ///
- ///
- ///
+ ///
public bool AddCheckTask4Machine(string idxMacchina, taskType taskKey, string taskVal)
{
bool answ = false;
@@ -153,13 +139,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Aggiunge un PARAMETRO OPZIONALE all'elenco di quelli salvati (in modalità upsert)
- ///
- ///
- ///
- ///
- ///
+ ///
public bool AddOptPar4Machine(string idxMacchina, string taskKey, string taskVal)
{
bool answ = false;
@@ -187,13 +167,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Aggiunge un tName all'elenco di quelli salvati (in modalità upsert)
- ///
- ///
- ///
- ///
- ///
+ ///
public bool AddTask4Machine(string idxMacchina, Enums.taskType taskKey, string taskVal)
{
bool answ = false;
@@ -245,13 +219,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Aggiunge un set di task x macchina all'elenco di quelli salvati (in modalità upsert)
- ///
- ///
- ///
- ///
- ///
+ ///
public async Task AddTask4MacListAsync(string idxMacchina, Dictionary taskDict)
{
bool answ = false;
@@ -310,16 +278,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Insert record allarme
- ///
- /// Data evento
- /// Idx macchina
- /// area memoria
- /// indice memoria
- /// valOut status
- /// valOut decodificato
- ///
+ ///
public async Task AlarmInsertAsync(DateTime dtRif, string idxMacchina, string memAddress, int memIndex, int statusVal, string valDecoded)
{
// aggiorno record sul DB
@@ -328,9 +287,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restituisce l'anagrafica STATI per intero
- ///
+ ///
public async Task> AnagStatiGetAllAsync()
{
return await GetOrFetchAsync(
@@ -342,11 +299,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Elenco ultimi articoli data amcchina
- ///
- ///
- ///
+ ///
public async Task> ArticoliGetLastByMaccAsync(string idxMacc)
{
return await GetOrFetchAsync(
@@ -358,16 +311,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Effettua split ODL
- ///
- /// macchina
- /// effettuare conferma qty
- /// imposta la qty prox ODL da ODL che si chiude
- /// matricola operatore
- /// Round Step quantità prox ODL (corrente come riferimento)
- /// Cod ext da associare all'ODL
- ///
+ ///
public async Task AutoStartOdlAsync(string idxMacchina, bool doConfirm, bool qtyFromLast, int matrOpr, int roundStep = 100, string keyRichiesta = "")
{
string answ = "KO";
@@ -640,15 +584,7 @@ namespace MP.IOC.Data
return mongoController.CalcRecipe(currRecipe);
}
- ///
- /// controlla se da il segnale di "microstato" deriva un evento da generare - modalità OFFLINE
- ///
- /// idx macchina
- /// valOut 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, Dictionary? datiMaccCache = null)
{
// recupero SE IMPIEGATO REDIS i valori del Dictionary della macchina...
@@ -757,12 +693,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Restituisce l'elenco delle date dei dossier x una macchina (se presenti) Impiegata anche
- /// cache redis
- ///
- ///
- ///
+ ///
public async Task> DossierLastByMachAsync(string idxMacchina)
{
return await GetOrFetchAsync(
@@ -774,11 +705,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Task completo sistemazione dossier quotidiani mancanti
- ///
- ///
- ///
+ ///
public async Task FixDailyDossierAsync(string idxMacc)
{
string answ = "";
@@ -855,12 +782,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza
- /// ODL NO invio/gestione ODL)
- ///
- ///
- ///
+ ///
public async Task GetCurrOdlAsync(string idxMacchina)
{
string result = "";
@@ -881,11 +803,7 @@ namespace MP.IOC.Data
return result;
}
- ///
- /// Restituisce il valOut dell'ultimo ODL
- ///
- ///
- ///
+ ///
public async Task GetLastOdlAsync(string idxMacchina)
{
return await GetOrFetchAsync(
@@ -897,12 +815,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Effettua calcolo data-ora di riferimento per il server a partire da
- ///
- ///
- ///
- ///
+ ///
public DateTime GetSrvDtEvent(string dtEve, string dtCurr)
{
DateTime dataOraEvento = DateTime.Now;
@@ -949,11 +862,7 @@ namespace MP.IOC.Data
return dataOraEvento;
}
- ///
- /// Restituisce il valOut booleano se la macchina sia abilitata all'input
- ///
- ///
- ///
+ ///
public async Task IobInsEnabAsync(string idxMacchina)
{
var key = Utils.RedKeyDatiMacc(idxMacchina, MpIoNS);
@@ -969,11 +878,7 @@ namespace MP.IOC.Data
return val != null && (val == "1" || val.ToLower() == "true");
}
- ///
- /// Restituisce il valOut booleano se la macchina sia master
- ///
- ///
- ///
+ ///
public async Task IobIsMasterAsync(string idxMacchina)
{
var key = Utils.RedKeyDatiMacc(idxMacchina, MpIoNS);
@@ -994,12 +899,7 @@ namespace MP.IOC.Data
return val != null && (val == "1" || val.ToLower() == "true");
}
- ///
- /// Restituisce il valOut booleano se la macchina sia abilitata all'inserimento COMPLETO nel
- /// Signal Log
- ///
- ///
- ///
+ ///
public async Task IobSLogEnabAsync(string idxMacchina)
{
bool answ = false;
@@ -1052,10 +952,7 @@ namespace MP.IOC.Data
return resultList;
}
- ///
- /// Elenco completo valori Macchine 2 Slave
- ///
- ///
+ ///
public async Task> Macchine2SlaveGetAllAsync()
{
return await GetOrFetchAsync(
@@ -1067,11 +964,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Elenco di tutte le macchine gestite
- ///
- ///
- ///
+ ///
public async Task> MacchineGetFilt(string codGruppo)
{
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
@@ -1084,11 +977,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Verifica se la macchina abbia un codice PATH ricette associato
- ///
- ///
- ///
+ ///
public async Task MacchineRecipeArchive(string idxMacchina)
{
return await GetOrFetchAsync(
@@ -1105,11 +994,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Lista parametri correnti (ObjItemDTO) della macchina (ex getCurrObjItems)
- ///
- ///
- ///
+ ///
public async Task> MachineParamListAsync(string idxMacchina)
{
// setup parametri costanti
@@ -1140,11 +1025,7 @@ namespace MP.IOC.Data
return result;
}
- ///
- /// Lista parametri correnti che necessitano di write della macchina (ex getCurrObjItems)
- ///
- ///
- ///
+ ///
public async Task> MachineParamListPendingWriteAsync(string idxMacchina)
{
List? result = new List();
@@ -1154,12 +1035,7 @@ namespace MP.IOC.Data
return result;
}
- ///
- /// Esegue aggiornamento MachineParamList (ex CurrObjItems) Async
- ///
- ///
- ///
- ///
+ ///
public async Task MachineParamListSetAsync(string idxMacchina, List currData)
{
string serVal = JsonConvert.SerializeObject(currData);
@@ -1168,12 +1044,7 @@ namespace MP.IOC.Data
return fatto;
}
- ///
- /// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD)
- ///
- ///
- ///
- ///
+ ///
public async Task MachineParamUpsertAsync(string idxMacchina, List innovations)
{
bool answ = false;
@@ -1216,11 +1087,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restitusice elenco KVP dei campi DatiMacchine + StatoMacchine per l'impianto indicato
- ///
- ///
- ///
+ ///
public async Task> mDatiMacchineAsync(string idxMacchina)
{
// hard coded dimensione vettore DatiMacchine
@@ -1243,11 +1110,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
- ///
- ///
- ///
+ ///
public Dictionary mOptParMacchina(string idxMacchina)
{
// hard coded dimensione vettore DatiMacchine
@@ -1258,11 +1121,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restitusice elenco KVP dei TASK SALVATI (da passare a IOB-WIN) per l'impianto indicato
- ///
- ///
- ///
+ ///
public Dictionary mSavedTaskMacchina(string idxMacchina)
{
// hard coded dimensione vettore DatiMacchine
@@ -1280,10 +1139,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Elenco da tabella MappaStatoExplModel
- ///
- ///
+ ///
public async Task> MseGetAllAsync(bool forceDb = false)
{
if (forceDb)
@@ -1299,11 +1155,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Restitusice elenco KVP (async) per evitare blocchi quando chiamato da metodi asincroni
- ///
- ///
- ///
+ ///
public async Task[]> mTabMSMIAsync(string idxMacchina)
{
KeyValuePair[] answ = new KeyValuePair[1];
@@ -1324,11 +1176,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
- ///
- ///
- ///
+ ///
public Dictionary mTaskMacchina(string idxMacchina)
{
// hard coded dimensione vettore DatiMacchine
@@ -1346,11 +1194,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato
- ///
- ///
- ///
+ ///
public async Task> mTaskMacchinaAsync(string idxMacchina)
{
// hard coded dimensione vettore DatiMacchine
@@ -1361,35 +1205,14 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Generazione autoOdl
- ///
- ///
- ///
- ///
- ///
- ///
+ ///
public async Task OdlAutoDayGenAsync(string idxMacchina, DateTime dataInizio, DateTime dataFine, string codArticolo)
{
var result = await IocDbController.OdlAutoDayGenAsync(idxMacchina, dataInizio, dataFine, codArticolo);
return result;
}
- ///
- /// Generazione autoOdl
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ ///
public async Task OdlAutoDayGenFullAsync(string idxMacchina, DateTime dataInizio, DateTime dataFine, string codArticolo, int? pzPODL, int? pzPallet, string? keyRichiesta, int? tcAssegnato, string? codGruppo, bool flgCreaPODL, bool flgCheckTC)
{
var result = await IocDbController.OdlAutoDayGenFullAsync(idxMacchina, dataInizio, dataFine, codArticolo, pzPODL, pzPallet, keyRichiesta, tcAssegnato, codGruppo, flgCreaPODL, flgCheckTC);
@@ -1407,11 +1230,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Recupero PODL da chiave
- ///
- ///
- ///
+ ///
public async Task POdlGetByKey(int idxPODL)
{
if (idxPODL == 0)
@@ -1431,7 +1250,7 @@ namespace MP.IOC.Data
public async Task> POdlGetByMaccArtAsync(string idxMacchina, string codArticolo, string codGruppo, bool onlyFree)
{
var currKey = $"{Utils.redisPOdlByMaccArt}:{idxMacchina}";
-
+
return await GetOrFetchAsync(
operationName: "POdlGetByMaccArtAsync",
cacheKey: $"{Utils.redisPOdlByMaccArt}:{idxMacchina}{(string.IsNullOrEmpty(codArticolo) ? "" : $":A{codArticolo}")}{(string.IsNullOrEmpty(codGruppo) ? "" : $":G{codGruppo}")}{(onlyFree ? ":FREE" : ":ALL")}",
@@ -1441,17 +1260,7 @@ namespace MP.IOC.Data
);
}
- ///
- /// Processa registrazione FL da IOB
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ ///
public async Task ProcessFluxLogAsync(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore, bool disabKA)
{
// se non vietato...
@@ -1493,98 +1302,7 @@ 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
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ ///
public async Task ProcessInputAsync(string idxMacchina, string valore, string dtEve, string dtCurr, string contatore)
{
string answ = "";
@@ -1641,19 +1359,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Processa registrazione UserLog da IOB
- ///
- /// Macchina
- /// Flusso: DI/RC/RC
- /// valOut = note/valString
- /// data evento
- /// data corrente
- /// contatore invio
- /// Matricola Operatore
- /// label = causale scarto / tagCode
- /// valNum = esitoOk (0/1) / Quantità di scarto associata
- ///
+ ///
public async Task ProcessUserLogAsync(string idxMacchina, string flux, string valore, string dtEve, string dtCurr, int contatore, int matrOpr, string label, int valNum)
{
// scrivo keep alive!!! (se necessario, altrimenti è in cache...)
@@ -1716,11 +1422,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restituisce il contapezzi salvato per la macchina
- ///
- ///
- ///
+ ///
public async Task pzCounter(string idxMacchina)
{
int answ = -1;
@@ -1745,11 +1447,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restituisce il contapezzi come CONTEGGIO da TCRilevati per la macchina - ASYNC
- ///
- ///
- ///
+ ///
public async Task PzCounterTcAsync(string idxMacchina)
{
int answ = -1;
@@ -1762,11 +1460,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Ricerca ricetta su MongoDB dato PODL
- ///
- ///
- ///
+ ///
public async Task RecipeGetByPODL(int idxPODL)
{
RecipeModel? result = null;
@@ -1780,11 +1474,7 @@ namespace MP.IOC.Data
return result;
}
- ///
- /// Effettua conteggio chaivi REDIS dato pattern ricerca
- ///
- ///
- ///
+ ///
public int RedisCountKey(string keyPattern)
{
int num = 0;
@@ -1809,32 +1499,20 @@ namespace MP.IOC.Data
return num;
}
- ///
- /// Esegue eliminazione memoria redis keyVal
- ///
- ///
- ///
+ ///
public bool RedisDelKey(string keyVal)
{
bool answ = redisDb.KeyDelete((RedisKey)keyVal);
return answ;
}
- ///
- /// Esegue eliminazione memoria redis keyVal
- ///
- ///
- ///
+ ///
public async Task RedisDelKeyAsync(RedisKey keyVal)
{
return await redisDb.KeyDeleteAsync(keyVal);
}
- ///
- /// Esegue flush memoria redis dato keyVal, async
- ///
- ///
- ///
+ ///
public async Task RedisFlushPatternAsync(RedisValue pattern)
{
Log.Debug($"Richiesta flush pattern: {pattern}");
@@ -1993,10 +1671,7 @@ namespace MP.IOC.Data
}
}
- ///
- /// Inserisce record RRL + fa pulizia vecchi record
- ///
- ///
+ ///
public async Task RemRebootLogAddAsync(RemoteRebootLogModel newRec)
{
// verifica preliminare ultima esecuzione (max 1 ogni 60 min...)
@@ -2021,12 +1696,7 @@ namespace MP.IOC.Data
return fatto;
}
- ///
- /// Elimina da elenco KVP il TASK per l'impianto indicato
- ///
- ///
- ///
- ///
+ ///
public async Task> RemTask2ExeMacchinaAsync(string idxMacchina, taskType tName)
{
// hard coded dimensione vettore DatiMacchine
@@ -2050,13 +1720,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Resetta (rileggendo) i dati della State Machine multi ingressi nel formato
- /// currKey: IdxMacchina
- /// value: IdxFamigliaIngresso
- ///
- ///
- ///
+ ///
public async Task[]> resetMSMIAsync(string idxMacchina)
{
var currHash = Utils.RedKeyMsmi(idxMacchina);
@@ -2081,12 +1745,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB
- ///
- /// Macchina
- /// Pezzi da registrare
- ///
+ ///
public async Task saveCaricoPezzi(string idxMacchina, string qty)
{
// default: 0, non registrato x cautela...
@@ -2186,14 +1845,7 @@ namespace MP.IOC.Data
return fatto;
}
- ///
- /// salva il segnale di "microstato" (segnale) ASYNC
- ///
- /// idx macchina
- /// valOut ingresso
- /// data-ora evento (server)
- /// contatore sequenza dati inviati
- ///
+ ///
public async Task saveSigLogAsync(string idxMacchina, string valore, DateTime dtEve, int contatore)
{
SignalLogModel newRec = new SignalLogModel()
@@ -2207,12 +1859,7 @@ namespace MP.IOC.Data
return await _iocRepository.SignalLogInsertAsync(newRec);
}
- ///
- /// scrive un evento di keepalive sulla tabella
- ///
- ///
- ///
- ///
+ ///
public async Task ScriviKeepAliveAsync(string IdxMacchina, DateTime oraMacchina)
{
// cerco se ho keep alive in redis,
@@ -2228,12 +1875,7 @@ namespace MP.IOC.Data
}
}
- ///
- /// Salvataggio YAML completo di configurazione dell'IOB
- ///
- ///
- ///
- ///
+ ///
public async Task SetIobConfYamlAsync(string idxMacchina, string iobConfFull)
{
bool answ = false;
@@ -2261,13 +1903,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restitusice elenco KVP dei campi della State Machine ingressi nel formato
- /// currKey: cState_nVal (current MICRO-STATE + "_" + new Value)
- /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE
- ///
- ///
- ///
+ ///
public async Task[]> StateMachInByKeyAsync(int idxFamIn)
{
// hard coded dimensione vettore DatiMacchine
@@ -2292,12 +1928,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD)
- ///
- ///
- ///
- ///
+ ///
public async Task UpsertCurrObjItemsAsync(string idxMacchina, List innovations)
{
bool answ = false;
@@ -2334,14 +1965,7 @@ namespace MP.IOC.Data
return answ;
}
- ///
- /// Restituisce il valore SPECIFICATO per la state machine ingressi
- /// value: iTipoEv_nState (IdxTipoEv da trasmettere + New MICRO-STATE)
- ///
- ///
- ///
- ///
- ///
+ ///
public async Task ValoreSmiAsync(int idxFamIn, int idxMicroStato, int valoreIn)
{
string valOut = "";
@@ -2418,33 +2042,17 @@ namespace MP.IOC.Data
private static ILogger _logger = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
private static IMtcSetupService MtcService = null!;
-#if false
+ private readonly IAnagRepository _anagRepository;
+
///
- /// Elenco completo valori Macchine 2 Slave
+ /// Cache Fusion (Memory + Redis + DB)
///
- ///
- public List Macchine2SlaveGetAll()
- {
- List? result = new List();
- string currKey = $"{Utils.redisBaseAddr}:M2STab";
- RedisValue rawData = redisDb.StringGet(currKey);
- if (rawData.HasValue)
- {
- result = JsonConvert.DeserializeObject>(rawData);
- }
- else
- {
-#if false
- result = IocDbController.Macchine2Slave();
- rawData = JsonConvert.SerializeObject(result);
- redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
-#endif
- result = new List();
- }
- return result ?? new List();
- }
-#endif
+ private readonly IFusionCache _cache;
+
+ private readonly IIocRepository _iocRepository;
+ private readonly IProductionRepository _productionRepository;
private readonly IServiceScopeFactory _scopeFactory;
+ private readonly ISystemRepository _systemRepository;
///
/// Provider CultureInfo x parse valori (es dataora)
@@ -2494,69 +2102,10 @@ namespace MP.IOC.Data
private bool useFactory = false;
- ///
- /// Cache Fusion (Memory + Redis + DB)
- ///
- private readonly IFusionCache _cache;
-
#endregion Private Fields
#region Private Methods
- ///
- /// Verifica se sia necessario inserire un cambio di stato impianto (DiarioDi Bordo) in modalità batch
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// Helper standard FusionCache - recupero da L1/L2/L3 con tracking activity
- ///
- private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)
- {
- using var activity = new ActivitySource("MP.IOC.Tracer").StartActivity(operationName);
- string source;
- var tryGet = await _cache.TryGetAsync(cacheKey);
- if (tryGet.HasValue)
- {
- source = "MEMORY";
- var result = tryGet.Value!;
- activity?.SetTag("data.source", source);
- activity?.Stop();
- if (activity?.Duration.TotalMilliseconds > 0)
- {
- Log.Trace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms");
- }
- return result;
- }
- bool fromDB = false;
- var cacheOptions = new FusionCacheEntryOptions()
- .SetDuration(expiration)
- .SetFailSafe(true);
- cacheOptions.MemoryCacheDuration = expiration / 3;
-
- var final = await _cache.GetOrSetAsync(
- cacheKey,
- async _ =>
- {
- fromDB = true;
- return await fetchFunc();
- },
- options: cacheOptions,
- tags: tagList
- );
-
- source = fromDB ? "DB" : "REDIS";
- activity?.SetTag("data.source", source);
- activity?.Stop();
- return final!;
- }
-
private async Task CheckCambiaStatoBatchAsync(tipoInputEvento tipoInput, string IdxMacchina, DateTime InizioStato, int IdxTipo, string CodArt, string Value, int MatrOpr, string pallet)
{
await _iocRepository.CheckCambiaStatoBatchAsync(tipoInput, IdxMacchina, InizioStato, IdxTipo, CodArt, Value, MatrOpr, pallet);
@@ -2607,7 +2156,7 @@ namespace MP.IOC.Data
default:
break;
- }
+ }
#endif
}
@@ -2714,6 +2263,60 @@ namespace MP.IOC.Data
return answ;
}
+ ///
+ /// Verifica se sia necessario inserire un cambio di stato impianto (DiarioDi Bordo) in modalità batch
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// Helper standard FusionCache - recupero da L1/L2/L3 con tracking activity
+ ///
+ private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)
+ {
+ using var activity = new ActivitySource("MP.IOC.Tracer").StartActivity(operationName);
+ string source;
+ var tryGet = await _cache.TryGetAsync(cacheKey);
+ if (tryGet.HasValue)
+ {
+ source = "MEMORY";
+ var result = tryGet.Value!;
+ activity?.SetTag("data.source", source);
+ activity?.Stop();
+ if (activity?.Duration.TotalMilliseconds > 0)
+ {
+ Log.Trace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms");
+ }
+ return result;
+ }
+ bool fromDB = false;
+ var cacheOptions = new FusionCacheEntryOptions()
+ .SetDuration(expiration)
+ .SetFailSafe(true);
+ cacheOptions.MemoryCacheDuration = expiration / 3;
+
+ var final = await _cache.GetOrSetAsync(
+ cacheKey,
+ async _ =>
+ {
+ fromDB = true;
+ return await fetchFunc();
+ },
+ options: cacheOptions,
+ tags: tagList
+ );
+
+ source = fromDB ? "DB" : "REDIS";
+ activity?.SetTag("data.source", source);
+ activity?.Stop();
+ return final!;
+ }
+
///
/// 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
@@ -2775,6 +2378,53 @@ namespace MP.IOC.Data
return result;
}
+ ///
+ /// 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;
+ }
+
private async Task POdlFlushCache()
{
bool answ = false;
@@ -2908,8 +2558,6 @@ namespace MP.IOC.Data
}
else
{
-
-
}
// dati master/slave
string isMaster = (await ListMasterAsync()).Contains(idxMacc) ? "1" : "0";
@@ -2973,34 +2621,6 @@ namespace MP.IOC.Data
return answ;
}
-#if false
- ///
- /// Scrive una riga di evento nel db + check cambio stato DiarioDiBordo
- ///
- /// codice macchina
- ///
- private inputComandoMapo scriviRigaEvento(EventListModel newRec)
- {
- bool inserito = false;
- try
- {
- // inserisco evento
- inserito = IocDbController.EvListInsert(newRec);
- // faccio controllo per eventuale cambio stato da tab transizioni...
- CheckCambiaStatoBatchAsync(tipoInputEvento.hw, newRec.IdxMacchina, newRec.InizioStato ?? DateTime.Now, newRec.IdxTipo, newRec.CodArticolo, newRec.Value, newRec.MatrOpr, newRec.pallet);
- }
- catch (Exception exc)
- {
- Log.Error($"Errore in scriviRigaEvento | IdxMacchina {newRec.IdxMacchina} | IdxTipo {newRec.IdxTipo} | codArticolo {newRec.CodArticolo} | Value {newRec.Value} | MatrOpr {newRec.MatrOpr} | Pallet {newRec.pallet} | dTime {newRec.InizioStato}{Environment.NewLine}{exc}");
- }
- // formatto output
- inputComandoMapo answ = new inputComandoMapo();
- answ.outValue = inserito.ToString();
- answ.needStatusRefresh = true;
- return answ;
- }
-#endif
-
///
/// Scrive una riga di evento nel db + check cambio stato DiarioDiBordo
///
@@ -3049,7 +2669,6 @@ namespace MP.IOC.Data
}
else
{
-
try
{
// inserisco evento
@@ -3069,8 +2688,6 @@ namespace MP.IOC.Data
return answ;
}
-
-
///
/// Scrive una riga di evento manuale (barcode) nel db + check cambio stato DiarioDiBordo
///
@@ -3148,6 +2765,92 @@ 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;
+ }
+
+#if false
+ ///
+ public List Macchine2SlaveGetAll()
+ {
+ List? result = new List();
+ string currKey = $"{Utils.redisBaseAddr}:M2STab";
+ RedisValue rawData = redisDb.StringGet(currKey);
+ if (rawData.HasValue)
+ {
+ result = JsonConvert.DeserializeObject>(rawData);
+ }
+ else
+ {
+#if false
+ result = IocDbController.Macchine2Slave();
+ rawData = JsonConvert.SerializeObject(result);
+ redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
+#endif
+ result = new List();
+ }
+ return result ?? new List();
+ }
+#endif
+#if false
+ ///
+ /// Scrive una riga di evento nel db + check cambio stato DiarioDiBordo
+ ///
+ /// codice macchina
+ ///
+ private inputComandoMapo scriviRigaEvento(EventListModel newRec)
+ {
+ bool inserito = false;
+ try
+ {
+ // inserisco evento
+ inserito = IocDbController.EvListInsert(newRec);
+ // faccio controllo per eventuale cambio stato da tab transizioni...
+ CheckCambiaStatoBatchAsync(tipoInputEvento.hw, newRec.IdxMacchina, newRec.InizioStato ?? DateTime.Now, newRec.IdxTipo, newRec.CodArticolo, newRec.Value, newRec.MatrOpr, newRec.pallet);
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in scriviRigaEvento | IdxMacchina {newRec.IdxMacchina} | IdxTipo {newRec.IdxTipo} | codArticolo {newRec.CodArticolo} | Value {newRec.Value} | MatrOpr {newRec.MatrOpr} | Pallet {newRec.pallet} | dTime {newRec.InizioStato}{Environment.NewLine}{exc}");
+ }
+ // formatto output
+ inputComandoMapo answ = new inputComandoMapo();
+ answ.outValue = inserito.ToString();
+ answ.needStatusRefresh = true;
+ return answ;
+ }
+#endif
#if false
///
/// Restituisce il valOut SPECIFICATO per la state machine ingressi
@@ -3162,7 +2865,7 @@ namespace MP.IOC.Data
var currHash = Utils.GetHashSMI(idxFamIn);
string field = string.Format("{0}_{1}", idxMicroStato, valoreIn);
return RedisGetHashFieldAsync(currHash, field);
- }
+ }
#endif
///