diff --git a/IOB-UT-NEXT/Objects.cs b/IOB-UT-NEXT/Objects.cs
index d680955d..c728c8cf 100644
--- a/IOB-UT-NEXT/Objects.cs
+++ b/IOB-UT-NEXT/Objects.cs
@@ -825,4 +825,17 @@ namespace IOB_UT_NEXT
public string valString { get; set; } = "";
}
+
+
+ ///
+ /// Informazioni generiche su batch produzione rilevati
+ ///
+ 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;
+ }
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/Iob/Generic.cs b/IOB-WIN-NEXT/Iob/Generic.cs
index 123317c1..25fb5bbf 100644
--- a/IOB-WIN-NEXT/Iob/Generic.cs
+++ b/IOB-WIN-NEXT/Iob/Generic.cs
@@ -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
}
///
- /// URL per AVVIO PODL corrente (metodo GET)...
+ /// URL per AVVIO di un ODL da PODL indicato (metodo GET)...
///
- public string urlOLDStartFromPODL
+ public string urlOdlStartFromPOdl
{
get
{
@@ -857,6 +859,28 @@ namespace IOB_WIN_NEXT.Iob
return answ;
}
}
+ ///
+ /// URL per creazione di un PODL da cod art (metodo GET)...
+ ///
+ 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;
+ }
+ }
+
+
+
///
/// URL per chiusura PODL --> 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;
}
-
///
- /// 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)
///
- /// Articolo (descrizione)
- /// DataOra di riferimento evento start
- protected bool ArticleTryStartPodl(string artDescript, DateTime dtRif)
+ /// Cod Articolo del PODL da avviare
+ /// num pz richiesti
+ 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;
+ }
+ ///
+ /// Recupera ODL attivo su impianto
+ ///
+ protected int CurrOdl()
+ {
+ int answ = 0;
+ string sCurrODL = utils.callUrl(urlGetCurrODL);
+ int.TryParse(sCurrODL, out answ);
+ return answ;
+ }
+ ///
+ /// Processa avvio PODL 8ed eventuale chiusura precedente)
+ ///
+ /// Idx del PODL da avviare
+ /// DataOra di riferimento evento start
+ 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 PODL)
- string tokenSearch = "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("", "");
- int.TryParse(rawVal, out idxPOdl);
- if (idxPOdl > 0)
- {
- // leggo inizio commessa
- tokenSearch = "";
- var rowStart = recipeRows.Where(x => x.Contains(tokenSearch)).FirstOrDefault();
- if (rowStart != null)
- {
- rawVal = rowStart.Trim().Replace(tokenSearch, "").Replace("", "");
- DateTime.TryParse(rawVal, out dtStartPOdl);
- }
-
- // leggo durata commessa
- tokenSearch = "";
- var rowDurSec = recipeRows.Where(x => x.Contains(tokenSearch)).FirstOrDefault();
- if (rowDurSec != null)
- {
- rawVal = rowDurSec.Trim().Replace(tokenSearch, "").Replace("", "");
- 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;
}
///
- /// Processa articolo (da descrizione):
- /// - recuperando i dati ODL CORRENTE
- /// - cerca articolo corrispondente
- /// - se corrisponde CHIUDE
+ /// Processa chiusura ODL
///
- /// Articolo (descrizione)
+ /// Idx dell'ODL da chiudere
/// DataOra di riferimento evento stop
- 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;
+ }
+ ///
+ /// Processa chiusura PODL
+ ///
+ /// Idx del PODL da chiudere
+ /// DataOra di riferimento evento stop
+ 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;
}
diff --git a/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs b/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs
index 7efcd427..f7587e3d 100644
--- a/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs
+++ b/IOB-WIN-NEXT/IobFile/IobFileSoitaab.cs
@@ -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");
+ }
+ ///
+ /// Variabile isRunning (NON realtime)
+ ///
+ 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);
+ }
+ }
///
/// Esegue processing + invio dati tab SignLog
@@ -474,10 +517,8 @@ namespace IOB_WIN_NEXT.IobFile
// init oggetto x processing
Dictionary sigLogFromFile = new Dictionary();
// 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 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 elencoProdBatch = new List();
+ 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 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
}