248 lines
8.0 KiB
C#
248 lines
8.0 KiB
C#
using IOB_UT_NEXT;
|
||
using MapoSDK;
|
||
using System;
|
||
using System.Linq;
|
||
using System.Net.NetworkInformation;
|
||
|
||
namespace IOB_WIN_NEXT.IobNet
|
||
{
|
||
public class Ping : Iob.Generic
|
||
{
|
||
#region Public Constructors
|
||
|
||
/// <summary>
|
||
/// Estende l'init della classe base
|
||
/// </summary>
|
||
/// <param name="caller"></param>
|
||
/// <param name="IOBConf"></param>
|
||
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);
|
||
}
|
||
// fix coda ping
|
||
PingQueue = new DataQueue("000", "PingQueue", false);
|
||
lgDebug($"L'adapter effettuera' PING di controllo all'indirizzo {cIobConf.cncPingAddr} per forzare stato poweroff dopo {PoweroffTimeoutSec} sec");
|
||
}
|
||
|
||
#endregion Public Constructors
|
||
|
||
#region Public Methods
|
||
|
||
/// <summary>
|
||
/// metodo controllo ping lento, override AutoODL
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Effettua lettura semafori principale <paramref name="currDispData">Parametri da
|
||
/// aggiornare x display in form</paramref>
|
||
/// </summary>
|
||
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;
|
||
|
||
// 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;
|
||
}
|
||
|
||
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;
|
||
}
|
||
catch
|
||
{
|
||
currDispData.semIn = Semaforo.SR;
|
||
}
|
||
}
|
||
|
||
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($"PING: tryConnect step 01 | connectionOk: {connectionOk}");
|
||
if (!connectionOk)
|
||
{
|
||
//// 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("PING: ConnKO - tryConnect");
|
||
}
|
||
lgDebug("PING: tryConnect step 04");
|
||
|
||
lgDebug("PING: 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("PING OK");
|
||
}
|
||
else
|
||
{
|
||
// loggo no risposta ping ...
|
||
lgError("PING KO");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Override disconnessione
|
||
/// </summary>
|
||
public override void tryDisconnect()
|
||
{
|
||
lgInfo("Richiesta disconnessione adapter PING!");
|
||
connectionOk = false;
|
||
queueInEnabCurr = false;
|
||
}
|
||
|
||
#endregion Public Methods
|
||
|
||
#region Protected Fields
|
||
|
||
/// <summary>
|
||
/// Dimensione coda di ping x valutazione
|
||
/// </summary>
|
||
protected int maxQueuePing = 11;
|
||
|
||
/// <summary>
|
||
/// Coda degli esiti di ping x calcolo stato macchina
|
||
/// </summary>
|
||
protected DataQueue PingQueue = new DataQueue("000", "PingQueue", false);
|
||
|
||
protected int PoweroffTimeoutSec = 100;
|
||
|
||
/// <summary>
|
||
/// Veto controllo status x log...
|
||
/// </summary>
|
||
protected DateTime vetoCheckStatus = DateTime.Now;
|
||
|
||
#endregion Protected Fields
|
||
|
||
#region Protected Methods
|
||
|
||
protected void addTest(bool pingOk)
|
||
{
|
||
int score = pingOk ? 1 : 0;
|
||
// controllo: se era spenta e risulta ping ok --> reset coda!
|
||
if (B_input == 0 && pingOk)
|
||
{
|
||
B_input = 1;
|
||
PingQueue = new DataQueue("000", "PingQueue", false);
|
||
lgTrace($"PingQueue resetted on addTest");
|
||
}
|
||
PingQueue.Enqueue($"{score}");
|
||
while (PingQueue.Count > maxQueuePing)
|
||
{
|
||
string res = "";
|
||
PingQueue.TryDequeue(out res);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Calcola status ping:
|
||
/// - se ha ‹ 50% coda richiesta --› true
|
||
/// - se ha › 50% coda richiesta --› true se è maggior parte a 1 (true)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
protected bool pingStatusOk()
|
||
{
|
||
bool answ = true;
|
||
int numVal = PingQueue.Count;
|
||
if (numVal > maxQueuePing / 2)
|
||
{
|
||
var listaValori = PingQueue.ToList();
|
||
int numOk = listaValori.Where(x => x == "1").Count();
|
||
int numKo = numVal - numOk;
|
||
answ = numOk >= numKo;
|
||
lgTrace($"PING ok per: {numOk} > {numKo}");
|
||
}
|
||
else
|
||
{
|
||
lgTrace("PING ok per mancanza dati minimi test");
|
||
}
|
||
return answ;
|
||
}
|
||
|
||
#endregion Protected Methods
|
||
}
|
||
} |