From 5861298b91dfaa4e87a4dd0ca3e57cda5f10a738 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 5 Oct 2022 18:26:40 +0200 Subject: [PATCH] Bozza test export csv - esporta i file - NON rispetta description - no rispetta ordine --- IOB-UT-NEXT/DataExport.cs | 33 +++++ IOB-UT-NEXT/IOB-UT-NEXT.csproj | 1 + IOB-WIN-NEXT/IOB-WIN-NEXT.csproj | 6 + IOB-WIN-NEXT/IobGeneric.cs | 120 ++++++++++------- IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs | 202 ++++++++++++++++++++++++++++- IOB-WIN-NEXT/IobSimula.cs | 190 +++++++++++++++++++++++++++ IOB-WIN-NEXT/packages.config | 1 + IOB-WIN-NEXT/temp/.placeholder.txt | 1 + 8 files changed, 508 insertions(+), 46 deletions(-) create mode 100644 IOB-UT-NEXT/DataExport.cs create mode 100644 IOB-WIN-NEXT/temp/.placeholder.txt diff --git a/IOB-UT-NEXT/DataExport.cs b/IOB-UT-NEXT/DataExport.cs new file mode 100644 index 00000000..b63589ff --- /dev/null +++ b/IOB-UT-NEXT/DataExport.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace IOB_UT_NEXT +{ + public class DataExport + { + + /// + /// Effettua salvataggio in file di un generico oggetto in formato CSV + /// + /// + /// + /// + /// Separatore da impiegare (default ";") + /// + public static async Task SaveToCsv(List reportData, string path, char separator=';') + { + var lines = new List(); + IEnumerable props = TypeDescriptor.GetProperties(typeof(T)).OfType(); + var header = string.Join($"{separator}", props.ToList().Select(x => x.Name)); + lines.Add(header); + var valueLines = reportData.Select(row => string.Join($"{separator}", header.Split(separator).Select(a => row.GetType().GetProperty(a).GetValue(row, null)))); + //var valueLines = reportData.Select(row => string.Join(";", header.Split(';').Select(a => row.GetType().GetProperty(a).GetValue(row, null)))); + lines.AddRange(valueLines); + await Task.Run(() => File.WriteAllLines(path, lines.ToArray())); + } + } +} diff --git a/IOB-UT-NEXT/IOB-UT-NEXT.csproj b/IOB-UT-NEXT/IOB-UT-NEXT.csproj index 52ea944d..a08e1cd4 100644 --- a/IOB-UT-NEXT/IOB-UT-NEXT.csproj +++ b/IOB-UT-NEXT/IOB-UT-NEXT.csproj @@ -141,6 +141,7 @@ + diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index e1f89d64..9acfffea 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -106,6 +106,9 @@ ..\packages\EasyModbusTCP.5.6.0\lib\net40\EasyModbus.dll + + ..\packages\EgwProxy.Ftp.3.6.2210.418\lib\EgwProxy.Ftp.dll + ..\packages\EgwProxy.Icoel.3.6.2206.2811\lib\EgwProxy.Icoel.dll @@ -302,6 +305,9 @@ + + Always + Always diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs index 641d5a11..bc91bdd3 100644 --- a/IOB-WIN-NEXT/IobGeneric.cs +++ b/IOB-WIN-NEXT/IobGeneric.cs @@ -17,7 +17,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; namespace IOB_WIN_NEXT { @@ -587,6 +586,11 @@ namespace IOB_WIN_NEXT } } + /// + /// Indica se la chiamata WDST dit racking watchdog sia disabilitata dall'invio nel FluxLog + /// + public bool disableWdst { get; set; } = false; + /// /// Indica lo stato Online/Offline della IOB /// @@ -635,11 +639,6 @@ namespace IOB_WIN_NEXT /// public bool isVerboseLog { get; set; } = utils.CRB("verbose"); - /// - /// Indica se la chiamata WDST dit racking watchdog sia disabilitata dall'invio nel FluxLog - /// - public bool disableWdst { get; set; } = false; - /// /// Ultimo Alarm letto /// @@ -3438,41 +3437,6 @@ namespace IOB_WIN_NEXT lgDebug("startAdapter completed"); } - - /// - /// Dizionario dei valori bloccati x evitare log eccessivo - /// - private Dictionary vetoLogError = new Dictionary(); - /// - /// Periodo di veto log in minuti - /// - private int vetoPeriodMin = 15; - /// - /// Verifica se il log di un dato errore sia permesso - /// - /// ID del valore log da loggare/verificare - /// - private bool logValuePermit(string logKey) - { - bool doLog = false; - if (vetoLogError.ContainsKey(logKey)) - { - // verifico se veto scaduto... - if (DateTime.Now > vetoLogError[logKey]) - { - doLog = true; - vetoLogError[logKey] = DateTime.Now.AddMinutes(vetoPeriodMin); - } - } - else - { - doLog = true; - vetoLogError.Add(logKey, DateTime.Now.AddMinutes(vetoPeriodMin)); - } - - return doLog; - } - /// /// ferma l'adapter... /// @@ -4519,6 +4483,36 @@ namespace IOB_WIN_NEXT return answ; } + /// + /// Recupera da server set di dati specifici x IOB + /// + /// + protected virtual async Task iobGetDataFromServer() + { + await Task.Delay(1); + return false; + } + + /// + /// Effettua upload verso server FTP della macchina dei files nella folder indicata + /// + /// + /// + protected virtual async Task iobSendFTP(string folderDir) + { + await Task.Delay(1); + return false; + } + + /// + /// Prepara files CSV da inviare alla macchina + /// + protected virtual async Task iobWriteLocalCSV() + { + await Task.Delay(1); + return false; + } + /// /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... /// @@ -4821,8 +4815,7 @@ namespace IOB_WIN_NEXT lgError("loadMemConf: parametro ENABLE_SEND_PZC_BLOCK non trovato, verificare anche MAX_SEND_PZC_BLOCK e MIN_SEND_PZC_BLOCK"); } - // abilitazione invio WDST - // disabilitazione controllo range valori DynData + // abilitazione invio WDST disabilitazione controllo range valori DynData if (!string.IsNullOrEmpty(getOptPar("DISABLE_SEND_WDST"))) { bool checkDisWdst = false; @@ -4830,7 +4823,6 @@ namespace IOB_WIN_NEXT disableWdst = checkDisWdst; } - // disabilitazione controllo range valori DynData if (!string.IsNullOrEmpty(getOptPar("disDynDataRangeCheck"))) { @@ -5249,6 +5241,20 @@ namespace IOB_WIN_NEXT #endregion Protected Methods + #region Private Fields + + /// + /// Dizionario dei valori bloccati x evitare log eccessivo + /// + private Dictionary vetoLogError = new Dictionary(); + + /// + /// Periodo di veto log in minuti + /// + private int vetoPeriodMin = 15; + + #endregion Private Fields + #region Private Properties /// @@ -5661,6 +5667,32 @@ namespace IOB_WIN_NEXT return answ; } + /// + /// Verifica se il log di un dato errore sia permesso + /// + /// ID del valore log da loggare/verificare + /// + private bool logValuePermit(string logKey) + { + bool doLog = false; + if (vetoLogError.ContainsKey(logKey)) + { + // verifico se veto scaduto... + if (DateTime.Now > vetoLogError[logKey]) + { + doLog = true; + vetoLogError[logKey] = DateTime.Now.AddMinutes(vetoPeriodMin); + } + } + else + { + doLog = true; + vetoLogError.Add(logKey, DateTime.Now.AddMinutes(vetoPeriodMin)); + } + + return doLog; + } + /// /// Classe fittizia in caso di processing GLOBALE di tutto in 1 solo colpo... /// diff --git a/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs b/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs index 81585114..b6ac8ac2 100644 --- a/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs +++ b/IOB-WIN-NEXT/IobOpcUaMBHCimolai.cs @@ -1,7 +1,11 @@ -using MapoSDK; +using IOB_UT_NEXT; +using MapoSDK; using Opc.Ua; using System; using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Threading.Tasks; namespace IOB_WIN_NEXT { @@ -32,7 +36,7 @@ namespace IOB_WIN_NEXT #region Public Methods /// - /// Processo i task richiesti e li elimino dalla coda 1:1 + /// Processo i task richiesti e li elimino dalla coda 2:2 /// /// public override Dictionary executeTasks(Dictionary task2exe) @@ -95,6 +99,12 @@ namespace IOB_WIN_NEXT setInizioProd(); break; + case taskType.syncDbData: + iobGetDataFromServer(); + iobWriteLocalCSV(); + iobSendFTP(""); + break; + default: taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC"; lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}"); @@ -146,6 +156,147 @@ namespace IOB_WIN_NEXT #endregion Public Methods + #region Protected Properties + + protected List ListaArticoli { get; set; } = new List(); + + protected List ListaJobs { get; set; } = new List(); + + #endregion Protected Properties + + #region Protected Methods + + /// + /// Recupera da server set di dati specifici x IOB : qui per compilare files CSV + /// + /// + protected override async Task iobGetDataFromServer() + { + bool answ = false; + // recupera dati da server tramite chiamate REST a MP/IO/IOB... + + // FIXME TODO !!! + Random rnd = new Random(); + int firstId = rnd.Next(1000); + simArticoli(firstId); + simJobs(firstId); + answ = true; + + return answ; + } + + /// + /// Effettua upload verso server FTP della macchina dei files nella folder indicata + /// + /// + /// + protected override async Task iobSendFTP(string folderDir) + { + // FIXME TODO !!! + + bool answ = false; + await Task.Delay(1); + + return answ; + } + + /// + /// Prepara files CSV da inviare alla macchina + /// + protected override async Task iobWriteLocalCSV() + { + bool answ = false; + // salvo articoli + string basePath = Directory.GetCurrentDirectory(); + string filePath = Path.Combine(basePath, "temp/articoli.csv"); + await DataExport.SaveToCsv(ListaArticoli, filePath); + + // salvo PODLE + filePath = Path.Combine(basePath, $"temp/{DateTime.Now:dd-MM-yyyy}.csv"); + await DataExport.SaveToCsv(ListaJobs, filePath); + + answ = true; + + return answ; + } + + #endregion Protected Methods + + #region Protected Classes + + protected class ArtRow + { + #region Public Properties + + [Description("Articolo")] + public string Articolo { get; set; } = ""; + + [Description("Identificazione")] + public string Descrizione { get; set; } = ""; + + [Description("Limitazione_velocita_sollevamento[%]")] + public int LimiteVel { get; set; } = 100; + + [Description("Matricola_articolo")] + public string Matricola { get; set; } = ""; + + [Description("Peso_teorico_linea1[ton]")] + public int Peso_01 { get; set; } = 0; + + [Description("Peso_teorico_linea2[ton]")] + public int Peso_02 { get; set; } = 0; + + [Description("Peso_teorico_linea3[ton]")] + public int Peso_03 { get; set; } = 0; + + [Description("Peso_teorico_linea4[ton]")] + public int Peso_04 { get; set; } = 0; + + [Description("Pos. Carrello 1[mm]")] + public int PosizCarrello_01 { get; set; } = 0; + + [Description("Pos. Carrello 2[mm]")] + public int PosizCarrello_02 { get; set; } = 0; + + [Description("Pos. Carrello 3[mm]")] + public int PosizCarrello_03 { get; set; } = 0; + + [Description("Pos. Carrello 4[mm]")] + public int PosizCarrello_04 { get; set; } = 0; + + #endregion Public Properties + } + + protected class JobRow + { + #region Public Properties + + [Description("Articolo")] + public string Articolo { get; set; } = ""; + + [Description("Commessa")] + public string Commessa { get; set; } = ""; + + [Description("Data inserimento")] + public string DataIns { get; set; } = ""; + + [Description("Identificazione")] + public string Descrizione { get; set; } = ""; + + [Description("Lavorazione")] + public string Lavorazione { get; set; } = ""; + + [Description("Matricola")] + public string Matricola { get; set; } = ""; + + [Description("Ora inserimento")] + public string OraIns { get; set; } = ""; + + #endregion Public Properties + } + + #endregion Protected Classes + #region Private Methods /// @@ -206,6 +357,53 @@ namespace IOB_WIN_NEXT return answ; } + private void simArticoli(int firstId) + { + // FAKE: crea finti dati... + Random rnd = new Random(); + ListaArticoli = new List(); + for (int i = firstId; i <= firstId + 5; i++) + { + ArtRow artRow = new ArtRow() + { + Matricola = $"{i}", + Articolo = $"Articolo_{i:000}", + Descrizione = $"Descrizione_{i:000}", + Peso_01 = rnd.Next(100), + Peso_02 = rnd.Next(100), + Peso_03 = rnd.Next(100), + Peso_04 = rnd.Next(100), + PosizCarrello_01 = rnd.Next(0, 2000), + PosizCarrello_02 = rnd.Next(2100, 5000), + PosizCarrello_03 = rnd.Next(6000, 15000), + PosizCarrello_04 = rnd.Next(16000, 25000) + }; + ListaArticoli.Add(artRow); + } + } + + private void simJobs(int firstId) + { + // FAKE: crea finti dati... + Random rnd = new Random(); + ListaJobs = new List(); + for (int i = firstId; i <= firstId + 5; i++) + { + DateTime adesso = DateTime.Now; + JobRow jobRow = new JobRow() + { + Matricola = $"{i}", + Commessa = $"ODL000{i:0000}", + Articolo = $"Articolo_{i:000}", + Descrizione = $"Descrizione_{i:000}", + DataIns = $"{adesso:dd/MM/yyyy}", + OraIns = $"{adesso.AddMinutes(-i):HH:mm}", + Lavorazione = "TEST LAV" + }; + ListaJobs.Add(jobRow); + } + } + #endregion Private Methods } } \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobSimula.cs b/IOB-WIN-NEXT/IobSimula.cs index c9ba35a7..a6bffbef 100644 --- a/IOB-WIN-NEXT/IobSimula.cs +++ b/IOB-WIN-NEXT/IobSimula.cs @@ -3,6 +3,9 @@ using MapoSDK; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Threading.Tasks; namespace IOB_WIN_NEXT { @@ -90,6 +93,193 @@ namespace IOB_WIN_NEXT // parto processando dynData processDynData(); + + // simulazione processo FTP (Cimolai) - FIXME TODO DeleteME + simulaFTP(); + } + + private void simulaFTP() + { + // fixme todo: test scrittura file csv... + iobGetDataFromServer(); + iobWriteLocalCSV(); + iobSendFTP(""); + } + + + protected class ArtRow + { + #region Public Properties + + [Description("Articolo")] + public string Articolo { get; set; } = ""; + + [Description("Identificazione")] + public string Descrizione { get; set; } = ""; + + [Description("Limitazione_velocita_sollevamento[%]")] + public int LimiteVel { get; set; } = 100; + + [Description("Matricola_articolo")] + public string Matricola { get; set; } = ""; + + [Description("Peso_teorico_linea1[ton]")] + public int Peso_01 { get; set; } = 0; + + [Description("Peso_teorico_linea2[ton]")] + public int Peso_02 { get; set; } = 0; + + [Description("Peso_teorico_linea3[ton]")] + public int Peso_03 { get; set; } = 0; + + [Description("Peso_teorico_linea4[ton]")] + public int Peso_04 { get; set; } = 0; + + [Description("Pos. Carrello 1[mm]")] + public int PosizCarrello_01 { get; set; } = 0; + + [Description("Pos. Carrello 2[mm]")] + public int PosizCarrello_02 { get; set; } = 0; + + [Description("Pos. Carrello 3[mm]")] + public int PosizCarrello_03 { get; set; } = 0; + + [Description("Pos. Carrello 4[mm]")] + public int PosizCarrello_04 { get; set; } = 0; + + #endregion Public Properties + } + + protected class JobRow + { + #region Public Properties + + [Description("Articolo")] + public string Articolo { get; set; } = ""; + + [Description("Commessa")] + public string Commessa { get; set; } = ""; + + [Description("Data inserimento")] + public string DataIns { get; set; } = ""; + + [Description("Identificazione")] + public string Descrizione { get; set; } = ""; + + [Description("Lavorazione")] + public string Lavorazione { get; set; } = ""; + + [Description("Matricola")] + public string Matricola { get; set; } = ""; + + [Description("Ora inserimento")] + public string OraIns { get; set; } = ""; + + #endregion Public Properties + } + + protected List ListaArticoli { get; set; } = new List(); + + protected List ListaJobs { get; set; } = new List(); + + /// + /// Recupera da server set di dati specifici x IOB : qui per compilare files CSV + /// + /// + protected override async Task iobGetDataFromServer() + { + bool answ = false; + // recupera dati da server tramite chiamate REST a MP/IO/IOB... + + // FIXME TODO !!! + Random rnd = new Random(); + int firstId = rnd.Next(1000); + simArticoli(firstId); + simJobs(firstId); + answ = true; + + return answ; + } + private void simArticoli(int firstId) + { + // FAKE: crea finti dati... + Random rnd = new Random(); + ListaArticoli = new List(); + for (int i = firstId; i <= firstId + 5; i++) + { + ArtRow artRow = new ArtRow() + { + Matricola = $"{i}", + Articolo = $"Articolo_{i:000}", + Descrizione = $"Descrizione_{i:000}", + Peso_01 = rnd.Next(100), + Peso_02 = rnd.Next(100), + Peso_03 = rnd.Next(100), + Peso_04 = rnd.Next(100), + PosizCarrello_01 = rnd.Next(0, 2000), + PosizCarrello_02 = rnd.Next(2100, 5000), + PosizCarrello_03 = rnd.Next(6000, 15000), + PosizCarrello_04 = rnd.Next(16000, 25000) + }; + ListaArticoli.Add(artRow); + } + } + + private void simJobs(int firstId) + { + // FAKE: crea finti dati... + Random rnd = new Random(); + ListaJobs = new List(); + for (int i = firstId; i <= firstId + 5; i++) + { + DateTime adesso = DateTime.Now; + JobRow jobRow = new JobRow() + { + Matricola = $"{i}", + Commessa = $"ODL000{i:0000}", + Articolo = $"Articolo_{i:000}", + Descrizione = $"Descrizione_{i:000}", + DataIns = $"{adesso:dd/MM/yyyy}", + OraIns = $"{adesso.AddMinutes(-i):HH:mm}", + Lavorazione = "TEST LAV" + }; + ListaJobs.Add(jobRow); + } + } + + /// + /// Effettua upload verso server FTP della macchina dei files nella folder indicata + /// + /// + /// + protected override async Task iobSendFTP(string folderDir) + { + // FIXME TODO !!! + + bool answ = false; + await Task.Delay(1); + + return answ; + } + + /// + /// Prepara files CSV da inviare alla macchina + /// + protected override async Task iobWriteLocalCSV() + { + bool answ = false; + // salvo articoli + string basePath = Directory.GetCurrentDirectory(); + string filePath = Path.Combine(basePath, "temp/articoli.csv"); + await DataExport.SaveToCsv(ListaArticoli, filePath); + + // salvo PODLE + filePath = Path.Combine(basePath, $"temp/{DateTime.Now:dd-MM-yyyy}.csv"); + await DataExport.SaveToCsv(ListaJobs, filePath); + + answ = true; + + return answ; } #endregion Public Constructors diff --git a/IOB-WIN-NEXT/packages.config b/IOB-WIN-NEXT/packages.config index 66dc567d..3e3f685d 100644 --- a/IOB-WIN-NEXT/packages.config +++ b/IOB-WIN-NEXT/packages.config @@ -2,6 +2,7 @@ + diff --git a/IOB-WIN-NEXT/temp/.placeholder.txt b/IOB-WIN-NEXT/temp/.placeholder.txt new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/IOB-WIN-NEXT/temp/.placeholder.txt @@ -0,0 +1 @@ + \ No newline at end of file