using IOB_UT_NEXT; using MapoSDK; using System; using System.Net.NetworkInformation; using System.Threading; namespace IOB_WIN_NEXT.IobNet { public class Ping : Iob.Generic { #region Public Constructors /// /// Estende l'init della classe base /// /// public Ping(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { lgInfo("NEW IobPing (WatchDog)"); // init datetime counters DateTime adesso = DateTime.Now; lastPzCountSend = adesso; lastWarnODL = adesso; vetoCheckStatus = adesso; // 2023.09.05 imposto anche primo ping e check disconnected... lastPING = adesso; lastDisconnCheck = adesso; var POWEROFF_TIMEOUT_SEC = getOptPar("POWEROFF_TIMEOUT_SEC"); if (!string.IsNullOrEmpty(POWEROFF_TIMEOUT_SEC)) { int.TryParse(POWEROFF_TIMEOUT_SEC, out PoweroffTimeoutSec); } lgDebug($"L'adapter effettuera' PING di controllo all'indirizzo {cIobConf.cncPingAddr} per forzare stato poweroff dopo {PoweroffTimeoutSec} sec"); } 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(); } #endregion Public Constructors #region Public Methods /// /// metodo controllo ping lento, override AutoODL /// public override void processDisconnectedTask() { // effettuo check ping! DateTime adesso = DateTime.Now; if (adesso.Subtract(lastPING).TotalSeconds >= PoweroffTimeoutSec) { // invio poweroff! newDisplayData currDispData = new newDisplayData(); readSemafori(ref currDispData); // SOLO SE ho poweroff da inviare... if (B_output == 0) { accodaSigIN(ref currDispData); // reset last ping... lastPING = DateTime.Now; } } } /// /// Effettua lettura semafori principale /// Parametri da aggiornare x display in form /// public override void readSemafori(ref newDisplayData currDispData) { byte[] MemBlock = new byte[2]; try { currDispData.semIn = Semaforo.SV; // in primis salvo data ping comunque... lastPING = DateTime.Now; // se passa il ping faccio il resto... if (testPingMachine == IPStatus.Success) { connectionOk = true; lastReadPLC = DateTime.Now; lastWatchDog = DateTime.Now; } else { numFailMax = 10; checkMaxPingFail(); } if (connectionOk) { B_input = 1; //numFailCurr = 0; } else { B_input = 0; } // annullo lettura bit signal IN pre/post x evitare invio automatico... B_output = B_input; B_previous = B_input; } catch { currDispData.semIn = Semaforo.SR; } // attesa extra di 1 sec... Thread.Sleep(1000); } private void checkMaxPingFail() { numFailCurr++; if (numFailCurr >= numFailMax) { lgInfo($"PING: Reached numFailMax: {numFailMax}"); connectionOk = false; numFailCurr = 0; } } /// /// Max num ping falliti prima di demordere /// protected int numFailMax = 3; /// /// Num ping falliti corrente /// protected int numFailCurr = 0; /// /// Override connessione /// public override void tryConnect() { bool doLog = (verboseLog || periodicLog); lgDebug($"PING: tryConnect step 01 | connectionOk: {connectionOk}"); if (!connectionOk) { // controllo che il ping sia stato tentato almeno pingTestSec fa... if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec")) { if (doLog) { lgInfo("PING: ConnKO - tryConnect"); } lgDebug("PING: tryConnect step 04"); // se passa il ping faccio il resto... if (testPingMachine == IPStatus.Success) { // in primis salvo data ping... lastPING = DateTime.Now; connectionOk = true; lgInfo("PING OK"); } else { // loggo no risposta ping ... lgError("PING KO"); numFailMax = 2; checkMaxPingFail(); } } } } /// /// Override disconnessione /// public override void tryDisconnect() { lgInfo("Richiesta disconnessione adapter PING!"); connectionOk = false; } #endregion Public Methods #region Protected Fields protected int PoweroffTimeoutSec = 100; /// /// Veto controllo status x log... /// protected DateTime vetoCheckStatus = DateTime.Now; #endregion Protected Fields } }