From 6699d4b467234e91a12dc311c70ea9738f4e855a Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 17 Nov 2023 18:29:20 +0100 Subject: [PATCH] Riscrittura Gomba x test separato pesate IN e pesate OUT --- IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.json | 3 + IOB-WIN-NEXT/IobSoap/Gomba.cs | 378 +++++++++++++++++++++----- 2 files changed, 312 insertions(+), 69 deletions(-) diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.json b/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.json index 13b4c6d8..da14d2eb 100644 --- a/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.json +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_GOMBA.json @@ -131,5 +131,8 @@ "factor": 1, "displOrdinal": 13 } + }, + "optKVP": { + "numLastWeight": 100 } } diff --git a/IOB-WIN-NEXT/IobSoap/Gomba.cs b/IOB-WIN-NEXT/IobSoap/Gomba.cs index 695cb109..c74b77d9 100644 --- a/IOB-WIN-NEXT/IobSoap/Gomba.cs +++ b/IOB-WIN-NEXT/IobSoap/Gomba.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Net.NetworkInformation; @@ -27,6 +28,12 @@ namespace IOB_WIN_NEXT.IobSoap lgInfo($"Richiesto Adapter IobSoap.Gomba con i parametri seguenti | ADDR: {IOBConf.cncIpAddr} | PORT: {IOBConf.cncPort}"); redKeyPesate = redisMan.redHash($"IOB:Status:{cIobConf.codIOB}:ListPesate"); lastPING = DateTime.Now.AddHours(-1); + // verifico se sia attiva gestione riduzione FluxLog... + if (!string.IsNullOrEmpty(getOptJsonKVP("numLastWeight"))) + { + int.TryParse(getOptJsonKVP("numLastWeight"), out numLastWeight); + lgInfo($"Gomba: setup specifico | numLastWeight: {numLastWeight}"); + } } #endregion Public Constructors @@ -129,12 +136,27 @@ namespace IOB_WIN_NEXT.IobSoap sw.Stop(); lgInfo($"getDynData | SOAP: effettuata chiamata reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo} | {listPesateCurr.Count} rec"); - // verifico se ci siano pesate nuove o meno... - if (listPesateCurr.Count != listPesateArch.Count || listPesateCurr.FirstOrDefault().dateIn > listPesateArch.FirstOrDefault().dateIn) + // preparo oggetti x confronto IN... + List listaCurrIN = listPesateCurr + .Where(x => x.dateInSpecified) + .OrderByDescending(x => x.dateIn) + .Select(x => new WeightRec(x)) + .ToList(); + List listaArchIN = listPesArcIN; + // preparo oggetti x confronto OUT... + List listaCurrOUT = listPesateCurr + .Where(x => x.dateOutSpecified) + .OrderByDescending(x => x.dateOut) + .Select(x => new WeightRec(x)) + .ToList(); + List listaArchOUT = listPesArcOUT; + + // faccio controllo per le pesate INGRESSO (x invio eventuali modifiche) confrontando prima con prima... + //if (((listaCurrIN.Count + listaArchIN.Count) > 0 && listaCurrIN.Count != listaArchIN.Count) || listaCurrIN.FirstOrDefault().DtEvent != listaArchIN.FirstOrDefault().DtEvent) + if (!AreEqual(listaCurrIN, listaArchIN)) { - // elenco indici - List listRmCurr = listPesateCurr.OrderBy(x => x.dateIn).Select(x => x.rm).ToList(); - List listRmArch = listPesateArch.OrderBy(x => x.dateIn).Select(x => x.rm).ToList(); + List listRmCurr = listaCurrIN.OrderBy(x => x.DtEvent).Select(x => x.RM).ToList(); + List listRmArch = listaArchIN.OrderBy(x => x.DtEvent).Select(x => x.RM).ToList(); // cerco nuove pesate confrontando rn archivio e curr... List listPresent = listRmCurr.Intersect(listRmArch).ToList(); foreach (var item in listPresent) @@ -146,31 +168,50 @@ namespace IOB_WIN_NEXT.IobSoap if (listRmCurr.Count > 0) { // prendo la prima - var firstRec = listPesateCurr.Find(x => x.rm == listRmCurr[0]); + var firstRec = listaCurrIN.Find(x => x.RM == listRmCurr[0]); if (firstRec != null) { - DictUpsert(ref outVal, "RM", firstRec.rm ?? ""); - } - // accodo x invio pesata valide IN se presenti... - if (firstRec.dateInSpecified) - { - // invio record SOLO PESO - DictUpsert(ref outVal, "lastWeightIn", $"{firstRec.weightIn ?? ""}"); - // registro record completo ultima pesata - DictUpsert(ref outVal, "lastRecIn", formatPesata(firstRec, true)); - } - // accodo x invio pesata valide OUT se presenti... - if (firstRec.dateOutSpecified) - { - // invio record SOLO PESO - DictUpsert(ref outVal, "lastWeightOut", $"{firstRec.weightIn ?? ""}"); - // registro record completo ultima pesata - DictUpsert(ref outVal, "lastRecOut", formatPesata(firstRec, false)); + DictUpsert(ref outVal, "RM", firstRec.RM ?? ""); } + // invio record SOLO PESO + DictUpsert(ref outVal, "lastWeightIn", $"{firstRec.weight:N2}"); + // registro record completo ultima pesata + DictUpsert(ref outVal, "lastRecIn", formatPesata(firstRec)); // la aggiungo alle pesate archiviate... - var tmpPesate = listPesateArch; - tmpPesate.Add(firstRec); - listPesateArch = tmpPesate; + AppendPesata(firstRec); + } + } + // se NON ho altro da aggiornare in INGRESSO... + else + { + // ora faccio controllo pesate USCITA (x invio eventuali modifiche) + if (!AreEqual(listaCurrOUT, listaArchOUT)) + { + List listRmCurr = listaCurrOUT.OrderBy(x => x.DtEvent).Select(x => x.RM).ToList(); + List listRmArch = listaArchOUT.OrderBy(x => x.DtEvent).Select(x => x.RM).ToList(); + // cerco nuove pesate confrontando rn archivio e curr... + List listPresent = listRmCurr.Intersect(listRmArch).ToList(); + foreach (var item in listPresent) + { + listRmCurr.Remove(item); + } + + // aggiungo solo 1 pesata, la + vecchia... + if (listRmCurr.Count > 0) + { + // prendo la prima + var firstRec = listaCurrOUT.Find(x => x.RM == listRmCurr[0]); + if (firstRec != null) + { + DictUpsert(ref outVal, "RM", firstRec.RM ?? ""); + } + // invio record SOLO PESO + DictUpsert(ref outVal, "lastWeightOut", $"{firstRec.weight:N2}"); + // registro record completo ultima pesata + DictUpsert(ref outVal, "lastRecOut", formatPesata(firstRec)); + // la aggiungo alle pesate archiviate... + AppendPesata(firstRec); + } } } @@ -196,7 +237,6 @@ namespace IOB_WIN_NEXT.IobSoap return outVal; } - /// /// Effettua lettura semafori principale Parametri da /// aggiornare x display in form @@ -208,7 +248,7 @@ namespace IOB_WIN_NEXT.IobSoap B_input = 1; currDispData.semIn = Semaforo.SV; - // se ho pesate in memoria nel periodo richiesto --> RUN + // se ho pesate in memoria nel periodo richiesto --> RUN if (listPesateCurr != null && listPesateCurr.Count > 0) { B_input += (1 << 1); @@ -228,15 +268,7 @@ namespace IOB_WIN_NEXT.IobSoap currDispData.semIn = Semaforo.SR; } } - /// - /// verifica stato ok ovvero connected oppure open - /// - /// - /// - protected bool checkStateOk(System.ServiceModel.CommunicationState currState) - { - return currState == System.ServiceModel.CommunicationState.Opened || currState == System.ServiceModel.CommunicationState.Created; - } + /// /// Override connessione /// @@ -286,24 +318,30 @@ namespace IOB_WIN_NEXT.IobSoap if (checkStateOk(gombaConn.State)) { connectionOk = true; - // test lettura elenco pesate... se NON nullo --> OK! - var weightArray = gombaConn.reqWeightList("ALL", dataFrom, dataTo); - - // riordino DESC - listPesateCurr = weightArray.OrderByDescending(x => x.dateIn).ToList(); + try + { + // test lettura elenco pesate... se NON nullo --> OK! + var weightArray = gombaConn.reqWeightList("ALL", dataFrom, dataTo); + // riordino DESC + listPesateCurr = weightArray.OrderByDescending(x => x.dateIn).ToList(); + } + catch (Exception exc) + { + lgError($"Eccezione in gombaConn.reqWeightList{Environment.NewLine}{exc}"); + } sw.Stop(); - lgInfo($"SOAP: effettuata chiamata reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}"); + lgInfo($"SOAP: effettuata chiamata connessione + reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}"); if (listPesateCurr != null && listPesateCurr.Count >= 0) { lgInfo($"szStatusConnection Gomba, recuperato elenco di {listPesateCurr.Count} pesate"); parentForm.commPlcActive = false; connectionOk = true; - // sistemo data da cui iniziare recuperi successivi se ho + di 10 record... - if (listPesateCurr.Count > 10) + // sistemo data da cui iniziare recuperi successivi se ho + di numLastWeight + if (listPesateCurr.Count > numLastWeight) { var lastRec = listPesateCurr .OrderByDescending(x => x.dateIn) - .Skip(5).FirstOrDefault(); + .Skip(numLastWeight).FirstOrDefault(); // metto giorno antecedente dtStartLive = lastRec.dateIn.Date.AddDays(-1); } @@ -366,10 +404,22 @@ namespace IOB_WIN_NEXT.IobSoap /// protected EgwProxy.Gomba.GombaServ.lwpServiceClient gombaConn; + protected int numLastWeight = 100; + #endregion Protected Fields #region Protected Methods + /// + /// verifica stato ok ovvero connected oppure open + /// + /// + /// + protected bool checkStateOk(System.ServiceModel.CommunicationState currState) + { + return currState == System.ServiceModel.CommunicationState.Opened || currState == System.ServiceModel.CommunicationState.Created; + } + /// /// Metodo da overridare x scrivere DAVVERO i parametri sul PLC /// @@ -413,7 +463,9 @@ namespace IOB_WIN_NEXT.IobSoap // se è OK if (answ.feedback == "C") { - string recPesata = formatPesata(answ, item.uid == "reqIN"); + var newWRec = new WeightRec(answ); + newWRec.isIn = item.uid == "reqIN"; + string recPesata = formatPesata(newWRec); lgInfo($"reqWeight | OK effettuato pesata | {recPesata}"); // aggiorno dati pesate IN/OUT... if (isIN) @@ -500,6 +552,47 @@ namespace IOB_WIN_NEXT.IobSoap #endregion Protected Methods + #region Protected Classes + + protected class WeightRec + { + #region Public Constructors + + public WeightRec(gestWeightOut newRec) + { + this.RM = newRec.rm; + this.DtEvent = newRec.dateOutSpecified ? newRec.dateOut : newRec.dateIn; + this.isIn = !newRec.dateOutSpecified; + this.cod1 = newRec.cod1; + this.cod2 = newRec.cod2; + this.cod3 = newRec.cod3; + this.cod4 = newRec.cod4; + this.cod5 = newRec.cod5; + this.cod6 = newRec.cod6; + string sWeight = newRec.dateOutSpecified ? newRec.weightOut : newRec.weightIn; + this.weight = double.Parse(sWeight, NumberStyles.Any, CultureInfo.InvariantCulture); + } + + #endregion Public Constructors + + #region Public Properties + + public string cod1 { get; set; } = ""; + public string cod2 { get; set; } = ""; + public string cod3 { get; set; } = ""; + public string cod4 { get; set; } = ""; + public string cod5 { get; set; } = ""; + public string cod6 { get; set; } = ""; + public DateTime DtEvent { get; set; } = DateTime.Today; + public bool isIn { get; set; } = true; + public string RM { get; set; } = "ND"; + public double weight { get; set; } = 0; + + #endregion Public Properties + } + + #endregion Protected Classes + #region Private Properties /// @@ -525,6 +618,171 @@ namespace IOB_WIN_NEXT.IobSoap /// private DateTime dtStartLive { get; set; } = DateTime.Today.AddMonths(-6); + /// + /// Gestione archivio serializzato delle pesate IN già processate + /// + private List listPesArcIN + { + get + { + List answ = new List(); + string redKey = $"{redKeyPesate}:IN"; + string rawData = redisMan.getRSV(redKey); + if (!string.IsNullOrEmpty(rawData)) + { + try + { + answ = JsonConvert.DeserializeObject>(rawData); + lgInfo($"Rilettura status listPesArcIN: trovati {answ.Count} record"); + answ = answ.OrderByDescending(x => x.DtEvent).ToList(); + } + catch (Exception exc) + { + lgError($"Errore in deserializzazione listPesArcIN{Environment.NewLine}{exc}"); + answ = new List(); + } + } + // rendo + return answ; + } + set + { + // riordino prima di procedere... + var tempList = value.OrderByDescending(x => x.DtEvent).ToList(); + // ...trimmo se fossero + di xxx record... + if (tempList.Count > numLastWeight) + { + tempList = tempList.Take(numLastWeight).ToList(); + } + string redKey = $"{redKeyPesate}:IN"; + string rawVal = JsonConvert.SerializeObject(tempList); + redisMan.setRSV(redKey, rawVal); + lgInfo($"Salvataggio status listPesArcIN | {tempList.Count} record"); + } + } + + /// + /// Gestione archivio serializzato delle pesate OUT già processate + /// + private List listPesArcOUT + { + get + { + List answ = new List(); + string redKey = $"{redKeyPesate}:OUT"; + string rawData = redisMan.getRSV(redKey); + if (!string.IsNullOrEmpty(rawData)) + { + try + { + answ = JsonConvert.DeserializeObject>(rawData); + lgInfo($"Rilettura status listPesArcOUT: trovati {answ.Count} record"); + answ = answ.OrderByDescending(x => x.DtEvent).ToList(); + } + catch (Exception exc) + { + lgError($"Errore in deserializzazione listPesArcOUT{Environment.NewLine}{exc}"); + answ = new List(); + } + } + // rendo + return answ; + } + set + { + // riordino prima di procedere... + var tempList = value.OrderByDescending(x => x.DtEvent).ToList(); + // ...trimmo se fossero + di xxx record... + if (tempList.Count > numLastWeight) + { + tempList = tempList.Take(numLastWeight).ToList(); + } + string redKey = $"{redKeyPesate}:OUT"; + string rawVal = JsonConvert.SerializeObject(tempList); + redisMan.setRSV(redKey, rawVal); + lgInfo($"Salvataggio status listPesArcOUT | {value.Count} record"); + } + } + + /// + /// Elenco pesate attuali + /// + private List listPesateCurr { get; set; } = new List(); + + private string redKeyPesate { get; set; } = ""; + + #endregion Private Properties + + #region Private Methods + + private static string formatCode(string currCode) + { + string code = string.IsNullOrEmpty(currCode) ? "-" : currCode; + return $" | {code}"; + } + + /// + /// Formatta record completo pesata + /// + /// record completo pesate Gomba + /// Indica se deve formattare i dati tipo IN (true) o OUT (false) + /// + private static string formatPesata(WeightRec rec) + { + string currVal = $"RM: {rec.RM} | "; + try + { + if (rec.isIn) + { + currVal += $"IN | "; + } + else + { + currVal += $"OUT | "; + } + currVal += $"{rec.DtEvent:yyyy-MM-dd HH:mm:ss} | {rec.weight:N2} kg"; + } + catch + { } + currVal += formatCode(rec.cod1); + currVal += formatCode(rec.cod2); + currVal += formatCode(rec.cod3); + currVal += formatCode(rec.cod4); + currVal += formatCode(rec.cod5); + currVal += formatCode(rec.cod6); + return currVal; + } + + private bool AppendPesata(WeightRec newRec) + { + bool fatto = false; + if (newRec.isIn) + { + var tmpPesate = listPesArcIN; + tmpPesate.Add(newRec); + listPesArcIN = tmpPesate; + } + else + { + var tmpPesate = listPesArcOUT; + tmpPesate.Add(newRec); + listPesArcOUT = tmpPesate; + } + return fatto; + } + + private bool AreEqual(List listCurr, List listArc) + { + //bool answ = ((listCurr.Count + listArc.Count) > 0 && listCurr.Count != listArc.Count) || listCurr.FirstOrDefault().DtEvent != listArc.FirstOrDefault().DtEvent; + bool allEmpty = (listCurr.Count + listArc.Count) == 0; + bool dateDiff = listCurr.OrderByDescending(x => x.DtEvent).FirstOrDefault().DtEvent != listArc.OrderByDescending(x => x.DtEvent).FirstOrDefault().DtEvent; + bool answ = allEmpty || dateDiff; + return answ; + } + + #endregion Private Methods + +#if false /// /// Gestione archivio serializzato delle pesate già processate /// @@ -548,8 +806,7 @@ namespace IOB_WIN_NEXT.IobSoap answ = new List(); } } - // riordino - // rendo + // riordino rendo return answ; } set @@ -559,24 +816,8 @@ namespace IOB_WIN_NEXT.IobSoap lgInfo($"Salvataggio status listPesateArch | {value.Count} record"); } } - - /// - /// Elenco pesate attuali - /// - private List listPesateCurr { get; set; } = new List(); - - private string redKeyPesate { get; set; } = ""; - - #endregion Private Properties - - #region Private Methods - - private static string formatCode(string currCode) - { - string code = string.IsNullOrEmpty(currCode) ? "-" : currCode; - return $" | {code}"; - } - +#endif +#if false /// /// Formatta record completo pesata /// @@ -607,7 +848,6 @@ namespace IOB_WIN_NEXT.IobSoap currVal += formatCode(rec.cod6); return currVal; } - - #endregion Private Methods +#endif } } \ No newline at end of file