using EgwCoreLib.Utils; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MP.Data.DatabaseModels; using MP.Data.DTO; using MP.Data.Objects; using Newtonsoft.Json; using NLog; using Org.BouncyCastle.Asn1.IsisMtt.Ocsp; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MP.Data.Services { public class TabDataService : BaseServ, IDisposable { #region Public Constructors /// /// Init servizio TAB /// /// public TabDataService(IConfiguration configuration) { _configuration = configuration; // setup compoenti REDIS redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); redisDb = redisConn.GetDatabase(); // conf DB ConnStr = _configuration.GetConnectionString("Mp.All"); if (string.IsNullOrEmpty(ConnStr)) { Log.Error("ConnString empty!"); } else { StringBuilder sb = new StringBuilder(); dbTabController = new Controllers.MpTabController(configuration); sb.AppendLine($"TabDataService | MpTabController OK"); dbIocController = new Controllers.MpIocController(configuration); sb.AppendLine($"TabDataService | MpIocController OK"); dbInveController = new Controllers.MpInveController(configuration); sb.AppendLine($"TabDataService | MpInveController OK"); Log.Info(sb.ToString()); // sistemo i parametri x redHas... CodModulo = _configuration.GetValue("OptConf:CodModulo"); var cstringArray = ConnStr.Split(";"); foreach (var item in cstringArray) { var cData = item.Trim().Split("="); if (cData.Length == 2) { if (!connStrParams.ContainsKey(cData[0])) { connStrParams.Add(cData[0], cData[1]); } } } // sistemo DataSource = connStrParams["Server"]; DataBase = connStrParams["Database"]; } } #endregion Public Constructors #region Public Properties /// /// Conmfig attivo da DB /// public List CurrConfig { get; set; } = new List(); #endregion Public Properties #region Public Methods /// /// Aggiunge un task all'elenco di quelli salvati (in modalità upsert) /// /// /// /// /// public bool addTask4Machine(string idxMacchina, Enums.taskType taskKey, string taskVal) { bool answ = false; string currHash = exeTaskHash(idxMacchina); string currSavedParHash = savedTaskHash(idxMacchina); Dictionary currTask = new Dictionary(); Dictionary savedTask = new Dictionary(); try { //Log.Info($"Request: idxMacchina: {idxMacchina} | taskKey: {taskKey} | taskVal: {taskVal}"); // leggo task attuali... currTask = mTaskMacchina(idxMacchina); if (currTask.ContainsKey($"{taskKey}")) { currTask[$"{taskKey}"] = taskVal; } else { currTask.Add($"{taskKey}", taskVal); } answ = redisHashDictSet(currHash, currTask); Log.Info($"Task ADD - idxMacchina: {idxMacchina} | taskKey: {taskKey} | taskVal: {taskVal}"); } catch { } // verifico in base al tipo di task se fare backup... switch (taskKey) { case Enums.taskType.setArt: case Enums.taskType.setComm: case Enums.taskType.setPzComm: case Enums.taskType.setProg: // leggo task SALVATI attuali... savedTask = mSavedTaskMacchina(idxMacchina); savedTask[taskKey.ToString()] = taskVal; answ = redisHashDictSet(currSavedParHash, savedTask); break; case Enums.taskType.endProd: // salvo un DICT vuoto x resettare savedTask = new Dictionary(); answ = redisHashDictSet(currSavedParHash, savedTask); break; default: break; } return answ; } /// /// Elenco allarmi macchina /// /// Macchina /// Inizio periodo /// Fine periodo /// /// public async Task> AlarmLogListFilt(string idxMacchina, DateTime dtFrom, DateTime dtTo, bool showMulti) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:AlarmLog:{idxMacchina}:{dtFrom:yyyyMMdd-HHmmss}:{dtTo::yyyyMMdd-HHmmss}:{showMulti}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.AlarmLogListFilt(idxMacchina, dtFrom, dtTo, showMulti)); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"AlarmLogListFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Registrato ACK allarme /// /// Id Allarme /// Data Ack /// User Ack /// public bool AlarmLogSetAck(int alarmLogId, DateTime dtAck, string userAck) { bool answ = dbTabController.AlarmLogSetAck(alarmLogId, dtAck, userAck); return answ; } /// /// Registrato ACK allarme /// /// Id Allarme /// Data Ack /// public bool AlarmLogSetNotify(int alarmLogId, DateTime dtNotify) { bool answ = dbTabController.AlarmLogSetNotify(alarmLogId, dtNotify); return answ; } /// /// Elenco completo EVENTI /// /// public async Task> AnagEventiGetAll() { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:AnagEventi:ALL"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.AnagEventiGetAll(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"AnagEventiGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco EVENTI validi x macchina /// /// public async Task> AnagEventiGetByMacch(string IdxMacch) { // setup parametri costanti DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = DateTime.Today.AddDays(1); string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:VSEB:{IdxMacch}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.AnagEventiGetByMacc(IdxMacch); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"AnagEventiGetByMacch | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Restituisce l'anagrafica EVENTI per intero /// /// public async Task> AnagTagsOrd() { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:AnagTags"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.AnagTagsOrd(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"AnagTagsOrd | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco completo STATI /// /// public async Task> AnaStatiGetAll() { // setup parametri costanti DateTime startDate = new DateTime(2000, 1, 1); DateTime endDate = DateTime.Today.AddDays(1); string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:AnagStati"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.AnagStatiGetAll(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"AnaStatiGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Recupera elenco ultimi commenti /// /// Idx macchina, "*" = tutte /// Num di giorni da recuperare da adesso /// public async Task> CommentiGetLastByMacc(string idxMacchina, int numDays) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); DateTime adesso = DateTime.Now; // cerco in redis... string currKey = $"{redisBaseKey}:Commenti:{idxMacchina}:{adesso:yyMMdd-HHmm}:{numDays}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.CommentiGetLastByMacc(idxMacchina, numDays); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"CommentiGetLastByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma /// --> dtEvent) /// /// idx macchina da confermare /// 0=periodo, 1 = giorno, 2 = turno /// qta pezzi BUONI da confermare /// qta pezzi SCARTO da confermare /// DataOra in cui registrare approvazione /// Matricola operatore /// public bool ConfermaProdMacchina(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp, int MatrOpr) { bool answ = false; answ = dbTabController.ConfermaProdMacchina(idxMacchina, modoConfProd, numPzConfermati, numPzScarto, DataOraApp, MatrOpr); return answ; } /// /// Effettua conferma prod macchina dell'intero periodo da confermare (ultima conferma /// --> dtEvent) /// /// idx macchina da confermare /// 0=periodo, 1 = giorno, 2 = turno /// qta pezzi BUONI da confermare /// /// qta pezzi LASCIATI alla macchina da confermare (2 eventi 121 rettifica neg/pos) /// /// qta pezzi SCARTO da confermare /// DataOra in cui registrare approvazione /// Matricola operatore /// public bool ConfermaProdMacchinaFull(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzLasciati, int numPzScarto, DateTime DataOraApp, int MatrOpr) { bool answ = false; answ = dbTabController.ConfermaProdMacchinaFull(idxMacchina, modoConfProd, numPzConfermati, numPzLasciati, numPzScarto, DataOraApp, MatrOpr); return answ; } /// /// Config values attivi /// /// public List ConfigGetAll() { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:Conf"; RedisValue rawData = redisDb.StringGet(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.ConfigGetAll(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"ConfigGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Recupera il valore in formato STRING /// /// Valore da cercare /// String in cui salvare il valore se trovato /// public bool ConfigGetVal(string chiave, ref string varObj) { bool answ = false; // se mancasse provo a configurare.. if (CurrConfig == null || CurrConfig.Count == 0) { SetupConfig(); } if (CurrConfig != null && CurrConfig.Count > 0) { // sistemo i parametri opzionali... ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave); if (risultato != null) { varObj = risultato.Valore; answ = !string.IsNullOrEmpty(risultato.Valore); } } return answ; } /// /// Recupera il valore in formato INT /// /// Valore da cercare /// Int in cui salvare il valore se trovato /// public bool ConfigGetVal(string chiave, ref int varObj) { bool answ = false; // se mancasse provo a configurare.. if (CurrConfig == null || CurrConfig.Count == 0) { SetupConfig(); } if (CurrConfig != null && CurrConfig.Count > 0) { // sistemo i parametri opzionali... ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave); if (risultato != null) { answ = int.TryParse(risultato.Valore, out varObj); } } return answ; } /// /// Recupera il valore in formato DOUBLE /// /// Valore da cercare /// Int in cui salvare il valore se trovato /// public bool ConfigGetVal(string chiave, ref double varObj) { bool answ = false; // se mancasse provo a configurare.. if (CurrConfig == null || CurrConfig.Count == 0) { SetupConfig(); } if (CurrConfig != null && CurrConfig.Count > 0) { // sistemo i parametri opzionali... ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave); if (risultato != null) { NumberStyles numStyle; CultureInfo culture; numStyle = NumberStyles.Number; culture = CultureInfo.InvariantCulture; //culture = CultureInfo.CreateSpecificCulture("en-US"); answ = double.TryParse(risultato.Valore, numStyle, culture, out varObj); } } return answ; } /// /// Recupera il valore in formato BOOL /// /// Valore da cercare /// Boolean in cui salvare il valore se trovato /// public bool ConfigGetVal(string chiave, ref bool varObj) { bool answ = false; // se mancasse provo a configurare.. if (CurrConfig == null || CurrConfig.Count == 0) { SetupConfig(); } if (CurrConfig != null && CurrConfig.Count > 0) { // sistemo i parametri opzionali... ConfigModel? risultato = CurrConfig.FirstOrDefault(x => x.Chiave == chiave); if (risultato != null) { answ = bool.TryParse(risultato.Valore, out varObj); } } return answ; } /// /// Inserimento record in DDB /// /// /// /// /// /// /// /// public async Task DDB_DoRecalc(string idxMacchina, DateTime inizio, int idxStatoStart, int nStepEventi, int nRecCheck, bool checkOnly) { bool answ = dbTabController.DDB_DoRecalc(idxMacchina, inizio, idxStatoStart, nStepEventi, nRecCheck, checkOnly); await FlushCache(); return answ; } /// /// Recupera record successivo da DDB /// /// /// /// public DiarioDiBordoModel DDB_getNext(string idxMacchina, DateTime inizioStato) { return dbTabController.DDB_getNext(idxMacchina, inizioStato); } public string DecryptData(string encData) { return SteamCrypto.DecryptString(encData, Constants.passPhrase); } public void Dispose() { // Clear database controller dbTabController.Dispose(); dbIocController.Dispose(); dbInveController.Dispose(); } /// /// Fix ODL per Elenco Lotti /// /// /// /// public async Task ElencoLottiUpsertByOdl(int idxOdl, bool flgStorico) { bool answ = false; try { // inserisco evento answ = dbTabController.ElencoLottiUpsertByOdl(idxOdl, flgStorico); await FlushCache("EL"); } catch (Exception exc) { string logMsg = $"Eccezione in ElencoLottiUpsertByOdl | idxOdl: {idxOdl} | flgStorico: {flgStorico}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Elenco operatori /// /// public async Task> ElencoOperatori() { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:ElencoOpr"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.ElencoOperatori(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"ElencoOperatori | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } public string EncryptData(string rawData) { return SteamCrypto.EncryptString(rawData, Constants.passPhrase); } /// /// Elimina una riga in EventList se trovata /// /// /// /// /// public async Task EvListDelete(string idxMacchina, DateTime dtEvento, int idxTipo) { bool fatto = false; try { // inserisco evento fatto = dbTabController.EvListDelete(idxMacchina, dtEvento, idxTipo); // reset cache eventi/commenti await FlushCache("EvList"); await FlushCache("Commenti"); } catch (Exception exc) { string logMsg = $"Eccezione in EvListDelete | macchina: {idxMacchina} | DataEv: {dtEvento} | idxTipo: {idxTipo}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return fatto; } /// /// Recupera record EventList date condizioni filtro /// /// Idx macchina, "*" = tutte /// Data limite per recupero antecedenti /// Tipo evento cercato, 0 = tutti /// Num massimo di record da recuperare /// public async Task> EvListGetLastBySearch(string idxMacchina, DateTime dtLimit, int idxTipo, int maxRec) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:EvList:Last:{idxMacchina}:{idxTipo}:{dtLimit:yyyyMMdd-HHmm}:{maxRec}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await dbTabController.EvListGetLastBySearch(idxMacchina, dtLimit, idxTipo, maxRec); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"EvListGetLastBySearch | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Scrive una riga in EventList inviato nel db + check /// /// Record da registrare /// public async Task EvListInsert(EventListModel newRec, Enums.tipoInputEvento tipoEv) { bool inserito = false; try { // inserisco evento inserito = await dbTabController.EvListInsert(newRec); // reset cache eventi/commenti await FlushCache("EvList"); await FlushCache("Commenti"); } catch (Exception exc) { string logMsg = $"Eccezione in fase di scrittura evento con i seguenti dati | macchina: {newRec.IdxMacchina} | IdxTipo: {newRec.IdxTipo} | CodArticolo: {newRec.CodArticolo} | Value {newRec.Value} | MatrOpr {newRec.MatrOpr} | Pallet {newRec.pallet}{Environment.NewLine}{exc}"; Log.Error(logMsg); } // se non è un commento... if (tipoEv != Enums.tipoInputEvento.commento) { try { // faccio controllo per eventuale cambio stato da tab transizioni... dbTabController.CheckCambiaStatoBatch(tipoEv, newRec.IdxMacchina, newRec.InizioStato ?? DateTime.Now, newRec.IdxTipo, newRec.CodArticolo, newRec.Value, newRec.MatrOpr, newRec.pallet); } catch (Exception exc) { string logMsg = $"Eccezione in checkCambiaStatoBatch(6) | tipoInputEvento: {tipoEv} |macchina: {newRec.IdxMacchina} | IdxTipo: {newRec.IdxTipo} | CodArticolo: {newRec.CodArticolo} | Value: {newRec.Value} | MatrOpr: {newRec.MatrOpr} | Pallet: {newRec.pallet}{Environment.NewLine}{exc}"; Log.Error(logMsg); } } // formatto output inputComandoMapo answ = new inputComandoMapo(); answ.outValue = inserito.ToString(); answ.needStatusRefresh = true; return answ; } /// /// Recupera elenco fermi non qualificati da filtro /// /// Idx macchina, "*" = tutte /// Num massimo di giorni antecedenti /// Durata minima (in minuti) /// public async Task> FermiNonQualificatiFilt(string idxMacchina, int gg, double durataMin) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:FNQ:{idxMacchina}:{gg}:{durataMin:N0}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.FermiNonQualificatiFilt(idxMacchina, gg, durataMin); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"FermiNonQualificatiFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Pulizia cache Redis (tutta) /// /// public async Task FlushCache() { RedisValue pattern = new RedisValue($"{redisBaseKey}:*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Pulizia cache Redis per chiave specifica (da redisBaseKey...) /// /// public async Task FlushCache(string KeyReq) { RedisValue pattern = new RedisValue($"{redisBaseKey}:{KeyReq}:*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Flush di tutta la cache relativa ad i dati ODL/PODL /// /// public async Task FlushOdlCache() { await FlushCache("ODL"); await FlushCache("PODL"); await FlushCache("VSODL"); await FlushCache("StatoMacc"); } /// /// Recupero info IOB x TAB (da info registrate IOB-WIN--> MP-IO) /// /// /// public async Task IobInfo(string IdxMacchina) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); IOB_data? result = new IOB_data(); // cerco in redis... string currKey = redHash($"hM2IOB:{IdxMacchina}"); RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } if (result == null) { result = new IOB_data(); } sw.Stop(); Log.Debug($"IobInfo | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// Elenco PODL macchina Macchina Solo disponibili (1) o tutte (0) Gruppo public async Task> ListPODLByMacc(string idxMacchina, bool onlyFree, bool onlyDirect) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:PODL:{idxMacchina}:{onlyFree}:{onlyDirect}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.ListPODLByMacc(idxMacchina, onlyFree, onlyDirect)); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"ListPODLByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco lotti esterni presenti sul db di ARCA /// /// Codice articolo /// Codice lotto /// Codice magazzino /// public async Task> LottoEsterno(string codArt, string codLotto, string codMagazzino) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:LottoExt:{codMagazzino}:{codArt}:{codLotto}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbInveController.LottoEsterno(codArt, codLotto, codMagazzino); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"LottoEsterno | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Effettua ricalcolo MSE x macchina indicata /// /// idx macchina da confermare /// Abilitazione insert ev macchina /// public bool MacchinaSetInsEnab(string idxMacchina, bool insEnabled) { bool answ = dbTabController.MacchinaSetInsEnab(idxMacchina, insEnabled); return answ; } /// /// Intera tabella relazione master/slave in machine (gestione setup master --> slave) /// /// public async Task> Macchine2Slave() { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:Mach2Slave"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.Macchine2Slave(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"Macchine2Slave | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Lista parametri correnti (ObjItemDTO) della macchina /// /// /// public List MachineParamList(string idxMacchina) { // setup parametri costanti string source = "NA"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = redHash($"CurrentParameters:{idxMacchina}"); RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue) { var rawVal = JsonConvert.DeserializeObject>($"{rawData}"); // ordino! result = rawVal .OrderBy(x => x.displOrdinal) .ThenBy(x => x.description) .ToList(); source = "REDIS"; } if (result == null) { result = new List(); source = "NONE"; } sw.Stop(); Log.Debug($"CurrParamList | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Aggiornamento parametro per macchina /// /// /// UID del parametro macchina come definito in file json /// /// public bool MachineParamUpdate(string idxMacchina, string uid, string reqValue) { bool answ = false; // recupero items... List dcList = MachineParamList(idxMacchina); List list2Update = new List(); // cerco quello da aggiornare var trovato = dcList.Find(obj => obj.uid == uid); // se non trova --> crea ed aggiunge... if (trovato == null) { dcList.Add(new ObjItemDTO() { uid = uid }); trovato = dcList.Find(obj => obj.uid == uid); } // se trovato procedo if (trovato != null) { // aggiorno valore richiesto + dt richiesta trovato.reqValue = reqValue; trovato.lastRequest = DateTime.Now; list2Update.Add(trovato); MachineParamUpsert(idxMacchina, list2Update); // accodo in task 2 exe la richiesta di processing addTask4Machine(idxMacchina, Enums.taskType.setParameter, trovato.uid); // salvo ANCHE il valore di setup ASSOCIATO... System.Enum.TryParse(trovato.uid, out Enums.taskType currTask); //taskType currTask = (taskType)System.Enum.Parse(typeof(taskType), trovato.uid); addTask4Machine(idxMacchina, currTask, reqValue); answ = true; } return answ; } /// /// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD) /// /// /// /// public bool MachineParamUpsert(string idxMacchina, List innovations) { bool answ = false; if (innovations != null) { Log.Info($"upsertCurrObjItems | idxMacchina: {idxMacchina} | {innovations.Count} innovations"); // leggo i valori attuali... List actValues = MachineParamList(idxMacchina); // per ogni valore passatomi faccio insert o update rispetto elenco valori correnti // in REDIS foreach (var item in actValues) { // cerco nelle innovazioni SE CI SIA il valore... var trovato = innovations.Find(obj => obj.uid == item.uid); // se non trovato nelle innovazioni... if (trovato == null) { // lo ri-aggiungo x non perderlo innovations.Add(item); Log.Trace($"innovations | add | item.uid: {item.uid} | item.value: {item.value}"); } // altrimenti aggiorno campo (non trasmesso) name e tengo il resto... else { trovato.name = item.name; Log.Info($"innovations | update | item.uid: {item.uid} | item.value: {item.value} --> {trovato.value} "); } } // serializzo e salvo string serVal = JsonConvert.SerializeObject(innovations); string currKey = redHash($"CurrentParameters:{idxMacchina}"); RedisValue rawData = redisDb.StringSet(currKey, serVal); } 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 Dictionary answ = new Dictionary(); // ORA recupero da memoria redis... try { var currKey = (RedisKey)savedTaskHash(idxMacchina); answ = redisHashDictGet(currKey); } catch (Exception exc) { Log.Info($"Errore in recupero dati SAVED TASK x Redis mSavedTaskMacchina | idxMacchina {idxMacchina}{Environment.NewLine}{exc}"); } return answ; } /// /// Recupera un valore MSE x una macchina sub specifica /// /// /// /// /// public MappaStatoExpl MseGetSub(string idxMacc, string idxMacchSub, bool forceDb) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); MappaStatoExpl result = new MappaStatoExpl(); // cerco in redis... string currKey = $"{Constants.redisMseKeySingle}:{idxMacchSub}"; RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue && !forceDb) { result = JsonConvert.DeserializeObject($"{rawData}"); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"Read from REDIS: {ts.TotalMilliseconds}ms"); } else { var rawResult = dbTabController.MseGetSub(idxMacc, idxMacchSub); if (rawResult != null && rawResult.Count > 0) { result = rawResult.FirstOrDefault(); } // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, UltraLongCache); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"Read from DB: {ts.TotalMilliseconds}ms"); } if (result == null) { result = new MappaStatoExpl(); } return result; } /// /// ODL da key /// /// /// /// public async Task OdlByIdx(int idxOdl, bool onlyUnused) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); ODLExpModel result = new ODLExpModel(); // cerco in redis... string currKey = $"{redisBaseKey}:ODL:{idxOdl}:{onlyUnused}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { var listRes = await Task.FromResult(dbTabController.OdlByIdx(idxOdl, onlyUnused)); result = listRes.FirstOrDefault(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new ODLExpModel(); } sw.Stop(); Log.Debug($"OdlByIdx | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Clear operazione setup ODL (annullamento) /// /// /// /// public async Task OdlClearSetup(int idxODL, string idxMacchina) { bool answ = false; try { // inserisco evento answ = dbTabController.OdlClearSetup(idxODL, idxMacchina); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlUpdate | idxODL: {idxODL} | idxMacchina: {idxMacchina}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// ODL corrente macchina /// /// /// public async Task OdlCurrByMacc(string idxMacchina, bool forceDb) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); ODLExpModel result = new ODLExpModel(); // cerco in redis... string currKey = $"{redisBaseKey}:ODL:{idxMacchina}:CURR"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue && !forceDb) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { var listRes = await Task.FromResult(dbTabController.OdlCurrByMacc(idxMacchina)); result = listRes.FirstOrDefault(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new ODLExpModel(); } sw.Stop(); Log.Debug($"OdlCurrByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Attrezzo stesso ODL dell'altra tavola /// /// /// /// /// public async Task OdlDividiDaAltraTavola(int idxODL, int matrOpr, string idxMacchinaTo) { bool answ = false; try { // inserisco evento answ = dbTabController.OdlDividiDaAltraTavola(idxODL, matrOpr, idxMacchinaTo); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlDividiDaAltraTavola | idxODL: {idxODL} | matrOpr: {matrOpr} | idxMacchinaTo: {idxMacchinaTo}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Registro fine prod ODL /// /// /// /// public async Task OdlFineProd(int idxODL, string idxMacchina) { bool answ = false; try { // inserisco evento answ = dbTabController.OdlFineProd(idxODL, idxMacchina); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlFineProd | idxODL: {idxODL} | idxMacchina: {idxMacchina}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Fix ODL per macchine SLAVE /// /// /// /// /// public async Task OdlFixMachineSlave(string idxMacchina, int numDayPrev, int doInsert) { bool answ = false; try { // inserisco evento answ = dbTabController.OdlFixMachineSlave(idxMacchina, numDayPrev, doInsert); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in ODLfixMachineSlave | idxMacchina: {idxMacchina} | numDayPrev: {numDayPrev} | doInsert: {doInsert}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Setup PODL Postumo /// /// /// /// /// /// /// /// public async Task OdlInizioSetup(int idxODL, int matrOpr, string idxMacchina, decimal tcRich, int pzPallet, string note) { bool answ = false; try { // inserisco evento answ = dbTabController.OdlInizioSetup(idxODL, matrOpr, idxMacchina, tcRich, pzPallet, note); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlInizioSetup | matrOpr: {matrOpr} | idxODL: {idxODL} | idxMacchina: {idxMacchina}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Ultimo ODL data macchina /// /// /// /// public ODLModel OdlLastByMacc(string idxMacchina, bool forceDb) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); ODLModel result = new ODLModel(); // cerco in redis... string currKey = $"{redisBaseKey}:ODL:{idxMacchina}:LAST"; RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue && !forceDb) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { var results = dbTabController.OdlLastByMacc(idxMacchina); // riordino result = results.FirstOrDefault(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, UltraLongCache); } if (result == null) { result = new ODLModel(); } sw.Stop(); Log.Debug($"OdlLastByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco ODL data macchina e periodo /// /// /// /// /// public async Task> OdlListByMaccPeriodo(string idxMacchina, DateTime dtStart, DateTime dtEnd) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:ODL:{idxMacchina}:{dtStart:yyyyMMdd-HHmmss}:{dtEnd:yyyyMMdd-HHmmss}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.OdlListByMaccPeriodo(idxMacchina, dtStart, dtEnd)); // riordino result = result.OrderByDescending(x => x.DataInizio).ToList(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"OdlListByMaccPeriodo | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Riapertura ULTIMO ODL data macchina /// /// /// public async Task OdlReopenOdlMacc(string idxMacchina) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); ODLModel result = new ODLModel(); // cerco in redis... string currKey = $"{redisBaseKey}:ODL:{idxMacchina}:LAST"; var results = await Task.FromResult(dbTabController.OdlReopenOdlMacc(idxMacchina)); // riordino result = results.FirstOrDefault(); // svuoto cache await FlushOdlCache(); if (result == null) { result = new ODLModel(); } sw.Stop(); Log.Debug($"OdlReopenOdlMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Setup ODL Postumo /// /// /// /// public async Task OdlSetupPostumo(int idxODL, string idxMacchina) { bool answ = false; try { // inserisco evento answ = await Task.FromResult(dbTabController.OdlSetupPostumo(idxODL, idxMacchina)); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlSetupPostumo | macchina: {idxMacchina} | idxODL: {idxODL}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Setup ODL Postumo /// /// /// /// /// public async Task OdlSetupPromPostuma(int idxPromOdl, int matrOpr, string idxMacchina) { bool answ = false; try { // inserisco evento answ = await Task.FromResult(dbTabController.OdlSetupPromPostuma(idxPromOdl, matrOpr, idxMacchina)); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlSetupPromPostuma | macchina: {idxMacchina} | idxPromOdl: {idxPromOdl} | MatrOpr: {matrOpr}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Split ODL /// /// /// /// /// /// /// /// /// /// public async Task OdlSplit(int idxODL, int matrOpr, string idxMacchina, decimal TCRich, int pzPallet, string note, bool startNewOdl, int qtyRich) { bool answ = false; try { // inserisco evento answ = await Task.FromResult(dbTabController.OdlSplit(idxODL, matrOpr, idxMacchina, TCRich, pzPallet, note, startNewOdl, qtyRich)); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlSplit | macchina: {idxMacchina} | idxODL: {idxODL}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Update ODL (es: in setup x chiusura attrezzaggio) /// /// /// /// /// /// /// public async Task OdlUpdate(int idxODL, int matrOpr, decimal tCRichAttr, int pzPallet, string note) { bool answ = false; try { // inserisco evento answ = dbTabController.OdlUpdate(idxODL, matrOpr, tCRichAttr, pzPallet, note); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in OdlUpdate | idxODL: {idxODL} | matrOpr: {matrOpr} | tCRichAttr: {tCRichAttr} | pzPallet: {pzPallet} | note: {note}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Delete dell'oggetto opr serializzato /// /// /// public async Task OperatoreDeleteRedis(int matrOpr) { string source = "REDIS"; Stopwatch sw = new Stopwatch(); sw.Start(); bool answ = false; // cerco in redis... string currKey = $"{redisUserDataKey}:CurrOpr:{matrOpr}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { var done = await ExecFlushRedisPattern(currKey); if (done) { answ = true; } } sw.Stop(); Log.Debug($"OperatoreDeleteRedis | {source} | {sw.Elapsed.TotalMilliseconds}ms"); await Task.Delay(1); return answ; } /// /// Legge l'oggetto operatore loggato /// /// /// public async Task OperatoreGetRedis(int matrOpr, Guid currDevGuid) { string source = "REDIS"; Stopwatch sw = new Stopwatch(); sw.Start(); string answ = ""; // cerco in redis... string currKey = $"{redisUserDataKey}:CurrOpr:{matrOpr}:CurrDevGuid:{currDevGuid}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { //var encrData = SteamCrypto.DecryptString(rawData, passPhrase); //answ = JsonConvert.DeserializeObject(rawData); answ = rawData; } if (answ == null) { answ = ""; } sw.Stop(); Log.Debug($"OperatoreGetRedis | {source} | {sw.Elapsed.TotalMilliseconds}ms"); await Task.Delay(1); return answ; } /// /// Log in operatore /// /// matricola operatore /// Auth Key /// public async Task OperatoreSearch(int matrOpr, string authKey) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); AnagOperatoriModel answ = null; answ = dbTabController.OperatoreSearch(matrOpr, authKey); if (answ == null) { answ = new AnagOperatoriModel(); } sw.Stop(); Log.Debug($"LoginOperatore | {source} | {sw.Elapsed.TotalMilliseconds}ms"); await Task.Delay(1); return answ; } /// /// legge l'hash dell'oggetto curr opr /// /// /// public async Task OperatoreSetRedis(int matrOpr, string currOpr, Guid currDevGuid) { setExpDays(); string source = "REDIS"; Stopwatch sw = new Stopwatch(); sw.Start(); string answ = ""; // cerco in redis... string currKey = $"{redisUserDataKey}:CurrOpr:{matrOpr}:CurrDevGuid:{currDevGuid}"; //RedisValue rawData = await redisDb.StringGetAsync(currKey); // serializzo e salvo... //rawData = JsonConvert.SerializeObject(currOpr); answ = currOpr; //var encrData = SteamCrypto.EncryptString(rawData, passPhrase); await redisDb.StringSetAsync(currKey, currOpr, ConfigCache); if (answ == null) { answ = ""; } sw.Stop(); Log.Debug($"OperatoreSetRedis | {source} | {sw.Elapsed.TotalMilliseconds}ms"); await Task.Delay(1); return answ; } /// /// Stato prod macchina /// /// /// public async Task> PezziProdMacchina(string idxMacchina) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:PzProd:{idxMacchina}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.PezziProdMacchina(idxMacchina); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"PezziProdMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Avvio setup ODL da PODL /// /// /// /// /// /// /// public async Task PODL_startSetup(PODLExpModel editRec, int matrOpr, decimal tcRich, int pzPallet, string note, DateTime dtEvent) { bool answ = false; try { // inserisco evento answ = dbTabController.PODL_startSetup(editRec, matrOpr, tcRich, pzPallet, note, dtEvent); await FlushOdlCache(); } catch (Exception exc) { string logMsg = $"Eccezione in PODL_startSetup | matrOpr: {matrOpr} | idxPODL: {editRec.IdxPromessa}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Recupero PODL da chiave /// /// /// public async Task PODLExp_getByKey(int idxPODL) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); PODLExpModel result = new PODLExpModel(); // cerco in redis... string currKey = $"{redisBaseKey}:PODL:{idxPODL}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.PODLExp_getByKey(idxPODL)); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new PODLExpModel(); } sw.Stop(); Log.Debug($"PODL_getByKey | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Restituisce il contapezzi salvato per la macchina /// /// /// public async Task pzCounter(string idxMacchina) { int answ = -1; string rCall = ""; saveCallRec("getCounter"); try { rCall = redisDb.StringGet(redHash($"PzCount:{idxMacchina}")); if (rCall != "" && rCall != null) { int.TryParse(rCall, out answ); } else { answ = await pzCounterTC(idxMacchina); // salvo in redis... await saveCounter(idxMacchina, answ.ToString()); } } catch (Exception exc) { Log.Error($"Eccezione in pzCounter{Environment.NewLine}{exc}"); } return answ; } /// /// Restituisce il contapezzi come CONTEGGIO da TCRilevati per la macchina /// /// /// public async Task pzCounterTC(string idxMacchina) { int answ = -1; saveCallRec("getCounterTC"); // 2023.11.08 versione originale con tentativi reiterati, eliminata #if false // variabile x controllo dati recuperati DS_ProdTempi.StatoProdDataTable datiProdAct = null; bool okDatiProd = false; int taSP_ms_ant = memLayer.ML.cdvi("taStatoProd_ms_anticipo"); DateTime dataRif = DateTime.Now.AddMilliseconds(-taSP_ms_ant); okDatiProd = getStatoProd(idxMacchina, ref datiProdAct, dataRif); // se NON avesse recuperato --> aspetto taSP_ms_ant e poi RICHIAMO procedura... int maxTry = 3; while (!okDatiProd && maxTry > 0) { Log.Info(string.Format("[pzCounterTC] Impossibile recuperare dati ODL x idxMacchina {0}", idxMacchina), tipoLog.WARNING); // sleep... Thread.Sleep(taSP_ms_ant * 2); // riprovo lettura... okDatiProd = getStatoProd(idxMacchina, ref datiProdAct, dataRif); maxTry--; } // ora proseguo SE ho trovato i dati... if (okDatiProd) { if (datiProdAct != null) { if (datiProdAct.Count > 0) { if (!datiProdAct[0].IsPzTotODLNull()) { // ...a questo punto recupero DAVVERO i dati (o almeno ci provo...) try { // controllo answ = datiProdAct[0].PzTotODL; } catch (Exception exc) { Log.Info(string.Format("[pzCounterTC] Eccezione in recupero PzTotODL x idxMacchina {0}{1}{2}", idxMacchina, Environment.NewLine, exc), tipoLog.EXCEPTION); } } } } } else { Log.Info(string.Format("[pzCounterTC] Dati ODL x idxMacchina {0} non recuperati dopo tentativi reiterati...", idxMacchina), tipoLog.WARNING); } #endif DateTime dataRif = DateTime.Now; var datiProd = await StatoProdMacchina(idxMacchina, dataRif); if (datiProd != null) { answ = datiProd.PzTotODL; } return answ; } /// /// Restituisce elenco RC filtrato /// /// /// /// /// /// public async Task> RegControlliFilt(string idxMacchina, int idxODL, DateTime dataFrom, DateTime dataTo, bool showMulti) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:RecContr:{idxMacchina}:{idxODL}:{dataFrom:yyyyyMMdd-HHmm}:{dataFrom:yyyyyMMdd-HHmm}:{showMulti}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.RegControlliFilt(idxMacchina, idxODL, dataFrom, dataTo, showMulti); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"RegControlliFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Registra controllo /// /// /// /// /// /// /// public async Task RegControlliInsert(string idxMacchina, int matrOpr, bool esitoOk, string note, DateTime dataOra) { bool answ = false; try { // inserisco evento answ = dbTabController.RegControlliInsert(idxMacchina, matrOpr, esitoOk, note, dataOra); await FlushCache("RecContr"); } catch (Exception exc) { string logMsg = $"Eccezione in RegControlliInsert | macchina: {idxMacchina} | DataOra: {dataOra} | MatrOpr: {matrOpr} | Qta {esitoOk} | Note: {note}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Restituisce elenco ULTIMI RC x macchina /// /// /// public async Task> RegControlliLast(string idxMacchina) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:RecContr:{idxMacchina}:LAST"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.RegControlliLast(idxMacchina); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"RegControlliLast | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Aggiunta record RegistroScarti /// /// /// /// /// /// /// public async Task> RegDichiarGetFilt(string idxMacchina, string tagCode, int matrOpr, int idxODL, DateTime dataFrom, DateTime dataTo) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:RegDichiar:{idxMacchina}:{tagCode}:{matrOpr}:{idxODL}:{dataFrom:yyyyyMMdd-HHmm}:{dataTo:yyyyyMMdd-HHmm}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.RegDichiarGetFilt(idxMacchina, tagCode, matrOpr, idxODL, dataFrom, dataTo); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"RegDichiarGetFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Aggiunta record Registro Dichiarazioni /// /// /// public async Task RegDichiarInsert(RegistroDichiarazioniModel newRec) { bool answ = false; try { // inserisco evento answ = await dbTabController.RegDichiarInsert(newRec); // reset cache eventi/commenti await FlushCache("RegDichiar"); } catch (Exception exc) { string logMsg = $"Eccezione in RegDichiarInsert | macchina: {newRec.IdxMacchina} | DtRec: {newRec.DtRec} | TagCode: {newRec.TagCode} | MatrOpr: {newRec.MatrOpr} | ValString {newRec.ValString}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Aggiunta record Registro Dichiarazioni /// /// /// public async Task RegDichiarUpdate(RegistroDichiarazioniModel newRec) { bool answ = false; try { // inserisco evento answ = await dbTabController.RegDichiarUpdate(newRec); // reset cache eventi/commenti await FlushCache("RegDichiar"); } catch (Exception exc) { string logMsg = $"Eccezione in RegDichiarUpdate | macchina: {newRec.IdxMacchina} | DtRec: {newRec.DtRec} | TagCode: {newRec.TagCode} | MatrOpr: {newRec.MatrOpr} | ValString {newRec.ValString}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Restituisce elenco RS filtrato /// /// /// /// /// /// /// public async Task> RegScartiGetFilt(string idxMacchina, int idxODL, DateTime dataFrom, DateTime dataTo, bool showMulti) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:RegScarti:{idxMacchina}:{idxODL}:{dataFrom:yyyyyMMdd-HHmm}:{dataTo:yyyyyMMdd-HHmm}:{showMulti}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.RegScartiGetFilt(idxMacchina, idxODL, dataFrom, dataTo, showMulti); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"RegScartiGetFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Restituisce elenco RSK filtrato x parent /// /// /// public async Task> RegScartiKitGetFilt(RegistroScartiModel ParentRec) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:RegScartiKit:{ParentRec.IdxMacchina}:{ParentRec.DataOra:yyyyyMMdd-HHmm}:{ParentRec.Causale}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.RegScartiKitGetFilt(ParentRec); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, FastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"RegScartiKitGetFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Aggiunta record RegistroScarti /// /// /// public async Task RegScartiInsert(RegistroScartiModel newRec) { bool answ = false; try { // inserisco evento answ = await dbTabController.RegScartiInsert(newRec); // reset cache eventi/commenti await FlushCache("RegScarti"); await FlushCache("RegScartiKit"); } catch (Exception exc) { string logMsg = $"Eccezione in RegScartiInsert | macchina: {newRec.IdxMacchina} | DataOra: {newRec.DataOra} | Causale: {newRec.Causale} | MatrOpr: {newRec.MatrOpr} | Qta {newRec.Qta} | Note: {newRec.Note}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Split record RegistroScarti --> RegistroScartiKit /// /// /// public async Task RegScartiKitSplit(RegistroScartiModel newRec) { bool answ = false; try { // inserisco evento answ = await dbTabController.RegScartiKitSplit(newRec); // reset cache eventi/commenti await FlushCache("RegScarti"); await FlushCache("RegScartiKit"); } catch (Exception exc) { string logMsg = $"Eccezione in RegScartiKitSplit | macchina: {newRec.IdxMacchina} | DataOra: {newRec.DataOra} | Causale: {newRec.Causale} | MatrOpr: {newRec.MatrOpr} | Qta {newRec.Qta} | Note: {newRec.Note}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Resetta (rileggendo) i dati della macchina /// /// /// public async Task> resetDatiMacchina(string idxMacchina) { Dictionary answ = new Dictionary(); // inizio con un bel reset... string currKey = $"{redisBaseKey}:MSFD"; await FlushCache(currKey); var tabMSFD = await VMSFDGetByMacc(idxMacchina); if (tabMSFD != null && tabMSFD.Count > 0) { var rigaMSFD = tabMSFD.FirstOrDefault(); // ora provo a compilare... try { // salvo 1:1 i valori... STATO answ.Add("IdxMicroStato", $"{rigaMSFD.IdxMicroStato}"); answ.Add("IdxStato", $"{rigaMSFD.IdxStato}"); answ.Add("CodArticolo", $"{rigaMSFD.CodArticolo}"); answ.Add("insEnabled", $"{rigaMSFD.InsEnabled}"); answ.Add("sLogEnabled", $"{rigaMSFD.SLogEnabled}"); answ.Add("pallet", $"{rigaMSFD.Pallet}"); answ.Add("CodArticolo_A", $"{rigaMSFD.CodArticoloA}"); answ.Add("CodArticolo_B", $"{rigaMSFD.CodArticoloB}"); answ.Add("TempoCicloBase", $"{rigaMSFD.TempoCicloBase}"); answ.Add("PzPalletProd", $"{rigaMSFD.PzPalletProd}"); answ.Add("MatrOpr", $"{rigaMSFD.MatrOpr}"); answ.Add("lastVal", $"{rigaMSFD.LastVal}"); answ.Add("TCBase", $"{rigaMSFD.TempoCicloBase}"); //...e SETUP answ.Add("CodMacc", rigaMSFD.Codmacchina); answ.Add("IdxFamIn", $"{rigaMSFD.IdxFamigliaIngresso}"); answ.Add("Multi", $"{rigaMSFD.Multi}"); answ.Add("BitFilt", $"{rigaMSFD.BitFilt}"); answ.Add("MaxVal", $"{rigaMSFD.MaxVal}"); answ.Add("BSR", $"{rigaMSFD.Bsr}"); answ.Add("ExplodeBit", $"{rigaMSFD.ExplodeBit}"); answ.Add("NumBit", $"{rigaMSFD.NumBit}"); answ.Add("IdxFamMacc", $"{rigaMSFD.IdxFamiglia}"); answ.Add("simplePallet", $"{rigaMSFD.SimplePallet}"); answ.Add("palletChange", $"{rigaMSFD.PalletChange}"); // cerco dati master/slave... var macSlave = await Macchine2Slave(); var mastList = macSlave .Where(x => x.IdxMacchina.Equals(idxMacchina, StringComparison.InvariantCultureIgnoreCase)) .ToList(); var slaveList = macSlave .Where(x => x.IdxMacchinaSlave.Equals(idxMacchina, StringComparison.InvariantCultureIgnoreCase)) .ToList(); string isMaster = mastList.Count > 0 ? "1" : "0"; string isSlave = slaveList.Count > 0 ? "1" : "0"; answ.Add("Master", isMaster); answ.Add("Slave", isSlave); } catch (Exception exc) { Log.Error($"Errore in compilazione dati MSFD:{Environment.NewLine}{exc}"); } // verifico il timeout che cambia a seconda che sia vero o falso insEnabled... int tOutShort = 0; int tOutLong = 0; ConfigGetVal("TmOut.MS.S", ref tOutShort); ConfigGetVal("TmOut.MS.L", ref tOutLong); int redDtMacTOut = tOutLong; try { redDtMacTOut = (answ["insEnabled"].ToLower() == "true") ? tOutShort : tOutLong; } catch (Exception exc) { Log.Info($"Eccezione in calcolo timeout dati macchina: idxMacchina{idxMacchina} | TShort: {tOutShort} | TLong {tOutLong}{Environment.NewLine}{exc}"); } // salvo in redis! redisHashDictSet(currKey, answ, TimeSpan.FromSeconds(redDtMacTOut)); } return answ; } /// /// Effettua reset microstato macchina /// /// public async Task resetMicrostatoMacchina(string idxMacchina) { // salvo microstato 0... MicroStatoMacchinaModel newRecMS = new MicroStatoMacchinaModel() { IdxMacchina = idxMacchina, InizioStato = DateTime.Now, IdxMicroStato = 0, Value = "FER" }; var result = dbTabController.MicroStatoMacchinaUpsert(newRecMS); // reset in redis await resetDatiMacchina(idxMacchina); } /// /// Effettua ricalcolo MSE x macchina indicata /// /// idx macchina da confermare /// Num massimo secondi di "vecchiaia" del dato /// public async Task RicalcMse(string idxMacchina, int maxAgeSec) { bool answ = false; answ = dbTabController.RicalcMse(idxMacchina, maxAgeSec); await FlushCache(Constants.redisMseKey); return answ; } /// /// Processa registrazione di un counter x una data macchina IOB /// /// /// contapezzi /// public async Task saveCounter(string idxMacchina, string counter) { // registro conteggio impiego chiamate REDIS saveCallRec("saveCounter"); string answ = "0"; // inizio processing vero e proprio INPUT... if (!string.IsNullOrEmpty(idxMacchina)) { if (!string.IsNullOrEmpty(counter)) { int newCounter = -1; int.TryParse(counter, out newCounter); // se il conteggio è >= 0 SALVO come nuovo conteggio... if (newCounter >= 0) { string redKey = redHash($"PzCount:{idxMacchina}"); // verifico SE ci sia chiave in redis (ALTRIMENTI rileggo da DB) string redVal = redisDb.StringGet(redKey); if (!string.IsNullOrEmpty(redVal)) { // salvo in Redis nell'area corretta il valore richiesto redisDb.StringSet(redKey, counter); // imposto risposta... answ = counter; } else { // rileggo da DB e salvo e poi restituisco questo... int currCount = await pzCounterTC(idxMacchina); redisDb.StringSet(redKey, $"{currCount}"); // imposto risposta... answ = currCount.ToString(); } } } else { string errore = "Errore: parametro counter vuoto"; Log.Error(errore); answ = errore; } } else { string errore = "Errore: parametro macchina vuoto"; Log.Error(errore); answ = errore; } return answ; } /// /// Processa registrazione ODL corrente x macchina /// /// /// cod ODL in produzione, se 0 > vuoto /// public string saveCurrODL(string idxMacchina, int currIdxOdl) { // registro conteggio impiego chiamate REDIS saveCallRec("saveCurrODL"); int currOdlCacheDur = 500; ConfigGetVal("currOdlCacheDur", ref currOdlCacheDur); string answ = ""; // inizio processing vero e proprio INPUT... if (idxMacchina != null) { if (idxMacchina != "") { // se ODL fosse 0 USO DURATA CACHE 1/4... if (currIdxOdl == 0) { currOdlCacheDur = currOdlCacheDur / 4; } redisDb.StringSet(redHash($"CurrODL:{idxMacchina}"), currIdxOdl, TimeSpan.FromSeconds(currOdlCacheDur)); // registro in risposta che è andato tutto bene... answ = "OK"; } else { string errore = $"Errore: parametri macchina vuoto (idxMacchina: {idxMacchina} | currIdxOdl: {currIdxOdl})"; Log.Error(errore); answ = errore; } } else { string errore = "Errore: mancano parametri macchina"; Log.Error(errore); answ = errore; } return answ; } /// /// Setup oggetto config con lettura da DB /// /// public void SetupConfig() { CurrConfig = ConfigGetAll(); } /// /// Restituisce elenco gruppi Scheda tecnica /// /// public async Task> ST_AnagGruppiList() { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:ST:AnagGruppi"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.ST_AnagGruppiList(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"ST_AnagGruppiList | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } public async Task ST_CheckCleanByOdl(int idxOdl) { bool answ = false; try { // inserisco evento answ = dbTabController.ST_CheckCleanByOdl(idxOdl); await FlushCache("ST"); } catch (Exception exc) { string logMsg = $"Eccezione in ST_CheckCleanByOdl | idxOdl: {idxOdl}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } public async Task ST_CheckUpsert(int idxOdl, int idxST, int oggetto, int num, string valueRead, string extCode, bool checkOk, string userMod, bool forced) { bool answ = false; try { // inserisco evento answ = dbTabController.ST_CheckUpsert(idxOdl, idxST, oggetto, num, valueRead, extCode, checkOk, userMod, forced); await FlushCache("ST"); } catch (Exception exc) { string logMsg = $"Eccezione in ST_CheckUpsert | idxOdl: {idxOdl}{Environment.NewLine}{exc}"; Log.Error(logMsg); } return answ; } /// /// Dati deroga SchedaTecnica serializzati in REDIS /// public StCheckOverride ST_DerogaGet(string Utente, int IdxST) { StCheckOverride answ = new StCheckOverride() { IdxST = 0 }; string keyDerogaST = redHash($"DerogaSt:{Utente}:{IdxST:000}"); string rawData = redisDb.StringGet(keyDerogaST); if (!string.IsNullOrEmpty(rawData)) { try { answ = JsonConvert.DeserializeObject(rawData); } catch (Exception exc) { Log.Error($"Eccezione in ST_DerogaSet | Utente: {Utente} | IdxST: {IdxST}{Environment.NewLine}{exc}"); } } return answ; } public bool ST_DerogaSet(StCheckOverride deroga) { bool fatto = false; try { string keyDerogaST = redHash($"DerogaSt:{deroga.Utente}:{deroga.IdxST:000}"); string rawData = JsonConvert.SerializeObject(deroga); redisDb.StringSet(keyDerogaST, rawData, TimeSpan.FromMinutes(2)); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in ST_DerogaSet | Utente: {deroga.Utente} | IdxST: {deroga.IdxST}{Environment.NewLine}{exc}"); } return fatto; } /// /// Recupero Righe (Actual) della scheda tecnica da GRUPPO + ODL /// /// /// /// public async Task> STAR_byGrpOdl(string codGruppo, int idxODL) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:STAR:{codGruppo}:{idxODL}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.STAR_byGrpOdl(codGruppo, idxODL); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"STAR_byGrpOdl | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Recupero Righe (Actual) della scheda tecnica da GRUPPO + ODL /// /// /// /// /// public async Task> STAR_byGrpOdlLbl(string codGruppo, string label, int idxODL) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:STAR:{codGruppo}:{label}:{idxODL}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.STAR_byGrpOdlLbl(codGruppo, label, idxODL); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"STAR_byGrpOdlLbl | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Recupero Righe pending da ODL /// /// /// public List STAR_pendByOdl(int idxODL) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:STAR:Pend:{idxODL}"; RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.STAR_pendByOdl(idxODL); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(5)); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"STAR_pendByOdl | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Stato macchina /// /// /// public StatoMacchineModel StatoMacchina(string idxMacchina) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); StatoMacchineModel? result = new StatoMacchineModel(); // cerco in redis... string currKey = $"{redisBaseKey}:StatoMacc:{idxMacchina}"; RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { result = dbTabController.StatoMacchina(idxMacchina); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(2)); } if (result == null) { result = new StatoMacchineModel(); } sw.Stop(); Log.Debug($"StatoMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Stato prod macchina (completo) /// /// /// /// public async Task StatoProdMacchina(string idxMacchina, DateTime dtReq) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); StatoProdModel? result = new StatoProdModel(); // cerco in redis... string currKey = $"{redisBaseKey}:StatoProd:{idxMacchina}:{dtReq:HHmm}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { result = dbTabController.StatoProdMacchina(idxMacchina, dtReq); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new StatoProdModel(); } sw.Stop(); Log.Debug($"StatoProdMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Turno macchina /// /// public async Task TurnoMacchinaGet(string idxMacchina) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); TurniMaccModel? result = new TurniMaccModel(); // cerco in redis... string currKey = $"{redisBaseKey}:TurniMacc:{idxMacchina}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.TurnoMacchinaGet(idxMacchina)); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new TurniMaccModel(); } sw.Stop(); Log.Debug($"TurnoMacchinaGet | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco turni macchina (all) /// /// public async Task> TurnoMacchinaGetAll() { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:TurniMacc:All"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.TurnoMacchinaGetAll()); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"TurnoMacchinaGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Toggle stato turno /// /// /// /// public bool TurnoMacchinaToggle(string idxMacchina, int numTurno) { bool answ = dbTabController.TurnoMacchinaToggle(idxMacchina, numTurno); FlushCache("TurniMacc").ConfigureAwait(false); return answ; } /// /// OVERLOAD vecchio nome function per MachineParamUpsert: Effettua UPSERT elenco parametri /// correnti x IOB (se c'è UPDATE, se manca ADD) /// /// /// /// public bool upsertCurrObjItems(string idxMacchina, List innovations) { return MachineParamUpsert(idxMacchina, innovations); } /// /// Intera vista v_MSFD /// /// public async Task> VMSFDGetAll() { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:MSFD:ALL"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbIocController.VMSFDGetAll(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VMSFDGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Vista v_MSFD x singola macchina (da stored) - singolo record /// /// /// public async Task> VMSFDGetByMacc(string idxMacc) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:MSFD:MACCH:{idxMacc}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbIocController.VMSFDGetByMacc(idxMacc); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VMSFDGetByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Vista v_MSFD delle machine MULTI filtrato x macchina (da stored) /// /// /// public async Task> VMSFDGetMultiByMacc(string idxMacc) { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:MSFD:MULTI:{idxMacc}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); //if (!string.IsNullOrEmpty($"{rawData}")) if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbIocController.VMSFDGetByMacc(idxMacc); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VMSFDGetMultiByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } public List VocabolarioGetAll() { // setup parametri costanti string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:Vocab"; RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = dbTabController.VocabolarioGetAll(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, UltraLongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VocabolarioGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco causali scarto /// /// public async Task> VSCS_getAll() { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:VSCS"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.VSCS_getAll()); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VSCS_getAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco ultimi ODL x macchina /// /// Macchina /// /// public async Task> VSOdlGetLastByMacc(string idxMacchina, int numRec) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:VSODL:{idxMacchina}:{numRec}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.VSOdlGetLastByMacc(idxMacchina, numRec)); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VSOdlGetLastByMacc | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } /// /// Elenco prossimi ODL/PODL x macchina /// /// Macchina /// /// /// public async Task> VSOdlGetUnused(string idxMacchina, bool showAll, int numDayAdd) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in redis... string currKey = $"{redisBaseKey}:VSODL:{idxMacchina}:ALL_{showAll}:{numDayAdd}"; RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); source = "REDIS"; } else { result = await Task.FromResult(dbTabController.VSOdlGetUnused(idxMacchina, showAll, numDayAdd)); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); Log.Debug($"VSOdlGetUnused | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } #endregion Public Methods #region Protected Fields protected int expMinutes = 1; /// /// Oggetto per connessione a REDIS /// protected ConnectionMultiplexer redisConn = null!; /// /// Oggetto DB redis da impiegare x chiamate R/W /// protected IDatabase redisDb = null!; #endregion Protected Fields #region Protected Properties /// /// Durata cache data dal valore in config /// protected TimeSpan ConfigCache { get => TimeSpan.FromMinutes(expMinutes); } #endregion Protected Properties #region Protected Methods protected void setExpDays() { ConfigGetVal("TAB_dtTimerScadLogin", ref expMinutes); } #endregion Protected Methods #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); private string CodModulo = ""; private string ConnStr = ""; private Dictionary connStrParams = new Dictionary(); private string DataBase = ""; private string DataSource = ""; private string redisBaseKey = "MP:TAB:Cache"; private string redisUserDataKey = "MP:TAB:Users"; #endregion Private Fields #region Private Properties private static Controllers.MpInveController dbInveController { get; set; } = null!; private static Controllers.MpIocController dbIocController { get; set; } = null!; private static Controllers.MpTabController dbTabController { get; set; } = null!; #endregion Private Properties #region Private Methods /// /// Esegue flush memoria redis dato pattern /// /// /// private async Task ExecFlushRedisPattern(RedisValue pattern) { bool answ = false; var listEndpoints = redisConn.GetEndPoints(); foreach (var endPoint in listEndpoints) { //var server = redisConnAdmin.GetServer(listEndpoints[0]); var server = redisConn.GetServer(endPoint); if (server != null) { var keyList = server.Keys(redisDb.Database, pattern); foreach (var item in keyList) { await redisDb.KeyDeleteAsync(item); } answ = true; } } return answ; } /// /// Hash dati EXE TASK x la macchina specificata /// /// /// private string exeTaskHash(string idxMacchina) { return redHash($"ExeTask:{idxMacchina}"); } /// /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato /// /// /// private Dictionary mTaskMacchina(string idxMacchina) { // hard coded dimensione vettore DatiMacchine Dictionary answ = new Dictionary(); // ORA recupero da memoria redis... try { var currKey = (RedisKey)exeTaskHash(idxMacchina); answ = redisHashDictGet(currKey); } catch (Exception exc) { Log.Info(string.Format("Errore in recupero dati EXE TASK x Redis mTaskMacchina - idxMacchina {2}:{0}{1}", Environment.NewLine, exc, idxMacchina)); } return answ; } private string redHash(string keyName) { string result = keyName; try { result = $"{CodModulo}:{DataSource}:{DataBase}:{keyName}".Replace("\\", "_"); } catch (Exception exc) { Log.Error($"Errore in redHash{Environment.NewLine}{exc}"); } return result; } /// /// Recupero HashSet redis come Dictionary /// /// /// private Dictionary redisHashDictGet(RedisKey currKey) { Dictionary answ = new Dictionary(); try { answ = redisDb .HashGetAll(currKey) .ToDictionary(x => $"{x.Name}", x => $"{x.Value}"); } catch (Exception exc) { Log.Info($"Errore redisHashDictGet | currKey: {currKey}{Environment.NewLine}{exc}"); } return answ; } /// /// Salvataggio Dictionary come HashSet Redis /// /// /// private bool redisHashDictSet(RedisKey currKey, Dictionary dict) { bool fatto = false; try { HashEntry[] data2ins = new HashEntry[dict.Count]; int i = 0; foreach (KeyValuePair kvp in dict) { data2ins[i] = new HashEntry(kvp.Key, kvp.Value); i++; } // salvo! redisDb.HashSet(currKey, data2ins); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in redisHashDictSet | currKey: {currKey}{Environment.NewLine}{exc}"); } return fatto; } /// /// Salvataggio Dictionary come HashSet Redis /// /// /// /// private bool redisHashDictSet(RedisKey currKey, Dictionary dict, TimeSpan ttl) { bool fatto = false; try { HashEntry[] data2ins = new HashEntry[dict.Count]; int i = 0; foreach (KeyValuePair kvp in dict) { data2ins[i] = new HashEntry(kvp.Key, kvp.Value); i++; } // salvo! redisDb.HashSet(currKey, data2ins); redisDb.KeyExpire(currKey, ttl); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in redisHashDictSet | currKey: {currKey}{Environment.NewLine}{exc}"); } return fatto; } /// /// registra su REDIS eventuale superamento numero limite di call x il metodo in oggetto /// /// private void saveCallRec(string callCountKey) { // conto la richiesta nel contatore REDIS long nCall = redisDb.StringIncrement(redHash($"COUNT:pCall:{callCountKey}")); //... se == nCall2Log scrivo su log e resetto int nCall2Log = 10; ConfigGetVal("nCall2Log", ref nCall2Log); if (nCall >= nCall2Log) { // loggo Log.Info($"{callCountKey}: {nCall} call received"); // resetto! redisDb.StringSet(redHash($"COUNT:pCall:{callCountKey}"), "0"); } } /// /// Hash dati SAVED (EXE) TASK x la macchina specificata x poter ripristinare in caso di /// perdita valore WRITE /// /// /// private string savedTaskHash(string idxMacchina) { return redHash($"SavedTask:{idxMacchina}"); } #endregion Private Methods } }