Update per primi test FTP IMI

This commit is contained in:
Samuele Locatelli
2024-10-07 16:32:21 +02:00
parent dabeefe3ed
commit 8ca5b48751
6 changed files with 328 additions and 102 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ namespace IOB_UT_NEXT
/// <summary>
/// Tempo di attesa standard prima della prossima ri-esecuzione
/// Tempo di attesa in SEC standard prima della prossima ri-esecuzione
/// </summary>
public int ReExecVeto { get; set; } = 60;
+22 -33
View File
@@ -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
+3 -3
View File
@@ -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"
}
}
+1 -1
View File
@@ -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
+5
View File
@@ -292,6 +292,11 @@ namespace IOB_WIN_NEXT.Iob
/// </summary>
public DateTime vetoSplit = DateTime.Now.AddMinutes(1);
/// <summary>
/// Veto (in sec) a nuovi ping (x IOB PING, FTP...)
/// </summary>
public int vetoPingSec = 1;
/// <summary>
/// alias booleano true = W
/// </summary>
+296 -64
View File
@@ -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
/// </summary>
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
/// </summary>
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();
}
/// <summary>
/// Override connessione
/// </summary>
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");
}
}
}
}
/// <summary>
/// Override disconnessione
/// </summary>
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();
/// <summary>
/// Dizionario dei divieti di esecuzione x i vari step
/// </summary>
private Dictionary<string, DateTime> StepsVeto = new Dictionary<string, DateTime>();
#endregion Private Fields
#region Private Properties
/// <summary>
@@ -326,17 +418,157 @@ namespace IOB_WIN_NEXT.IobNet
/// </summary>
private FtpTaskList currFtpTaskList { get; set; } = new FtpTaskList();
/// <summary>
/// CLient connessioni FTP
/// </summary>
private Manager ftpClient { get; set; } = new Manager("", "", "", "", false);
#endregion Private Properties
#region Private Methods
/// <summary>
/// Verifica se l'azione sia permessa o in stato veto a tempo
/// </summary>
/// <param name="currAct"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Imposta veto azione corrente
/// </summary>
/// <param name="currAct"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Esegue l'azione configurata
/// </summary>
/// <param name="step"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
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;
}
/// <summary>
/// Effettuo lettura file di conf
/// </summary>
/// <param name="fileName"></param>
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))
{