Modifica gestione Soitaab x processing logfile... datestare

This commit is contained in:
Samuele Locatelli
2023-11-03 12:23:40 +01:00
parent 339b2beda9
commit d4be8ca789
3 changed files with 255 additions and 160 deletions
+13
View File
@@ -825,4 +825,17 @@ namespace IOB_UT_NEXT
public string valString { get; set; } = "";
}
/// <summary>
/// Informazioni generiche su batch produzione rilevati
/// </summary>
public class ProdBatchData
{
public DateTime dtStart { get; set; } = DateTime.Now;
public DateTime? dtEnd { get; set; } = null;
public string codArt { get; set; } = "";
public int numPz { get; set; } = 0;
}
}
+78 -102
View File
@@ -1,6 +1,8 @@
using EgwProxy.Ftp;
using EgwProxy.MultiCncLib.OPENcontrol;
using IOB_UT_NEXT;
using MapoSDK;
using MathNet.Numerics;
using MathNet.Numerics.Statistics;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -839,9 +841,9 @@ namespace IOB_WIN_NEXT.Iob
}
/// <summary>
/// URL per AVVIO PODL corrente (metodo GET)...
/// URL per AVVIO di un ODL da PODL indicato (metodo GET)...
/// </summary>
public string urlOLDStartFromPODL
public string urlOdlStartFromPOdl
{
get
{
@@ -857,6 +859,28 @@ namespace IOB_WIN_NEXT.Iob
return answ;
}
}
/// <summary>
/// URL per creazione di un PODL da cod art (metodo GET)...
/// </summary>
public string urlCreatePOdl
{
get
{
string answ = "";
try
{
answ = $@"{cIobConf.serverData.TRANSP}://{cIobConf.serverData.MPIP}{cIobConf.serverData.MPURL}{cIobConf.serverData.CMDALIVE}/forceCreatePOdl/{cIobConf.codIOB}?";
}
catch (Exception exc)
{
lgError(exc, "Errore in composizione urlStartPODL");
}
return answ;
}
}
/// <summary>
/// URL per chiusura PODL --&gt; ODL corrente (metodo GET)...
@@ -6530,7 +6554,7 @@ namespace IOB_WIN_NEXT.Iob
protected bool trySetupPODL(int idxPODL)
{
bool fatto = false;
string fullUrl = $"{urlOLDStartFromPODL}{idxPODL}";
string fullUrl = $"{urlOdlStartFromPOdl}{idxPODL}";
try
{
// invio chiamata URL x avvio PODL su macchina
@@ -6555,7 +6579,7 @@ namespace IOB_WIN_NEXT.Iob
{
bool fatto = false;
//string format = "yyyyMMddHHmmssfff";
string fullUrl = $"{urlOLDStartFromPODL}{idxPODL}&doConfirm={doConfirm}&dtEve={dtEve:yyyyMMddHHmmssfff}&dtCurr={dtCurr:yyyyMMddHHmmssfff}";
string fullUrl = $"{urlOdlStartFromPOdl}{idxPODL}&doConfirm={doConfirm}&dtEve={dtEve:yyyyMMddHHmmssfff}&dtCurr={dtCurr:yyyyMMddHHmmssfff}";
try
{
// invio chiamata URL x avvio PODL su macchina
@@ -7407,7 +7431,7 @@ namespace IOB_WIN_NEXT.Iob
// prova ad avviare/chiudere PODL relativo (eventualmente duplicandolo)
dtEve = $"{dtStartPOdl:yyyyMMddHHmmssfff}";
dtCurr = $"{DateTime.Now:yyyyMMddHHmmssfff}";
callUrl($"{urlOLDStartFromPODL}{idxPOdl}&dtEve={dtEve}&dtCurr={dtCurr}", false);
callUrl($"{urlOdlStartFromPOdl}{idxPOdl}&dtEve={dtEve}&dtCurr={dtCurr}", false);
// ora chiamo chiusura...
dtEve = $"{dtEndPOdl:yyyyMMddHHmmssfff}";
@@ -7418,115 +7442,67 @@ namespace IOB_WIN_NEXT.Iob
}
return answ;
}
/// <summary>
/// Processa articolo (da descrizione):
/// - recuperando i dati PODL attivi
/// - cerca PRIMO articolo corrispondente
/// - x inviare chiamate ad MP-IO di chiusura precedente / apertura nuovo
/// Processa avvio PODL (ed eventuale chiusura precedente)
/// </summary>
/// <param name="artDescript">Articolo (descrizione)</param>
/// <param name="dtRif">DataOra di riferimento evento start</param>
protected bool ArticleTryStartPodl(string artDescript, DateTime dtRif)
/// <param name="codArt">Cod Articolo del PODL da avviare</param>
/// <param name="numPz">num pz richiesti</param>
protected int TryCreatePodl(string codArt, int numPz)
{
int answ = 0;
string resp = callUrl($"{urlCreatePOdl}CodArt={codArt}&numPz={numPz}", false);
int.TryParse(resp, out answ);
return answ;
}
/// <summary>
/// Recupera ODL attivo su impianto
/// </summary>
protected int CurrOdl()
{
int answ = 0;
string sCurrODL = utils.callUrl(urlGetCurrODL);
int.TryParse(sCurrODL, out answ);
return answ;
}
/// <summary>
/// Processa avvio PODL 8ed eventuale chiusura precedente)
/// </summary>
/// <param name="idxPOdl">Idx del PODL da avviare</param>
/// <param name="dtRif">DataOra di riferimento evento start</param>
protected bool SendStartPodl(int idxPOdl, DateTime dtRif)
{
// confronto con gli ODL da gestire
// lancio inizio del primo ODL dell'articolo, chiudendo eventuale ODL vecchio
// getArtCurrPODL IOB/getArtCurrPODL
// getCurrPODL IOB/getCurrPODL/SIMUL_03
// getPODL IOB/getPODL/SIMUL_03?idxPODL=123
// closePODL IOB/closePODL/SIMUL_03?idxPOdl=123&dtEve=20230323151100000&dtCurr=20230323221100000
// closeODL IOB/closeODL/SIMUL_03?idxOdl=123
// forceStartPOdl IOB/forceStartPOdl/SIMUL_03?idxPODL=123&dtEve=20230323151100000&dtCurr=20230323221100000
// urlOLDStartFromPODL
bool answ = false;
#if false
// init var
int idxPOdl = 0;
string rawVal = "";
// leggo righe file!
var recipeRows = File.ReadAllLines(recipeFile);
// per ogni file ricevuto controlla se viene dal MES (cerca <Variant>PODL)
string tokenSearch = "<Variant>PODL";
// recupero riga PODL...
var rowPodl = recipeRows.Where(x => x.Contains(tokenSearch)).FirstOrDefault();
if (rowPodl != null)
{
DateTime dtStartPOdl = DateTime.Today;
int duration = 0;
DateTime dtEndPOdl = DateTime.Today.AddMinutes(10);
string dtEve = "";
string dtCurr = "";
// inizio ricerca PODL
rawVal = rowPodl.Trim().Replace(tokenSearch, "").Replace("</Variant>", "");
int.TryParse(rawVal, out idxPOdl);
if (idxPOdl > 0)
{
// leggo inizio commessa
tokenSearch = "<Date>";
var rowStart = recipeRows.Where(x => x.Contains(tokenSearch)).FirstOrDefault();
if (rowStart != null)
{
rawVal = rowStart.Trim().Replace(tokenSearch, "").Replace("</Date>", "");
DateTime.TryParse(rawVal, out dtStartPOdl);
}
// leggo durata commessa
tokenSearch = "<DosDuration>";
var rowDurSec = recipeRows.Where(x => x.Contains(tokenSearch)).FirstOrDefault();
if (rowDurSec != null)
{
rawVal = rowDurSec.Trim().Replace(tokenSearch, "").Replace("</DosDuration>", "");
int.TryParse(rawVal, out duration);
dtEndPOdl = dtStartPOdl.AddSeconds(duration);
}
// prova ad avviare/chiudere PODL relativo (eventualmente duplicandolo)
dtEve = $"{dtStartPOdl:yyyyMMddHHmmssfff}";
dtCurr = $"{DateTime.Now:yyyyMMddHHmmssfff}";
callUrl($"{urlOLDStartFromPODL}{idxPOdl}&dtEve={dtEve}&dtCurr={dtCurr}", false);
// ora chiamo chiusura...
dtEve = $"{dtEndPOdl:yyyyMMddHHmmssfff}";
dtCurr = $"{DateTime.Now:yyyyMMddHHmmssfff}";
callUrl($"{urlPODLClose}{idxPOdl}&dtEve={dtEve}&dtCurr={dtCurr}", false);
}
answ = true;
}
#endif
DateTime dtCurr = DateTime.Now;
// chiamata avvio PODL (a posteriori)
string resp = callUrl($"{urlOdlStartFromPOdl}{idxPOdl}&dtEve={dtRif}&dtCurr={dtCurr}", false);
answ = resp == "OK";
return answ;
}
/// <summary>
/// Processa articolo (da descrizione):
/// - recuperando i dati ODL CORRENTE
/// - cerca articolo corrispondente
/// - se corrisponde CHIUDE
/// Processa chiusura ODL
/// </summary>
/// <param name="artDescript">Articolo (descrizione)</param>
/// <param name="idxOdl">Idx dell'ODL da chiudere</param>
/// <param name="dtRif">DataOra di riferimento evento stop</param>
protected bool ArticleTryCloseOdl(string artDescript, DateTime dtRif)
protected bool SendCloseOdl(int idxOdl, DateTime dtRif)
{
bool answ = false;
// getCurrODL IOB/getCurrODL/SIMUL_03
// check articolo... se corrisponde...
// closeODL IOB/closeODL/SIMUL_03?idxOdl=123
DateTime dtCurr = DateTime.Now;
string resp = callUrl($"{urlODLClose}{idxOdl}&dtEve={dtRif}&dtCurr={dtCurr}", false);
answ = resp == "OK";
return answ;
}
/// <summary>
/// Processa chiusura PODL
/// </summary>
/// <param name="idxPOdl">Idx del PODL da chiudere</param>
/// <param name="dtRif">DataOra di riferimento evento stop</param>
protected bool SendClosePOdl(int idxPOdl, DateTime dtRif)
{
bool answ = false;
DateTime dtCurr = DateTime.Now;
string resp = callUrl($"{urlPODLClose}{idxPOdl}&dtEve={dtRif}&dtCurr={dtCurr}", false);
answ = resp == "OK";
return answ;
}
+164 -58
View File
@@ -460,8 +460,51 @@ namespace IOB_WIN_NEXT.IobFile
return fatto;
}
private string lastArtDescr = "";
private bool isRunningSim = false;
private string redKeyProdRunState
{
get => redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:prodDecod:isRunningState");
}
private string redKeyProdLastArt
{
get => redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:prodDecod:lastArtDesc");
}
private string redKeyLogfileAct
{
get => redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:LogFile:Act");
}
private string redKeyLogfileLast
{
get => redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:LogFile:Last");
}
/// <summary>
/// Variabile isRunning (NON realtime)
/// </summary>
private bool isRunningState
{
get
{
bool answ = false;
string cStatus = redisMan.getRSV(redKeyProdRunState);
bool.TryParse(cStatus, out answ);
return answ;
}
set
{
redisMan.setRSV(redKeyProdRunState, $"{value}");
}
}
private string lastArtDescr
{
get
{
string answ = redisMan.getRSV(redKeyProdLastArt);
return answ;
}
set
{
redisMan.setRSV(redKeyProdLastArt, value);
}
}
/// <summary>
/// Esegue processing + invio dati tab SignLog
@@ -474,10 +517,8 @@ namespace IOB_WIN_NEXT.IobFile
// init oggetto x processing
Dictionary<DateTime, int> sigLogFromFile = new Dictionary<DateTime, int>();
// recupero i dati dai logs files, attuale e nuovo...
string redKeyAct = redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:LogFile:Act");
string redKeyLast = redisMan.redHash($"IOB:CurrData:{cIobConf.codIOB}:LogFile:Last");
string fileAct = redisMan.getRSV(redKeyAct);
string fileLast = redisMan.getRSV(redKeyLast);
string fileAct = redisMan.getRSV(redKeyLogfileAct);
string fileLast = redisMan.getRSV(redKeyLogfileLast);
// confronto con i dati dell'ultimo LOG FILE processato
int lenghtAct = fileAct != null ? fileAct.Length : 0;
int lenghtLast = fileLast != null ? fileLast.Length : 0;
@@ -554,83 +595,148 @@ namespace IOB_WIN_NEXT.IobFile
}
}
// recupero elenco PODL corrente...
List<PODLModel> reqPOdlList =MachineNextPodl();
/* ----------------------------------------------------------
* processo righe x costruire una lista di eventi produzione:
* - elenco di eventi contapezzi
* - lista xODL come articolo + quantità prodotta (_1, _2, ...)
* - eventuale ultimo xODL che resta aperto
*
* successivamente processing + invio info raccolte
* - recupero PODL aperti
* - apertura/chiusura PODL esistenti
* - creazione PODL mancanti
* - dichiarazione contapezzi
*
* ---------------------------------------------------------- */
string sVal = "";
string descrArt = "";
List<ProdBatchData> elencoProdBatch = new List<ProdBatchData>();
ProdBatchData lastProdBatch = new ProdBatchData();
// ora processo TUTTO x il generico caso fluxLog......
foreach (var fLog2send in logNew)
{
var artProcessed = false;
// separo per ";"
var currData = fLog2send.valString.Split(';');
if (currData.Length > 1)
{
// per prima cosa fluxLog a prescindere...
sVal = $"[LOGFILE]{currData[0]}|{currData[1]}";
// chiamo accodamento...
// ...e chiamo accodamento
accodaFLog(sVal, qEncodeFLog(fLog2send.dtRif, currData[0], currData[1]));
// veritico se sia simulazione o taglio...
if (currData[0] == "START")
switch (currData[0])
{
isRunningSim = currData[1] == "0";
}
// LIMITATAMENTE al caso PARTCODE --> gestione inizio/fine PODL
else if (currData[0] == "PARTCODE" && !isRunningSim)
{
// prendo articolo senza indice (_1, _2, _3, ...)
descrArt = descrArt.Contains("_") ? currData[1].Substring(0, currData[1].IndexOf("_")) : currData[1];
// cerco nell'elenco PODL scaricato, sennò provo a rileggere...
var candPOdl = reqPOdlList.Where(x => x.CodArticolo.Contains(descrArt)).ToList();
if (candPOdl == null || candPOdl.Count == 0)
{
reqPOdlList = MachineNextPodl();
}
// cerco di nuovo podl x articolo...
candPOdl = reqPOdlList.Where(x => x.CodArticolo.Contains(descrArt)).ToList();
if (candPOdl != null || candPOdl.Count > 0)
{
// confronto con codice articolo ultimo corrente
if (lastArtDescr != currData[1])
case "END":
// se è un end --> è comunque NON + runnning
isRunningState = false; // chiudo batch precedente + in elenco (SE era valido...)
if (!string.IsNullOrEmpty(lastProdBatch.codArt))
{
// cerco PODL corretto
lastProdBatch.dtEnd = fLog2send.dtRif;
elencoProdBatch.Add(lastProdBatch);
}
// reset articolo..
lastArtDescr = "";
// nuovo batch VUOTO
lastProdBatch = new ProdBatchData();
contapezziPLC = 0;
break;
case "START":
isRunningState = currData[1] == "1";
break;
// chiamo avvio PODL e chiudo eventuali altri precedenti...
artProcessed = ArticleTryStartPodl(currData[1], fLog2send.dtRif);
if (artProcessed)
case "PARTCODE":
// inizio confronto articolo con precedente x capire se sia NUOVO
descrArt = currData[1];
// devo scartare i "doppi percorsi"
if (descrArt != lastArtDescr)
{
// verifico se sia DAVVERO cambiato articolo... prendo articolo senza indice (_1, _2, _3, ...)
var artDataLast = lastArtDescr.Split('_');
var artDataNew = descrArt.Split('_');
// nuovo articolo (NON vuoto)
if (!string.IsNullOrEmpty(artDataNew[0]) && artDataLast[0] != artDataNew[0])
{
// salvo lastArt...
lastArtDescr = currData[1];
// tolgo PODL da lista...
// FIXME TODO
// chiudo batch precedente + in elenco (SE era valido...)
if (!string.IsNullOrEmpty(lastProdBatch.codArt))
{
// chiudo prod
lastProdBatch.dtEnd = fLog2send.dtRif;
elencoProdBatch.Add(lastProdBatch);
}
// nuovo batch
lastProdBatch = new ProdBatchData()
{
codArt = artDataNew[0],
dtStart = fLog2send.dtRif,
numPz = 1
};
}
// solo nuova copia articolo
else
{
// aumento numPezzi batch
lastProdBatch.numPz++;
}
// salvo nuovo art processato
lastArtDescr = descrArt;
}
}
}
// se fosse un VERO end chiude ODL dell'ultimo articolo...
else if (currData[0] == "END")
{
// se è ancora presente un articolo...
if (!string.IsNullOrEmpty(lastArtDescr))
{
// chiamo chiusura art corrente...
artProcessed = ArticleTryCloseOdl(lastArtDescr, fLog2send.dtRif);
if (artProcessed)
{
lastArtDescr = "";
}
}
break;
default:
break;
}
}
}
// recupero elenco PODL corrente...
List<PODLModel> reqPOdlList = MachineNextPodl();
// adesso processo tutti i prodBatch collezionati x invio
foreach (var item in elencoProdBatch)
{
int currIdxPOdl = 0;
// cerco se articolo sia in elenco PODL
var listPOdl = reqPOdlList
.Where(x => x.CodArticolo.Equals(item.codArt, StringComparison.InvariantCultureIgnoreCase))
.ToList();
// se trovato --> invio start/stop PODL
if (listPOdl != null && listPOdl.Count > 0)
{
var currPodl = listPOdl.FirstOrDefault();
if (currPodl != null)
{
currIdxPOdl = currPodl.IdxPromessa;
// elimino da elenco PODL
reqPOdlList.Remove(currPodl);
}
}
else
{
// se NON trovato --> creo PODL, poi avvio/chiudo
currIdxPOdl = TryCreatePodl(item.codArt, item.numPz);
}
// se idxPOdl valido
if (currIdxPOdl > 0)
{
// mando apertura PODL
SendStartPodl(currIdxPOdl, item.dtStart);
// chiudo PODL!
SendClosePOdl(currIdxPOdl, item.dtStart);
// incremento contapezzi generale x ogni set di pezzi (se non realtime sarà a posteriori... pazienza...)
contapezziPLC += item.numPz;
// provo ad inviare pezzi
trySendPzCountBlock("");
}
}
// salvo in last il valore di act...
redisMan.setRSV(redKeyLast, fileAct);
redisMan.setRSV(redKeyLogfileLast, fileAct);
// calcolo B_input valido
var lastRec = sigLogData.LastOrDefault();
if (lastRec != null)
@@ -644,7 +750,7 @@ namespace IOB_WIN_NEXT.IobFile
}
return fatto;
}
#endregion Private Methods
}