Files
Mapo-IOB-WIN/IOB-WIN-FORM/AdapterForm.cs
T
Samuele Locatelli 8bb0f158b5 SPLIT PROGETTO!!!
- proj di base con le 2 form da ereditare
- progetto globale che contiene TUTTI gli adapter (pronto a venire spezzettato
- gettate le basi x "portare fuori" i vari componenti oppure fare compilazione condizonale
2024-12-20 10:16:32 +01:00

1937 lines
65 KiB
C#

using IOB_UT_NEXT;
using MapoSDK;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace IOB_WIN_FORM
{
public partial class AdapterForm : Form
{
#region Public Fields
/// <summary>
/// oggetto logging
/// </summary>
public static Logger lg;
/// <summary>
/// Modello macchina
/// </summary>
public string curModel = "";
/// <summary>
/// Vendor macchina
/// </summary>
public string curVendor = "";
/// <summary>
/// configurazione caricata
/// </summary>
public IobConfiguration IOBConf;
/// <summary>
/// Oggetto x gestione dell'adapter GENERICO (x poter usare metodi di ognuno...)
/// </summary>
public Iob.Generic iobObj;
/// <summary>
/// tipo di adapter prescelto...
/// </summary>
public tipoAdapter tipoScelto = tipoAdapter.SIMULA;
#endregion Public Fields
#region Public Constructors
/// <summary>
/// Avvio MainForm
/// </summary>
/// <param name="codIOB"></param>
public AdapterForm(string codIOB)
{
CurrIOB = codIOB;
// continuo avvio...
InitializeComponent();
myGraphInitForm();
checkEditMes2Plc();
// inizializzo orologi
firstStart = DateTime.Now;
lastStartTry = DateTime.Now.AddHours(-1);
initDatamonitor();
waitRecMSec = utils.CRI("waitRecMSec");
LogManager.ReconfigExistingLoggers();
lg = LogManager.GetCurrentClassLogger();
displayTaskAndLog("AdapterForm Starting");
// se abilitato autoload conf leggo file corretto...
if (utils.CRB("autoLoadConf"))
{
try
{
loadIniFile(defConfFilePath);
lgInfo("INI LOADED");
}
catch (Exception exc)
{
displayTaskAndLog(string.Format("Eccezione in autoLoadConf: {0}", exc));
}
}
if (IOBConf == null || !utils.CRB("autoLoadConf"))
{
// definisco e avvio tipo adapter generico
tipoScelto = tipoAdapter.ND;
curVendor = "ACME";
curModel = "NONE";
IOBConf = new IobConfiguration();
loadIobType();
displayTaskAndLog("Waiting for config file selection");
}
// cerco tra i parametri opzionali se ho il parametro di
int timerIntMs = utils.CRI("timerIntMs");
if (IOBConf.optPar.ContainsKey("timerIntMs"))
{
// recupero
string rawVal = IOBConf.optPar["timerIntMs"];
if (!string.IsNullOrEmpty(rawVal))
{
int.TryParse(rawVal, out timerIntMs);
lgInfo($"Impostato timerIntMs da IOB.ini: {timerIntMs}");
}
}
// Start timer periodico comunicazione
gather.Interval = timerIntMs;
gather.Enabled = true;
displayTaskAndLog($"Main timer set: {gather.Interval}ms", true);
// Start timer periodico interfaccia
displTimer.Interval = utils.CRI("timerIntMs");
displTimer.Enabled = true;
displayTaskAndLog("Program Running", true);
// check oggetto not null
if (iobObj != null)
{
//verifico sia da inviare, ovvero non ci sia veto redis (da 12h..)
bool needSend = false;
string redKey = redisMan.redHash($"IOB:SendReboot:{CurrIOB}");
var rawVal = redisMan.getRSV(redKey);
// verifico uguaglianza MD5...
if (string.IsNullOrEmpty(rawVal))
{
needSend = true;
// calcolo attesa con errore random -/+ 10%
int ttlSec = 60 * 60 * 6 * rndGen.Next(900, 1100) / 1000;
redisMan.setRSV(redKey, $"{DateTime.Now}", ttlSec);
}
try
{
// verifico server online...
if (iobObj.checkServerAlive)
{
if (needSend)
{
// segnalo reboot (programma)...
Iob.Generic.callUrl(iobObj.urlReboot, true);
}
}
else
{
displayTaskAndLog("AdapterForm: Server OFFLINE");
}
}
catch (Exception exc)
{
lgError(string.Format("AdapterForm: EXCEPTION in fase di chiamata URL di reboot:{0}{1}{2}", iobObj.urlReboot, Environment.NewLine, exc));
}
}
displayTaskAndLog("Main Form OK", true);
}
#endregion Public Constructors
#region Public Properties
public int alQueueLen
{
set
{
qAlLen = value;
lblQueueAlarmLen.Text = qAlLen.ToString();
showQueueData();
// se supero max precedente, ed è > 10... loggo!
if (qAlLen > maxAlQueue && qAlLen > 10)
{
maxAlQueue = qAlLen;
lgInfo($"[WARN] Coda FLog di {value} record");
}
else
{
maxAlQueue--;
maxAlQueue = maxAlQueue < qAlLen ? qAlLen : maxAlQueue;
}
}
get
{
return qAlLen;
}
}
/// <summary>
/// Button restart encapsulato x gestione da classi derivate
/// </summary>
public Button btnRestart
{
get => restart;
}
/// <summary>
/// Button start encapsulato x gestione da classi derivate
/// </summary>
public Button btnStart
{
get => start;
}
/// <summary>
/// Button stop encapsulato x gestione da classi derivate
/// </summary>
public Button btnStop
{
get => stop;
}
/// <summary>
/// Visualizzazione stato di comunicazione attiva con PLC
/// </summary>
public bool commPlcActive
{
get
{
return _commPlcActive;
}
set
{
_commPlcActive = value;
// se true --> comunica/verde, altrimenti grigio
lblCNC.ForeColor = value ? Color.SeaGreen : Color.Black;
statusStrip1.Refresh();
}
}
/// <summary>
/// Visualizzazione stato di comunicazione attiva con PLC: 0 = NO PING 1 = PING OK 2 = IOB enabled
/// </summary>
public int commSrvActive
{
get
{
return _commSrvActive;
}
set
{
_commSrvActive = value;
switch (value)
{
case 0:
lblSrvUrl.ForeColor = Color.Red;
break;
case 1:
lblSrvUrl.ForeColor = Color.OrangeRed;
break;
case 2:
lblSrvUrl.ForeColor = Color.SeaGreen;
break;
default:
break;
}
statusStrip1.Refresh();
}
}
public string counterIob
{
get
{
return lblPzCountIob.Text;
}
set
{
lblPzCountIob.Text = value;
}
}
public string counterMac
{
get
{
return lblPzCountMac.Text;
}
set
{
lblPzCountMac.Text = value;
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (1 SX)...
/// </summary>
public string dataMonitor_0
{
set
{
DateTime adesso = DateTime.Now;
// salvo in cima alla lista...
dMonValues[0].Insert(0, value);
// se supero limite --> trim!
if (dMonValues[0].Count > nLine2show)
{
dMonValues[0] = dMonValues[0].Take(nLine2show).ToList();
}
if (dMonDisplVetoVeto[0] < adesso)
{
// se scaduto veto --> display!
lblRawData.Text = String.Join(Environment.NewLine, dMonValues[0]);
// update veto!
dMonDisplVetoVeto[0] = adesso.AddMilliseconds(delayShowLogMs);
}
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (1 SX)...
/// </summary>
public string dataMonitor_1
{
set
{
DateTime adesso = DateTime.Now;
// salvo nell'array...
dMonValues[1].Insert(0, value);
// se supero limite --> trim!
if (dMonValues[1].Count > nLine2show)
{
dMonValues[1] = dMonValues[1].Take(nLine2show).ToList();
}
if (dMonDisplVetoVeto[1] < adesso)
{
// se scaduto veto --> display!
lblOutMessage.Text = String.Join(Environment.NewLine, dMonValues[1]);
// update veto!
dMonDisplVetoVeto[1] = adesso.AddMilliseconds(delayShowLogMs);
}
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (2 centro)...
/// </summary>
public string dataMonitor_2
{
set
{
DateTime adesso = DateTime.Now;
// salvo nell'array...
dMonValues[2].Insert(0, value);
// se supero limite --> trim!
if (dMonValues[2].Count > nLine2show)
{
dMonValues[2] = dMonValues[2].Take(nLine2show).ToList();
}
if (dMonDisplVetoVeto[2] < adesso)
{
// se scaduto veto --> display!
lblOutMessage2.Text = String.Join(Environment.NewLine, dMonValues[2]);
// update veto!
dMonDisplVetoVeto[2] = adesso.AddMilliseconds(delayShowLogMs);
}
}
}
/// <summary>
/// Stringa dati monitoraggio mostrata (3 dx)...
/// </summary>
public string dataMonitor_3
{
set
{
DateTime adesso = DateTime.Now;
// salvo nell'array...
dMonValues[3].Insert(0, value);
// se supero limite --> trim!
if (dMonValues[3].Count > nLine2show)
{
dMonValues[3] = dMonValues[3].Take(nLine2show).ToList();
}
if (dMonDisplVetoVeto[3] < adesso)
{
// se scaduto veto --> display!
lblOutMessage3.Text = String.Join(Environment.NewLine, dMonValues[3]);
// update veto!
dMonDisplVetoVeto[3] = adesso.AddMilliseconds(delayShowLogMs);
}
}
}
/// <summary>
/// label del numero di record processati (libera)
/// </summary>
public string dataProcLabel
{
get
{
return lblDataProc.Text;
}
set
{
lblDataProc.Text = value;
}
}
/// <summary>
/// File configurazione default
/// </summary>
public string defConfFilePath
{
get
{
return string.Format(@"{0}\{1}.ini", utils.confDir, CurrIOB);
}
}
public bool enableEditMes2Plc { get; set; }
public int evQueueLen
{
set
{
qEvLen = value;
lblQueueLen.Text = qEvLen.ToString();
showQueueData();
// se supero max precedente, ed è > 10... loggo!
if (qEvLen > maxEvQueue && qEvLen > 10)
{
maxEvQueue = qEvLen;
lgInfo($"[WARN] Coda EV di {value} record");
}
else
{
maxEvQueue--;
maxEvQueue = maxEvQueue < qEvLen ? qEvLen : maxEvQueue;
}
}
get
{
return qEvLen;
}
}
public int flQueueLen
{
set
{
qFlLen = value;
lblQueueFLogLen.Text = qFlLen.ToString();
showQueueData();
// se supero max precedente, ed è > 10... loggo!
if (qFlLen > maxFlQueue && qFlLen > 10)
{
maxFlQueue = qFlLen;
lgInfo($"[WARN] Coda FLog di {value} record");
}
else
{
maxFlQueue--;
maxFlQueue = maxFlQueue < qFlLen ? qFlLen : maxFlQueue;
}
}
get
{
return qFlLen;
}
}
/// <summary>
/// Log verboso da configurazione (SOLO CHIAVE "verbose"...
/// </summary>
public bool isVerboseLog { get; set; } = utils.CRB("verbose");
public string lblCncText
{
get => lblCNC.Text;
set => lblCNC.Text = value;
}
public string lblSrvUrlText
{
get => lblSrvUrl.Text;
set => lblSrvUrl.Text = value;
}
/// <summary>
/// Logwatcher (in modalità "accodamento in testa" ultimi messaggi...)
/// </summary>
public string logWatcher
{
get
{
return lblLogfile.Text;
}
set
{
try
{
// aggiungo in testa la NUOVA stringa (eventualmente multiline)
logWatchString.Enqueue(value);
// se supero limite --> trim!
string sTemp = "";
while (logWatchString.Count > nLine2show)
{
logWatchString.TryDequeue(out sTemp);
//logWatchString = logWatchString.Take(nLine2show).ToList();
}
DateTime adesso = DateTime.Now;
if (logWatchWriteVeto < adesso)
{
this.UIThread(delegate
{
lblLogfile.Text = string.Join(Environment.NewLine, logWatchString);
lblLogfile.Refresh();
});
logWatchWriteVeto = adesso.AddMilliseconds(delayShowLogMs);
}
}
catch (Exception exc)
{
lgError($"Errore in esecuzione logWatcher{Environment.NewLine}--> {value}");
if (isVerboseLog)
{
lgError($"{exc}");
}
}
}
}
public int msQueueLen
{
set
{
qMsLen = value;
lblQueueMessLen.Text = qMsLen.ToString();
showQueueData();
// se supero max precedente, ed è > 10... loggo!
if (qMsLen > maxMsQueue && qMsLen > 10)
{
maxMsQueue = qMsLen;
lgInfo($"[WARN] Coda Ms di {value} record");
}
else
{
maxMsQueue--;
maxMsQueue = maxMsQueue < qMsLen ? qMsLen : maxMsQueue;
}
}
get
{
return qMsLen;
}
}
/// <summary>
/// Numero max linee da mostrare (da controllo)...
/// </summary>
public int nLine2show
{
get
{
int answ = 5;
try
{
Int32.TryParse(nLines.Text, out answ);
}
catch
{ }
return answ;
}
set
{
nLines.Text = value.ToString();
}
}
public int rtrQueueLen
{
set
{
qRTrLen = value;
lblQueueRwTrLog.Text = qRTrLen.ToString();
showQueueData();
// se supero max precedente, ed è > 10... loggo!
if (qRTrLen > maxRwTrQueue && qRTrLen > 10)
{
maxRwTrQueue = qRTrLen;
lgInfo($"[WARN] Coda RawTransf di {value} record");
}
else
{
maxRwTrQueue--;
maxRwTrQueue = maxRwTrQueue < qRTrLen ? qRTrLen : maxRwTrQueue;
}
}
get
{
return qRTrLen;
}
}
/// <summary>
/// Imposta COLORE SFONDO x Semaforo IN
/// </summary>
public Semaforo sIN
{
get
{
return _sIN;
}
set
{
_sIN = value;
var newColor = decSemaforo(value);
if (newColor != bIN.BackColor)
{
bIN.BackColor = newColor;
bIN.Refresh();
}
}
}
/// <summary>
/// Imposta COLORE SFONDO x Semaforo OUT
/// </summary>
public Semaforo sOUT
{
get
{
return _sOUT;
}
set
{
_sOUT = value;
var newColor = decSemaforo(value);
if (newColor != bOUT.BackColor)
{
bOUT.BackColor = newColor;
bOUT.Refresh();
}
}
}
/// <summary>
/// Task watcher (in modalità "accodamento in testa" ultimi messaggi...)
/// </summary>
public string taskWatcher
{
get
{
return lblTaskLog.Text;
}
set
{
try
{
logTaskString.Insert(0, value);
// se supero limite --> trim!
if (logTaskString.Count > nLine2show)
{
logTaskString = logTaskString.Take(nLine2show).ToList();
}
lblTaskLog.Text = string.Join(Environment.NewLine, logTaskString);
lblTaskLog.Refresh();
}
catch (Exception exc)
{
lgError($"Errore in esecuzione taskWatcher{Environment.NewLine}--> {value}");
if (isVerboseLog)
{
lgError($"{exc}");
}
}
}
}
public int ulQueueLen
{
set
{
qUlLen = value;
lblQueueULog.Text = qUlLen.ToString();
showQueueData();
// se supero max precedente, ed è > 10... loggo!
if (qUlLen > maxUlQueue && qUlLen > 10)
{
maxUlQueue = qUlLen;
lgInfo($"[WARN] Coda UL di {value} record");
}
else
{
maxUlQueue--;
maxUlQueue = maxUlQueue < qUlLen ? qUlLen : maxUlQueue;
}
}
get
{
return qUlLen;
}
}
#endregion Public Properties
#region Public Methods
/// <summary>
/// Decodifica colore da valore semaforico
/// </summary>
/// <param name="valore"></param>
/// <returns></returns>
public static Color decSemaforo(Semaforo valore)
{
Color colore = Color.LightGray;
switch (valore)
{
case Semaforo.SV:
colore = Color.LightGreen;
break;
case Semaforo.SG:
colore = Color.LightGoldenrodYellow;
break;
case Semaforo.SR:
colore = Color.Red;
break;
case Semaforo.SS:
colore = Color.DarkGray;
break;
default:
colore = Color.LightGray;
break;
}
return colore;
}
/// <summary>
/// Avvio l'adapter
/// </summary>
/// <param name="resetQueue">indica se sia richeisto di SVUOTARE le code delle info</param>
public void avviaAdapter(bool resetQueue)
{
displayTaskAndLog("Adapter starting", true);
// se NON sta girando...
if (!iobObj.adpRunning)
{
iobObj.startAdapter(resetQueue);
displayTaskAndLog("Adapter started!");
// fix buttons start/stop/dump
start.Enabled = false;
stop.Enabled = true;
restart.Enabled = true;
displayTaskAndLog("Start Timers", true);
// inizializzo contatori fast/mid/slow
fastCount = utils.CRI("fastCount");
normCount = utils.CRI("normCount");
slowCount = utils.CRI("slowCount");
verySlowCount = utils.CRI("verySlowCount");
sendStartFLog = utils.CRB("sendStartFLog");
displayTaskAndLog("Adapter Running...", true);
// init max queue
maxEvQueue = 1;
maxFlQueue = 1;
try
{
if (sendStartFLog)
{
// segnalo reboot (programma)...
iobObj.QueueFLog.Enqueue(iobObj.qEncodeFLog("IOB-STATUS", "IOB Adapter Started"));
}
}
catch (Exception exc)
{
lgError(string.Format("EXCEPTION in fase di chiamata URL di segnalazione AVVIO IOB:{0}{1}", Environment.NewLine, exc));
}
}
else
{
displayTaskAndLog("Adapter STILL Running...", true);
}
}
/// <summary>
/// mostra un testo sulla status bar + LOG
/// </summary>
/// <param name="txt2show"></param>
/// <param name="forceDebug"></param>
public void displayTaskAndLog(string txt2show, bool forceDebug = false)
{
lblStatus.Text = txt2show;
lblStatus.Invalidate();
if (forceDebug)
{
lgDebug(txt2show);
}
else
{
lgInfo(txt2show);
}
}
/// <summary>
/// Ferma l'adapter
/// </summary>
/// <param name="tryRestart">
/// determina se si debba tentare riavvio automatico (per caduta connessione)
/// </param>
/// <param name="forceDequeue">indica se sia richeisto di SVUOTARE le code delle info</param>
/// <param name="updateForm">indica se aggiornare la form prima di fermare</param>
public void fermaAdapter(bool tryRestart, bool forceDequeue, bool updateForm)
{
lgInfo($"fermaAdapter | {tryRestart} | {forceDequeue} | {updateForm}");
fermaTutto(false, tryRestart, forceDequeue, updateForm);
}
/// <summary>
/// Salva su file l'oggetto di persistenza dati
/// </summary>
/// <param name="filePath"></param>
public void savePersistLayer(string filePath)
{
// in primis check semaforo salvataggio...
if (!iobObj.adpSaving)
{
// alzo semaforo salvataggio
iobObj.adpSaving = true;
// se HO dei dati...
if (iobObj.persistenceLayer != null)
{
try
{
utils.WritePlain(iobObj.persistenceLayer, filePath);
}
catch (Exception exc)
{
lgError(string.Format("Errore salvataggio file{0}{1}", Environment.NewLine, exc));
}
}
else
{
lgDebug("persistenceLayer null, non salvato...");
}
// abbasso semaforo salvataggio
iobObj.adpSaving = false;
}
}
/// <summary>
/// Mostra update delle statistiche di comunicazione (numero chiamate, tempo medio...)
/// </summary>
/// <param name="txt2show"></param>
public void updateComStats(string txt2show)
{
lblComStats.Text = string.Format("{0} | ", txt2show);
}
/// <summary>
/// Effettua update form una volta ricevuto OBJ che contiene le varie innovazioni...
/// </summary>
/// <param name="currDispData"></param>
public void updateFormDisplay(newDisplayData currDispData)
{
// ciclo x ogni oggetto x caricare le innovazioni...
if (currDispData != null && currDispData.hasData)
{
DateTime adesso = DateTime.Now;
// RealTime display
if (!string.IsNullOrWhiteSpace(currDispData.newInData))
{
//dataMonitor_0 = limitLine2show($"{currDispData.newInData}{Environment.NewLine}{dataMonitor_0}");
dataMonitor_0 = currDispData.newInData;
}
if (!string.IsNullOrWhiteSpace(currDispData.newSignalData))
{
//dataMonitor_1 = limitLine2show($"{currDispData.newSignalData}{Environment.NewLine}{dataMonitor_1}");
dataMonitor_1 = currDispData.newSignalData;
}
if (!string.IsNullOrWhiteSpace(currDispData.newFLogData))
{
//dataMonitor_3 = limitLine2show($"{currDispData.newFLogData}{Environment.NewLine}{dataMonitor_3}");
dataMonitor_3 = currDispData.newFLogData;
}
if (!string.IsNullOrWhiteSpace(currDispData.newUrlCallData))
{
//dataMonitor_2 = limitLine2show($"{currDispData.newUrlCallData}{Environment.NewLine}{dataMonitor_2}");
dataMonitor_2 = currDispData.newUrlCallData;
}
// Bitmap lettura attuale
if (currDispData.counter >= 0)
{
if (logCounterVeto < adesso || lblCounter.Text != $"{currDispData.counter}")
{
lblCounter.Text = $"{currDispData.counter}";
lblCounter.Refresh();
logCounterVeto = adesso.AddMilliseconds(delayShowLogMs);
}
}
// Bitmap lettura attuale
if (!string.IsNullOrWhiteSpace(currDispData.currBitmap))
{
lblBitmap.Text = currDispData.currBitmap;
lblBitmap.Refresh();
}
// LiveLog
if (!string.IsNullOrWhiteSpace(currDispData.newLiveLogData))
{
logWatcher = currDispData.newLiveLogData;
}
// semafori
if (currDispData.semOut != Semaforo.ND)
{
// aggiorno SE diverso
if (sOUT != currDispData.semOut)
{
sOUT = currDispData.semOut;
}
}
if (currDispData.semIn != Semaforo.ND)
{
//aggiorno SE diverso
if (sIN != currDispData.semIn)
{
sIN = currDispData.semIn;
}
}
}
}
public void WriteTextSafe(string text)
{
this.UIThread(delegate
{
// accoda messaggio in gestione
dataMonitor_3 = text;
});
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// contatore veloce
/// </summary>
protected int fastCount;
/// <summary>
/// Data-Ora prima apertura FORM...
/// </summary>
protected DateTime firstStart;
/// <summary>
/// Oggetto ultimo inviato stato IOB x REDIS
/// </summary>
protected IobWinStatus lastIobStatus = new IobWinStatus() { lastUpdate = DateTime.Now.AddHours(-1), lastDataOut = DateTime.Now.AddHours(-1) };
/// <summary>
/// Oggetto ultimo inviato stato MP-IO x REDIS
/// </summary>
protected ServerMpStatus lastSrvStatus = new ServerMpStatus();
/// <summary>
/// ultimo tentativo riavvio...
/// </summary>
protected DateTime lastStartTry;
/// <summary>
/// contatore normale
/// </summary>
protected int normCount;
/// <summary>
/// Oggetto connessioen REDIS
/// </summary>
protected RedisIobCache redisMan = new RedisIobCache();
/// <summary>
/// Generatore numeri random
/// </summary>
protected Random rndGen = new Random();
/// <summary>
/// Contatore campionamento memoria
/// </summary>
protected int sampleMemCount;
/// <summary>
/// Indica se inviare avvio adapter con FluxLog
/// </summary>
protected bool sendStartFLog = false;
/// <summary>
/// contatore lento
/// </summary>
protected int slowCount;
/// <summary>
/// contatore sync allarmi
/// </summary>
protected int verySlowCount;
/// <summary>
/// Temnpo attesa std in MS
/// </summary>
protected int waitRecMSec = 30000;
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Valore protected comunicazione PLC
/// </summary>
protected bool _commPlcActive { get; set; } = false;
/// <summary>
/// Valore protetto stato comunicazione
/// </summary>
protected int _commSrvActive { get; set; } = 0;
/// <summary>
/// Valore protected semaforo IN
/// </summary>
protected Semaforo _sIN { get; set; } = Semaforo.ND;
/// <summary>
/// Valore protected semaforo OUT
/// </summary>
protected Semaforo _sOUT { get; set; } = Semaforo.ND;
/// <summary>
/// Codice IOB della macchina cui connettersi (x scegliere corretto file di conf...)
/// </summary>
protected string CurrIOB { get; set; }
protected int delayShowLogMs { get; set; } = utils.CRI("delayShowLogMs");
/// <summary>
/// Dictionary dei divieti del datamonitor
/// </summary>
protected Dictionary<int, DateTime> dMonDisplVetoVeto { get; set; } = new Dictionary<int, DateTime>();
/// <summary>
/// array degli oggetti datamonitor da mostrare
/// </summary>
protected Dictionary<int, List<string>> dMonValues { get; set; } = new Dictionary<int, List<string>>();
/// <summary>
/// Veto a NUOVE scritture in COUNTER...
/// </summary>
protected DateTime logCounterVeto { get; set; } = DateTime.Now;
/// <summary>
/// Lista String da mostrare quale TaskLog corrente...
/// </summary>
protected List<string> logTaskString { get; set; } = new List<string>();
/// <summary>
/// Lista String da mostrare quale WatchLog corrente...
/// </summary>
protected ConcurrentQueue<string> logWatchString { get; set; } = new ConcurrentQueue<string>();
/// <summary>
/// Veto a NUOVE scritture in logWatch...
/// </summary>
protected DateTime logWatchWriteVeto { get; set; } = DateTime.Now;
protected int maxAlQueue { get; set; }
protected int maxEvQueue { get; set; }
protected int maxFlQueue { get; set; }
protected int maxMsQueue { get; set; }
protected int maxRwTrQueue { get; set; }
protected int maxUlQueue { get; set; }
protected int qAlLen { get; set; }
protected int qEvLen { get; set; }
protected int qFlLen { get; set; }
protected int qMsLen { get; set; }
protected int qRTrLen { get; set; }
protected int qUlLen { get; set; }
protected int totQueue
{
get
{
return qEvLen + qFlLen + qAlLen + qMsLen + qUlLen;
}
}
#endregion Protected Properties
#region Protected Methods
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// GEstione evento refresh
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void IobObj_eh_refreshed(object sender, iobRefreshedEventArgs e)
{
// aggiorno!
updateFormDisplay(e.DisplayDataObject);
}
/// <summary>
/// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere...
/// </summary>
/// <param name="txt2log"></param>
protected void lgDebug(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = this.CurrIOB;
lg.Debug(txt2log);
// salvo anche in logwatcher...
newDisplayData currDispData = new newDisplayData();
currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | INFO | {txt2log}";
updateFormDisplay(currDispData);
}
/// <summary>
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
/// </summary>
/// <param name="txt2log"></param>
protected void lgError(string txt2log)
{
if (!string.IsNullOrEmpty(txt2log))
{
lg.Factory.Configuration.Variables["codIOB"] = this.CurrIOB;
lg.Error(txt2log);
// salvo anche in logwatcher... SE non si dimostra ricorsivo...
if (!txt2log.Contains("logWatcher"))
{
newDisplayData currDispData = new newDisplayData();
currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | ERROR | {txt2log}";
updateFormDisplay(currDispData);
}
}
}
/// <summary>
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
/// </summary>
/// <param name="txt2log"></param>
protected void lgInfo(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = this.CurrIOB;
lg.Info(txt2log);
// salvo anche in logwatcher...
newDisplayData currDispData = new newDisplayData();
currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | INFO | {txt2log}";
updateFormDisplay(currDispData);
}
/// <summary>
/// Effettua logging TRACE corretto impostanto anche la variabile IOB prima di scrivere...
/// </summary>
/// <param name="txt2log"></param>
protected void lgTrace(string txt2log)
{
lg.Factory.Configuration.Variables["codIOB"] = this.CurrIOB;
lg.Trace(txt2log);
// salvo anche in logwatcher...
newDisplayData currDispData = new newDisplayData();
currDispData.newLiveLogData = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} | TRACE | {txt2log}";
updateFormDisplay(currDispData);
}
/// <summary>
/// carica IOB richiesto
/// </summary>
protected virtual void loadIobType()
{
if (IOBConf != null)
{
switch (tipoScelto)
{
case tipoAdapter.ND:
default:
iobObj = new Iob.Simula(this, IOBConf);
start.Enabled = false;
break;
}
lblCNC.Text = $"CNC: {IOBConf.tipoIob} [{IOBConf.cncIpAddr}:{IOBConf.cncPort}]";
lblSrvUrl.Text = $"SRV: {IOBConf.serverData.MPIP} | URL: {IOBConf.serverData.MPURL}{IOBConf.serverData.CMDBASE}";
// aggancio evento refresh
iobObj.eh_refreshed += IobObj_eh_refreshed;
// carico i default values su interfaccia
setDefaults();
displayTaskAndLog($"Caricata conf per adapter {tipoScelto}");
}
}
/// <summary>
/// Init form (grafica) con helper x testi e varie
/// </summary>
protected void myGraphInitForm()
{
lblStatus.Text = "Loading";
// aggiunta tooltip x send forzato
ToolTip ttForceSend = new ToolTip();
// imposto delay.
ttForceSend.AutoPopDelay = 3000;
ttForceSend.InitialDelay = 500;
ttForceSend.ReshowDelay = 500;
// sempre visibile (che sia o meno attiva la form).
ttForceSend.ShowAlways = true;
// imposto tooltip
ttForceSend.SetToolTip(this.chkForceDequeue, "Forza invio eventi allo stop");
}
/// <summary>
/// impostazione valori defaults
/// </summary>
protected void setDefaults()
{
stop.Enabled = false;
alQueueLen = 0;
flQueueLen = 0;
msQueueLen = 0;
rtrQueueLen = 0;
ulQueueLen = 0;
nLine2show = utils.CRI("numRowConsole");
}
/// <summary>
/// MOstra info su coda complessiva
/// </summary>
protected void showQueueData()
{
lblQueueLenTop.Text = totQueue == 0 ? "realtime" : $"ev: {qEvLen} | flog: {qFlLen} | tot: {totQueue}";
}
#endregion Protected Methods
#region Private Fields
/// <summary>
/// Dizionario dei valori bloccati x evitare log eccessivo
/// </summary>
private Dictionary<string, DateTime> vetoLogError = new Dictionary<string, DateTime>();
/// <summary>
/// Periodo di veto log in minuti
/// </summary>
private int vetoPeriodMin = 15;
#endregion Private Fields
#region Private Delegates
private delegate void SafeCallDelegate(string text);
#endregion Private Delegates
#region Private Methods
private void btnForceAutoOdl_Click(object sender, EventArgs e)
{
iobObj.forceResetOdl();
}
private void BtnOpenLog_Click(object sender, EventArgs e)
{
try
{
string logPath = $"{System.AppDomain.CurrentDomain.BaseDirectory}logs\\{CurrIOB}\\{DateTime.Today:yyyy-MM-dd}.log";
Process.Start(logPath);
}
catch (Exception exc)
{
lgError($"Eccezione in show log (MAIN):{Environment.NewLine}{exc}");
}
}
private void BtnSendPLC_Click(object sender, EventArgs e)
{
// invia a MES il parametro selezionato (es ART / ODL / PRG NAME, come task2exe..)
Dictionary<string, string> forcedTask = new Dictionary<string, string>();
// guardo i parametri...
if (!string.IsNullOrEmpty(txtValue.Text))
{
forcedTask.Add(cmbParamValues.SelectedValue.ToString(), txtValue.Text);
}
// chiedo esecuzione task!
iobObj.processTask(forcedTask);
chkEdit.Checked = false;
toggleEditMes2Plc();
}
private void checkAssignSize()
{
int valSize = 0;
int.TryParse(txtMReadSize.Text, out valSize);
// verifico sia valida con lenght array...
int maxSize = iobObj.RawInput.Length - iobObj.RawDataInputStart;
valSize = valSize > maxSize ? maxSize : valSize;
// riporto
iobObj.RawDataInputSize = valSize;
}
private void checkAssignStart()
{
int valStart = 0;
int.TryParse(txtMReadStart.Text, out valStart);
// verifico sia valida con start/lenght array...
int maxStart = iobObj.RawInput.Length - 1;
valStart = valStart > maxStart ? maxStart : valStart;
// riporto
iobObj.RawDataInputStart = valStart;
}
private void checkEditMes2Plc()
{
cmbParamValues.Enabled = enableEditMes2Plc;
txtValue.Enabled = enableEditMes2Plc;
if (enableEditMes2Plc)
{
// aggiorno (se possibile) i parametri selezionabili...
fixComboParameters();
}
}
private void checkFastTask()
{
// decremento...
fastCount--;
// se il counter è a zero eseguo...
if (fastCount <= 0)
{
fastCount = utils.CRI("fastCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.HF);
}
}
private void checkNormTask()
{
// decremento...
normCount--;
// se il counter è a zero eseguo...
if (normCount <= 0)
{
normCount = utils.CRI("normCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.MF);
}
}
private void checkSampleMem()
{
// decremento contatore...
sampleMemCount--;
if (sampleMemCount <= 0)
{
sampleMemCount = utils.CRI("sampleMemCount");
// avvio fase raccolta dati e invio con adapter
iobObj.saveMemDump(dumpType.SAMPLE);
}
}
private void checkSendTask()
{
// avvio fase invio con adapter (code MST)
iobObj.getAndSend(gatherCycle.VHF);
}
private void checkSlowTask()
{
slowCount--;
if (slowCount <= 0)
{
slowCount = utils.CRI("slowCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.LF);
}
}
private void checkVerySlowData()
{
verySlowCount--;
if (verySlowCount <= 0)
{
verySlowCount = utils.CRI("verySlowCount");
// avvio fase raccolta dati e invio con adapter
iobObj.getAndSend(gatherCycle.VLF);
}
}
private void ChkEdit_CheckedChanged(object sender, EventArgs e)
{
toggleEditMes2Plc();
}
/// <summary>
/// Chiusura adapter
/// </summary>
private void closeAdapter()
{
lgDebug("closeAdapter | true | false | true | false");
fermaTutto(true, false, true, false);
}
private void displTimer_Tick(object sender, EventArgs e)
{
}
/// <summary>
/// Ferma tutti i componenti adapter + update buttons
/// </summary>
/// <param name="stopTimer">
/// indica se fermare il timer (gather) principale (solo se non si chiude)
/// </param>
/// <param name="tryRestart">indica se tentare di riconnettersi</param>
/// <param name="forceDequeue">indica se sia richeisto di SVUOTARE le code delle info</param>
/// <param name="updateForm">indica se si debba aggiornare la form (no se si sta chiudendo...)</param>
private void fermaTutto(bool stopTimer, bool tryRestart, bool forceDequeue, bool updateForm)
{
try
{
iobObj.stopAdapter(tryRestart, forceDequeue);
// salvo!
savePersistLayer(utils.defPersLayerFile);
savePersistLayer(utils.histPersLayerFile);
stop.Enabled = false;
start.Enabled = true;
restart.Enabled = false;
if (stopTimer)
{
gather.Enabled = false;
}
newDisplayData currDispData = new newDisplayData();
currDispData.semIn = Semaforo.SS;
currDispData.semOut = Semaforo.SS;
if (updateForm)
{
updateFormDisplay(currDispData);
}
}
catch (Exception exc)
{
lgError($"Errore in chiusura:{Environment.NewLine}{exc}");
}
}
private void fixComboParameters()
{
if (iobObj != null)
{
if (iobObj.memMap != null)
{
if (iobObj.memMap.mMapWrite != null)
{
if (iobObj.memMap.mMapWrite.Count > 0)
{
var oldParams = cmbParamValues.DataSource;
List<string> parametri = new List<string>();
foreach (var item in iobObj.memMap.mMapWrite)
{
parametri.Add(item.Key);
}
// salvo selezione
int oldIdx = cmbParamValues.SelectedIndex;
// riassegno e ri-seleziono
cmbParamValues.DataSource = parametri;
cmbParamValues.SelectedIndex = oldIdx >= 0 ? oldIdx : 0;
}
}
}
}
}
private void gather_Tick(object sender, EventArgs e)
{
bool doLog = false;
if (iobObj != null)
{
if (iobObj.periodicLog)
{
doLog = true;
}
try
{
refreshFormData();
// check esecuzione SendTask (VHF) COMUNQUE...
checkSendTask();
// eseguo cicli attivi SOLO se adapter è in EFFETTIVO running...
if (iobObj.adpRunning)
{
if (iobObj.connectionOk)
{
// se richiesto faccio memory DUMP INIZIALE!
if (iobObj.doStartMemDump)
{
lgInfo("Inizio dump memoria");
iobObj.saveMemDump(dumpType.STARTUP);
// fatto! non ripeto...
iobObj.doStartMemDump = false;
lgInfo("Finito dump memoria");
}
// controllo se sia abilitato sampleDump della meoria (periodico)
if (iobObj.doSampleMemory)
{
checkSampleMem();
}
// check esecuzione FastTask
checkFastTask();
// check esecuzione NormTask
checkNormTask();
// check esecuzione SlowTask
checkSlowTask();
// check esecuzione AlarmSync
checkVerySlowData();
if (utils.CRI("waitEndCycle") > 0)
{
Thread.Sleep(utils.CRI("waitEndCycle"));
}
}
else
{
// qui attende meno...
DateTime dtVeto = lastStartTry.AddMilliseconds(waitRecMSec / 5);
if (iobObj.adpTryRestart && (DateTime.Now > dtVeto))
{
if (doLog)
{
lgInfo($"Retry Time Elapsed ({waitRecMSec} ms)--> tryConnect");
}
lastStartTry = DateTime.Now;
iobObj.tryConnect();
}
}
}
else
{
if (doLog)
{
lgInfo("Adapter stopped");
}
// verifico SE debba tentare il riavvio, ovvero NON running ma adpTryRestart
// e non ho riprovato x oltre waitRecMSec
DateTime dtVeto = lastStartTry.AddMilliseconds(waitRecMSec);
if (iobObj.adpTryRestart && (DateTime.Now > dtVeto))
{
lastStartTry = DateTime.Now;
avviaAdapter(chkForceDequeue.Checked);
}
}
}
catch (Exception exc)
{
lgError(string.Format("Eccezione in fase di gatherTick: {0}{1}", Environment.NewLine, exc));
}
}
}
/// <summary>
/// Init oggetti datamonitor
/// </summary>
private void initDatamonitor()
{
for (int i = 0; i < 4; i++)
{
dMonDisplVetoVeto.Add(i, DateTime.Now);
dMonValues.Add(i, new List<string>());
}
}
/// <summary>
/// Carica file ini della configurazione richiesta
/// </summary>
/// <param name="iniConfFile"></param>
private void loadIniFile(string iniConfFile)
{
// out di cosa faccio...
displayTaskAndLog($"[STARTUP] Loading iniConfFile: {iniConfFile}");
// leggo file
IniFile fIni = new IniFile(iniConfFile);
// leggo vendor e modello...
curVendor = fIni.ReadString("MACHINE", "VENDOR", "ACME");
curModel = fIni.ReadString("MACHINE", "MODEL", "NONE");
// verifico tipo adapter
try
{
tipoScelto = (tipoAdapter)Enum.Parse(typeof(tipoAdapter), fIni.ReadString("IOB", "CNCTYPE", "DEMO"));
}
catch (Exception exc)
{
string rawVal = fIni.ReadString("IOB", "CNCTYPE", "DEMO");
lgError($"Eccezione in conversione tipo adapter: richiesto {rawVal} | tipo non codificato...{Environment.NewLine}{exc}");
tipoScelto = tipoAdapter.ND;
}
// carivo vettore parametri opzionai
Dictionary<string, string> optParRead = new Dictionary<string, string>();
string[] optParRows = fIni.ReadSection("OPTPAR");
if (optParRows.Length > 0)
{
try
{
string[] kvp;
foreach (var item in optParRows)
{
kvp = item.Split('=');
optParRead.Add(kvp[0], kvp[1]);
}
lgDebug($"Caricati {optParRead.Count} parametri opzionali da OPTPAR");
}
catch (Exception exc)
{
lgError(string.Format("EXCEPTION in fase di lettura OPTPAR: {0}{1}", Environment.NewLine, exc));
}
}
var appVers = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
// inizializzio conf IOB
IOBConf = new IobConfiguration
{
pingMsTimeout = fIni.ReadInteger("IOB", "PING_MS_TIMEOUT", 500),
vendor = curVendor,
model = curModel,
tipoIob = tipoScelto,
optPar = optParRead,
versIOB = $"{appVers}",
codIOB = fIni.ReadString("IOB", "IOB_NAME", CurrIOB),
EnableRedisQueue = bool.Parse(fIni.ReadString("IOB", "EnableRedisQueue", "false")),
disableExeTask = bool.Parse(fIni.ReadString("IOB", "DIS_EXE_TASK", "false")),
disableStateCh = bool.Parse(fIni.ReadString("IOB", "DIS_STATE_CH", "false")),
filenameIOB = CurrIOB,
minDeltaSec = fIni.ReadInteger("IOB", "MinDeltaSec", 6),
cncIpAddr = fIni.ReadString("CNC", "IP", "::1"),
cncPingAddr = fIni.ReadString("CNC", "PING_IP", fIni.ReadString("CNC", "IP", "::1")),
cncPort = fIni.ReadString("CNC", "PORT", "0"),
iniFileName = iniConfFile,
cpuType = fIni.ReadString("CNC", "CPUTYPE", ""),
rack = (short)fIni.ReadInteger("CNC", "RACK", 0),
slot = (short)fIni.ReadInteger("CNC", "SLOT", 0),
serverData = new serverMapo(fIni.ReadString("SERVER", "MPIP", "::1"), fIni.ReadString("SERVER", "MPURL", "/MP/IO"), fIni.ReadString("SERVER", "CMDBASE", "/IOB/input/"), fIni.ReadString("SERVER", "CMDFLOG", "/IOB/flog/"), fIni.ReadString("SERVER", "CMDULOG", "/IOB/ulog/"), fIni.ReadString("SERVER", "CMDALIVE", "/"), fIni.ReadString("SERVER", "CMDENABLED", "/"), fIni.ReadString("SERVER", "CMDREBO", "/"), fIni.ReadString("SERVER", "CMD_ODL_STARTED", "/IOB/getCurrOdlStart/"), fIni.ReadString("SERVER", "CLI_INST", "SW_CLI"), fIni.ReadString("SERVER", "CMD_FORCLE_SPLIT_ODL", "/IOB/forceSplitOdlFull/"), fIni.ReadString("SERVER", "CMD_IDLE_TIME", "/IOB/getIdlePeriod/"), fIni.ReadString("SERVER", "CMDRAWTRANSF", "/IOB/rawTransfJson/")),
MAX_COUNTER_BLINK = Convert.ToInt32(fIni.ReadString("BLINK", "MAX_COUNTER_BLINK", "1")),
BLINK_FILT = Convert.ToInt32(fIni.ReadString("BLINK", "BLINK_FILT", "0")),
TCMaxDelayFactor = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_TC_FACTOR", "1.2").Replace(".", ",")),
TCLambda = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_LAMBDA", "0.5").Replace(".", ",")),
TCMaxIncrPz = Convert.ToDouble(fIni.ReadString("OPTPAR", "TC_MAX_INCR", "5").Replace(".", ",")),
waitRecMSec = Convert.ToInt32(fIni.ReadString("OPTPAR", "WAIT_REC_MSEC", "90000"))
};
lgDebug($"Creato IOBConf!");
// salvo serializzando json... nella folder x Cliente oppure Vendor_Model
string confJson = JsonConvert.SerializeObject(IOBConf, Formatting.Indented);
string path = fileMover.GetExecutingDirectoryName(); // Directory.GetCurrentDirectory();
string fileName = Path.GetFileName(iniConfFile).Replace(".ini", ".iob");
string dirPath = $"{path}\\DATA\\{IOBConf.serverData.ClientInstall}";
string fullPath = $"{dirPath}\\{fileName}";
// verifica directory
baseUtils.checkDir(dirPath);
// salvataggio
File.WriteAllText(fullPath, confJson);
loadIobType();
// avvio macchina con adapter specificato...
if (utils.CRB("autoStartOnLoad"))
{
displayTaskAndLog("Auto Starting...", true);
// avvio!
avviaAdapter(chkForceDequeue.Checked);
displayTaskAndLog("Auto Started!", true);
}
}
/// <summary>
/// Verifica se il log di un dato errore sia permesso
/// </summary>
/// <param name="logKey">ID del valore log da loggare/verificare</param>
/// <returns></returns>
private bool logValuePermit(string logKey)
{
bool doLog = false;
if (vetoLogError.ContainsKey(logKey))
{
// verifico se veto scaduto...
if (DateTime.Now > vetoLogError[logKey])
{
doLog = true;
vetoLogError[logKey] = DateTime.Now.AddMinutes(vetoPeriodMin);
}
}
else
{
doLog = true;
vetoLogError.Add(logKey, DateTime.Now.AddMinutes(vetoPeriodMin));
}
return doLog;
}
/// <summary>
/// Fase chiusura Form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
lgTrace("MainForm_FormClosing");
closeAdapter();
}
/// <summary>
/// Completato resize form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Resize(object sender, EventArgs e)
{
}
/// <summary>
/// Mostrata form
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainForm_Shown(object sender, EventArgs e)
{
displayTaskAndLog("Main Form SHOWN (Adapter)", true);
}
private void mLoadConf_Click(object sender, EventArgs e)
{
// mostro selettore file x leggere adapter..
OpenFileDialog openFileDial = new OpenFileDialog();
// directory iniziale
openFileDial.InitialDirectory = utils.confDir; // string.Format(@"{0}\{1}", Application.StartupPath, utils.CRS("dataConfPath"));
// Set filter options and filter index.
openFileDial.Filter = "INI Files (.ini)|*.ini|All Files (*.*)|*.*";
openFileDial.FilterIndex = 1;
// altre opzioni
openFileDial.Multiselect = false;
// Call the ShowDialog method to show the dialog box.
DialogResult userClickedOK = openFileDial.ShowDialog();
// Process input if the user clicked OK.
if (userClickedOK == DialogResult.OK)
{
string iniConfFile = openFileDial.FileName;
loadIniFile(iniConfFile);
lgInfo("INI LOADED");
}
}
private void refreshFormData()
{
// aggiorno visualizzazioni varie in form...
alQueueLen = iobObj.QueueAlarm.Count;
evQueueLen = iobObj.QueueIN.Count;
flQueueLen = iobObj.QueueFLog.Count;
msQueueLen = iobObj.QueueMessages.Count;
rtrQueueLen = iobObj.QueueRawTransf.Count;
ulQueueLen = iobObj.QueueULog.Count;
// aggiorno labels counters...
counterIob = $"pz IOB {iobObj.contapezziIOB}";
counterMac = $"pz PLC {iobObj.contapezziPLC}";
Dictionary<string, string> setPar = new Dictionary<string, string>();
setPar.Add("IP", iobObj.cIobConf.cncIpAddr);
setPar.Add("PORT", iobObj.cIobConf.cncPort);
string note = $"{iobObj.cIobConf.codIOB} | DT ultimo avvio: {iobObj.dtAvvioAdp}";
// verifico IOB status
IobWinStatus currIobStatus = new IobWinStatus()
{
//CodIob = iobObj.cIobConf.codIOB,
CodIob = iobObj.cIobConf.filenameIOB,
IobType = iobObj.cIobConf.tipoIob.ToString(),
queueAlLen = alQueueLen,
queueEvLen = evQueueLen,
queueFlLen = flQueueLen,
queueMsLen = msQueueLen,
queueRawTransfLen = rtrQueueLen,
queueUlLen = ulQueueLen,
counterIOB = iobObj.contapezziIOB,
counterMAC = iobObj.contapezziPLC,
lastUpdate = lastIobStatus.lastUpdate > iobObj.lastWatchDog ? lastIobStatus.lastUpdate : iobObj.lastWatchDog,
online = utils.IOB_Online,
lastDataIn = iobObj.lastReadPLC,
lastDataOut = iobObj.lastIobOnline,
setupParams = setPar,
freeNotes = note
};
// se diverso SALVO!
if (!currIobStatus.Equals(lastIobStatus))
{
// aggiorno data
currIobStatus.lastUpdate = DateTime.Now;
// salvo su redis e in obj corrente
iobObj.redisMan.iobStatus = currIobStatus;
lastIobStatus = currIobStatus;
}
// se diverso SALVO MP IO status
if (lastSrvStatus.online != utils.MPIO_Online)
{
// aggiorno
ServerMpStatus currSrvStatus = iobObj.redisMan.servStatus;
currSrvStatus.online = utils.MPIO_Online;
currSrvStatus.lastUpdate = DateTime.Now;
// salvo su redis e in obj corrente
iobObj.redisMan.servStatus = currSrvStatus;
lastSrvStatus = currSrvStatus;
}
}
/// <summary>
/// Button restart
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void restart_Click(object sender, EventArgs e)
{
string message = "Attenzione: con l'operazione di reset veranno persi (e non inviati) i dati eventualmente accumulati (indipendentemente dalla selezione del checkbox 'svuota coda').";
string caption = "Conferma Reset Dati IOB";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result;
// verifica con messagebox
result = MessageBox.Show(message, caption, buttons);
// solo se ho conferma da utente
if (result == DialogResult.Yes)
{
// faccio stop... SENZA inviare
fermaAdapter(false, false, true);
displayTaskAndLog("RESTARTING: Adapter Stopped", true);
// rileggo INI
loadIniFile(defConfFilePath);
displayTaskAndLog("RESTARTING: Ini File Reloaded", true);
// faccio start... CON RESET delle code
avviaAdapter(true);
displayTaskAndLog("RESTARTING: Adapter Started", true);
// resetto i data monitor...
dataMonitor_0 = "";
dataMonitor_1 = "";
dataMonitor_2 = "";
dataMonitor_3 = "";
}
}
private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
{
}
/// <summary>
/// Avvio dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void start_Click(object sender, EventArgs e)
{
avviaAdapter(chkForceDequeue.Checked);
// salvo che ho avviato adapter
lgInfo("Completato LOAD Adapter");
}
/// <summary>
/// fermata dell'adapter
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void stop_Click(object sender, EventArgs e)
{
fermaAdapter(false, chkForceDequeue.Checked, true);
// salvo che ho fermato adapter
lgInfo("UNLOAD Adapter");
}
private void TabData_Selected(object sender, TabControlEventArgs e)
{
}
private void toggleEditMes2Plc()
{
// abilita i campi --> PLC per editing
enableEditMes2Plc = !enableEditMes2Plc;
checkEditMes2Plc();
}
private void txtMReadSize_TextChanged(object sender, EventArgs e)
{
checkAssignSize();
}
private void txtMReadStart_TextChanged(object sender, EventArgs e)
{
checkAssignStart();
checkAssignSize();
}
#endregion Private Methods
}
}