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))
{