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