8bb0f158b5
- proj di base con le 2 form da ereditare - progetto globale che contiene TUTTI gli adapter (pronto a venire spezzettato - gettate le basi x "portare fuori" i vari componenti oppure fare compilazione condizonale
740 lines
30 KiB
C#
740 lines
30 KiB
C#
using EgwProxy.Gomba.GombaServ;
|
|
using IOB_UT_NEXT;
|
|
using MapoSDK;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Net.NetworkInformation;
|
|
|
|
namespace IOB_WIN_NEXT.IobSoap
|
|
{
|
|
/// <summary>
|
|
/// Adapter specializzato per GOMA e le chiamate tramite WS Soap alla bilancia, libreria EgwProxy.Gomba
|
|
/// </summary>
|
|
public class Gomba : Iob.GenericNext
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Costruttore dell'IOB SOAP della bilancia GOMBA
|
|
/// </summary>
|
|
/// <param name="caller">AdapterForm chiamante</param>
|
|
/// <param name="IOBConf">Configurazione IOB per avvio</param>
|
|
public Gomba(AdapterFormNext caller, IobConfiguration IOBConf) : base(caller, IOBConf)
|
|
{
|
|
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
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Implementazione custom esecuzione task specifici
|
|
/// </summary>
|
|
/// <param name="task2exe"></param>
|
|
/// <returns></returns>
|
|
public override Dictionary<string, string> executeTasks(Dictionary<string, string> task2exe)
|
|
{
|
|
/*---------------------------------------
|
|
* gestione execute task SPECIFICI x pesa:
|
|
* - salva i parametri richiesta (RM, cod1..cod6)
|
|
* - esegue metodo richiesta (IN/OUT)
|
|
*---------------------------------------*/
|
|
|
|
// Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
|
|
Dictionary<string, string> taskDone = new Dictionary<string, string>();
|
|
if (task2exe != null)
|
|
{
|
|
lgTrace($"executeTasks: richiesta esecuzione {task2exe.Count} task");
|
|
// controllo se memMap != null...
|
|
if (memMap != null)
|
|
{
|
|
bool taskOk = false;
|
|
string taskVal = "";
|
|
// cerco task specifici: qui sono NON standard...
|
|
foreach (var item in task2exe)
|
|
{
|
|
lgInfo($"TASK | {item.Key} --> {item.Value}");
|
|
taskOk = false;
|
|
taskVal = "";
|
|
// converto richiesta in enum...
|
|
taskType tName = taskType.nihil;
|
|
Enum.TryParse(item.Key, out tName);
|
|
// controllo sulla KEY...
|
|
switch (tName)
|
|
{
|
|
case taskType.setParameter:
|
|
// richiedo da URL i parametri WRITE da popolare
|
|
lgInfo("Chiamata setParameter --> processMemWriteRequests");
|
|
taskVal = processMemWriteRequests();
|
|
// se restituiscce "" faccio altra prova...
|
|
if (string.IsNullOrEmpty(taskVal))
|
|
{
|
|
// i parametri me li aspetto come stringa composta paramName|paramvalue
|
|
if (item.Value.Contains("|"))
|
|
{
|
|
string[] paramsJob = item.Value.Split('|');
|
|
taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
|
|
}
|
|
else
|
|
{
|
|
taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
|
|
lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
|
|
break;
|
|
}
|
|
// aggiungo task!
|
|
taskDone.Add(item.Key, taskVal);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!");
|
|
}
|
|
}
|
|
|
|
return taskDone;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero dati dinamici...
|
|
/// </summary>
|
|
public override Dictionary<string, string> getDynData()
|
|
{
|
|
// valore non presente in vers default... se gestito fare override
|
|
Dictionary<string, string> outVal = new Dictionary<string, string>();
|
|
// controllo se ho indicato ancora che ci siano pesate già lette da inviare...
|
|
if (num2send() > 0)
|
|
{
|
|
// preparo oggetti x confronto ...
|
|
List<WeightRec> listaArch = listPesateArchivio;
|
|
|
|
// se non ho nulla in archivio prendo ultima pesata (essendo DESC è la prima cronologicamente)
|
|
if (listaArch.Count == 0)
|
|
{
|
|
WeightRec lastRec = listPesateCurr.LastOrDefault();
|
|
// aggiungo...
|
|
SavePesata(ref outVal, lastRec);
|
|
}
|
|
// ora il confronto è cronologico sulle pesate + recenti...
|
|
else
|
|
{
|
|
// prendo prima della lista pesate archiviate = più recente come dt da cui partire...
|
|
DateTime dtRif = listaArch.FirstOrDefault().DtEvent;
|
|
var firstRec = listPesateCurr
|
|
.Where(x => x.DtEvent > dtRif)
|
|
.OrderBy(x => x.DtEvent)
|
|
.FirstOrDefault();
|
|
if (firstRec != null)
|
|
{
|
|
SavePesata(ref outVal, firstRec);
|
|
}
|
|
}
|
|
|
|
// processo comunque le aree memoria READ...
|
|
if (memMap.mMapRead.Count > 0)
|
|
{
|
|
foreach (var item in memMap.mMapRead)
|
|
{
|
|
var currVal = getCurrProdData(item.Key, "");
|
|
if (!outVal.ContainsKey(item.Key))
|
|
{
|
|
outVal.Add(item.Key, $"{currVal}");
|
|
}
|
|
// se fosse logReq --> resetto...
|
|
if (item.Key == "logReq" && !string.IsNullOrEmpty(currVal))
|
|
{
|
|
upsertKey(item.Key, "");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// altrimenti rileggo e cerco se ci siano
|
|
else
|
|
{
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
try
|
|
{
|
|
// test lettura elenco pesate... se NON nullo --> OK!
|
|
var weightArray = gombaConn.reqWeightList("ALL", dataFrom, dataTo);
|
|
// riordino DESC
|
|
listPesateCurr = WeightRec.ConvertPesate(weightArray.OrderByDescending(x => x.dateIn).ToList());
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError($"Eccezione in gombaConn.reqWeightList{Environment.NewLine}{exc}");
|
|
}
|
|
sw.Stop();
|
|
lgInfo($"getDynData | SOAP: effettuata chiamata reqWeightList in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo} | {listPesateCurr.Count} rec");
|
|
}
|
|
// indico esecuzione e proseguo
|
|
lastReadPLC = DateTime.Now;
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
|
/// aggiornare x display in form</paramref>
|
|
/// </summary>
|
|
public override void readSemafori(ref newDisplayData currDispData)
|
|
{
|
|
if (connectionOk)
|
|
{
|
|
B_input = 1;
|
|
currDispData.semIn = Semaforo.SV;
|
|
|
|
// se ho pesate in memoria nel periodo richiesto --> RUN
|
|
if (listPesateCurr != null && listPesateCurr.Count > 0)
|
|
{
|
|
B_input += (1 << 1);
|
|
}
|
|
// metto manuale
|
|
else
|
|
{
|
|
B_input += (1 << 4);
|
|
}
|
|
|
|
// accodo NON emergenza
|
|
B_input += (1 << 7);
|
|
}
|
|
else
|
|
{
|
|
B_input = 0;
|
|
currDispData.semIn = Semaforo.SR;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override connessione
|
|
/// </summary>
|
|
public override void tryConnect()
|
|
{
|
|
if (!connectionOk)
|
|
{
|
|
// controllo che il ping sia stato tentato almeno pingTestSec fa...
|
|
if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
|
|
{
|
|
if (verboseLog || periodicLog)
|
|
{
|
|
lgInfo("Gomba: ConnKO - tryConnect");
|
|
}
|
|
// in primis salvo data ping...
|
|
lastPING = DateTime.Now;
|
|
// se passa il ping faccio il resto...
|
|
if (testPingMachine == IPStatus.Success)
|
|
{
|
|
string szStatusConnection = "";
|
|
try
|
|
{
|
|
// ora provo connessione...
|
|
parentForm.commPlcActive = true;
|
|
|
|
// init del proxy!!!
|
|
string endpointAddr = $"https://{cIobConf.cncIpAddr}:{cIobConf.cncPort}/ws";
|
|
lgInfo($"Tentativo avvio SOAP su endpoint {endpointAddr}");
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
|
|
// salto verifica certificato
|
|
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
|
|
|
|
// riprovo connessione SE non fosse andata...
|
|
int maxTry = 5;
|
|
int nTry = 1;
|
|
// tento avvio WS SOAP!
|
|
gombaConn = new EgwProxy.Gomba.GombaServ.lwpServiceClient("lwpServicePort", new System.ServiceModel.EndpointAddress(endpointAddr));
|
|
while (gombaConn == null || (nTry <= maxTry && !checkStateOk(gombaConn.State)))
|
|
{
|
|
lgInfo($"Tentativo connessione Gomba: | endpointAddr: {endpointAddr} | nTry: {nTry}");
|
|
// tento avvio WS SOAP!
|
|
gombaConn = new EgwProxy.Gomba.GombaServ.lwpServiceClient("lwpServicePort", new System.ServiceModel.EndpointAddress(endpointAddr));
|
|
nTry++;
|
|
}
|
|
if (checkStateOk(gombaConn.State))
|
|
{
|
|
connectionOk = true;
|
|
List<gestWeightOut> weightArray = new List<gestWeightOut>();
|
|
try
|
|
{
|
|
// test lettura elenco pesate... se NON nullo --> OK!
|
|
weightArray = gombaConn.reqWeightList("ALL", dataFrom, dataTo).OrderByDescending(x => x.dateIn).ToList();
|
|
// riordino DESC
|
|
listPesateCurr = WeightRec.ConvertPesate(weightArray);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError($"Eccezione in gombaConn.reqWeightList{Environment.NewLine}{exc}");
|
|
}
|
|
sw.Stop();
|
|
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 numLastWeight
|
|
if (weightArray.Count > numLastWeight)
|
|
{
|
|
var lastRec = weightArray
|
|
.OrderByDescending(x => x.dateIn)
|
|
.Skip(numLastWeight).FirstOrDefault();
|
|
// metto giorno antecedente
|
|
dtStartLive = lastRec.dateIn.Date.AddDays(-1);
|
|
}
|
|
// processo pesate!
|
|
demFactDynData = 1;
|
|
processDynData();
|
|
}
|
|
}
|
|
// refresh stato connessione!!!
|
|
if (connectionOk)
|
|
{
|
|
queueInEnabCurr = true;
|
|
if (adpRunning)
|
|
{
|
|
lgInfo("Connessione OK");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lgError("Impossibile procedere, connessione mancante...");
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgFatal($"Errore nella connessione all'adapter Gomba: {szStatusConnection}{Environment.NewLine}{exc}");
|
|
connectionOk = false;
|
|
lgInfo($"Eccezione in TryConnect, Adapter Gomba NON running, pausa di {utils.CRI("waitRecMSec")} msec prima di ulteriori tentativi di riconnessione");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// loggo no risposta ping ...
|
|
connectionOk = false;
|
|
if (verboseLog || periodicLog)
|
|
{
|
|
lgInfo($"Attenzione: Gomba controllo PING fallito per IP {cIobConf.cncPingAddr}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
needRefresh = true;
|
|
}
|
|
}
|
|
|
|
public override void tryDisconnect()
|
|
{
|
|
// registro solo che è disconnesso
|
|
connectionOk = false;
|
|
queueInEnabCurr = false;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Proxy per connessione al SOAP webservice GOMBA
|
|
/// </summary>
|
|
protected EgwProxy.Gomba.GombaServ.lwpServiceClient gombaConn;
|
|
|
|
protected int numLastWeight = 100;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// verifica stato ok ovvero connected oppure open
|
|
/// </summary>
|
|
/// <param name="currState"></param>
|
|
/// <returns></returns>
|
|
protected bool checkStateOk(System.ServiceModel.CommunicationState currState)
|
|
{
|
|
return currState == System.ServiceModel.CommunicationState.Opened || currState == System.ServiceModel.CommunicationState.Created;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
|
|
/// </summary>
|
|
/// <param name="updatedPar"></param>
|
|
protected override void plcWriteParams(ref List<objItem> updatedPar)
|
|
{
|
|
lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params");
|
|
foreach (var item in updatedPar)
|
|
{
|
|
lgInfo($"ITEM | {item.uid} | {item.value}");
|
|
// salvo i valori di setup x prox pesata...
|
|
upsertKey(item.uid, item.value);
|
|
bool fatto = false;
|
|
bool isPesata = false;
|
|
bool isIN = false;
|
|
gestWeightOut answ = new gestWeightOut();
|
|
// se è richiesta pesata IN/OUT --> mando chiamata
|
|
if (item.uid == "reqPesata")
|
|
{
|
|
isPesata = true;
|
|
isIN = item.reqValue.ToUpper() == "IN";
|
|
//isIN = item.value.ToUpper() == "IN";
|
|
try
|
|
{
|
|
answ = reqWeight(isIN);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError($"Eccezione in plcWriteParams.reqWeight | isIn: {isIN}{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
else if (item.uid == "RM" || item.uid.StartsWith("Cod"))
|
|
{
|
|
// comunque segno fatto x altri casi
|
|
fatto = true;
|
|
}
|
|
|
|
// se è pesata...
|
|
if (isPesata)
|
|
{
|
|
// se è OK
|
|
if (answ.feedback == "C")
|
|
{
|
|
lgInfo($"reqWeight | Effettuato richiesta | {answ.feedback} | {answ.notes}");
|
|
// resetto pesata
|
|
upsertKey(item.uid, "");
|
|
}
|
|
else
|
|
{
|
|
lgError($"reqWeight | Errore in richiesta peso GOMBA | {answ.feedback} | {answ.notes}");
|
|
}
|
|
item.value = "";
|
|
item.reqValue = "";
|
|
item.lastRead = DateTime.Now;
|
|
item.UM = "";
|
|
// salvo esito richiesta comunque
|
|
upsertKey("logReq", $"{answ.feedback} | {answ.notes}");
|
|
// faccio in modo di eseguire subito getDynData
|
|
demFactDynData = 1;
|
|
processDynData();
|
|
}
|
|
else
|
|
{
|
|
// se fatto --> aggiorno!
|
|
if (fatto)
|
|
{
|
|
//item.value = item.reqValue;
|
|
item.reqValue = "";
|
|
item.lastRead = DateTime.Now;
|
|
item.UM = "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue richiesta PESO
|
|
/// </summary>
|
|
/// <param name="reqIN">Tipo richiesta: IN (true) / OUT (false)</param>
|
|
/// <returns></returns>
|
|
protected gestWeightOut reqWeight(bool reqIN)
|
|
{
|
|
lgInfo($"reqWeight | IN: {reqIN}");
|
|
gestWeightOut answ = null;
|
|
try
|
|
{
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
// preparo parametri
|
|
string tipoRic = reqIN ? "IN" : "OUT";
|
|
string rm = getCurrProdData("RM", $"{DateTime.Now:yyyyMMdd-HHmmss}");// string.IsNullOrEmpty(currProdData["RM"]) ? $"{DateTime.Now:yyyyMMdd-HHmmss}" : currProdData["RM"];
|
|
string Cod1 = getCurrProdData("Cod1", ""); //string.IsNullOrEmpty(currProdData["Cod1"]) ? "" : currProdData["Cod1"];
|
|
string Cod2 = getCurrProdData("Cod2", ""); //string.IsNullOrEmpty(currProdData["Cod2"]) ? "" : currProdData["Cod2"];
|
|
string Cod3 = getCurrProdData("Cod3", ""); //string.IsNullOrEmpty(currProdData["Cod3"]) ? "" : currProdData["Cod3"];
|
|
string Cod4 = getCurrProdData("Cod4", ""); //string.IsNullOrEmpty(currProdData["Cod4"]) ? "" : currProdData["Cod4"];
|
|
string Cod5 = getCurrProdData("Cod5", ""); //string.IsNullOrEmpty(currProdData["Cod5"]) ? "" : currProdData["Cod5"];
|
|
string Cod6 = getCurrProdData("Cod6", ""); //string.IsNullOrEmpty(currProdData["Cod6"]) ? "" : currProdData["Cod6"];
|
|
// faccio chiamata
|
|
answ = gombaConn.memWeight(tipoRic, rm, Cod1, Cod2, Cod3, Cod4, Cod5, Cod6);
|
|
sw.Stop();
|
|
lgInfo($"reqWeight: effettuata chiamata SOAP in {sw.Elapsed.TotalMilliseconds}ms | {dataFrom} --> {dataTo}");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError($"reqWeight | errore richiesta pesatura{Environment.NewLine}{exc}");
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
protected void SavePesata(ref Dictionary<string, string> currDict, WeightRec newRec)
|
|
{
|
|
DictUpsert(ref currDict, "RM", newRec.RM ?? "");
|
|
string tag = newRec.isIn ? "In" : "Out";
|
|
DictUpsert(ref currDict, $"lastWeight{tag}", $"{newRec.weight:N2}");
|
|
// registro record completo ultima pesata
|
|
DictUpsert(ref currDict, $"lastRec{tag}", formatPesata(newRec));
|
|
// la aggiungo alle pesate archiviate...
|
|
AppendPesata(newRec);
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Protected Classes
|
|
|
|
protected class WeightRec
|
|
{
|
|
#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
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Effettua converione come lista cronologica pesate (singoli record IN/OUT)
|
|
/// </summary>
|
|
/// <param name="pesateOrig"></param>
|
|
/// <returns></returns>
|
|
public static List<WeightRec> ConvertPesate(List<gestWeightOut> pesateOrig)
|
|
{
|
|
List<WeightRec> answ = new List<WeightRec>();
|
|
foreach (var item in pesateOrig)
|
|
{
|
|
// verifico se ci sia record IN...
|
|
if (item.dateInSpecified)
|
|
{
|
|
var newRec = new WeightRec()
|
|
{
|
|
RM = item.rm,
|
|
DtEvent = item.dateIn,
|
|
isIn = true,
|
|
cod1 = item.cod1,
|
|
cod2 = item.cod2,
|
|
cod3 = item.cod3,
|
|
cod4 = item.cod4,
|
|
cod5 = item.cod5,
|
|
cod6 = item.cod6,
|
|
weight = double.Parse(item.weightIn, NumberStyles.Any, CultureInfo.InvariantCulture)
|
|
};
|
|
answ.Add(newRec);
|
|
}
|
|
// verifico se ci sia record IN...
|
|
if (item.dateOutSpecified)
|
|
{
|
|
var newRec = new WeightRec()
|
|
{
|
|
RM = item.rm,
|
|
DtEvent = item.dateOut,
|
|
isIn = false,
|
|
cod1 = item.cod1,
|
|
cod2 = item.cod2,
|
|
cod3 = item.cod3,
|
|
cod4 = item.cod4,
|
|
cod5 = item.cod5,
|
|
cod6 = item.cod6,
|
|
weight = double.Parse(item.weightOut, NumberStyles.Any, CultureInfo.InvariantCulture)
|
|
};
|
|
answ.Add(newRec);
|
|
}
|
|
}
|
|
// riordino...
|
|
answ = answ.OrderByDescending(x => x.DtEvent).ToList();
|
|
// restituisco!
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
|
|
#endregion Protected Classes
|
|
|
|
#region Private Properties
|
|
|
|
/// <summary>
|
|
/// Data inizio periodo dati Bilancia:
|
|
/// - al boot impostato a -6 mesi
|
|
/// - dopo lettura impostato a data ultimi 5 record
|
|
/// </summary>
|
|
private string dataFrom
|
|
{
|
|
get => dtStartLive.ToString("dd/MM/yyyy");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Data fine periodo dati Bilancia: oggi + 1gg
|
|
/// </summary>
|
|
private string dataTo
|
|
{
|
|
get => DateTime.Today.AddDays(1).ToString("dd/MM/yyyy");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Data riferimento x avvio processo controllo
|
|
/// </summary>
|
|
private DateTime dtStartLive { get; set; } = DateTime.Today.AddMonths(-6);
|
|
|
|
/// <summary>
|
|
/// Gestione archivio serializzato delle pesate già processate
|
|
/// </summary>
|
|
private List<WeightRec> listPesateArchivio
|
|
{
|
|
get
|
|
{
|
|
List<WeightRec> answ = new List<WeightRec>();
|
|
string redKey = $"{redKeyPesate}:ALL";
|
|
string rawData = redisMan.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<List<WeightRec>>(rawData);
|
|
lgInfo($"Rilettura status listPesateArchivio: trovati {answ.Count} record");
|
|
answ = answ.OrderByDescending(x => x.DtEvent).ToList();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
lgError($"Errore in deserializzazione listPesateArchivio{Environment.NewLine}{exc}");
|
|
answ = new List<WeightRec>();
|
|
}
|
|
}
|
|
// 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}:ALL";
|
|
string rawVal = JsonConvert.SerializeObject(tempList);
|
|
redisMan.setRSV(redKey, rawVal);
|
|
lgInfo($"Salvataggio status listPesateArchivio | {tempList.Count} record");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco pesate attuali
|
|
/// </summary>
|
|
private List<WeightRec> listPesateCurr { get; set; } = new List<WeightRec>();
|
|
|
|
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}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Formatta record completo pesata
|
|
/// </summary>
|
|
/// <param name="rec">record completo pesate Gomba</param>
|
|
/// <param name="isIN">Indica se deve formattare i dati tipo IN (true) o OUT (false)</param>
|
|
/// <returns></returns>
|
|
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 void AppendPesata(WeightRec newRec)
|
|
{
|
|
var tmpPesate = listPesateArchivio;
|
|
tmpPesate.Add(newRec);
|
|
listPesateArchivio = tmpPesate;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola numero pesate da inviare confrontando lista curr ed arch
|
|
/// </summary>
|
|
private int num2send()
|
|
{
|
|
int answ = 0;
|
|
if (listPesateCurr.Count > 0)
|
|
{
|
|
var listaArch = listPesateArchivio.OrderByDescending(x => x.DtEvent).ToList();
|
|
// se NON ne ho in archivio --> tutte!
|
|
if (listaArch.Count == 0)
|
|
{
|
|
answ = listPesateCurr.Count;
|
|
}
|
|
// altrimenti solo nuove
|
|
else
|
|
{
|
|
// prendo prima della lista pesate archiviate = più recente come dt da cui partire...
|
|
DateTime dtRif = listaArch.FirstOrDefault().DtEvent;
|
|
answ = listPesateCurr
|
|
.Where(x => x.DtEvent > dtRif)
|
|
.Count();
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |