diff --git a/IOB-UT-NEXT/FtpActConf.cs b/IOB-UT-NEXT/FtpActConf.cs index 72f52294..4efecd24 100644 --- a/IOB-UT-NEXT/FtpActConf.cs +++ b/IOB-UT-NEXT/FtpActConf.cs @@ -45,7 +45,7 @@ namespace IOB_UT_NEXT /// - /// Tempo di attesa standard prima della prossima ri-esecuzione + /// Tempo di attesa in SEC standard prima della prossima ri-esecuzione /// public int ReExecVeto { get; set; } = 60; diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.ini b/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.ini index 34891bac..333be2b0 100644 --- a/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.ini +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.ini @@ -9,12 +9,15 @@ VENDOR=SONATEST MODEL=VEO [CNC] -IP=192.168.10.234 -PING_IP=192.168.10.234 +IP=10.74.82.204 +PING_IP=10.74.82.204 +;IP=192.168.10.234 +;PING_IP=192.168.10.234 GETPRGNAME=false [SERVER] -MPIP=http://192.168.0.110 +MPIP=http://10.74.82.218 +;MPIP=http://192.168.0.110 MPURL=/MP/IO CMDBASE=/IOB/input/ CMDFLOG=/IOB/flog/ @@ -33,43 +36,29 @@ SIZE_WRITE=0 [BLINK] ;MAX_COUNTER_BLINK = 30 MAX_COUNTER_BLINK = 30 -;bit0 = 0 -;bit1 = 0 -;bit2 = 0 -;bit3 = 0 -;bit4 = 0 -;bit5 = 0 -;bit6 = 0 -;bit7 = 0 BLINK_FILT=0 [OPTPAR] -;AUTO_CHANGE_ODL=TRUE -;CHANGE_ODL_MODE=MACHINE -;CHANGE_ODL_HOURS=24 -;CHANGE_ODL_IDLE_MIN=5 PZCOUNT_MODE=NONE +; gestione contapezzi DISABLE_PZCOUNT=TRUE -;ENABLE_SEND_PZC_BLOCK=TRUE -;MIN_SEND_PZC_BLOCK=0 -;MAX_SEND_PZC_BLOCK=100 -;ENABLE_DYN_DATA=FALSE -;FORCE_DYN_DATA=TRUE -;ENABLE_DATA_FILTER=TRUE -;ENABLE_CLI_RESTART=TRUE -MAX_ELAPSED_TIME_SEC=60 -MAX_TRY_PING=3 +ENABLE_SEND_PZC_BLOCK=FALSE +MIN_SEND_PZC_BLOCK=0 +MAX_SEND_PZC_BLOCK=100 +; gestione DynData +ENABLE_DYN_DATA=TRUE +FORCE_DYN_DATA=TRUE +DISABLE_DYN_DATA=TRUE DISABLE_SEND_WDST=TRUE -FTP_SERVER=192.168.60.234 -FTP_USER=ftpaccess -FTP_PWD=ftpaccess -FTP_CERT= -FTP_SKIP=TRUE -FTP_LOC_DIR=C:\\Steamware\\FTP\\SONATEST -FTP_REM_DIR=COMMESSE -;CSV_ADD_HEADER=true + +; gestioni PING +MAX_TRY_PING=3 +VETO_QUEUE_IN=5 +VETO_PING_SEC=5 +MAX_ELAPSED_TIME_SEC=60 + ;VETO_SEND_SNAPSHOT=3 -;;NO_PING=TRUE +POWEROFF_TIMEOUT_SEC=60 ; conf parametri memoria READ/WRITE FTP_PARAM=IMI_SONATEST.json diff --git a/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.json b/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.json index 3154b25c..3b36d5e9 100644 --- a/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.json +++ b/IOB-WIN-NEXT/DATA/CONF/IMI_SONATEST.json @@ -4,7 +4,7 @@ "ActionId": "FtpDownload", "ServerAddr": "egw-tscale-04", "ServerPort": 21, - "ConnUser": "Testftpuser", + "ConnUser": "testftpuser", "ConnPasswd": "we4reFromB3rghem!", "RawCert": "", "SkipCert": true, @@ -16,8 +16,8 @@ "Description": "Mirror Remote 2 Local Directory", "Action": "mirrorDirR2L", "ParamList": { - "RemoteDir": "Ftpdata/syncfolder", - "LocalDir": "Temp\\localdest" + "RemoteDir": "ftpdata/syncfolder", + "LocalDir": "c:\\Steamware\\FTP\\SONATEST" } } diff --git a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini index 35b2236e..c2a740d2 100644 --- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini +++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini @@ -45,6 +45,6 @@ CLI_INST=SteamWareSim ;STARTLIST=SIM_DP_01 ;NB: mettere copy always ai file di conf x fare test... -STARTLIST=3028 +STARTLIST=IMI_SONATEST MAXCNC=10 \ No newline at end of file diff --git a/IOB-WIN-NEXT/Iob/BaseObj.cs b/IOB-WIN-NEXT/Iob/BaseObj.cs index b2833a84..45f09a64 100644 --- a/IOB-WIN-NEXT/Iob/BaseObj.cs +++ b/IOB-WIN-NEXT/Iob/BaseObj.cs @@ -292,6 +292,11 @@ namespace IOB_WIN_NEXT.Iob /// public DateTime vetoSplit = DateTime.Now.AddMinutes(1); + /// + /// Veto (in sec) a nuovi ping (x IOB PING, FTP...) + /// + public int vetoPingSec = 1; + /// /// alias booleano true = W /// diff --git a/IOB-WIN-NEXT/IobNet/Ftp.cs b/IOB-WIN-NEXT/IobNet/Ftp.cs index 94e74a40..31f5c01e 100644 --- a/IOB-WIN-NEXT/IobNet/Ftp.cs +++ b/IOB-WIN-NEXT/IobNet/Ftp.cs @@ -1,9 +1,11 @@ using EgwProxy.Ftp; +using FluentFTP; using IOB_UT_NEXT; using MapoSDK; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; @@ -37,6 +39,11 @@ namespace IOB_WIN_NEXT.IobNet // 2023.09.05 imposto anche primo ping e check disconnected... lastPING = adesso; lastDisconnCheck = adesso; + var VETO_PING_SEC = getOptPar("VETO_PING_SEC"); + if (!string.IsNullOrEmpty(VETO_PING_SEC)) + { + int.TryParse(VETO_PING_SEC, out vetoPingSec); + } var POWEROFF_TIMEOUT_SEC = getOptPar("POWEROFF_TIMEOUT_SEC"); if (!string.IsNullOrEmpty(POWEROFF_TIMEOUT_SEC)) { @@ -64,15 +71,15 @@ namespace IOB_WIN_NEXT.IobNet { // il compito della richiesta è SEMPRE scrivere folder dell'ODL corrente SE NON LA TROVASSE - // uso metodo base x salvare esito scrittura var writeResult = base.executeTasks(task2exe); +#if false /*--------------------------------------------------------------------------- - * va creata una folder x ogni ODL (una volta LANCIATO da tablet) APERTO - * - nella folder scriviamo un file con articolo, qta, commessa - * - la folder sarà usata x salvare OGNI file necessario e di rilevazione - *---------------------------------------------------------------------------*/ + * va creata una folder x ogni ODL (una volta LANCIATO da tablet) APERTO + * - nella folder scriviamo un file con articolo, qta, commessa + * - la folder sarà usata x salvare OGNI file necessario e di rilevazione + *---------------------------------------------------------------------------*/ // aggiungo comportamento custom: se ho impostato nome ricetta (programma) --> imposto // richiesta caricamento se ho richiesto reset o fine lavoro --> imposto azzeramento @@ -147,6 +154,7 @@ namespace IOB_WIN_NEXT.IobNet lgError($"Attenzione! memMap è nullo, non posso eseguire task2exe!"); } } +#endif return writeResult; } @@ -157,46 +165,49 @@ namespace IOB_WIN_NEXT.IobNet /// - esegue step /// - registra eventuali DynData da salvare /// - public override void processCustomTaskMF() + public override void processCustomTaskLF() { lgInfo($"Richiesto processCustomTaskLF"); // verifico di avere compiti da svolgere... if (currFtpTaskList != null && currFtpTaskList.ListTask != null && currFtpTaskList.ListTask.Count > 0) { - Manager ftpClient = new Manager("", "", "", "", false); foreach (var srvFtp in currFtpTaskList.ListTask) { - // ora setup server FTP x item... - ftpClient = new Manager(srvFtp.ServerAddr, srvFtp.ConnUser, srvFtp.ConnPasswd, srvFtp.RawCert, srvFtp.SkipCert); - - serverTest(ftpClient); - } - } -#if false - var currBatch = IcoelSizer.GetCurrentBatch(); - lgTrace("SOAP: effettuata chiamata IcoelSizer.GetCurrentBatch()"); - if (currBatch != null) - { - // verifico se i batch siano variati... e quindi da inviare... - bool doSend = (currBatchList == null || currBatchList.Count == 0); - if (currBatch.Count > 0 && !doSend) - { - foreach (var item in currBatch) + // verifico eventuale veto all'esecuzione... + if (ActionEnabled(srvFtp)) { - // se variato ID è cambiato - doSend = doSend || (currBatchList[item.Key].Id != item.Value.Id); + // imposto nuovo veto... + ActionResetVeto(srvFtp); + // ora setup server FTP x item... + ftpClient = new Manager(srvFtp.ServerAddr, srvFtp.ConnUser, srvFtp.ConnPasswd, srvFtp.RawCert, srvFtp.SkipCert); + // test server ok... + if (ftpClient.serverOk()) + { + int stepDone = 0; + string srvType = ftpClient.serverType(); + lgTrace($"Connesso a server {srvType} | {srvFtp.ServerAddr} | inizio processing {srvFtp.StepsList.Count} steps"); + // ciclo tra i vari steps! + foreach (var step in srvFtp.StepsList) + { + bool fatto = doStep(step); + stepDone += fatto ? 1 : 0; + } + lgInfo($"Completata esecuzione steps FTP | {srvFtp.ActionId} | {stepDone}/{srvFtp.StepsList.Count} Done/Req"); + } + else + { + //connectionOk = false; + //tryDisconnect(); + lgError($"Impossibile connettersi al server {srvFtp.ServerAddr}"); + } + } + else + { + lgTrace($"Saltata esecuzione {srvFtp.ActionId} | veto attivo"); } } - // se devo inviare impacchetto dati - if (doSend) - { - accodaRawData(rawTransfType.IcoelBatch, currBatch); - currBatchList = currBatch; - } } -#endif - lastReadPLC = DateTime.Now; } @@ -206,49 +217,119 @@ namespace IOB_WIN_NEXT.IobNet /// public override void readSemafori(ref newDisplayData currDispData) { - // lo stato è come ping machine, x ora puntato a IP unico (WiFi?) DateTime adesso = DateTime.Now; - byte[] MemBlock = new byte[2]; - try + // salto se fosse attivo il veto ping... + if (lastPING.AddSeconds(vetoPingSec) < adesso) { - currDispData.semIn = Semaforo.SV; - // in primis salvo data ping comunque... - lastPING = DateTime.Now; + // lo stato è come ping machine, x ora puntato a IP unico (WiFi?) + byte[] MemBlock = new byte[2]; + try + { + currDispData.semIn = Semaforo.SV; + // in primis salvo data ping comunque... + lastPING = adesso; - // salvo esito ping - bool pingOK = testPingMachine == IPStatus.Success; - addTest(pingOK); + // salvo esito ping + bool pingOK = testPingMachine == IPStatus.Success; + addTest(pingOK); - // se passa il ping faccio il resto... - if (pingStatusOk()) - { - connectionOk = true; - lastReadPLC = DateTime.Now; - lastWatchDog = DateTime.Now; - } - else - { - connectionOk = false; - } + // se passa il ping faccio il resto... + if (pingStatusOk()) + { + connectionOk = true; + lastReadPLC = adesso; + lastWatchDog = adesso; + } + else + { + connectionOk = false; + } - if (connectionOk) - { - B_input = 1; + if (connectionOk) + { + B_input = 1; + } + else + { + B_input = 0; + } + // annullo lettura bit signal IN pre/post x evitare invio automatico... + B_output = B_input; + B_previous = B_input; } - else + catch { - B_input = 0; + currDispData.semIn = Semaforo.SR; } - // annullo lettura bit signal IN pre/post x evitare invio automatico... - B_output = B_input; - B_previous = B_input; } - catch + } + + public override void startAdapter(bool resetQueue) + { + base.startAdapter(resetQueue); + // 2023.09.05 imposto anche primo ping e check disconnected... + DateTime adesso = DateTime.Now; + lastWatchDog = adesso; + //lastPING = adesso; + lastReadPLC = adesso; + lastDisconnCheck = adesso; + // faccio un primo check POST ritardo + tryConnect(); + } + + /// + /// Override connessione + /// + public override void tryConnect() + { + bool doLog = (verboseLog || periodicLog); + lgDebug($"FTP: tryConnect step 01 | connectionOk: {connectionOk}"); + if (!connectionOk) { - currDispData.semIn = Semaforo.SR; + //// resetto coda... + //PingQueue = new DataQueue("000", "PingQueue", false); + // controllo che il ping sia stato tentato almeno pingTestSec fa... + if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) + { + if (doLog) + { + lgInfo("FTP: ConnKO - tryConnect"); + } + lgDebug("FTP: tryConnect step 04"); + + lgDebug("FTP: Reset PingQueue"); + + bool pingOK = testPingMachine == IPStatus.Success; + addTest(pingOK); + + // se passa il ping faccio il resto... + if (pingStatusOk()) + { + // in primis salvo data ping... + lastPING = DateTime.Now; + connectionOk = true; + queueInEnabCurr = true; + lgInfo("FTP OK"); + } + else + { + // loggo no risposta ping ... + lgError("FTP KO"); + } + } } } + /// + /// Override disconnessione + /// + public override void tryDisconnect() + { + lgInfo("Richiesta disconnessione adapter PING!"); + connectionOk = false; + queueInEnabCurr = false; + } + #endregion Public Methods #region Protected Fields @@ -319,6 +400,17 @@ namespace IOB_WIN_NEXT.IobNet #endregion Protected Methods + #region Private Fields + + private static Stopwatch sw = new Stopwatch(); + + /// + /// Dizionario dei divieti di esecuzione x i vari step + /// + private Dictionary StepsVeto = new Dictionary(); + + #endregion Private Fields + #region Private Properties /// @@ -326,17 +418,157 @@ namespace IOB_WIN_NEXT.IobNet /// private FtpTaskList currFtpTaskList { get; set; } = new FtpTaskList(); + /// + /// CLient connessioni FTP + /// + private Manager ftpClient { get; set; } = new Manager("", "", "", "", false); + #endregion Private Properties #region Private Methods + /// + /// Verifica se l'azione sia permessa o in stato veto a tempo + /// + /// + /// + private bool ActionEnabled(FtpActConf currAct) + { + bool enabled = true; + // se veto presente + if (StepsVeto.ContainsKey(currAct.ActionId)) + { + // controllo scadenza + enabled = StepsVeto[currAct.ActionId] < DateTime.Now; + } + return enabled; + } + + /// + /// Imposta veto azione corrente + /// + /// + /// + private bool ActionResetVeto(FtpActConf currAct) + { + bool fatto = false; + if (StepsVeto.ContainsKey(currAct.ActionId)) + { + StepsVeto[currAct.ActionId] = DateTime.Now.AddSeconds(currAct.ReExecVeto); + } + else + { + StepsVeto.Add(currAct.ActionId, DateTime.Now.AddSeconds(currAct.ReExecVeto)); + } + return fatto; + } + + /// + /// Esegue l'azione configurata + /// + /// + /// + /// + private bool doStep(ActionConfig step) + { + bool fatto = false; + // faccio switch in base al tipo di azione da eseguire... + switch (step.Action) + { + case ActType.CheckDir: + break; + + case ActType.CheckFile: + break; + + case ActType.CreateDir: + break; + + case ActType.DelDir: + break; + + case ActType.DelFile: + break; + + case ActType.DownloadDir: + + break; + + case ActType.DownloadFile: + break; + + case ActType.GenRandomDir: + break; + + case ActType.ListContent: + break; + + case ActType.MirrorDirL2R: + break; + + case ActType.MirrorDirR2L: + // eseguo mirroring directory + string remoteDir = ""; + string localDir = ""; + if (step.ParamList != null && step.ParamList.Count > 1) + { + sw.Restart(); + remoteDir = step.ParamList["RemoteDir"] ?? ""; + localDir = step.ParamList["LocalDir"] ?? ""; + // verifico esistenza dir locale... + if (!Directory.Exists(localDir)) + { + Directory.CreateDirectory(localDir); + } + //verifico dir remota + var preTest = ftpClient.dirExists(remoteDir); + if (preTest) + { + fatto = ftpClient.getDir(localDir, remoteDir, FluentFTP.FtpFolderSyncMode.Mirror); + if (!fatto) + { + lgError($"Error: {remoteDir} NOT mirrored!"); + } + } + else + { + lgError($"Dir remota non trovata! remDir: {remoteDir}"); + } + } + else + { + lgError("Error: missing parameters!"); + } + sw.Stop(); + if (fatto) + { + lgInfo($"Directory {remoteDir} mirrored R2L! | {sw.ElapsedMilliseconds:N1} ms"); + } + + break; + + case ActType.PingServer: + break; + + case ActType.UploadDir: + break; + + case ActType.UploadFile: + break; + + default: + break; + } + return fatto; + } + /// /// Effettuo lettura file di conf /// /// private void loadFtpConfFile(string fileName) { - string jsonFullPath = $"{System.Windows.Forms.Application.StartupPath}/DATA/CONF/{fileName}"; + string jsonFullPath = Path.Combine(System.Windows.Forms.Application.StartupPath, "DATA", "CONF", fileName); lgInfo($"Apertura file {jsonFullPath}"); using (StreamReader reader = new StreamReader(jsonFullPath)) {