using MagData; using MapoDb; using MapoSDK; using MP_IO.Interfaces; using Newtonsoft.Json; using StackExchange.Redis; using SteamWare; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Web.Mvc; namespace MP_IO.Controllers { public class IOBController : Controller, IIOBService { #region Public Methods /// SALVA x macchina KVP parametro/valore: /// /// GET: IOB/addOptPar/SIMUL_03?pName=PZREQ&pValue=1000 /// /// public string addOptPar(string id, string pName, string pValue) { string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { DataLayerObj.addOptPar4Machine(id, pName, pValue); answ = getOptPar(id); } catch { } return answ; } /// /// AGGIUNGE TASK richiesto x macchina: /// /// GET: IOB/addTask2Exe/3010?taskName=startSetup&taskVal=T190406101512 /// GET: IOB/addTask2Exe/3010?taskName=stopSetup&taskVal=T190406101512 /// GET: IOB/addTask2Exe/SIMUL_03?taskName=setProg&taskVal=P00000001 /// GET: IOB/addTask2Exe/SIMUL_03?taskName=setComm&taskVal=ODL_0000123 /// GET: IOB/addTask2Exe/SIMUL_03?taskName=setArt&taskVal=ART_0000321 /// /// /// /// public string addTask2Exe(string id, string taskName, string taskVal) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il carattere "|" che poi trasformiamo ora in "#" if (!string.IsNullOrEmpty(id)) { id = id.Replace("|", "#"); } // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { // converto stringa in tipo task... taskType tName = taskType.nihil; bool fatto = Enum.TryParse(taskName, out tName); if (fatto) { DataLayerObj.addTask4Machine(id, tName, taskVal); } else { logger.lg.scriviLog($"addTask2Exe: impossibile riconoscere il comando {taskName} come uno dei tipi ammessi, NON aggiunto", tipoLog.ERROR); } answ = getTask2Exe(id); } catch { } return answ; } /// /// Richiesta chiusura manuale ODL x macchina (popup utente): /// /// GET: IOB/askCloseODL/SIMUL_03?idxOdl=123 /// /// id macchina /// idx dell'ODL da chiudere /// bool esecuzione public bool askCloseODL(string id, int idxOdl) { bool answ = false; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(true); try { // preparo una richiesta di chiusura... DisplayAction CurrAction = new DisplayAction() { Topic = "Chiusura ODL", Message = "Rilevato possibile fine operazioni, Vuoi chiudere la commessa?", ShowCancel = true, ShowClose = true, ShowConfirm = true, CancelAction = "DisableAction", ConfirmAction = "CloseODL", DtReq = DateTime.Now, IsActive = true, Parameter = $"{idxOdl}" }; answ = DataLayerObj.ActionSetReq(CurrAction); } catch { } return answ; } /// /// Chiude ODL x macchina: /// /// GET: IOB/closeODL/SIMUL_03?idxOdl=123&dtEve=20230323151100000&dtCurr=20230323221100000 /// /// id macchina /// idx dell'ODL da chiudere /// DataOra evento /// DataOra corrente x fix /// bool esecuzione public bool closeODL(string id, int idxOdl, string dtEve = "", string dtCurr = "") { bool answ = false; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try {// chiamata diretta sul DB... DateTime dtEvento = DateTime.Now; //se ho una data-ora chiusura la calcolo... bool rtimeProc = string.IsNullOrEmpty(dtEve); if (!rtimeProc) { dtEvento = DataLayerObj.GetSrvDtEvent(dtEve, dtCurr); } DataLayerObj.taODL.forceClose(idxOdl, id, dtEvento); answ = true; } catch { } return answ; } /// /// Chiude PODL --> ODL x macchina: /// /// GET: IOB/closePODL/SIMUL_03?idxPOdl=123&dtEve=20230323151100000&dtCurr=20230323221100000 /// /// id macchina /// idx del POdl da chiudere /// DataOra evento /// DataOra corrente x fix /// bool esecuzione public bool closePODL(string id, int idxPOdl, string dtEve = "", string dtCurr = "") { bool answ = false; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { //cerco PODL e se questo ha un ODL associato... var tabPodl = DataLayerObj.taPODL.getByKey(idxPOdl); // se trovato... if (tabPodl != null && tabPodl.Rows.Count > 0) { int idxOdl = tabPodl[0].IdxODL; // chiamata diretta sul DB... DateTime dtEvento = DateTime.Now; //se ho una data-ora chiusura la calcolo... bool rtimeProc = string.IsNullOrEmpty(dtEve); if (!rtimeProc) { dtEvento = DataLayerObj.GetSrvDtEvent(dtEve, dtCurr); } DataLayerObj.taODL.forceClose(idxOdl, id, dtEvento); } } catch { } return answ; } /// /// GET: IOB/enabled/SIMUL_03 /// /// /// public string enabled(string id) { string answ = "ND"; // se id nullo --> KO! if (id == null) { answ = "KO"; } else { try { answ = DataLayerMan.insEnab(id) ? "OK" : "NO"; // 2025.03.04 aggiunto keepalive x evitare C101 MapoDb.MapoDb connDb = new MapoDb.MapoDb(); connDb.scriviKeepAlive(id, DateTime.Now); } catch (Exception exc) { logger.lg.scriviLog(string.Format("Errore in enabled{0}{1}", Environment.NewLine, exc)); answ = "NO"; } } return answ; } /// /// Processa una chiamata POST per l'invio di un array Json di oggetti input (EVENTI) /// POST: IOB/evListJson/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string evListJson(string id) { int insDone = 0; string answ = "-"; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader( Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // se ho dati... if (content != "") { DataLayer DataLayerObj = new DataLayer(); // procedo a deserializzare in blocco l'oggetto... evJsonPayload receivedData = new evJsonPayload(); try { // deserializzo. receivedData = JsonConvert.DeserializeObject(content); } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase deserializzazione inputJson{Environment.NewLine}{exc}"); answ = "NO"; } // se ho qualcosa da processare... if (receivedData != null) { // per ogni valore --> processo! try { foreach (var item in receivedData.eventList) { if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"Valori letti: id: {id} | valore: {item.valore}", tipoLog.INFO); } // formato datetime come yyyyMMddHHmmssfff -->es: 20181223180600000 answ = DataLayerObj.processInput(id, item.valore, item.dtEve.ToString("yyyyMMddHHmmssfff"), item.dtCurr.ToString("yyyyMMddHHmmssfff"), item.cnt.ToString()); insDone++; } // se vuoto --> OK! if (string.IsNullOrEmpty(answ)) { answ = $"OK {insDone} processed"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase invio valori inputJson{Environment.NewLine}{exc}"); answ = "NO"; } } } return answ; } /// /// Sistema Dossier/Snapshot giornalieri x impianto indicato, andando a generare 1 Dossier /// giornaliero x ogni giornata dall'ultimo registrato alla data corrente /// es: http://url_site/MP/IO/IOB/fixDailyDossier/SIMUL_03 /// /// /// public string fixDailyDossier(string id) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); // effettuo processing try { DataLayer DataLayerObj = new DataLayer(); // verifico se si possa processare, ovvero tab ConfFlux x macchina sia valorizzata... var confDataMach = DataLayerObj.confFluxMach(id); if (confDataMach.Count > 0) { // determino ultima data da processare (inizio oggi, a mezzanotte) DateTime dtTo = DateTime.Today; DateTime dtFrom = dtTo; // determino data di partenza, prima da dossier esistenti var listaDoss = DataLayerObj.dossierLastByMach(id); if (listaDoss.Count > 0) { // primo giorno DOPO ultima registrazione dtFrom = listaDoss.OrderByDescending(x => x).FirstOrDefault().AddDays(1); } else { // ...o da fluxLog acquisiti... var listaFL = DataLayerObj.fluxLogFirstByMach(id); if (listaFL.Count > 0) { // giorno successivo a prima registrazione dtFrom = listaFL.OrderBy(x => x).FirstOrDefault().AddDays(1); } } string caller = $"takeFlogSnapshot({id})"; DateTime dtStart = dtFrom.Date; DateTime dtEnd = dtFrom; // max 10 dossier alla volta (se non configurato diversamente) int maxAdd = memLayer.ML.CRI("IO_numDossMaxCreate"); if (dtStart < dtTo) { // verifico di avere almeno 1 dossier da produrre ciclo fino ad esaurire le // date da processare while (dtStart < dtTo && maxAdd > 0) { // sistemo end dtEnd = dtStart.AddDays(1); // effettuo chiamata registrazione snapshot! answ = doSaveFLSnapshot(id, dtStart, dtEnd, caller); // incremento START... dtStart = dtEnd; // riduco il numero di chiamate ammesse x singolo task maxAdd--; } // reset cache dossier... DataLayerObj.dossierLastByMachReset(id); } else { answ = "NO more to add"; } } else { answ = "NO ConfFluxData"; } } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in recupero fixDailyDossier{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Sistema ODL giornalieri x impianto indicato, andando a generare 1 ODL giornaliero x ogni /// giornata dall'ultimo ODL aperto alla data corrente /// es: http://url_site/MP/IO/IOB/fixDailyOdl/SIMUL_03 /// /// /// public string fixDailyOdl(string id) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); // chiamo metodo redis/db... try { DataLayer DataLayerObj = new DataLayer(); // recupero ultimo ODL macchina... var lastOdlStarted = DataLayerObj.taODL.getLastByMacc(id); if (lastOdlStarted != null && lastOdlStarted.Count > 0) { // calcolo data ultimo avviato e chiedo dal giorno dopo... DateTime dtFrom = lastOdlStarted[0].DataInizio.AddDays(1); DateTime dtTo = DateTime.Today; if (dtTo >= dtFrom) { string codArt = lastOdlStarted[0].CodArticolo; // chiamo la stored x sistemare gli ODL DataLayerObj.taODL.AutoDayGener(id, dtFrom, dtTo, codArt); } answ = "OK"; } } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in fixDailyOdl{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Sistema ODL giornalieri x impianto indicato, andando a generare 1 ODL giornaliero x ogni /// giornata dall'ultimo ODL aperto alla data corrente + conferma pezzi (es TFT x ODL /// giornalieri energia) /// es: http://url_site/MP/IO/IOB/fixDailyOdlConfPzCount/SIMUL_03 /// /// /// public string fixDailyOdlConfPzCount(string id) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); // chiamo metodo redis/db... try { DataLayer DataLayerObj = new DataLayer(); // recupero ultimo ODL macchina... var lastOdlStarted = DataLayerObj.taODL.getLastByMacc(id); if (lastOdlStarted != null && lastOdlStarted.Count > 0) { // calcolo data ultimo avviato e chiedo dal giorno dopo... DateTime dtFrom = lastOdlStarted[0].DataInizio.AddDays(1); DateTime dtTo = DateTime.Today; if (dtTo >= dtFrom) { string codArt = lastOdlStarted[0].CodArticolo; // chiamo la stored x sistemare gli ODL DataLayerObj.taODL.AutoDayGenerFull(id, dtFrom, dtTo, codArt, null, null, null, null, null, true, false); } answ = "OK"; } } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in fixDailyOdlConfPzCount{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Invio record flog secco /// GET: IOB/flog/SIMUL_03?flux=PROG&valore=P0001&dtEve=20161223180600000&dtCurr=20161223180600000&cnt=999&disabKA=false /// /// IdxMacchina /// CodFlux /// Valore da registrare /// DataOra evento (IOB time) /// DataOra corrente (IOB time) /// Contatore eventi (IOB) /// Disabilitazione scrittura record KeepAlive /// public string flog(string id, string flux, string valore, string dtEve, string dtCurr, string cnt, string disabKA = "false") { string answ = ""; // formato yyyymmddHHMMSSnnn ovvero da anno a millisecondi if (cnt == null) { cnt = "0"; } DateTime dataOraEvento = DateTime.Now; if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"Valori letti: id: {id} | flux: {flux} valore: {valore}", tipoLog.INFO); } try { DataLayer DataLayerObj = new DataLayer(); int count = 0; Int32.TryParse(cnt, out count); bool disKa = false; bool.TryParse(disabKA, out disKa); answ = DataLayerObj.processFluxLog(id, flux, valore, dtEve, dtCurr, count, disKa); } catch (Exception exc) { logger.lg.scriviLog($"Errore in flog{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Processa una chiamata POST per l'invio di un array Json di oggetti fluxLog /// PUT: IOB/flogJson/SIMUL_03 /// /// ID dell'IOB /// Disabilitazione della scrittura del record KeepAlive /// [HttpPost] public string flogJson(string id, string disabKA = "false") { int insDone = 0; bool disKa = false; bool.TryParse(disabKA, out disKa); string answ = "-"; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader( Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // se ho dati... if (content != "") { answ = processFLogJson(id, disKa, insDone, answ, content); } return answ; } /// /// Creazione nuovo ODL dato CodXdl + numPz /// GET: IOB/forceCreatePOdl/SIMUL_03?CodXdl=ABCD_1234&numPz=5 /// /// /// /// /// /// IdxODL creato public int forceCreatePOdl(string id, string CodArt, string CodGruppo, int numPz) { int answ = 0; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.ForceCreatePOdl(id, CodArt, numPz, CodGruppo); return answ; } /// /// Chiude ODL precedente ed avvia uno nuovo (duplicandolo e sitemando quantità RIMANENTE), /// e CONFERMA produzione... /// /// GET: IOB/forceSplitOdl/SIMUL_03 /// /// /// Esito chiamata (OK/vuoto) public string forceSplitOdl(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); DataLayer DataLayerObj = new DataLayer(); return DataLayerObj.AutoStartOdl(id, true, true, 100, 0, ""); } /// /// Chiude ODL precedente ed avvia uno nuovo (duplicandolo e sitemando quantità /// RIMANENTE), e CONFERMA produzione... /// /// GET: IOB/forceSplitOdl/SIMUL_03?doConfirm=true&qtyFromLast=true&roundStep=150&extOrderCode=ABCDE1234 /// /// /// id impianto /// /// /// /// /// Cod esterno da legare all'ODL x tracciare lotti prod /// matricola operatore che effettua la fuzione (default = 0) /// Esito chiamata (OK/vuoto) public string forceSplitOdlFull(string id, bool doConfirm, bool qtyFromLast, int? roundStep, string keyRichiesta = "", int matrOpr = 0) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); DataLayer DataLayerObj = new DataLayer(); if (roundStep == null) { roundStep = 100; } return DataLayerObj.AutoStartOdl(id, doConfirm, qtyFromLast, (int)roundStep, matrOpr, keyRichiesta); } /// /// Avvia PODL indicato /// - se esistesse un ODL da altro PODL --> chiude /// - se fosse già in essere ODL collegato --> lascia aperto /// - se fosse chiuso ODL collegato --> duplica PODL e poi avvia nuovo ODL. /// /// GET: IOB/forceStartPOdl/SIMUL_03?idxPODL=123&dtEve=20230323151100000&dtCurr=20230323221100000 /// /// /// idx del PDL da avviare /// data-ora di avvio (opzionale) /// data-ora attuale (opzionale) /// matricola operatore (default 0) /// Esito chiamata (OK/vuoto) public string forceStartPOdl(string id, int idxPODL, string dtEve = "", string dtCurr = "", int matrOpr = 0) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); DataLayer DataLayerObj = new DataLayer(); string answ = DataLayerObj.ForceStartPOdl(id, idxPODL, true, matrOpr, dtEve, dtCurr); return answ; } /// /// Recupera elenco articoli dei PODL correnti: /// /// GET: IOB/getArtCurrPODL /// /// Json contenente lista oggetti ARTICOLI serializzati public string getArtCurrPODL() { string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... DS_ProdTempi.AnagArticoliDataTable elencoArt = DataLayerObj.taAnagArt.getByCurrPODL(); answ = JsonConvert.SerializeObject(elencoArt); } catch { } return answ; } /// /// Recupera ArtNum dato CodXdl (per impianti che accettano solo INT in scrittura): /// /// GET: IOB/getArtNum/SIMUL_03?CodXdl=ABC123 /// /// IdxMacchina (NON considerato) /// CodXdl richiesto, se vuoto restituisce TUTTI i valori in tabella di decodifica /// Json contenente le righe delle codifiche attive Articolo/Numero public string getArtNum(string id, string CodArt = "") { // in realtà ID macchina non conta e lo ignoriamo... string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { // recupero dati macchina... Dictionary valori = DataLayerObj.getArtNum(CodArt); answ = JsonConvert.SerializeObject(valori); } catch { } return answ; } /// /// Recupera elenco articoli USATI: /// /// GET: IOB/getArtUsed /// /// Json contenente lista oggetti ARTICOLI serializzati public string getArtUsed() { string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoArt = DataLayerObj.taAnagArt.getUsed(); answ = JsonConvert.SerializeObject(elencoArt); } catch { } return answ; } /// /// Recupera COUNTER x macchina: /// /// GET: IOB/getCounter/5 /// /// /// public string getCounter(string id) { string answ = ""; try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.pzCounter(id).ToString(); } catch (Exception exc) { logger.lg.scriviLog($"Errore in counter TC (get){Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Recupera COUNTER x macchina dal CONTEGGIO dei TCRecorded: /// /// GET: IOB/getCounterTCRec/5 /// /// /// public string getCounterTCRec(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.pzCounterTC(id).ToString(); } catch (Exception exc) { logger.lg.scriviLog($"Errore in counter TC (get){Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Recupera DATI correnti x macchina: /// /// GET: IOB/getCurrData/SIMUL_03 /// /// /// Json contenente la riga di stato macchina public string getCurrData(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { // recupero dati macchina... Dictionary valori = DataLayerObj.mDatiMacchine(id); answ = JsonConvert.SerializeObject(valori); } catch { } return answ; } /// /// Recupera ODL corrente x macchina: /// /// GET: IOB/getCurrODL/SIMUL_03 /// /// /// public string getCurrODL(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; try { DataLayer DataLayerObj = new DataLayer(); answ = $"{DataLayerObj.currODL(id)}"; } catch (Exception exc) { logger.lg.scriviLog(string.Format("Errore in currODL (get){0}{1}", Environment.NewLine, exc)); answ = "NO"; } return answ; } /// /// Restituisce la quantità pezzi dell'odl correntemente in lavorazione sulla macchina... /// GET: IOB/getCurrOdlQtaReq/SIMUL_01 /// /// /// public int getCurrOdlQtaReq(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); int answ = 0; DS_ProdTempi.ODLDataTable currData = null; // chiamo metodo redis/db... try { DataLayer DataLayerObj = new DataLayer(); currData = DataLayerObj.currODLRowTab(id); if (currData != null && currData.Count > 0) { answ = currData[0].NumPezzi; } } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in getCurrOdlQtaReq{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Restituisce intera riga dell'odl correntemente in lavorazione sulla macchina... /// GET: IOB/getCurrOdlRow/SIMUL_01 /// /// /// public string getCurrOdlRow(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; DS_ProdTempi.ODLDataTable currData = null; // chiamo metodo redis/db... try { DataLayer DataLayerObj = new DataLayer(); currData = DataLayerObj.currODLRowTab(id); answ = JsonConvert.SerializeObject(currData); } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in getCurrOdlRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Restituisce data-ora inizio dell'odl correntemente in lavorazione sulla macchina... /// es: http://url_site/MP/IO/IOB/getCurrOdlStart/SIMUL_03 /// /// /// public string getCurrOdlStart(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); DateTime answ = new DateTime(DateTime.Now.Year - 1, 12, 31); // chiamo metodo redis/db... try { DataLayer DataLayerObj = new DataLayer(); DS_ProdTempi.ODLDataTable currTab = DataLayerObj.currODLRowTab(id); if (currTab.Count > 0) { DS_ProdTempi.ODLRow odlRow = currTab[0]; answ = odlRow.DataInizio; } } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in recupero getCurrOdlStart{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ.ToString("yyyy-MM-dd HH:mm:ss"); } /// /// Recupera DATI PODL correnti (=NON AVVIATI) x macchina: /// /// GET: IOB/getCurrPODL/SIMUL_03 /// /// id macchina, se "" mostra tutto /// Json contenente lista oggetti PODL serializzati public string getCurrPODL(string id) { // lasciato x retrocompatibilità, FixMe ToDo ELiminare con udpate IOB.... return getPOdlNext(id); } /// /// Restituisce intera riga dello stato di macchina... /// GET: IOB/getCurrStatoRow/SIMUL_01 /// /// /// public string getCurrStatoRow(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; DS_applicazione.StatoMacchineDataTable currData = null; // chiamo metodo redis/db... try { DataLayer DataLayerObj = new DataLayer(); currData = DataLayerObj.currSMTab(id); answ = JsonConvert.SerializeObject(currData); } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in recupero getCurrStatoRow{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Restituisce un array JSon di files di una IOB /// PUT: IOB/getFiles/SIMUL_03 /// /// ID dell'IOB /// Oggetto Json in formato MapoSDK.fileEmbed public string getFiles(string id) { string answ = ""; // procedo a deserializzare in blocco l'oggetto... try { // recupero TUTTI i files della folder dell'IOB richiesta string basePath = Server.MapPath(memLayer.ML.CRS("uploadFileDir")); string dirPath = $"{basePath}\\{id}"; var fileList = fileMover.obj.elencoFilesDir(dirPath); fileEmbed objFiles = new fileEmbed(); MapoSDK.smallFile currFile = null; string fileContent = ""; foreach (var item in fileList) { fileContent = System.IO.File.ReadAllText($"{dirPath}\\{item.Nome}"); currFile = new MapoSDK.smallFile() { fileName = item.Nome, content = fileContent.Replace("\r\n", Environment.NewLine) }; objFiles.fileList.Add(currFile); } // serializzo answ = JsonConvert.SerializeObject(objFiles); } catch (Exception exc) { logger.lg.scriviLog($"Errore in uploadFile{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Restituisce il valore dello stato di IDLE della macchina, quindi SOLO SE NON é in lavoro /// e già convertito in minuti... /// GET: IOB/getIdlePeriod/SIMUL_01 /// /// /// public int getIdlePeriod(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); int answ = 0; DataLayer DataLayerObj = new DataLayer(); DS_applicazione.StatoMacchineDataTable currData = null; // chiamo metodo redis/db... try { currData = DataLayerObj.currSMTab(id); if (currData.Count > 0) { // recupero da redis elenco stati DS_applicazione.AnagraficaStatiDataTable anagStati = DataLayerObj.AnagraficaStati(); DS_applicazione.AnagraficaStatiRow currStato = anagStati.FindByIdxStato(currData[0].IdxStato); // calcolo SE sia idle... OVVERO SEMAFORO NON VERDE!!! if (currStato.Semaforo != "sVe") { // calcolo durata... answ = (int)DateTime.Now.Subtract(currData[0].InizioStato).TotalMinutes; } } } catch (Exception exc) { logger.lg.scriviLog($"Eccezione in recupero getIdlePeriod{Environment.NewLine}{exc}", tipoLog.EXCEPTION); } return answ; } /// /// Restituisce il (primo) codice IOB da dover gestire (se un IOBMAN chiede di gestirne uno /// in +...) /// /// IP del Gateway /// public string getIob2call(string GWIP) { string answ = ""; // !!!FARE!!! temporanemanete genera a caso vuoto o 3000 x permettere test... altrimenti // gestisce VERA coda... secondi pari... int resto = 0; Math.DivRem(DateTime.Now.Second, 2, out resto); if (resto == 0) { answ = "3000"; } return answ; } /// /// Recupera elenco articoli USATI per ultimi: /// - quelli dei PODL correnti /// - quelli degli ultimi n (DOSS_LastArt in config) ODL lavorati /// /// GET: IOB/getArtByMacc /// /// Json contenente lista oggetti ARTICOLI serializzati public string getLastArtByMacc(string id) { string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoArt = DataLayerObj.taAnagArt.getLastByMacc(id); answ = JsonConvert.SerializeObject(elencoArt); } catch { } return answ; } /// /// Recupera DATI dell'ultimo dossier dato articolo: /// /// GET: IOB/getLastDossArt/cod_articolo /// /// codice articolo, se vuoto --> non fa nulla /// Json contenente lista oggetti DOSSIER serializzati public string getLastDossArt(string id) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" if (string.IsNullOrEmpty(id)) { answ = "N.A."; } else { id = id.Replace("|", "#"); // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoDoss = DataLayerObj.taDOSS.getLastByArt(id); answ = JsonConvert.SerializeObject(elencoDoss); } catch { } } return answ; } /// /// Recupera DATI dell'ultimo dossier dato articolo: /// /// GET: IOB/getLastDossArt/cod_articolo /// /// codice articolo, se vuoto --> non fa nulla /// Json contenente lista oggetti DOSSIER serializzati public string getLastDossByMacc(string id) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" if (string.IsNullOrEmpty(id)) { answ = "N.A."; } else { id = id.Replace("|", "#"); // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoDoss = DataLayerObj.taDOSS.getLastByMacc(id); answ = JsonConvert.SerializeObject(elencoDoss); } catch { } } return answ; } /// /// Recupera DATI dell'ultimo dossier dato PODL correnti: /// /// GET: IOB/getLastDossPODL /// /// Json contenente lista oggetti DOSSIER serializzati public string getLastDossPODL() { string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoDoss = DataLayerObj.taDOSS.getLastByPODL(); answ = JsonConvert.SerializeObject(elencoDoss); } catch { } return answ; } /// /// Recupera elenco ListValues data tabella: /// /// GET: IOB/getListValByTable /// /// nome tabella x cui filtrare risultati, se "" mostra tutto /// Json contenente lista oggetti ListValue serializzati public string getListValByTable(string id) { string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoOdl = DataLayerObj.taListVal.getByTableField(id, "*"); answ = JsonConvert.SerializeObject(elencoOdl); } catch { } return answ; } /// /// Restituisce dati di associazione tra macchina, device IOB chiamante e sue info /// /// Id della macchina /// public string getM2IOB(string id) { string answ = ""; try { // recupero da redis... string hM2IOB = DataLayer.hM2IOB(id); string dataSer = memLayer.ML.getRSV(hM2IOB); if (dataSer != "" && dataSer != null) { // restituisco Json answ = dataSer; } else { answ = "NO"; } } catch { answ = "KO"; } return answ; } /// /// restituisce elenco parametri correnti come una List Json di oggetti objItem /// GET: IOB/getObjItems/SIMUL_03 /// /// ID dell'IOB /// public string getObjItems(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // procedo a recuperare l'oggetto... List currParams = new List(); try { DataLayer DataLayerObj = new DataLayer(); // deserializzo currParams = DataLayerObj.getCurrObjItems(id); // se != null --> salvo! if (currParams != null) { answ = JsonConvert.SerializeObject(currParams); } } catch (Exception exc) { logger.lg.scriviLog($"Errore in getObjItems{Environment.NewLine}{exc}"); answ = "NO"; } } return answ; } /// /// restituisce elenco parametri CHE RICHIEDONO scrittura su PLC come una List Json di /// oggetti objItem /// GET: IOB/getObjItems2Write/SIMUL_03 /// /// ID dell'IOB /// public string getObjItems2Write(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // procedo a recuperare l'oggetto... List currParams = new List(); try { DataLayer DataLayerObj = new DataLayer(); // deserializzo currParams = DataLayerObj.getCurrObjItemsPendigWrite(id); // se != null --> salvo! if (currParams != null) { answ = JsonConvert.SerializeObject(currParams); } } catch (Exception exc) { logger.lg.scriviLog($"Errore in getCurrParams{Environment.NewLine}{exc}"); answ = "NO"; } } return answ; } /// /// Recupera ODL x macchina e data, se + di 1 quello di durata maggiore: /// /// GET: IOB/getOdlAtDate/SIMUL_03 /// /// IdxMacchina /// DataRiferimento, formato yyyyMMdd (8 cifre) /// public string getOdlAtDate(string id, string dateRif) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); // converto la data in formato dateTime... e ottengo intervallo data indicata da // mezzanotte a 23:59:59... CultureInfo provider = CultureInfo.InvariantCulture; DateTime dtFrom = DateTime.Today; bool fatto = DateTime.TryParseExact(dateRif, "yyyyMMdd", provider, DateTimeStyles.None, out dtFrom); if (fatto) { // data fine giorno dopo DateTime dtTo = dtFrom.AddDays(1); // cerco ODL alla data (validi) DataLayer DataLayerObj = new DataLayer(); DS_ProdTempi.ODLDataTable odlList = DataLayerObj.taODL.getByMacchinaPeriodoNoNull(id, dtFrom, dtTo); // se non trovo aumento ricerca all'indietro... int maxTry = 14; while (odlList.Count == 0 && maxTry > 0) { dtFrom = dtFrom.AddDays(-1); odlList = DataLayerObj.taODL.getByMacchinaPeriodoNoNull(id, dtFrom, dtTo); maxTry++; } int idxOdl = 0; // se > 1 --> prendo il + durevole if (odlList.Count > 1) { double maxPeriod = 0; foreach (var item in odlList) { DateTime dtStart = item.DataInizio > dtFrom ? item.DataInizio : dtFrom; DateTime dtEnd = item.DataFine < dtTo ? item.DataFine : dtTo; double currPeriod = dtEnd.Subtract(dtStart).TotalMinutes; if (currPeriod > maxPeriod) { maxPeriod = currPeriod; idxOdl = item.IdxODL; } } } else if (odlList.Count == 1) { idxOdl = odlList[0].IdxODL; } else { // cerco ODL prendendo qualche gg prima... } // conversione! answ = $"{idxOdl}"; } return answ; } /// /// Recupera TASK richiesto x macchina: /// /// GET: IOB/getOptPar/SIMUL_03 /// /// /// Json contenente 1..n task da eseguire public string getOptPar(string id) { string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); connDb.scriviKeepAlive(id, DateTime.Now); try { // leggo da REDIS eventuale elenco task x macchina... DataLayer DataLayerObj = new DataLayer(); Dictionary valori = DataLayerObj.mOptParMacchina(id); answ = JsonConvert.SerializeObject(valori); } catch { } return answ; } /// /// Recupera DATI PODL x macchina e codice PODL: /// /// GET: IOB/getPODL/SIMUL_03?idxPODL=123 /// /// /// idx del PDL da avviare /// Json contenente lista oggetti PODL serializzati public string getPODL(string id, int idxPODL) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" if (!string.IsNullOrEmpty(id)) { id = id.Replace("|", "#"); } string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati da chaive, ignorando info macchina... var elencoOdl = DataLayerObj.taPODL.getByKey(idxPODL); answ = JsonConvert.SerializeObject(elencoOdl); } catch { } return answ; } /// /// Recupera DATI PODL Running/Actual (AVVIATO e in corso) x macchina: /// /// GET: IOB/getPOdlAct/SIMUL_03 /// /// id macchina, se "" mostra tutto /// Json contenente lista 1 oggetto PODL serializzato, se presente public string getPOdlAct(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" if (!string.IsNullOrEmpty(id)) { id = id.Replace("|", "#"); } string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero IdxOdl corrente string sIdxOdl = DataLayerObj.currODL(id); int IdxOdl = 0; int.TryParse(sIdxOdl, out IdxOdl); // recupero Podl running x macchina ... DS_ProdTempi.PromesseODLDataTable elencoOdl = DataLayerObj.taPODL.getByIdxOdl(IdxOdl); answ = JsonConvert.SerializeObject(elencoOdl); } catch { } return answ; } /// /// Recupera DATI PODL NEXT (=NON AVVIATI) x macchina: (copia di getCurrPODL) /// /// GET: IOB/getPOdlNext/SIMUL_03 /// /// id macchina, se "" mostra tutto /// Json contenente lista oggetti PODL serializzati public string getPOdlNext(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" if (!string.IsNullOrEmpty(id)) { id = id.Replace("|", "#"); } string answ = ""; // init obj DataLayer DataLayer DataLayerObj = new DataLayer(); try { // recupero dati macchina... var elencoOdl = DataLayerObj.taPODL.getByMaccArt(id, "", "", true); answ = JsonConvert.SerializeObject(elencoOdl); } catch { } return answ; } /// /// Recupera TASK richiesto x macchina: /// /// GET: IOB/getTask2Exe/SIMUL_03 /// /// /// Json contenente 1..n task da eseguire public string getTask2Exe(string id) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il carattere "|" che poi trasformiamo ora in "#" if (!string.IsNullOrEmpty(id)) { id = id.Replace("|", "#"); } string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { // leggo da REDIS eventuale elenco task x macchina... Dictionary valori = DataLayerObj.mTaskMacchina(id); answ = JsonConvert.SerializeObject(valori); } catch { } return answ; } /// /// Recupera codice numerico ODL/PODL dato CodXdl, in pratica la parte finale SENZA ODL/PODL /// Funzione per impianti che accettano solo INT in scrittura: /// /// GET: IOB/getXdlNum/SIMUL_03?CodXdl=ODL00000123 /// /// IdxMacchina (NON considerato) /// /// CodXdl richiesto, se vuoto restituisce TUTTI i valori in tabella di decodifica /// /// SINGOLO VALORE calcolato on the fly public string getXdlNum(string id, string CodXdl = "") { // in realtà ID macchina non conta e lo ignoriamo... string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { // sostituisco PODL/ODL con "" e lascio zero iniziali (conversione INT in IOB) answ = CodXdl.Replace("PODL", "").Replace("ODL", ""); } catch { } return answ; } // GET: IOB (è un check alive del server) public string Index() { //if (memLayer.ML.CRB("IOB_RedEnab")) if (true) { // conto la richiesta nel contatore REDIS long nCall = memLayer.ML.setRCntI(DataLayer.mHash("COUNT:pCall:IOB_INDEX")); //... se == nCall2Log scrivo su log e resetto long nCall2Log = 100;// memLayer.ML.cdvi("nCall2Log"); //long nCall2Log = memLayer.ML.cdvi("nCall2Log"); if (nCall >= nCall2Log) { // loggo logger.lg.scriviLog(string.Format("IOB_INDEX: effettuate {0} call", nCall), tipoLog.INFO); // resetto! memLayer.ML.resetRCnt(DataLayer.mHash("COUNT:pCall:IOB_INDEX")); } } return "OK"; } // GET: IOB/input/SIMUL_03?valore=3&dtEve=20181206180600000&dtCurr=20181206180600000&cnt=999 public string input(string id, string valore, string dtEve, string dtCurr, string cnt) { string answ = ""; // formato yyyymmddHHMMSSnnn ovvero da anno a millisecondi if (cnt == null) { cnt = "0"; } DateTime dataOraEvento = DateTime.Now; if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"Valori letti: id: {id} | valore: {valore}", tipoLog.INFO); } try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.processInput(id, valore, dtEve, dtCurr, cnt); } catch (Exception exc) { logger.lg.scriviLog(string.Format("Errore in processInput{0}{1}", Environment.NewLine, exc)); answ = "NO"; } return answ; } /// /// Processa una chiamata POST per l'invio di un array Json di oggetti LIVE REC /// PUT: IOB/liveJson/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string liveJson(string id) { string answ = "-"; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader( Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... try { // deserializzo. liveIOB receivedData = JsonConvert.DeserializeObject(content); DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.processLiveJson(id, receivedData); // se vuoto --> OK! if (string.IsNullOrEmpty(answ)) { answ = "OK 1 done"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in liveJson{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } // GET: IOB/liveRec/SIMUL_03?&liveData=chiave1|valore1#chiave2|valore#|chiave3|valore3 public string liveRec(string id, string liveData) { string answ = ""; DateTime dataOraEvento = DateTime.Now; if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"Valori Live:{Environment.NewLine}id: {id}{Environment.NewLine}liveData: {liveData}", tipoLog.INFO); } try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.processLiveRec(id, liveData); } catch (Exception exc) { logger.lg.scriviLog($"Errore in liveRec{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Processa una chiamata POST per l'invio di un array Json di oggetti rawTransfer /// (generiche info da deserializzare) /// POST: IOB/rawTransfJson/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string rawTransfJson(string id) { int insDone = 0; string answ = ""; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader( Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // se ho dati... if (content != "") { DataLayer DataLayerObj = new DataLayer(); MagDataLayer DataLayerMagObj = new MagDataLayer(); // deserializzo come un dictionary generico di oggetti rawDataType/string List receivedData = new List(); // procedo a deserializzare in blocco l'oggetto... try { // deserializzo. receivedData = JsonConvert.DeserializeObject>(content); } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase deserializzazione rawTransfJson{Environment.NewLine}{exc}"); answ = "NO"; } // se ho qualcosa da processare... if (receivedData != null) { try { foreach (var item in receivedData) { // per ora salvo su REDIS ultimo x tipo DataLayerObj.lastRawTrasfData = JsonConvert.SerializeObject(item.mesContent); // !!! FixMe ToDo fare deserializzazione e salvataggio su MongoDB // salvataggio su tab RawTrasf su DB IS // in base al tipo processo... switch (item.mesType) { case rawTransfType.IcoelBatch: break; case rawTransfType.IcoelVarInfo: break; case rawTransfType.RegGiacenze: // elenco ODL da svuotare preventivamente x insert... List listOdl = new List(); // processo scrittura giacenze... processo 1:1 record di RegGiacenze List recData = new List(); foreach (var singleRow in item.mesContent) { var listGiac = JsonConvert.DeserializeObject(singleRow.Value.ToString()); recData.Add(listGiac); if (!listOdl.Contains(listGiac.IdxODL)) { listOdl.Add(listGiac.IdxODL); } } // svuoto le giacenze degli ODL oggetto di import... bool fatto = DataLayerMagObj.resetRegGiacByOdl(listOdl); if (fatto) { // invio x salvare fatto = DataLayerMagObj.salvaRegGiac(recData); } break; case rawTransfType.ND: default: break; } insDone++; } // se vuoto --> OK! if (string.IsNullOrEmpty(answ)) { answ = $"OK {insDone} processed"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase invio valori rawTransfJson{Environment.NewLine}{exc}"); answ = "NO"; } } } return answ; } /// /// ELIMINA TASK richiesto x macchina: /// /// GET: IOB/remOptPar/SIMUL_03?pName=PZREQ /// /// /// public string remOptPar(string id, string pName) { string answ = ""; // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { DataLayerObj.remOptPar4Machine(id, pName); answ = getOptPar(id); } catch { } return answ; } /// /// ELIMINA TASK richiesto x macchina: /// /// GET: IOB/remTask2Exe/SIMUL_03?taskName=T180326160502 /// /// /// public string remTask2Exe(string id, string taskName) { string answ = ""; // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il carattere "|" che poi trasformiamo ora in "#" if (!string.IsNullOrEmpty(id)) { id = id.Replace("|", "#"); } // scrivo keep alive!!! (se necessario, altrimenti è in cache...) MapoDb.MapoDb connDb = new MapoDb.MapoDb(); DataLayer DataLayerObj = new DataLayer(); connDb.scriviKeepAlive(id, DateTime.Now); try { // converto stringa in tipo task... taskType tName = taskType.nihil; bool fatto = Enum.TryParse(taskName, out tName); if (fatto) { DataLayerObj.remTask4Machine(id, tName); } else { logger.lg.scriviLog($"remTask2Exe: impossibile riconoscere il comando {taskName} come uno dei tipi ammessi, NON rimosso", tipoLog.ERROR); } answ = getTask2Exe(id); } catch { } return answ; } /// /// Effettua RESET dell'ODL corrente x macchina: /// /// GET: IOB/resetCurrODL/5 /// /// /// public string resetCurrODL(string id) { DataLayer DataLayerObj = new DataLayer(); return DataLayerObj.emptyCurrODL(id); } /// /// Processa una chiamata POST per l'invio di un array Json di oggetti plcMemConf /// PUT: IOB/saveConf/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string saveConf(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... plcMemMap currMemMap = null; try { // deserializzo. currMemMap = JsonConvert.DeserializeObject(content); // se != null --> salvo! if (currMemMap != null) { DataLayer DataLayerObj = new DataLayer(); DataLayerObj.setIobMemMap(id, currMemMap); answ = "OK"; } } catch { } } return answ; } /// /// Processa una chiamata POST per l'invio di un oggetto YAML testuale corrispondente alla configurazione dell'IOB /// PUT: IOB/saveConfYaml/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string saveConfYaml(string id) { string answ = ""; if (string.IsNullOrEmpty(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; if (content != null) { try { DataLayer DataLayerObj = new DataLayer(); DataLayerObj.setIobConfYaml(id, content); answ = "OK"; } catch (Exception exc) { logger.lg.scriviLog($"Errore in saveConfYaml{Environment.NewLine}{exc}"); } } } return answ; } /// /// Processa una chiamata POST per l'invio di un array Json di oggetti di conf DataItems (es /// per MTC) /// PUT: IOB/saveDataItems/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string saveDataItems(string id) { string answ = ""; logger.lg.scriviLog($"Richiesta saveDataItems per id {id}"); if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } // Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... List dataItems = null; try { logger.lg.scriviLog($"Ricevuto payload di {content.Length} chars"); // deserializzo. dataItems = JsonConvert.DeserializeObject>(content); // se != null --> salvo! if (dataItems != null) { // chiamo metodo update direttamente! MtcDataModelArchive.man.saveMachineDataItems(id, dataItems); answ = "OK"; logger.lg.scriviLog($"Effettuato salvataggio saveDataItems per id {id}:{Environment.NewLine}{content}"); } } catch { } } return answ; } /// /// Processa una chiamata POST per l'invio di una Dictionary HashList da salvare in redis /// POST: IOB/saveMachineIobConf/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string saveMachineIobConf(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto dictionary... Dictionary currDict = new Dictionary(); try { // deserializzo. currDict = JsonConvert.DeserializeObject>(content); string keyHashDict = DataLayer.hMachineIobConf(id); // se != null --> salvo! if (currDict != null) { bool fatto = memLayer.ML.redSaveHashDict(keyHashDict, currDict); answ = fatto ? "OK" : "KO"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in saveMachineIobConf{Environment.NewLine}{exc}"); answ = "EXC"; } } return answ; } /// /// SALVA in blocco un incremento pezzi x macchina restituendo il valore appena inviato o, /// se mancasse chaive redis, del valore da DB /// /// GET: IOB/savePzCountInc/5?qty=10 /// /// codice macchina /// num peziz da salvare in blocco /// public string savePzCountInc(string id, string qty) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; DateTime dataOraEvento = DateTime.Now; // salvo SEMPRE log x questo tipo di dati! logger.lg.scriviLog($"Salvataggio incremento contapezzi | id: {id} | pezzi: {qty}", tipoLog.INFO); try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.saveCaricoPezzi(id, qty); } catch (Exception exc) { logger.lg.scriviLog($"Errore in savePzCountInc{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// SALVA in blocco un incremento pezzi x macchina restituendo il valore appena inviato o, /// se mancasse chiave REDIS, del valore da DB /// /// GET: IOB/savePzCountIncAtDate/5?qty=10&dtEve=20230323151100000&dtCurr=20230323221100000 /// /// codice macchina /// num peziz da salvare in blocco /// data-ora dichiarazione (opzionale) /// data-ora attuale (opzionale) /// public string savePzCountIncAtDate(string id, string qty, string dtEve = "", string dtCurr = "") { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = ""; DateTime dataOraEvento = DateTime.Now; // salvo SEMPRE log x questo tipo di dati! logger.lg.scriviLog($"Salvataggio incremento contapezzi | id: {id} | pezzi: {qty}", tipoLog.INFO); try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.saveCaricoPezzi(id, qty, dtEve, dtCurr); } catch (Exception exc) { logger.lg.scriviLog($"Errore in savePzCountIncAtDate{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Registrazione variazione allarmi /// /// GET: IOB/sendAlarmBankUpdate/SIMUL_03?memAddr=SIM_BANK&index=0&currStatus=22 /// /// /// [HttpPost] public string sendAlarmBankUpdate(string id, string memAddr, int index, int currStatus) { DataLayer DataLayerObj = new DataLayer(); // esempio valido x MAPO string answ = ""; logger.lg.scriviLog($"Richiesta sendAlarmBankUpdate per id {id}"); if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } // Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... List ActiveAlarms = null; try { logger.lg.scriviLog($"Ricevuto payload di {content.Length} chars"); // deserializzo. ActiveAlarms = JsonConvert.DeserializeObject>(content); // se != null --> salvo! if (ActiveAlarms != null) { string alarmDecoded = "-"; if (ActiveAlarms != null && ActiveAlarms.Count > 0) { alarmDecoded = String.Join(" | ", ActiveAlarms); } DataLayerObj.taAlarmLog.insertQuery(DateTime.Now, id, memAddr, index, currStatus, alarmDecoded); answ = "OK"; } } catch { } } return answ; // esempio GWMS } /// /// Salva MAC adress + IP dopo il reboot /// GET: IOB/sendReboot/SIMUL_05?mac=18:C0:4D:37:3C:8C /// /// IP del Gateway /// public string sendReboot(string id, string mac) { string answ = "NO"; string IPv4 = ""; string agent = ""; try { // recupero IP del client remoto IPv4 = Request.UserHostName; agent = Request.UserAgent; } catch { } try { // uso datalayer che COMPRENDE MapoDb... DataLayer DataLayerObj = new DataLayer(); int num2keep = 5; var rConf = DataLayerObj.ListConfig.Where(x => x.chiave == "IO_NumReboot2Keep").FirstOrDefault(); if (rConf != null) { int.TryParse(rConf.valore, out num2keep); } // chiamo registrazione reboot DataLayerObj.MapoDbObj.registraStartup(id, IPv4, agent, mac, num2keep); answ = "OK"; } catch (Exception exc) { if (memLayer.ML.CRI("_logLevel") > 5) { string errore = string.Format("Errore: {0}{1}", Environment.NewLine, exc); logger.lg.scriviLog(errore, tipoLog.EXCEPTION); } } return answ; } /// /// Salva IP del gateway dopo il reboot /// /// IP del Gateway /// public string sendRebootGateway(string GWIP) { string answ = "OK"; // !!!FARE!!! deve salvare il riavvio dell'applicazione GATEWAY multiclient return answ; } /// /// SALVA Counter x macchina restituendo il valore appena inviato o, se mancasse chiave /// redis, del valore da DB /// /// GET: IOB/setCounter/5?counter=10 /// /// cod macchina /// contapezzi da salvare /// public string setCounter(string id, string counter) { // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il // carattere "|" che poi trasformiamo ora in "#" id = id.Replace("|", "#"); string answ = "-1"; DateTime dataOraEvento = DateTime.Now; if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"Salvataggio counter | id: {id}", tipoLog.INFO); } try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.saveCounter(id, counter); } catch (Exception exc) { logger.lg.scriviLog(string.Format("Errore in counter (set){0}{1}", Environment.NewLine, exc)); } return answ; } /// /// Salva associazione tra macchina, device IOB chiamante e sue info /// /// Id della macchina /// Nome dell'IOB di acquisizione della macchina /// public string setM2IOB(string id, string IOB_name) { string answ = ""; try { // recupero IP del client remoto string IPv4 = Request.UserHostName; string agent = Request.UserAgent; // creo oggetto IOB_data... IOB_data m2IOB = new IOB_data { name = IOB_name, IP = IPv4, iType = IobType.ND, typeCss = "fa fa-question-circle-o", CNC_Counter = false }; // imposto tipo ed icona come windows/linux secondo UserAgent... if (agent.IndexOf("WIN") >= 0) { m2IOB.iType = IobType.WIN; m2IOB.typeCss = "fa fa-windows"; m2IOB.CNC_Counter = true; } else if (agent.IndexOf("Python") >= 0) { m2IOB.iType = IobType.rPi; m2IOB.typeCss = "fa fa-linux"; } // serializzo... string dataSer = JsonConvert.SerializeObject(m2IOB); // salvo in redis... string hM2IOB = DataLayer.hM2IOB(id); memLayer.ML.setRSV(hM2IOB, dataSer); // salvo tutto OK answ = "OK"; } catch { answ = "KO"; } return answ; } /// /// Processa una chiamata POST per l'invio di una List Json di oggetti objItem /// POST: IOB/setObjItems/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string setObjItems(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... List currParams = new List(); try { // deserializzo. currParams = JsonConvert.DeserializeObject>(content); // se != null --> salvo! if (currParams != null) { DataLayer DataLayerObj = new DataLayer(); bool fatto = DataLayerObj.setCurrObjItems(id, currParams); answ = fatto ? "OK" : "KO"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in setCurrParams{Environment.NewLine}{exc}"); answ = "EXC"; } } return answ; } /// /// Processa una chiamata POST per l'invio di una Dictionary HashList da salvare in redis /// POST: IOB/setRedisHashDict/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string setRedisHashDict(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto dictionary... Dictionary currDict = new Dictionary(); try { // deserializzo. currDict = JsonConvert.DeserializeObject>(content); string keyHashDict = DataLayer.hIobDict(id); // se != null --> salvo! if (currDict != null) { bool fatto = memLayer.ML.redSaveHashDict(keyHashDict, currDict); answ = fatto ? "OK" : "KO"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in setRedisHashDict{Environment.NewLine}{exc}"); answ = "EXC"; } } return answ; } // GET: IOB/slog/SIMUL_03 public string slog(string id) { string answ = "ND"; // se id nullo --> KO! if (id == null) { answ = "KO"; } else { try { DataLayer DataLayerObj = new DataLayer(); // salvo risposta answ = DataLayerObj.sLogEnab(id) ? "OK" : "NO"; } catch (Exception exc) { logger.lg.scriviLog(string.Format("Errore in sLog{0}{1}", Environment.NewLine, exc)); answ = "NO"; } } return answ; } // GET: IOB/takeFlogSnapshot/SIMUL_03 public string takeFlogSnapshot(string id) { string answ = ""; string caller = $"takeFlogSnapshot({id})"; DateTime adesso = DateTime.Now; DateTime dtEnd = adesso; DateTime dtStart = adesso.AddDays(-1); //effettuo chiamata! answ = doSaveFLSnapshot(id, dtStart, dtEnd, caller); return answ; } // GET: IOB/ulog/SIMUL_03?flux=PROG&valore=P0001&dtEve=20161223180600000&dtCurr=20161223180600000&cnt=999&matrOpr=0=0&label=&valNum public string ulog(string id, string flux, string valore, string dtEve, string dtCurr, string cnt, string matrOpr, string label, string valNum) { string answ = ""; // formato yyyymmddHHMMSSnnn ovvero da anno a millisecondi if (cnt == null) { cnt = "0"; } DateTime dataOraEvento = DateTime.Now; if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"ulog | Valori letti: id: {id} | flux: {flux} valore: {valore} | matrOpr: {matrOpr} | label: {label} | valNum: {valNum}", tipoLog.INFO); } try { DataLayer DataLayerObj = new DataLayer(); int count = 0; int nMatrOpr = 0; int nValNum = 0; Int32.TryParse(cnt, out count); Int32.TryParse(matrOpr, out nMatrOpr); Int32.TryParse(valNum, out nValNum); answ = DataLayerObj.processUserLog(id, flux, valore, dtEve, dtCurr, count, nMatrOpr, label, nValNum); } catch (Exception exc) { logger.lg.scriviLog($"Errore in ulog{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Processa una chiamata POST per l'invio di una List Json 1+ UserAction (contiene /// controlli, scarti, dichiarazioni) /// POST: IOB/ulogJson/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string ulogJson(string id) { int insDone = 0; string answ = "-"; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader( Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // se ho dati... if (content != "") { DataLayer DataLayerObj = new DataLayer(); // procedo a deserializzare in blocco l'oggetto... ulogJsonPayload receivedData = new ulogJsonPayload(); try { // deserializzo. receivedData = JsonConvert.DeserializeObject(content); } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase deserializzazione ulogJson{Environment.NewLine}{exc}"); answ = "NO"; } // se ho qualcosa da processare... if (receivedData != null) { // per ogni valore --> salvo! try { foreach (var item in receivedData.fluxData) { // formato datetime come yyyyMMddHHmmssfff -->es: 20181223180600000 answ = DataLayerObj.processUserLog(id, item.flux, item.valore, item.dtEve.ToString("yyyyMMddHHmmssfff"), item.dtCurr.ToString("yyyyMMddHHmmssfff"), item.cnt, item.matrOpr, item.label, item.valNum); } // se vuoto --> OK! if (string.IsNullOrEmpty(answ)) { answ = $"OK {insDone} processed"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase invio valori ulogJson{Environment.NewLine}{exc}"); answ = "NO"; } } } return answ; } /// /// Processa una chiamata POST per l'invio di un SET di file "a nome" di un IOB, formato MapoSDK.fileEmbed /// PUT: IOB/uploadFile/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string uploadFile(string id) { string answ = ""; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... try { // deserializzo. fileEmbed receivedData = JsonConvert.DeserializeObject(content); // salvo nella cartella di Upload... string basePath = Server.MapPath(memLayer.ML.CRS("uploadFileDir")); string dirPath = $"{basePath}\\{id}"; // fix directory... Directory.CreateDirectory(dirPath); foreach (var item in receivedData.fileList) { // scrivo! System.IO.File.WriteAllText($"{dirPath}\\{item.fileName}", item.content); } answ = "OK"; } catch (Exception exc) { logger.lg.scriviLog($"Errore in uploadFile{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Processa una chiamata POST per l'invio di una List Json di UNO O PIU' oggetti objItem /// POST: IOB/upsertObjItems/SIMUL_03 /// /// ID dell'IOB /// [HttpPost] public string upsertObjItems(string id) { string answ = ""; if (string.IsNullOrWhiteSpace(id)) { answ = "Missing IOB"; } else { // questa classe è derivata da Controller.Response... x cui recupero lo stream in // altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... List innovazioni = new List(); try { // deserializzo. innovazioni = JsonConvert.DeserializeObject>(content); // se != null --> salvo! if (innovazioni != null) { // salvo DataLayer DataLayerObj = new DataLayer(); DataLayerObj.upsertCurrObjItems(id, innovazioni); answ = "OK"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in upsertObjItems{Environment.NewLine}{exc}"); answ = "NO"; } } return answ; } #endregion Public Methods #region Protected Fields protected static DataLayer DataLayerMan = new DataLayer(); #endregion Protected Fields #region Private Methods /// /// Effettua vera chiamata x salvataggio snapshot dati FluxLog /// /// /// /// /// private static string doSaveFLSnapshot(string id, DateTime dtStart, DateTime dtEnd, string caller) { string answ; DateTime dataOraEvento = DateTime.Now; if (memLayer.ML.CRI("_logLevel") > 6) { logger.lg.scriviLog($"{caller} | Richiesta snapshot dati FluxLog macchina: id: {id} | periodo: {dtStart} - {dtEnd}", tipoLog.INFO); } try { DataLayer DataLayerObj = new DataLayer(); answ = DataLayerObj.takeFlogSnapshotLast(id, dtStart, dtEnd); } catch (Exception exc) { logger.lg.scriviLog($"Errore in {caller}{Environment.NewLine}{exc}"); answ = "NO"; } return answ; } /// /// Effettivo processing FLogJson /// /// /// /// /// /// /// private string processFLogJson(string id, bool disabKA, int insDone, string answ, string content) { DataLayer DataLayerObj = new DataLayer(); // procedo a deserializzare in blocco l'oggetto... flogJsonPayload receivedData = new flogJsonPayload(); try { // deserializzo. receivedData = JsonConvert.DeserializeObject(content); } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase deserializzazione flogJson{Environment.NewLine}{exc}"); answ = "NO"; } // se ho qualcosa da processare... if (receivedData != null) { // per ogni valore --> salvo! try { foreach (var item in receivedData.fluxData) { // formato datetime come yyyyMMddHHmmssfff -->es: 20181223180600000 answ = DataLayerObj.processFluxLog(id, item.flux, item.valore, item.dtEve.ToString("yyyyMMddHHmmssfff"), item.dtCurr.ToString("yyyyMMddHHmmssfff"), item.cnt, disabKA); } // se vuoto --> OK! if (string.IsNullOrEmpty(answ)) { answ = $"OK {insDone} processed"; } } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase invio valori flogJson{Environment.NewLine}{exc}"); answ = "NO"; } // leggo parametri correnti... DateTime adesso = DateTime.Now; try { List currParams = DataLayerObj.getCurrObjItems(id); // ora per ogni valore RICEVUTO costruisco un oggetto in innovazioni da // inviare...x salvare in stato parametri... List innovazioni = new List(); foreach (var item in receivedData.fluxData) { // flux = uuid del parametro objItem trovato = currParams.Find(obj => obj.uid == item.flux); // se lo trovo aggiorno... if (trovato != null) { // aggiorno valore e data trovato.value = item.valore; trovato.lastRead = adesso; trovato.lastMessage = item.valore; // se fosse un valore WRITE if (trovato.writable) { // ...e mi ha dato un valore vuoto --> mando un fix x riscrittura if (string.IsNullOrEmpty(item.valore)) { logger.lg.scriviLog($"flogJson | verifica parametri | {trovato.uid} | reqVal: {trovato.reqValue}"); taskType currTask = (taskType)Enum.Parse(typeof(taskType), trovato.uid); DataLayerObj.addCheckTask4Machine(id, currTask, item.valore); } } else { // richiesto 10 sec prima... trovato.lastRequest = adesso.AddSeconds(-10); } } // altrimenti AGGIUNGO (READ ONLY)... else { trovato = new objItem { uid = item.flux, name = item.flux, value = item.valore, lastRead = adesso, lastRequest = adesso.AddSeconds(-10), writable = false }; } // lo carico in innovation innovazioni.Add(trovato); } // faccio upsert innovations! DataLayerObj.upsertCurrObjItems(id, innovazioni); logger.lg.scriviLog($"processFLogJson | {id} | Updated {innovazioni.Count} par"); } catch (Exception exc) { logger.lg.scriviLog($"Errore in fase salvataggio innovazioni parametri correnti da flogJson{Environment.NewLine}{exc}", tipoLog.EXCEPTION); answ = "NO"; } } return answ; } #endregion Private Methods } }