diff --git a/CVCncLib/CVCncLib.dll b/CVCncLib/CVCncLib.dll
index fa1d7911..77ac5221 100644
Binary files a/CVCncLib/CVCncLib.dll and b/CVCncLib/CVCncLib.dll differ
diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 82854520..99e1da4b 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -269,6 +269,16 @@ namespace IOB_UT_NEXT
///
ND,
+ ///
+ /// Adapter ModBus TCP generico
+ ///
+ MODBUS_TCP,
+
+ ///
+ /// Adapter ModBus TCP versione HAM (Pizzaferri)
+ ///
+ MODBUS_TCP_HAM,
+
///
/// Adapter MTConnect
///
diff --git a/IOB-UT-NEXT/IOB-UT-NEXT.csproj b/IOB-UT-NEXT/IOB-UT-NEXT.csproj
index 663002a2..e727dce1 100644
--- a/IOB-UT-NEXT/IOB-UT-NEXT.csproj
+++ b/IOB-UT-NEXT/IOB-UT-NEXT.csproj
@@ -59,8 +59,8 @@
..\packages\SharpZipLib.1.3.1\lib\net45\ICSharpCode.SharpZipLib.dll
-
- ..\packages\MapoSDK.6.13.2105.1421\lib\net40\MapoSDK.dll
+
+ ..\packages\MapoSDK.6.13.2109.1112\lib\net40\MapoSDK.dll
..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs
index b559c19d..6b391f1a 100644
--- a/IOB-UT-NEXT/ToMapo.cs
+++ b/IOB-UT-NEXT/ToMapo.cs
@@ -188,6 +188,82 @@ namespace IOB_UT_NEXT
#endregion Public Methods
}
+#if false
+ ///
+ /// Struttura della conf memoria ModBus
+ ///
+ public class BaseModbusConf
+ {
+ public enum DataType
+ {
+ ND = 0,
+ BIT,
+ INT,
+ REAL
+ }
+
+ public enum MemType
+ {
+ ND = 0,
+ DiscreteInput = 1,
+ Coil = 2,
+ InputRegister = 3,
+ HoldingRegister = 4
+ }
+
+ ///
+ /// Elenco aree memoria ModBus in lettura
+ ///
+ public List mMapRead { get; set; } = new List();
+
+ ///
+ /// Elenco aree memoria ModBus in scrittura
+ ///
+ public List mMapWrite { get; set; } = new List();
+
+ ///
+ /// struttura di base memoria ModBus
+ ///
+ public class ModbusMemArea
+ {
+ public ushort BaseAddr { get; set; } = 0;
+ public string RawAddr { get; set; } = "";
+ public ushort Size { get; set; } = 0;
+
+ [JsonConverter(typeof(StringEnumConverter))]
+ public MemType Type { get; set; } = MemType.ND;
+
+ public List VarList { get; set; } = new List();
+ }
+
+ public class VarConf
+ {
+ public string description { get; set; } = "";
+ public int factor { get; set; } = 1;
+
+ public bool hasRange
+ {
+ get
+ {
+ return !this.minVal.Equals(this.maxVal);
+ }
+ }
+
+ public ushort index { get; set; } = 0;
+ public int maxVal { get; set; } = 0;
+ public string memAddr { get; set; } = "";
+ public int minVal { get; set; } = 0;
+ public string name { get; set; } = "none";
+ public ushort size { get; set; } = 0;
+
+ [JsonConverter(typeof(StringEnumConverter))]
+ public DataType tipoMem { get; set; } = DataType.ND;
+
+ public string value { get; set; } = "";
+ }
+ }
+#endif
+
///
/// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect, OPC-UA, ...)
///
diff --git a/IOB-UT-NEXT/packages.config b/IOB-UT-NEXT/packages.config
index 70c5455c..3ad1f452 100644
--- a/IOB-UT-NEXT/packages.config
+++ b/IOB-UT-NEXT/packages.config
@@ -1,6 +1,6 @@

-
+
diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs
index d319f5b8..4af037c8 100644
--- a/IOB-WIN-NEXT/AdapterForm.cs
+++ b/IOB-WIN-NEXT/AdapterForm.cs
@@ -1186,6 +1186,16 @@ namespace IOB_WIN_NEXT
start.Enabled = true;
break;
+ case tipoAdapter.MODBUS_TCP:
+ iobObj = new IobModbusTCP(this, IOBConf);
+ start.Enabled = true;
+ break;
+
+ case tipoAdapter.MODBUS_TCP_HAM:
+ iobObj = new IobModbusTCPHam(this, IOBConf);
+ start.Enabled = true;
+ break;
+
case tipoAdapter.MTConnect:
iobObj = new IobMTC(this, IOBConf);
start.Enabled = true;
diff --git a/IOB-WIN-NEXT/AdapterForm.cs.bak b/IOB-WIN-NEXT/AdapterForm.cs.bak
deleted file mode 100644
index 3fd42bdd..00000000
--- a/IOB-WIN-NEXT/AdapterForm.cs.bak
+++ /dev/null
@@ -1,1783 +0,0 @@
-using IOB_UT_NEXT;
-using MapoSDK;
-using Newtonsoft.Json;
-using NLog;
-using NLog.Config;
-using NLog.Targets;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Drawing;
-using System.IO;
-using System.Threading;
-using System.Windows.Forms;
-
-namespace IOB_WIN_NEXT
-{
- public partial class AdapterForm : Form
- {
- #region Protected Fields
-
- ///
- /// contatore veloce
- ///
- protected int fastCount;
-
- ///
- /// Data-Ora prima apertura FORM...
- ///
- protected DateTime firstStart;
-
- ///
- /// Oggetto ultimo inviato stato IOB x REDIS
- ///
- protected IobWinStatus lastIobStatus = new IobWinStatus();
-
- ///
- /// Oggetto ultimo inviato stato MP-IO x REDIS
- ///
- protected ServerMpStatus lastSrvStatus = new ServerMpStatus();
-
- ///
- /// ultimo tentativo riavvio...
- ///
- protected DateTime lastStartTry;
-
- ///
- /// contatore normale
- ///
- protected int normCount;
-
- ///
- /// Contatore campionamento memoria
- ///
- protected int sampleMemCount;
-
- ///
- /// contatore lento
- ///
- protected int slowCount;
-
- ///
- /// contatore sync allarmi
- ///
- protected int verySlowCount;
-
- ///
- /// Temnpo attesa std in MS
- ///
- protected int waitRecMSec = 30000;
-
- #endregion Protected Fields
-
- #region Public Fields
-
- ///
- /// oggetto logging
- ///
- public static Logger lg;
-
- ///
- /// Modello macchina
- ///
- public string curModel = "";
-
- ///
- /// Vendor macchina
- ///
- public string curVendor = "";
-
- ///
- /// configurazione caricata
- ///
- public IobConfiguration IOBConf;
-
- ///
- /// Oggetto x gestione dell'adapter GENERICO (x poter usare metodi di ognuno...)
- ///
- public IobGeneric iobObj;
-
- ///
- /// tipo di adapter prescelto...
- ///
- public tipoAdapter tipoScelto = tipoAdapter.SIMULA;
-
- #endregion Public Fields
-
- #region Public Constructors
-
- ///
- /// Avvio MainForm
- ///
- ///
- public AdapterForm(string codIOB)
- {
- CurrIOB = codIOB;
- // continuo avvio...
- InitializeComponent();
- myGraphInitForm();
-
- checkEditMes2Plc();
-
- // inizializzo orologi
- firstStart = DateTime.Now;
- lastStartTry = DateTime.Now;
-
- initDatamonitor();
-
- waitRecMSec = utils.CRI("waitRecMSec");
-
- LogManager.ReconfigExistingLoggers();
-
- lg = LogManager.GetCurrentClassLogger();
- displayTaskAndLog("MainForm 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(string.Format("Main timer set: {0}ms", gather.Interval));
-
- // Start timer periodico interfaccia
- displTimer.Interval = utils.CRI("timerIntMs");
- displTimer.Enabled = true;
-
- displayTaskAndLog("Program Running");
-
- // check oggetto not null
- if (iobObj != null)
- {
- try
- {
- // verifico server online...
- if (iobObj.checkServerAlive)
- {
- // segnalo reboot (programma)...
- IobGeneric.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");
- }
-
- #endregion Public Constructors
-
- #region Private Delegates
-
- private delegate void SafeCallDelegate(string text);
-
- #endregion Private Delegates
-
- #region Protected Properties
-
- ///
- /// Valore protected comunicazione PLC
- ///
- protected bool _commPlcActive { get; set; } = false;
-
- ///
- /// Valore protetto stato comunicazione
- ///
- protected int _commSrvActive { get; set; } = 0;
-
- ///
- /// Valore protected semaforo IN
- ///
- protected Semaforo _sIN { get; set; } = Semaforo.ND;
-
- ///
- /// Valore protected semaforo OUT
- ///
- protected Semaforo _sOUT { get; set; } = Semaforo.ND;
-
- ///
- /// Codice IOB della macchina cui connettersi (x scegliere corretto file di conf...)
- ///
- protected string CurrIOB { get; set; }
-
- protected int delayShowLogMs { get; set; } = utils.CRI("delayShowLogMs");
-
- ///
- /// Dictionary dei divieti del datamonitor
- ///
- protected Dictionary dMonDisplVetoVeto { get; set; } = new Dictionary();
-
- ///
- /// array degli oggetti datamonitor da mostrare
- ///
- protected Dictionary dMonValues { get; set; } = new Dictionary();
-
- ///
- /// Veto a NUOVE scritture in COUNTER...
- ///
- protected DateTime logCounterVeto { get; set; } = DateTime.Now;
-
- ///
- /// Stringa corrente di log...
- ///
- protected string logWatchString { get; set; } = "";
-
- ///
- /// Veto a NUOVE scritture in logWatch...
- ///
- 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 qAlLen { get; set; }
-
- protected int qEvLen { get; set; }
-
- protected int qFlLen { get; set; }
-
- protected int qMsLen { get; set; }
-
- protected int totQueue
- {
- get
- {
- return qEvLen + qFlLen + qAlLen + qMsLen;
- }
- }
-
- #endregion Protected Properties
-
- #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;
- }
- }
-
- ///
- /// Visualizzazione stato di comunicazione attiva con PLC
- ///
- public bool commPlcActive
- {
- get
- {
- return _commPlcActive;
- }
- set
- {
- _commPlcActive = value;
- // se true --> comunica/verde, altrimenti grigio
- lblCNC.ForeColor = value ? Color.SeaGreen : Color.Black;
- statusStrip1.Refresh();
- }
- }
-
- ///
- /// Visualizzazione stato di comunicazione attiva con PLC:
- /// 0 = NO PING
- /// 1 = PING OK
- /// 2 = IOB enabled
- ///
- 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;
- }
- }
-
- ///
- /// Stringa dati monitoraggio mostrata (1 SX)...
- ///
- public string dataMonitor_0
- {
- get
- {
- return dMonValues[0];
- }
- set
- {
- DateTime adesso = DateTime.Now;
- // salvo nell'array...
- dMonValues[0] = value;
- if (dMonDisplVetoVeto[0] < adesso)
- {
- // se scaduto veto --> display!
- lblRawData.Text = value;
- // update veto!
- dMonDisplVetoVeto[0] = adesso.AddMilliseconds(delayShowLogMs);
- }
- }
- }
-
- ///
- /// Stringa dati monitoraggio mostrata (1 SX)...
- ///
- public string dataMonitor_1
- {
- get
- {
- return dMonValues[1];
- }
- set
- {
- DateTime adesso = DateTime.Now;
- // salvo nell'array...
- dMonValues[1] = value;
- if (dMonDisplVetoVeto[1] < adesso)
- {
- // se scaduto veto --> display!
- lblOutMessage.Text = value;
- // update veto!
- dMonDisplVetoVeto[1] = adesso.AddMilliseconds(delayShowLogMs);
- }
- }
- }
-
- ///
- /// Stringa dati monitoraggio mostrata (2 centro)...
- ///
- public string dataMonitor_2
- {
- get
- {
- return dMonValues[2];
- }
- set
- {
- DateTime adesso = DateTime.Now;
- // salvo nell'array...
- dMonValues[2] = value;
- if (dMonDisplVetoVeto[2] < adesso)
- {
- // se scaduto veto --> display!
- lblOutMessage2.Text = value;
- // update veto!
- dMonDisplVetoVeto[2] = adesso.AddMilliseconds(delayShowLogMs);
- }
- }
- }
-
- ///
- /// Stringa dati monitoraggio mostrata (3 dx)...
- ///
- public string dataMonitor_3
- {
- get
- {
- return dMonValues[3];
- }
- set
- {
- DateTime adesso = DateTime.Now;
- // salvo nell'array...
- dMonValues[3] = value;
- if (dMonDisplVetoVeto[3] < adesso)
- {
- // se scaduto veto --> display!
- lblOutMessage3.Text = value;
- // update veto!
- dMonDisplVetoVeto[3] = adesso.AddMilliseconds(delayShowLogMs);
- }
- }
- }
-
- ///
- /// label del numero di record processati (libera)
- ///
- public string dataProcLabel
- {
- get
- {
- return lblDataProc.Text;
- }
- set
- {
- lblDataProc.Text = value;
- }
- }
-
- ///
- /// File configurazione default
- ///
- 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;
- }
- }
-
- ///
- /// Log verboso da configurazione (SOLO CHAIVE "verbose"...
- ///
- public bool isVerboseLog { get; set; } = utils.CRB("verbose");
-
- ///
- /// Logwatcher (in modalità "accodamento in testa" ultimi messaggi...)
- ///
- public string logWatcher
- {
- get
- {
- return lblLogfile.Text;
- }
- set
- {
- try
- {
- logWatchString = limitLine2show($"{value}{Environment.NewLine}{logWatchString}");
- DateTime adesso = DateTime.Now;
- if (logWatchWriteVeto < adesso)
- {
- this.UIThread(delegate
- {
- lblLogfile.Text = 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 FLog di {value} record");
- }
- else
- {
- maxMsQueue--;
- maxMsQueue = maxMsQueue < qMsLen ? qMsLen : maxMsQueue;
- }
- }
- get
- {
- return qMsLen;
- }
- }
-
- ///
- /// Numero max linee da mostrare (da controllo)...
- ///
- public int nLine2show
- {
- get
- {
- int answ = 5;
- try
- {
- Int32.TryParse(nLines.Text, out answ);
- }
- catch
- { }
- return answ;
- }
- set
- {
- nLines.Text = value.ToString();
- }
- }
-
- ///
- /// Imposta COLORE SFONDO x Semaforo IN
- ///
- public Semaforo sIN
- {
- get
- {
- return _sIN;
- }
- set
- {
- _sIN = value;
- var newColor = decSemaforo(value);
- if (newColor != bIN.BackColor)
- {
- bIN.BackColor = newColor;
- bIN.Refresh();
- }
- }
- }
-
- ///
- /// Imposta COLORE SFONDO x Semaforo OUT
- ///
- public Semaforo sOUT
- {
- get
- {
- return _sOUT;
- }
- set
- {
- _sOUT = value;
- var newColor = decSemaforo(value);
- if (newColor != bOUT.BackColor)
- {
- bOUT.BackColor = newColor;
- bOUT.Refresh();
- }
- }
- }
-
- ///
- /// Task watcher (in modalità "accodamento in testa" ultimi messaggi...)
- ///
- public string taskWatcher
- {
- get
- {
- return lblTaskLog.Text;
- }
- set
- {
- try
- {
- lblTaskLog.Text = limitLine2show($"{value}{Environment.NewLine}{lblTaskLog.Text}");
- lblTaskLog.Refresh();
- }
- catch (Exception exc)
- {
- lgError($"Errore in esecuzione taskWatcher{Environment.NewLine}--> {value}");
- if (isVerboseLog)
- {
- lgError($"{exc}");
- }
- }
- }
- }
-
- #endregion Public Properties
-
- #region Private Methods
-
- 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 forcedTask = new Dictionary();
- // 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 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();
- }
-
- ///
- /// Chiusura adapter
- ///
- private void closeAdapter()
- {
- fermaTutto(true, false, true, false);
- }
-
- private void displTimer_Tick(object sender, EventArgs e)
- {
- }
-
- ///
- /// Ferma tutti i componenti adapter + update buttons
- ///
- /// indica se fermare il timer (gather) principale (solo se non si chiude)
- /// indica se tentare di riconnettersi
- /// indica se sia richeisto di SVUOTARE le code delel info
- /// indica se si debba aggiornare la form (no se si sta chiudendo...)
- private void fermaTutto(bool stopTimer, bool tryRestart, bool forceDequeue, bool updateForm)
- {
- 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;
- iobObj.tryDisconnect();
- }
-
- newDisplayData currDispData = new newDisplayData();
- currDispData.semIn = Semaforo.SS;
- currDispData.semOut = Semaforo.SS;
- if (updateForm)
- {
- updateFormDisplay(currDispData);
- }
- }
-
- 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 parametri = new List();
- 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
- {
- DateTime dtVeto = lastStartTry.AddMilliseconds(waitRecMSec);
- 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));
- }
- }
- }
-
- ///
- /// Init oggetti datamonitor
- ///
- private void initDatamonitor()
- {
- for (int i = 0; i < 4; i++)
- {
- dMonDisplVetoVeto.Add(i, DateTime.Now);
- dMonValues.Add(i, "");
- }
- }
-
- ///
- /// GEstione evento refresh
- ///
- ///
- ///
- private void IobObj_eh_refreshed(object sender, iobRefreshedEventArgs e)
- {
- // aggiorno!
- updateFormDisplay(e.DisplayDataObject);
- }
-
- ///
- /// Carica file ini della configurazione richiesta
- ///
- ///
- 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)
- {
- lgError($"Eccezione in conversione tipo adapter: richiesto un tipo non codificato...{Environment.NewLine}{exc}");
- tipoScelto = tipoAdapter.ND;
- }
- // carivo vettore parametri opzionai
- Dictionary optParRead = new Dictionary();
- 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]);
- }
- lgInfo($"Caricati {optParRead.Count} parametri opzionali da OPTPAR");
- }
- catch (Exception exc)
- {
- lgError(string.Format("EXCEPTION in fase di lettura OPTPAR: {0}{1}", Environment.NewLine, exc));
- }
- }
- // inizializzio conf IOB
- IOBConf = new IobConfiguration
- {
- pingMsTimeout = fIni.ReadInteger("IOB", "PING_MS_TIMEOUT", 500),
- vendor = curVendor,
- model = curModel,
- tipoIob = tipoScelto,
- optPar = optParRead,
- versIOB = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(),
- codIOB = CurrIOB,
- cncIpAddr = 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", "/"), fIni.ReadString("SERVER", "CMDBASE", "/"), fIni.ReadString("SERVER", "CMDFLOG", "/"), 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/")),
- 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(".", ","))
- };
- lgInfo($"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
- Directory.CreateDirectory(dirPath);
- // salvataggio
- File.WriteAllText(fullPath, confJson);
-
- loadIobType();
- // avvio macchina con adapter specificato...
- if (utils.CRB("autoStartOnLoad"))
- {
- displayTaskAndLog("Auto Starting...");
- // avvio!
- avviaAdapter(chkForceDequeue.Checked);
- displayTaskAndLog("Auto Started!");
- }
- try
- {
- // segnalo reboot (programma)... metto in coda invio...
- //iobObj.sendToMoonPro(urlType.FLog, "IOB INI Loaded");
- //iobObj.QueueFLog.Enqueue(iobObj.qEncodeFLog("IOB-STATUS", "IOB INI Loaded"));
- }
- catch (Exception exc)
- {
- lgError(string.Format("EXCEPTION in fase di chiamata URL di segnalazione caricamento INI file:{0}{1}", Environment.NewLine, exc));
- }
- }
-
- ///
- /// carica IOB richiesto
- ///
- private void loadIobType()
- {
- if (IOBConf != null)
- {
- switch (tipoScelto)
- {
- case tipoAdapter.SIMULA:
- iobObj = new IobSimula(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.FILE_GEN:
- iobObj = new IobFile(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.FILE_EUROM63:
- iobObj = new IobFileEurom63(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.FANUC:
- iobObj = new IobFanuc(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.KAWASAKI:
- iobObj = new IobKawasaki(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.MTConnect:
- iobObj = new IobMTC(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.OMRON:
- iobObj = new IobOmron(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.OpcUa:
- iobObj = new IobOpcUa(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.OpcUaEwon:
- iobObj = new IobOpcUaEwon(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.OSAI_OPEN:
- case tipoAdapter.OSAI_CNDEX:
- case tipoAdapter.OSAI_VB6:
- // versione CVCncLib
- iobObj = new IobOSAI(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS:
- iobObj = new IobSiemens(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_APROCHIM:
- iobObj = new IobSiemensAprochim(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_AT2001:
- iobObj = new IobSiemensAt2001(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_COMUR:
- iobObj = new IobSiemensComur(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_FAPE:
- iobObj = new IobSiemensFape(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_INGENIA:
- iobObj = new IobSiemensIngenia(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_LASCO:
- iobObj = new IobSiemensLasco(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_PRESSOIL_CEI:
- iobObj = new IobSiemensPressoilCei(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_SAET:
- iobObj = new IobSiemensSaet(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_SIMEC:
- iobObj = new IobSiemensSimec(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.SIEMENS_TORRI:
- iobObj = new IobSiemensTorri(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.WPS:
- iobObj = new IobWPS(this, IOBConf);
- start.Enabled = true;
- break;
-
- case tipoAdapter.ND:
- default:
- iobObj = new IobSimula(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(string.Format("Caricata conf per adapter {0}", tipoScelto));
- }
- }
-
- ///
- /// Fase chiusura Form
- ///
- ///
- ///
- private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
- {
- closeAdapter();
- }
-
- ///
- /// Completato resize form
- ///
- ///
- ///
- private void MainForm_Resize(object sender, EventArgs e)
- {
- }
-
- ///
- /// Mostrata form
- ///
- ///
- ///
- private void MainForm_Shown(object sender, EventArgs e)
- {
- displayTaskAndLog("Main Form SHOWN (Adapter)");
- }
-
- 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...
- evQueueLen = iobObj.QueueIN.Count;
- flQueueLen = iobObj.QueueFLog.Count;
- alQueueLen = iobObj.QueueAlarm.Count;
- msQueueLen = iobObj.QueueMessages.Count;
- // aggiorno labels counters...
- counterIob = $"pz IOB {iobObj.contapezziIOB}";
- counterMac = $"pz PLC {iobObj.contapezziPLC}";
- // verifico IOB status
- IobWinStatus currIobStatus = new IobWinStatus()
- {
- CodIob = iobObj.cIobConf.codIOB,
- queueEvLen = evQueueLen,
- queueFlLen = flQueueLen,
- queueAlLen = alQueueLen,
- queueMsLen = msQueueLen,
- counterIOB = iobObj.contapezziIOB,
- counterMAC = iobObj.contapezziPLC,
- lastUpdate = lastIobStatus.lastUpdate,
- online = utils.IOB_Online,
- lastDataIn = iobObj.lastReadPLC
- };
- // se diverso SALVO!
- if (lastIobStatus.online != currIobStatus.online || lastIobStatus.lastDataIn != currIobStatus.lastDataIn || lastIobStatus.counterIOB != currIobStatus.counterIOB || lastIobStatus.counterMAC != currIobStatus.counterMAC || lastIobStatus.queueEvLen != currIobStatus.queueEvLen || lastIobStatus.queueFlLen != currIobStatus.queueFlLen || lastIobStatus.queueAlLen != currIobStatus.queueAlLen || lastIobStatus.queueMsLen != currIobStatus.queueMsLen)
- {
- // 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;
- }
- }
-
- ///
- /// Button restart
- ///
- ///
- ///
- 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");
- // rileggo INI
- loadIniFile(defConfFilePath);
- displayTaskAndLog("RESTARTING: Ini File Reloaded");
- // faccio start... CON RESET delel code
- avviaAdapter(true);
- displayTaskAndLog("RESTARTING: Adapter Started");
- // resetto i data monitor...
- dataMonitor_0 = "";
- dataMonitor_1 = "";
- dataMonitor_2 = "";
- dataMonitor_3 = "";
- }
- }
-
- ///
- /// impostazione valori defaults
- ///
- private void setDefaults()
- {
- stop.Enabled = false;
-
- evQueueLen = 0;
- flQueueLen = 0;
- nLine2show = utils.CRI("numRowConsole");
- }
-
- private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
- {
- }
-
- ///
- /// Avvio dell'adapter
- ///
- ///
- ///
- private void start_Click(object sender, EventArgs e)
- {
- avviaAdapter(chkForceDequeue.Checked);
- // salvo che ho avviato adapter
- lgInfo("Completato LOAD Adapter");
- }
-
- ///
- /// fermata dell'adapter
- ///
- ///
- ///
- 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();
- }
-
- #endregion Private Methods
-
- #region Protected Methods
-
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
-
- ///
- /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
- ///
- ///
- 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);
- }
- }
- }
-
- ///
- /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
- ///
- ///
- 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);
- }
-
- ///
- /// Init form (grafica) con helper x testi e varie
- ///
- 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");
- }
-
- ///
- /// MOstra info su coda complessiva
- ///
- protected void showQueueData()
- {
- lblQueueLenTop.Text = totQueue == 0 ? "realtime" : $"ev: {qEvLen} | flog: {qFlLen} | tot: {totQueue}";
- }
-
- #endregion Protected Methods
-
- #region Public Methods
-
- ///
- /// Decodifica colore da valore semaforico
- ///
- ///
- ///
- 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;
- }
-
- ///
- /// Avvio l'adapter
- ///
- /// indica se sia richeisto di SVUOTARE le code delel info
- public void avviaAdapter(bool resetQueue)
- {
- displayTaskAndLog("Adapter starting");
- // 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");
- // inizializzo contatori fast/mid/slow
- fastCount = utils.CRI("fastCount");
- normCount = utils.CRI("normCount");
- slowCount = utils.CRI("slowCount");
- verySlowCount = utils.CRI("verySlowCount");
- displayTaskAndLog("Adapter Running...");
- // init max queue
- maxEvQueue = 1;
- maxFlQueue = 1;
-
- try
- {
- // segnalo reboot (programma)...
- iobObj.QueueFLog.Enqueue(iobObj.qEncodeFLog("IOB-STATUS", "IOB 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...");
- }
- }
-
- ///
- /// mostra un testo sulla status bar + LOG
- ///
- ///
- public void displayTaskAndLog(string txt2show)
- {
- lblStatus.Text = txt2show;
- lblStatus.Invalidate();
- lgInfo(txt2show);
- }
-
- ///
- /// Ferma l'adapter
- ///
- /// determina se si debba tentare riavvio automatico (per caduta connessione)
- /// indica se sia richeisto di SVUOTARE le code delel info
- /// indica se aggiornare la form prima di fermare
- public void fermaAdapter(bool tryRestart, bool forceDequeue, bool updateForm)
- {
- fermaTutto(false, tryRestart, forceDequeue, updateForm);
- }
-
- ///
- /// Effettua un trim della stringa al numero max di linee da mostrare a video
- ///
- ///
- ///
- public string limitLine2show(string newString)
- {
- if (!string.IsNullOrEmpty(newString))
- {
- // se num righe superiore a limite trimmo...
- if (newString.Split('\n').Length > nLine2show)
- {
- //int idx = newString.LastIndexOf('\r');
- int idx = newString.LastIndexOf(Environment.NewLine);
- newString = newString.Substring(0, idx);
- }
- }
- return newString;
- }
-
- ///
- /// Salva su file l'oggetto di persistenza dati
- ///
- ///
- 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
- {
- lgInfo("persistenceLayer null, non salvato...");
- }
- // abbasso semaforo salvataggio
- iobObj.adpSaving = false;
- }
- }
-
- ///
- /// Mostra update delle statistiche di comunicazione (numero chiamate, tempo medio...)
- ///
- ///
- public void updateComStats(string txt2show)
- {
- lblComStats.Text = string.Format("{0} | ", txt2show);
- }
-
- ///
- /// Effettua update form una volta ricevuto OBJ che contiene le varie innovazioni...
- ///
- ///
- 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}");
- }
- if (!string.IsNullOrWhiteSpace(currDispData.newSignalData))
- {
- dataMonitor_1 = limitLine2show($"{currDispData.newSignalData}{Environment.NewLine}{dataMonitor_1}");
- }
- if (!string.IsNullOrWhiteSpace(currDispData.newFLogData))
- {
- dataMonitor_3 = limitLine2show($"{currDispData.newFLogData}{Environment.NewLine}{dataMonitor_3}");
- }
- if (!string.IsNullOrWhiteSpace(currDispData.newUrlCallData))
- {
- dataMonitor_2 = limitLine2show($"{currDispData.newUrlCallData}{Environment.NewLine}{dataMonitor_2}");
- }
-
- // 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
- {
- lblOutMessage3.Text = text;
- });
-
- //if (lblOutMessage3.InvokeRequired)
- //{
- // var d = new SafeCallDelegate(WriteTextSafe);
- // lblOutMessage3.Invoke(d, new object[] { text });
- //}
- //else
- //{
- //}
- }
-
- #endregion Public Methods
- }
-}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
index 6605c424..c04f13d0 100644
--- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
@@ -64,7 +64,9 @@ CLI_INST=SteamWareSim
;STARTLIST=TEST
;STARTLIST=SIMUL_01
;STARTLIST=1032
-STARTLIST=PIZ08
+;STARTLIST=1033
+;STARTLIST=PIZ08
+STARTLIST=PIZ04
;STARTLIST=OPC_UA
MAXCNC=10
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini b/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini
new file mode 100644
index 00000000..b2c6e223
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini
@@ -0,0 +1,70 @@
+;Configurazione IOB-WIN
+[IOB]
+;Impianto HAM per Pizzaferri
+CNCTYPE=MODBUS_TCP_HAM
+PING_MS_TIMEOUT=500
+
+[MACHINE]
+VENDOR=HAM
+MODEL=HAM
+
+[CNC]
+IP=hampizzaferri.dyndns.org
+PORT=502
+
+[SERVER]
+;MPIP=https://localhost:44339
+MPIP=https://gwms.egalware.com
+MPURL=/api
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/IOB/sendReboot?idxMacchina=
+
+[MEMORY]
+ADDR_READ=40001
+ADDR_WRITE=40401
+SIZE_READ=34
+;SIZE_READ=5046
+SIZE_WRITE=358
+
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
+PZCOUNT_MODE=STD.DB85.DBRE16
+DISABLE_PZCOUNT=TRUE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+; GEST DATI DYN
+ENABLE_DYN_DATA=TRUE
+FORCE_DYN_DATA=TRUE
+
+; clock base (da 10ms)
+timerIntMs=100
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=PIZ04.json
+
+NO_PING=FALSE
+; conf aree allarme
+ALARM_CONF=PIZ04_alarm.json
+
+[BRANCH]
+NAME=master
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ04.json b/IOB-WIN-NEXT/DATA/CONF/PIZ04.json
new file mode 100644
index 00000000..4889aa31
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04.json
@@ -0,0 +1,255 @@
+{
+ //"mMapWrite": {
+ // "setProg": {
+ // "name": "setProg",
+ // "description": "Programma",
+ // "tipoMem": "String",
+ // "memAddr": "DB6.DBB50",
+ // "index": 50,
+ // "size": 50
+ // },
+ // "setComm": {
+ // "name": "setComm",
+ // "description": "Commessa",
+ // "tipoMem": "String",
+ // "memAddr": "DB6.DBB0",
+ // "index": 0,
+ // "size": 50
+ // },
+ // "setArt": {
+ // "name": "setArt",
+ // "description": "Articolo",
+ // "tipoMem": "String",
+ // "memAddr": "DB6.DBB100",
+ // "index": 100,
+ // "size": 50
+ // },
+ // "setPzComm": {
+ // "name": "setPzComm",
+ // "description": "Qty",
+ // "memAddr": "DB30.DBB212",
+ // "tipoMem": "DInt",
+ // "index": 212,
+ // "size": 4
+ // }
+ //},
+ "mMapRead": {
+ "Level": {
+ "name": "GiacSerb",
+ "description": "Livello Serbatoio",
+ "memAddr": "40001",
+ "tipoMem": "Real",
+ "index": 1,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 280,
+ "minVal": 0,
+ "maxVal": 100
+ },
+ "MainPress": {
+ "name": "PressSerb",
+ "description": "Pressione Serbatoio",
+ "memAddr": "40003",
+ "tipoMem": "Real",
+ "index": 3,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 25
+ },
+ "PressBH": {
+ "name": "PBH",
+ "description": "Pressione media all’interno dell’accumulo GNC (pacco bombole) di alta pressione",
+ "memAddr": "40019",
+ "tipoMem": "Real",
+ "index": 19,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 400
+ },
+ "PressBL": {
+ "name": "PBM",
+ "description": "Pressione media all’interno dell’accumulo GNC (pacco bombole) di media pressione",
+ "memAddr": "40021",
+ "tipoMem": "Real",
+ "index": 21,
+ "size": 2,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1,
+ "minVal": 0,
+ "maxVal": 400
+ },
+ //"TE2A": {
+ // "name": "TE2A",
+ // "description": "Temperatura Controllo Tenute Pompa A",
+ // "memAddr": "DB85.DBB0",
+ // "tipoMem": "Real",
+ // "index": 0,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE1A": {
+ // "name": "TE1A",
+ // "description": "Temperatura Raffreddamento Pompa A",
+ // "memAddr": "DB85.DBB4",
+ // "tipoMem": "Real",
+ // "index": 4,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE3A": {
+ // "name": "TE3A",
+ // "description": "Temperatura Cavitazione Pompa A",
+ // "memAddr": "DB85.DBB8",
+ // "tipoMem": "Real",
+ // "index": 8,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"Temp01": {
+ // "name": "TE04",
+ // "description": "Temperatura Torcia Aria Fredda",
+ // "memAddr": "DB85.DBB12",
+ // "tipoMem": "Real",
+ // "index": 12,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"Temp02": {
+ // "name": "TT17",
+ // "description": "Temperatura Spurgo Torcia Serbatoio",
+ // "memAddr": "DB85.DBB36",
+ // "tipoMem": "Real",
+ // "index": 36,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE06": {
+ // "name": "TE06",
+ // "description": "Temperatura Uscita Vaporizzatore",
+ // "memAddr": "DB85.DBB40",
+ // "tipoMem": "Real",
+ // "index": 40,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE05": {
+ // "name": "TE05",
+ // "description": "Temperatura Carica Fredda",
+ // "memAddr": "DB85.DBB60",
+ // "tipoMem": "Real",
+ // "index": 60,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE2B ": {
+ // "name": "TE2B",
+ // "description": "Temperatura Controllo Tenute Pompa B",
+ // "memAddr": "DB85.DBB64",
+ // "tipoMem": "Real",
+ // "index": 64,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE1B ": {
+ // "name": "TE1B",
+ // "description": "Temperatura Raffreddamento Pompa B",
+ // "memAddr": "DB85.DBB68",
+ // "tipoMem": "Real",
+ // "index": 68,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"TE3B": {
+ // "name": "TE3B",
+ // "description": "Temperatura Cavitazione Pompa B",
+ // "memAddr": "DB85.DBB72",
+ // "tipoMem": "Real",
+ // "index": 72,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"PressH": {
+ // "name": "PT300A",
+ // "description": "Alta Pressione",
+ // "memAddr": "DB85.DBB120",
+ // "tipoMem": "Real",
+ // "index": 120,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"PressM": {
+ // "name": "PT300M",
+ // "description": "Media Pressione",
+ // "memAddr": "DB85.DBB124",
+ // "tipoMem": "Real",
+ // "index": 124,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"LivelloPerc": {
+ // "name": "LT15%",
+ // "description": "Livello Serbatorio %",
+ // "memAddr": "DB85.DBB148",
+ // "tipoMem": "Real",
+ // "index": 148,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"MinTemp01": {
+ // "name": "MinTempTE04",
+ // "description": "Minima Temperatura Linea Sfiato Gas TE04",
+ // "memAddr": "DB85.DBB152",
+ // "tipoMem": "Real",
+ // "index": 152,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //},
+ //"MinTemp02": {
+ // "name": "MinTempTT17",
+ // "description": "Minima Temperatura Linea Sfiato Gas Torcia Serbatoio TT17",
+ // "memAddr": "DB85.DBB156",
+ // "tipoMem": "Real",
+ // "index": 156,
+ // "size": 4,
+ // "func": "MAX",
+ // "period": 60,
+ // "factor": 1
+ //}
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ04_alarm.json b/IOB-WIN-NEXT/DATA/CONF/PIZ04_alarm.json
new file mode 100644
index 00000000..2b51df57
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04_alarm.json
@@ -0,0 +1,125 @@
+[
+ //{
+ // "description": "Allarmi Impianto",
+ // "tipoMem": "Boolean",
+ // "memAddr": "DB85.DBB232",
+ // "index": 232,
+ // "size": 6,
+ // "messages": [
+ // "Emergenza Non Ripristinata",
+ // "Emergenza QE Intervenuta",
+ // "Emergenza Puls. Dispencer B Invervenuta",
+ // "Emergenza Puls. Dispencer A Invervenuta",
+ // "Stato Interruttore Erogatore Liquido B",
+ // "Allarme Controllo Tensione di Rete",
+ // "Allarme Controllo Tensione Antincendio",
+ // "Stato Interruttore Erogatore Liquido A",
+ // "Stato Sezionatore Generale",
+ // "Stato Interruttore Protezione SPD",
+ // "Stato Interruttore Sirena e Rotoalarm",
+ // "Stato Interruttore Luci Emergenza",
+ // "Stato Interruttore Pompa PC1A",
+ // "Stato Interruttore Pompa PC1B",
+ // "Stato Interruttore Pompa Sommersa C",
+ // "Stato Termica Boil-Off",
+ // "##234.0",
+ // "Preallarme Centralina Metano",
+ // "Allarme Centralina Metano",
+ // "Emergenza Puls. Dispencer C Invervenuta",
+ // "Mancaza Pressione Aria",
+ // "Minima Temperatura Linea Sfiato Gas TE04",
+ // "Minima Temperatura Linea Sfiato Gas Torcia Serbatoio TT17",
+ // "Massima Temperatura Linea Sfiato Gas Torcia Serbatoio TT17",
+ // "Almeno Un Emergenza Intervenuta",
+ // "Arresto Operativo da PT1(predisposizione)",
+ // "Stato Interruttore Alimentazione Punto Zero",
+ // "##234.11",
+ // "##234.12",
+ // "##234.13",
+ // "##234.14",
+ // "Configurazione Incongruente",
+ // "Pulsante Emergenza 2 SB17.3A Premuto",
+ // "Pulsante Emergenza 1 SB17.3B Premuto",
+ // "Pulsante Emergenza SB17.3C Premuto",
+ // "Pulsante Emergenza 3 SB17.5 Premuto",
+ // "Pulsante Emergenza 4 SB17.7 Premuto",
+ // "##236.5",
+ // "##236.6",
+ // "##236.7",
+ // "GT_TE2A",
+ // "GT_TE1A",
+ // "GT_TE3A",
+ // "GT_TE04",
+ // "GT_LT15",
+ // "GT_PT01",
+ // "GT_PT300R",
+ // "GT_PT16"
+ // ]
+ //},
+ //{
+ // "description": "Allarmi Serbatoio",
+ // "tipoMem": "Boolean",
+ // "memAddr": "DB85.DBB248",
+ // "index": 248,
+ // "size": 2,
+ // "messages": [
+ // "Serbatoio Troppo Pieno",
+ // "Serbatoio Pieno_HH",
+ // "Serbatoio Pieno_H",
+ // "Serbatoio Vuoto_LL",
+ // "H Pressione Serbatoio",
+ // "HH Pressione Serbatoio",
+ // "LL Temperatura Ingresso BoilOff TE08",
+ // "Minima Pressione Serbatoio per Partenza Pompe",
+ // "Timeout Apertura Valvola PV1",
+ // "Timeout Chiusura Valvola PV1",
+ // "Timeout Apertura Valvola PV70",
+ // "Timeout Chiusura Valvola PV70",
+ // "##248.12",
+ // "##248.13",
+ // "##248.14",
+ // "##248.15"
+ // ]
+ //},
+ //{
+ // "description": "Allarmi Pompa Alta Pressione A",
+ // "tipoMem": "Boolean",
+ // "memAddr": "DB85.DBB252",
+ // "index": 252,
+ // "size": 4,
+ // "messages": [
+ // "Ritardo Avvio Pompa PC1B",
+ // "##252.1",
+ // "Temperatura Freddo TE1B NON Raggiunta",
+ // "HH Temperatura Cavitazione TE3B",
+ // "Allarme Temperatura Tenute Pompa TE2B",
+ // "LL Temperatura Ingresso Stoccaggio TE06",
+ // "Allarme Temperatura Ingresso Stoccaggio TE07",
+ // "Aumento Pressione PT01",
+ // "##Max Pressione PT01",
+ // "##256.9",
+ // "##256.10",
+ // "##256.11",
+ // "##256.12",
+ // "##256.13",
+ // "##256.14",
+ // "##256.15",
+ // "Timeout Apertura PV3B",
+ // "Timeout Apertura PV5B",
+ // "Timeout Apertura PV6B",
+ // "Timeout Apertura PV7",
+ // "##258.4",
+ // "##258.5",
+ // "##258.6",
+ // "##258.7",
+ // "##258.8",
+ // "##258.9",
+ // "##258.10",
+ // "##258.11",
+ // "##258.12",
+ // "##258.13",
+ // "##258.14",
+ // "##258.15"
+ // ]
+ //}
+]
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/DATA/CONF/VL22.ini b/IOB-WIN-NEXT/DATA/CONF/VL22.ini
index 567d968e..ea000363 100644
--- a/IOB-WIN-NEXT/DATA/CONF/VL22.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/VL22.ini
@@ -67,6 +67,8 @@ MAX_SEND_PZC_BLOCK=100
;GESTIONE DATI DYN
ENABLE_DYN_DATA=TRUE
FORCE_DYN_DATA=TRUE
+; gestione scrittura string/char[]: true = string / false = char[]
+WRITE_PRE=TRUE
USE_NEW_EXE_TASK=TRUE
; conf parametri memoria READ/WRITE
diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
index ffe9e62b..ddcbb005 100644
--- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
+++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
@@ -83,12 +83,15 @@
..\CncLib\ExtLib\CndexLinkDotNet.dll
+
+ ..\packages\EasyModbusTCP.5.6.0\lib\net40\EasyModbus.dll
+
False
ExtLib\krcc.dll
-
- ..\packages\MapoSDK.6.13.2105.1421\lib\net40\MapoSDK.dll
+
+ ..\packages\MapoSDK.6.14.2109.2809\lib\net40\MapoSDK.dll
..\packages\MTConnect.NET.2.9.1.28314\lib\net40\MTConnect-NET.dll
@@ -97,7 +100,7 @@
..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
- ..\packages\NLog.4.7.9\lib\net45\NLog.dll
+ ..\packages\NLog.4.7.11\lib\net45\NLog.dll
..\packages\OmronFinsTCP.Net.3.0.0.0\lib\net40\OmronFinsTCP.Net.dll
@@ -172,6 +175,8 @@
+
+
@@ -347,12 +352,21 @@
Always
+
+ Always
+
+
+ Always
+
Always
Always
+
+ Always
+
Always
diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs
index 52ed95d7..054dde52 100644
--- a/IOB-WIN-NEXT/IobGeneric.cs
+++ b/IOB-WIN-NEXT/IobGeneric.cs
@@ -536,8 +536,17 @@ namespace IOB_WIN_NEXT
address = IPAddress.Loopback;
int maxRetry = maxPingRetry + 1;
int numRetry = 1; ;
- string ipAdrr = cIobConf.serverData.MPIP.Replace($"{cIobConf.serverData.TRANSP}://", "");
- IPAddress.TryParse(ipAdrr, out address);
+ string ipAddr = cIobConf.serverData.MPIP.Replace($"{cIobConf.serverData.TRANSP}://", "");
+ IPAddress.TryParse(ipAddr, out address);
+ // se null --> provo DNS...
+ if (address == null)
+ {
+ var rawAddresses = Dns.GetHostAddresses(ipAddr);
+ if (rawAddresses.Length > 0)
+ {
+ address = rawAddresses[0];
+ }
+ }
try
{
// se != null --> uso address...
@@ -557,12 +566,12 @@ namespace IOB_WIN_NEXT
// se ho timeout riprovo...
while (reply.Status != IPStatus.Success && numRetry < maxRetry)
{
- lgInfo($"Ping KO | reply: {reply.Status} --> retry");
+ lgInfo($"Server Ping KO | reply: {reply.Status} --> retry");
reply = pingSender.Send(address, pingServerMsTimeout * numRetry / 2);
numRetry++;
if (reply.Status == IPStatus.Success)
{
- lgInfo("PING OK!");
+ lgInfo("Server PING OK!");
break;
}
}
@@ -4072,7 +4081,8 @@ namespace IOB_WIN_NEXT
{ }
///
- /// Effettua processing del recupero delle speed (RPM, feedrate) degli assi
+ /// Effettua processing del recupero dei valori dinamici:
+ /// es: speed (RPM, feedrate) degli assi, valori pressioni, temeprature
///
public void processDynData()
{
diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs
new file mode 100644
index 00000000..01ba2870
--- /dev/null
+++ b/IOB-WIN-NEXT/IobModbusTCP.cs
@@ -0,0 +1,1246 @@
+using EasyModbus;
+using IOB_UT_NEXT;
+using MapoSDK;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace IOB_WIN_NEXT
+{
+ /* --------------------------------------------------------------------------------
+ * Controlli ModBusTCP COMECA
+ * - protocollo ModBus TCP
+ *
+ * -------------------------------------------------------------------------------- */
+
+ public class IobModbusTCP : IobGeneric
+ {
+ #region Protected Fields
+
+ protected ModbusClient currPLC;
+
+ ///
+ /// Ultimo controllo ping x evitare ping flood...
+ ///
+ protected DateTime lastPingConn = DateTime.Now.AddMinutes(-10);
+
+ ///
+ /// Esito ultimo ping
+ ///
+ protected bool lastPingOk = false;
+
+ ///
+ /// Setup blocchi memorie read (indirizzo inizio, size)
+ ///
+ protected Dictionary memSetR = new Dictionary();
+
+ ///
+ /// Setup blocchi memorie write (indirizzo inizio, size)
+ ///
+ protected Dictionary memSetW = new Dictionary();
+
+ ///
+ /// parametri di connessione
+ ///
+ protected connParamModBusTCP parametri;
+
+ ///
+ /// Oggetto cronometro x test vari...
+ ///
+ protected Stopwatch sw = new Stopwatch();
+
+ #endregion Protected Fields
+
+ #region Public Constructors
+
+ /// Classe base con i metodi x ModBusTCP
+ ///
+ ///
+ ///
+ public IobModbusTCP(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("NEW IOB ModBus TCP");
+ setupMemBlocks();
+ memMap = new plcMemMap();
+ if (IOBConf != null)
+ {
+ // gestione invio ritardato contapezzi
+ pzCountDelay = utils.CRI("pzCountDelay");
+ lastPzCountSend = DateTime.Now;
+ lastWarnODL = DateTime.Now;
+ // inizializzo parametri...
+ parametri = new connParamModBusTCP()
+ {
+ ipAdrr = "127.0.0.1",
+ port = 502,
+ pingMsTimeout = IOBConf.pingMsTimeout,
+ memAddrRead = "40001",
+ memAddrWrite = "41001",
+ memSizeRead = 0,
+ memSizeWrite = 0
+ };
+ setParamPlc();
+
+ // salvo info su conf IOB...
+ string iobConfSer = "";
+ try
+ {
+ iobConfSer = JsonConvert.SerializeObject(IOBConf, Formatting.Indented);
+ }
+ catch
+ { }
+ // finito!
+ lgInfo($"Init IOB, con {iobConfSer}");
+ }
+ else
+ {
+ lgError("Impossibile avviare, IOBConf nullo/non valido!");
+ }
+ }
+
+ #endregion Public Constructors
+
+ #region Protected Properties
+
+ ///
+ /// Dizionario delle ultime operazioni di scrittura per OGNI memoria (in modo che fa log ogni x sec...)
+ ///
+ protected Dictionary lastMemWrite { get; set; } = new Dictionary();
+
+ #endregion Protected Properties
+
+ #region Private Methods
+
+ private static int getScaledInt(dataConf currMem)
+ {
+ int valInt;
+ // prima faccio eventuale fattore di scala...
+ int.TryParse(currMem.value, out valInt);
+ if (currMem.factor > 1)
+ {
+ valInt = valInt * currMem.factor;
+ }
+
+ return valInt;
+ }
+
+ private static uint getScaledUInt(dataConf currMem)
+ {
+ uint valUInt;
+ // prima faccio eventuale fattore di scala...
+ uint.TryParse(currMem.value, out valUInt);
+ if (currMem.factor > 1)
+ {
+ valUInt = valUInt * (uint)currMem.factor;
+ }
+
+ return valUInt;
+ }
+
+ ///
+ /// Verifica SE sia il caso di fare il log della memoria indicata
+ ///
+ ///
+ ///
+ private void maybeLogWrite(string memAddrWrite, string logValue)
+ {
+ bool doWrite = true;
+ DateTime adesso = DateTime.Now;
+ if (!lastMemWrite.ContainsKey(memAddrWrite))
+ {
+ lastMemWrite.Add(memAddrWrite, adesso.AddMinutes(-1));
+ }
+ // ora mi leggo valore ultimas crittura e confronto con adesso
+ try
+ {
+ doWrite = (lastMemWrite[memAddrWrite].AddSeconds(vetoSeconds) < adesso);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in maybeLogWrite{Environment.NewLine}{exc}");
+ }
+ // se encessario --> LOG!
+ if (doWrite)
+ {
+ lgInfo(logValue);
+ lastMemWrite[memAddrWrite] = adesso;
+ }
+ }
+
+ #endregion Private Methods
+
+ #region Protected Methods
+
+ ///
+ /// Decodifica il resto dell'area x i dati accessori (allarmi, ...)
+ ///
+ protected virtual void decodeOtherData()
+ {
+ }
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO/GWMS
+ /// - per lo scopo specifico IN REALTA' non conta lo stato macchina.... ma lo inviamo lo stesso
+ ///
+ protected virtual void decodeToBaseBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+ }
+
+ ///
+ /// Override metodo x scrittura parametri su PLC
+ ///
+ ///
+ protected override void plcWriteParams(ref List updatedPar)
+ {
+#if false
+ dataConf currMem = null;
+ int byteSize = 0;
+ byte[] MemBlock = new byte[1];
+ string memAddrWrite = "";
+ bool fatto = false;
+ string serObj = "";
+ if (updatedPar != null)
+ {
+ // controllo i parametri... ne gestisco 4...
+ foreach (var item in updatedPar)
+ {
+ try
+ {
+ memAddrWrite = "";
+ int valInt = 0;
+ uint valUInt = 0;
+ // cerco in area memMapWrite...
+ if (memMap.mMapWrite.ContainsKey(item.uid))
+ {
+ // recupero!
+ currMem = memMap.mMapWrite[item.uid];
+ byteSize = currMem.size;
+ memAddrWrite = currMem.memAddr;
+ MemBlock = new byte[byteSize];
+ // faccio preliminarmente upsertKey...
+ upsertKey(currMem.name, currMem.value);
+ serObj = JsonConvert.SerializeObject(item, Formatting.Indented);
+ lgInfo($"Inizio processing plcWriteParams per {currMem.name} | valore richiesto {currMem.value}{Environment.NewLine}---------------UPDATED PARAM---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
+ serObj = JsonConvert.SerializeObject(currMem, Formatting.Indented);
+ lgInfo($"---------------MEMORY CONTENT---------------{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
+ switch (currMem.tipoMem)
+ {
+ case plcDataType.Boolean:
+ break;
+
+ case plcDataType.Int:
+ valInt = getScaledInt(currMem);
+ saveIntOnMemBlock(ref MemBlock, 0, valInt.ToString());
+ break;
+
+ case plcDataType.DInt:
+ valInt = getScaledInt(currMem);
+ saveDIntOnMemBlock(ref MemBlock, 0, valInt.ToString());
+ break;
+
+ case plcDataType.Word:
+ valUInt = getScaledUInt(currMem);
+ saveWordOnMemBlock(ref MemBlock, 0, valInt.ToString());
+ break;
+
+ case plcDataType.DWord:
+ valUInt = getScaledUInt(currMem);
+ saveDWordOnMemBlock(ref MemBlock, 0, valInt.ToString());
+ break;
+
+ case plcDataType.Real:
+ saveRealOnMemBlock(ref MemBlock, 0, currMem.value);
+ break;
+
+ case plcDataType.String:
+ // se ho writePre --> "allungo" di 2 la dimensione della stringa x MemBlock...
+ if (writePre)
+ {
+ MemBlock = new byte[byteSize + 2];
+ }
+ saveStringOnMemBlock(ref MemBlock, 0, currMem.size, currMem.value);
+ break;
+
+ default:
+ break;
+ }
+ lgInfo($"---------------MemBlock data---------------{Environment.NewLine}{BitConverter.ToString(MemBlock)}{Environment.NewLine}--------------- END data ---------------");
+ if (!string.IsNullOrEmpty(memAddrWrite))
+ {
+ // scrivo su ModBusTCP
+ fatto = S7WriteBB(ref MemBlock, memAddrWrite);
+ // se fatto --> aggiorno!
+ if (fatto)
+ {
+ item.value = item.reqValue;
+ item.reqValue = "";
+ item.lastRead = DateTime.Now;
+ }
+ // se configurato faccio verifica write...
+ if (getOptPar("WRITE_CHECK") == "TRUE")
+ {
+ byte[] MemBlockRead = new byte[MemBlock.Length];
+ S7ReadBB(ref MemBlockRead, memAddrWrite, MemBlock.Length);
+ // se non corrispondessero loggo!
+ if (!MemBlock.SequenceEqual(MemBlockRead))
+ {
+ lgError($"Errore: mancata corrispondenza tra dati scritti e letti:{Environment.NewLine}Write: {BitConverter.ToString(MemBlock)}{Environment.NewLine}read: {BitConverter.ToString(MemBlockRead)}");
+ }
+ else
+ {
+ lgInfo($"Scrittura corretta: {BitConverter.ToString(MemBlockRead)}");
+ }
+ }
+ }
+ else
+ {
+ lgInfo($"Errore: memAddrWrite vuoto!");
+ }
+ }
+ else
+ {
+ lgInfo($"Errore uid non trovato in area write memory: {item.uid}, ci sono {memMap.mMapWrite.Count} in area write");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in fase di plcWriteParams per item {item.uid} con valore {item.value}{Environment.NewLine}{exc}");
+ }
+ }
+ }
+#endif
+ }
+
+ ///
+ /// Imposto parametri PLC
+ ///
+ protected override void setParamPlc()
+ {
+ // Creo oggetto connessione NC
+ parentForm.commPlcActive = true;
+ lgInfo($"Start init Adapter ModBus TCP all'IP {cIobConf.cncIpAddr} | port: {cIobConf.cncPort} | --> IOB {cIobConf.codIOB}");
+ // SE è necessario refresh...
+ if (needRefresh)
+ {
+ lgInfo("Refreshing connection...");
+ if (parametri != null)
+ {
+ try
+ {
+ parametri.ipAdrr = cIobConf.cncIpAddr;
+ parametri.port = int.Parse(cIobConf.cncPort);
+ // leggo file init...
+ lgInfo("Reading ini file...");
+ IniFile fIni = new IniFile(cIobConf.iniFileName);
+ // ora leggo valori speciali
+ parametri.memAddrRead = fIni.ReadString("MEMORY", "ADDR_READ", "");
+ parametri.memAddrWrite = fIni.ReadString("MEMORY", "ADDR_WRITE", "");
+ parametri.memSizeRead = fIni.ReadInteger("MEMORY", "SIZE_READ", 0);
+ parametri.memSizeWrite = fIni.ReadInteger("MEMORY", "SIZE_WRITE", 0);
+ // salvo vettori memoria...
+ lgInfo("Set RawInput dimensions...");
+ RawInput = new byte[parametri.memSizeRead];
+ RawOutput = new byte[parametri.memSizeWrite];
+ // salvo parametri conn!
+ lgInfo(string.Format("Parametri memoria: memAddrRead: {0} | memAddrWrite: {1} | memSizeRead: {2} | memSizeWrite: {3}", parametri.memAddrRead, parametri.memAddrWrite, parametri.memSizeRead, parametri.memSizeWrite));
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in parse parametri da IOBConf");
+ }
+ // ora tento avvio PLC... SE PING OK...
+ IPStatus esitoPing = testPingMachine;
+ if (esitoPing == IPStatus.Success)
+ {
+ needRefresh = false;
+ try
+ {
+ //Ip-Address and Port of Modbus-TCP-Server
+ currPLC = new ModbusClient(parametri.ipAdrr, parametri.port);
+
+ // disconnetto e connetto...
+ if (isVerboseLog)
+ {
+ lgInfo("ModBus TCP: tryDisconnect");
+ }
+ tryDisconnect();
+
+ // lo ripeto x evitare che ci sia un loop... e tryConnect richiami la procedura corrente...
+ needRefresh = false;
+ lgInfo("ModBus TCP: tryConnect");
+ tryConnect();
+ lgInfo("End init Adapter ModBusTCP");
+ if (isVerboseLog)
+ {
+ lgInfo("ModBus TCP CONNESSIONE AVVENUTA");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in INIT ModBusTCP");
+ }
+ }
+ else
+ {
+ lgError($"Errore in ping: esito {esitoPing}");
+ }
+ parentForm.commPlcActive = false;
+ // carico conf vettore memoria...
+ loadMemConf();
+ bool enableByApp = utils.CRB("enableContapezzi");
+ bool enableByIob = (getOptPar("ENABLE_PZCOUNT") == "TRUE");
+ bool disableByIob = (getOptPar("DISABLE_PZCOUNT") == "TRUE");
+ if ((enableByApp || enableByIob) && !(disableByIob))
+ {
+ lgInfo("ModBus TCP: inizio gestione contapezzi");
+ try
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
+ if (cIobConf.optPar.Count > 0 && !string.IsNullOrWhiteSpace(getOptPar("PZCOUNT_MODE")))
+ {
+ if (getOptPar("PZCOUNT_MODE").StartsWith("STD"))
+ {
+ lgInfo("Init contapezzi ModBusTCP: pzCntReload(true)");
+ pzCntReload(true);
+ // refresh associazione Macchina - IOB
+ sendM2IOB();
+ // per adesso imposto lettura PLC == contapezzi (poi farà vera lettura...)
+ contapezziPLC = contapezziIOB;
+ }
+ else
+ {
+ contapezziIOB = 0;
+ lgInfo("Contapezzi STD disabilitato: modalità {0}", getOptPar("PZCOUNT_MODE"));
+ }
+ }
+ else
+ {
+ contapezziIOB = 0;
+ lgInfo("Parametro mancante PZCOUNT_MODE");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in contapezzi ModBusTCP");
+ }
+ }
+ }
+ else
+ {
+ lgError("Parametri null!");
+ }
+ }
+ }
+
+ ///
+ /// effettua il setup dei memblock da gestire (NON leggo intera memoria ma tanti blocchi...)
+ ///
+ protected virtual void setupMemBlocks()
+ { }
+
+ ///
+ /// Test connessione CNC
+ ///
+ ///
+ protected bool testCncConn()
+ {
+ bool answ = currPLC.Connected;
+ if (!answ)
+ {
+ // riduco i controlli ping.. li faccio solo ogni 5 ping period se precedente positivo...
+ DateTime adesso = DateTime.Now;
+ if (lastPingOk && adesso.Subtract(lastPingConn).TotalMilliseconds < 5 * parametri.pingMsTimeout)
+ {
+ answ = lastPingOk;
+ }
+ else
+ {
+ IPStatus pingStatus = testPingMachine;
+
+ // se non ok riprovo 1 volta dopo attesa
+ if (pingStatus != IPStatus.Success)
+ {
+ Thread.Sleep(2 * cIobConf.pingMsTimeout);
+ pingStatus = testPingMachine;
+ }
+ // se non passa ancora errore!
+ if (pingStatus != IPStatus.Success)
+ {
+ lgError($"Errore in testCncConn | reply Status {pingStatus} | IP: {parametri.ipAdrr} | T.Out: {parametri.pingMsTimeout}ms");
+ }
+ // se passa il ping faccio il resto...
+ else
+ {
+ if (!currPLC.Connected)
+ {
+ currPLC.Connect();
+ }
+
+ if (!currPLC.Available(500))
+ {
+ lgError($"PLC ModBus NON disponibile: {currPLC.IPAddress} | {currPLC.Port}");
+ }
+ else
+ {
+ if (!currPLC.Connected)
+ {
+ lgError($"PLC ModBus NON connesso:{currPLC.IPAddress} | {currPLC.Port}");
+ }
+ else
+ {
+ // tutto ok
+ parentForm.updateComStats("Connection OK");
+ answ = true;
+ }
+ }
+ }
+ // salvo stato ping
+ lastPingConn = adesso;
+ }
+ lastPingOk = answ;
+ }
+
+ return answ;
+ }
+
+ #endregion Protected Methods
+
+ #region Public Methods
+
+ ///
+ /// Metodo dispose x il currPLC contenuto
+ ///
+ public void Dispose()
+ {
+ currPLC.Disconnect();
+ }
+
+ ///
+ /// Processo i task richiesti e li elimino dalla coda 1:1
+ ///
+ ///
+ public override Dictionary executeTasks(Dictionary task2exe)
+ {
+ lgInfo($"Chiamata executeTasks specifica ModBus TCP: {task2exe.Count} task ricevuti");
+ // Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ return taskDone;
+ }
+
+ ///
+ /// decodifica tipo indirizzo dal codice
+ ///
+ ///
+ ///
+ public modBusAddrType getAddrType(string memAddr)
+ {
+ modBusAddrType answ = modBusAddrType.Coil;
+ // leggo prima cifra...
+ answ = (modBusAddrType)Enum.Parse(typeof(modBusAddrType), memAddr.Substring(0, 1));
+ return answ;
+ }
+
+ ///
+ /// Recupero dati dinamici...
+ /// ATTENZIONE factor usato come FONDOSCALA.... quindi 28'000 --> MOLTIPLICO per 28'000
+ ///
+ public override Dictionary getDynData()
+ {
+ // valore non presente in vers default... se gestito fare override
+ Dictionary outVal = new Dictionary();
+ if (utils.CRB("enableTSVC"))
+ {
+ // processing SOLO SE ho in memoria abbastanza dati...
+ if (RawInput.Length < parametri.memSizeRead)
+ {
+ lgError($"Impossibile processare getDynData x ModBus TCP PLC, vettore memoria troppo piccolo: {RawInput.Length} byte / {parametri.memSizeRead} byte presenti/richiesti)");
+ }
+ else
+ {
+ try
+ {
+ // processo x ogni valore configurato...
+ if (memMap.mMapRead.Count > 0)
+ {
+ // inizializzo i valori
+ bool[] listBool = new bool[1];
+ int[] listInt = new int[2];
+ double valore = 0;
+ // procedo x ogni valore configurato......
+ foreach (var item in memMap.mMapRead)
+ {
+ // in primis DEVO determinare di quale TIPO di valore ho bisogno... dalla PRIMA cifra di memAddr...
+ modBusAddrType memAddrType = getAddrType(item.Value.memAddr);
+ // in base al tipo leggo array...
+ switch (memAddrType)
+ {
+ case modBusAddrType.Coil:
+ listBool = readCoil(item.Value.index, item.Value.size);
+ valore = listBool[0] ? 1 : 0;
+ break;
+
+ case modBusAddrType.DiscreteInput:
+ listBool = readDiscrInputs(item.Value.index, item.Value.size);
+ valore = listBool[0] ? 1 : 0;
+ break;
+
+ case modBusAddrType.InputRegister:
+ listInt = readInputReg(item.Value.index, item.Value.size);
+ //verifico se sia INT o real x convertire...
+ switch (item.Value.tipoMem)
+ {
+ case plcDataType.Real:
+ if (item.Value.size == 4)
+ {
+ valore = ModbusClient.ConvertRegistersToDouble(listInt) * item.Value.factor;
+ }
+ else if (item.Value.size == 2)
+ {
+ valore = ModbusClient.ConvertRegistersToFloat(listInt) * item.Value.factor;
+ }
+ break;
+
+ case plcDataType.Int:
+ default:
+ if (item.Value.size == 4)
+ {
+ valore = ModbusClient.ConvertRegistersToLong(listInt) * item.Value.factor;
+ }
+ else if (item.Value.size == 2)
+ {
+ valore = ModbusClient.ConvertRegistersToInt(listInt) * item.Value.factor;
+ }
+ break;
+ }
+ break;
+
+ case modBusAddrType.HoldingRegister:
+ listInt = readHoldReg(item.Value.index - 1, item.Value.size);
+ //verifico se sia INT o real x convertire...
+ switch (item.Value.tipoMem)
+ {
+ case plcDataType.Real:
+ if (item.Value.size == 4)
+ {
+ valore = ModbusClient.ConvertRegistersToDouble(listInt) * item.Value.factor;
+ }
+ else if (item.Value.size == 2)
+ {
+ valore = ModbusClient.ConvertRegistersToFloat(listInt) * item.Value.factor;
+ }
+ break;
+
+ case plcDataType.Int:
+ default:
+ if (item.Value.size == 4)
+ {
+ valore = ModbusClient.ConvertRegistersToLong(listInt) * item.Value.factor;
+ }
+ else if (item.Value.size == 2)
+ {
+ valore = ModbusClient.ConvertRegistersToInt(listInt) * item.Value.factor;
+ }
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ saveValue(ref outVal, valore, item.Key);
+ }
+ }
+ else
+ {
+ lgInfo($"getDynData: {memMap.mMapRead.Count} record in mMapRead");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in getDynData x ModBus TCP PLC");
+ }
+ }
+ }
+ else
+ {
+ lgInfo($"Non processo getDynData: enableTSVC = false");
+ }
+ if (periodicLog || outVal.Count > 0)
+ {
+ lgInfo($"Esito getDynData: {outVal.Count} valori VALIDI in outVal");
+ }
+ return outVal;
+ }
+
+ ///
+ /// Lettura valori Coils (1...)
+ ///
+ ///
+ ///
+ ///
+ public bool[] readCoil(int startAddr, int qty)
+ {
+ bool[] answ = new bool[1];
+ if (currPLC.Connected)
+ {
+ answ = currPLC.ReadCoils(startAddr, qty);
+ }
+ return answ;
+ }
+
+ ///
+ /// Lettura valori DiscreteInputs (2...)
+ ///
+ ///
+ ///
+ ///
+ public bool[] readDiscrInputs(int startAddr, int qty)
+ {
+ bool[] answ = new bool[1];
+ if (currPLC.Connected)
+ {
+ answ = currPLC.ReadDiscreteInputs(startAddr, qty);
+ }
+ return answ;
+ }
+
+ ///
+ /// Lettura valori Holding Register (3...)
+ ///
+ ///
+ ///
+ ///
+ public int[] readHoldReg(int startAddr, int qty)
+ {
+ int[] answ = new int[2];
+ if (currPLC.Connected)
+ {
+ answ = currPLC.ReadHoldingRegisters(startAddr, qty);
+ }
+ return answ;
+ }
+
+ ///
+ /// Lettura valori Input Register (4...)
+ ///
+ ///
+ ///
+ ///
+ public int[] readInputReg(int startAddr, int qty)
+ {
+ int[] answ = new int[2];
+ if (currPLC.Connected)
+ {
+ answ = currPLC.ReadInputRegisters(startAddr, qty);
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua lettura semafori principale
+ /// Parametri da aggiornare x display in form
+ ///
+ public override void readSemafori(ref newDisplayData currDispData)
+ {
+ base.readSemafori(ref currDispData);
+ byte[] MemBlock = new byte[2];
+ try
+ {
+ currDispData.semIn = Semaforo.SV;
+
+ if (verboseLog)
+ {
+ lgInfo("inizio read semafori");
+ }
+
+ //// ciclo a leggere TUTTI i blocchi di memoria impostati
+ //foreach (var item in memSetR)
+ //{
+ // // leggo TUTTI i byte configurati...
+ // MemBlock = new byte[item.Value];
+ // S7ReadBB(ref MemBlock, $"{item.Key}", item.Value);
+ // Buffer.BlockCopy(MemBlock, 0, RawInput, item.Key, item.Value);
+ //}
+
+ //// leggo TUTTI i byte configurati...
+ //MemBlock = new byte[parametri.memSizeRead];
+ //bool fatto = S7ReadBB(ref MemBlock);
+ //Buffer.BlockCopy(MemBlock, 0, RawInput, 0, parametri.memSizeRead);
+ if (verboseLog)
+ {
+ lgInfo(string.Format("RawInput[0]: {0}", utils.binaryForm(RawInput[0])));
+ }
+
+ // salvo il solo BYTE dell'input decifrando il semaforo...
+ decodeToBaseBitmap();
+ decodeOtherData();
+ // riporto bitmap...
+ reportRawInput(ref currDispData);
+ }
+ catch
+ {
+ currDispData.semIn = Semaforo.SR;
+ }
+ }
+
+ ///
+ /// wrapper chiamata LETTURA in blocco MULTI BYTE dell'area read DI DEFAULT...
+ ///
+ ///
+ ///
+ public bool S7ReadBB(ref byte[] Value)
+ {
+ return S7ReadBB(ref Value, parametri.memAddrRead, parametri.memSizeRead);
+ }
+
+ ///
+ /// wrapper chiamata LETTURA in blocco MULTI BYTE...
+ ///
+ /// MATRICE valori letti
+ /// Area memoria da leggere...
+ /// Numero byte da leggere
+ ///
+ public bool S7ReadBB(ref byte[] Value, string memAddrRead, int numByte)
+ {
+ bool answ = false;
+ if (Value != null)
+ {
+ sw.Restart();
+ parentForm.commPlcActive = true;
+#if false
+ if (testCncConn())
+ {
+ // decodifico memoria...
+ memAreaSiemens memoria = new memAreaSiemens(memAddrRead);
+ Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
+ // copio in value, sennò do errore...
+ if (memByteRead.Length == Value.Length)
+ {
+ Value = memByteRead;
+ }
+ else
+ {
+ lgError($"Mismatch dimensione array memoria: indirizzo: {memAddrRead} | passato array di {Value.Length} byte, letti da S7 {memByteRead.Length} byte");
+ }
+ string titolo = $"READ BLOCK MEM BYTE: {parametri.memAddrRead} --> {numByte} byte";
+ if (verboseLog)
+ {
+ lgInfo(titolo);
+ }
+
+ string contenuto = $"Contenuto area memoria acquisita{Environment.NewLine}";
+ string byteVal = "";
+ for (int i = 0; i < memByteRead.Length; i++)
+ {
+ byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0');
+ contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine);
+ }
+ // loggo lettura...
+ if (verboseLog)
+ {
+ lgInfo(contenuto);
+ }
+ }
+ else
+ {
+ connectionOk = false;
+ }
+#endif
+ parentForm.commPlcActive = false;
+ sw.Stop();
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("{0}|{1}", parametri.memAddrRead, numByte), sw.ElapsedTicks);
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// wrapper chiamata LETTURA in blocco MULTI BYTE... default size a parametri.memSizeRead
+ ///
+ ///
+ /// Area memoria da leggere...
+ ///
+ public bool S7ReadBB(ref byte[] Value, string memAddrRead)
+ {
+ bool answ = false;
+ answ = S7ReadBB(ref Value, memAddrRead, parametri.memSizeRead);
+ return answ;
+ }
+
+ ///
+ /// wrapper chiamata SCRITTURA in blocco MULTI BYTE, DI DEFAULT su area configurata x scrittura CONTINUA...
+ ///
+ ///
+ ///
+ public bool S7WriteBB(ref byte[] Value)
+ {
+ return S7WriteBB(ref Value, parametri.memAddrWrite);
+ }
+
+ ///
+ /// Override scrittura in area DBB
+ ///
+ ///
+ ///
+ ///
+ public bool S7WriteBB(ref byte[] Value, string memAddrWrite)
+ {
+ bool answ = false;
+ if (Value == null)
+ {
+ lgError($"Errore in S7WriteBB: Value è null");
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(memAddrWrite))
+ {
+ lgError($"Errore in S7WriteBB: memAddrWrite è vuoto");
+ }
+ else
+ {
+ sw.Restart();
+#if false
+ if (testCncConn())
+ {
+ try
+ {
+ // decodifico memoria...
+ memAreaSiemens memoria = new memAreaSiemens(memAddrWrite);
+ int numByte = Value.Length;
+ ErrorCode errorCode = currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, Value);
+ switch (errorCode)
+ {
+ case ErrorCode.NoError:
+ answ = true;
+ maybeLogWrite(memAddrWrite, $"S7WriteBB-01 Effettuata correttamente scrittura su PLC: MEMORIA {memAddrWrite} | numByte: {Value.Length} | ValOriginale: {Value}");
+ break;
+
+ case ErrorCode.WrongCPU_Type:
+ case ErrorCode.ConnectionError:
+ case ErrorCode.IPAddressNotAvailable:
+ case ErrorCode.WrongVarFormat:
+ case ErrorCode.WrongNumberReceivedBytes:
+ case ErrorCode.SendData:
+ case ErrorCode.ReadData:
+ case ErrorCode.WriteData:
+ lgError($"Errore in S7WriteBB su {memAddrWrite}: {errorCode.ToString()} | numByte: {Value.Length}| {Value.ValToBinString()}");
+ answ = false;
+ break;
+
+ default:
+ break;
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in S7WriteBB | memAddrWrite {memAddrWrite} | numByte: {Value.Length}{Environment.NewLine}{exc}");
+ }
+ }
+#endif
+ sw.Stop();
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Override scrittura in area DBB
+ ///
+ /// Valore byte[] da scrivere
+ /// Numero del DB (es 700 per DB700)
+ /// Indice interno al datablock del byte da cui partire
+ ///
+ public bool S7WriteBB(ref byte[] Value, int DbNum, int IndiceMem)
+ {
+ bool answ = false;
+ if (Value == null)
+ {
+ lgError($"Errore in S7WriteBB: Value è null");
+ }
+ else
+ {
+ if (DbNum < 0 || IndiceMem < 0)
+ {
+ lgError($"Errore in S7WriteBB | DbNum: {DbNum} | IndiceMem: {IndiceMem}");
+ }
+ else
+ {
+ sw.Restart();
+#if false
+ if (testCncConn())
+ {
+ try
+ {
+ int numByte = Value.Length;
+ ErrorCode errorCode = currPLC.WriteBytes(DataType.DataBlock, DbNum, IndiceMem, Value);
+ switch (errorCode)
+ {
+ case ErrorCode.NoError:
+ lgInfo($"S7WriteBB-02 Effettuata correttamente scrittura su PLC: DB {DbNum}.{IndiceMem} | numByte: {Value.Length}| {Value.ValToBinString()}");
+ break;
+
+ case ErrorCode.WrongCPU_Type:
+ case ErrorCode.ConnectionError:
+ case ErrorCode.IPAddressNotAvailable:
+ case ErrorCode.WrongVarFormat:
+ case ErrorCode.WrongNumberReceivedBytes:
+ case ErrorCode.SendData:
+ case ErrorCode.ReadData:
+ case ErrorCode.WriteData:
+ lgError($"Errore in S7WriteBB su DB {DbNum}.{IndiceMem}: {errorCode.ToString()} | numByte: {Value.Length}| {Value.ValToBinString()}");
+ break;
+
+ default:
+ break;
+ }
+ answ = true;
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in S7WriteBB: DbNum {DbNum}, IndiceMem: {IndiceMem}, numByte: {Value.Length}{Environment.NewLine}{exc}");
+ }
+ }
+#endif
+ sw.Stop();
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Salvo in memblock il valore Int indicato con formattazione ModBus TCP
+ ///
+ /// Blocco memoria come byte[] dove scrivere
+ /// Posizione inizio scrittura
+ /// valore da scrivere
+ public void saveIntOnMemBlock(ref byte[] MemBlock, int startPos, string valore)
+ {
+ try
+ {
+ short valInt = 0;
+ short.TryParse(valore, out valInt);
+ byte[] strByte = S7.Net.Types.Int.ToByteArray(valInt);
+ int byteLen = 2;
+ Buffer.BlockCopy(strByte, 0, MemBlock, startPos, byteLen);
+ //var verifica = S7.Net.Types.String.FromByteArray(MemBlock);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in gestione scrittura INT {valore} alla posizione {startPos} byte{Environment.NewLine}{exc}");
+ }
+ }
+
+ ///
+ /// Salvo in memblock il valore Int indicato con formattazione ModBus TCP
+ ///
+ /// Blocco memoria come byte[] dove scrivere
+ /// Nome del parametro da recuperare da prodData x scrivere
+ /// Posizione inizio scrittura
+ public void saveIntOnMemBlock(ref byte[] MemBlock, string stringKey, int startPos)
+ {
+ if (currProdData.ContainsKey(stringKey))
+ {
+ try
+ {
+ string valore = currProdData[stringKey];
+ saveIntOnMemBlock(ref MemBlock, startPos, valore);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in gestione scrittura INT {stringKey}{Environment.NewLine}{exc}");
+ }
+ }
+ }
+
+ ///
+ /// Salvo in memblock il valore stringa indicato con formattazione ModBus TCP
+ ///
+ /// Blocco memoria come byte[] dove scrivere
+ /// Posizione inizio scrittura
+ /// Valore scrivere
+ public void saveRealOnMemBlock(ref byte[] MemBlock, int startPos, string valore)
+ {
+ try
+ {
+ byte[] stringPar = new byte[2];
+
+ double valReal = 0;
+ double.TryParse(valore, out valReal);
+ byte[] strByte = S7.Net.Types.Double.ToByteArray(valReal);
+ int byteLen = 4;
+ Buffer.BlockCopy(strByte, 0, MemBlock, startPos, byteLen);
+ //var verifica = S7.Net.Types.String.FromByteArray(MemBlock);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in gestione scrittura REAL {valore} alla posizione {startPos} byte{Environment.NewLine}{exc}");
+ }
+ }
+
+ ///
+ /// Salvo in memblock il valore stringa indicato con formattazione ModBus TCP
+ ///
+ /// Blocco memoria come byte[] dove scrivere
+ /// Valore scrivere
+ /// Posizione inizio scrittura
+ public void saveRealOnMemBlock(ref byte[] MemBlock, string stringKey, int startPos)
+ {
+ if (currProdData.ContainsKey(stringKey))
+ {
+ try
+ {
+ string valore = currProdData[stringKey];
+ saveRealOnMemBlock(ref MemBlock, startPos, valore);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in gestione scrittura REAL {stringKey}{Environment.NewLine}{exc}");
+ }
+ }
+ }
+
+ ///
+ /// Effettua salvataggio in LUT del valore ricevuto (double)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void saveValue(ref Dictionary outVal, double valore, string chiave)
+ {
+ //check obj preliminare
+ if (outVal == null)
+ {
+ outVal = new Dictionary();
+ }
+ bool scaduto = stackVal_TSVC(chiave, valore);
+ // recupero VC
+ valore = getVal_TSVC(chiave, scaduto);
+ if (scaduto)
+ {
+ outVal.Add(chiave, $"{valore}");
+ }
+ LastTSVC[chiave] = valore;
+ }
+
+ ///
+ /// Override connessione
+ ///
+ public override void tryConnect()
+ {
+ bool doLog = (verboseLog || periodicLog);
+ lgInfo("ModBus TCP: tryConnect step 01");
+ if (!connectionOk)
+ {
+ // SE è necessario refresh...
+ if (needRefresh)
+ {
+ lgInfo("ModBus TCP: tryConnect step 02");
+
+ // reimporto parametri PLC se necessario...
+ setParamPlc();
+ }
+ lgInfo("ModBus TCP: tryConnect step 03");
+
+ // controllo che il ping sia stato tentato almeno pingTestSec fa...
+ if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
+ {
+ if (doLog)
+ {
+ lgInfo("ModBus TCP: ConnKO - tryConnect");
+ }
+ lgInfo("ModBus TCP: tryConnect step 04");
+
+ // in primis salvo data ping...
+ lastPING = DateTime.Now;
+ // se passa il ping faccio il resto...
+ if (testPingMachine == IPStatus.Success)
+ {
+ string szStatusConnection = "ND";
+ try
+ {
+ // ora provo connessione...
+ parentForm.commPlcActive = true;
+ currPLC.Connect();
+ szStatusConnection = "OPEN";
+ parentForm.commPlcActive = false;
+ connectionOk = currPLC.Connected;
+ lgInfo($"StatusConnection: {szStatusConnection}");
+ // refresh stato allarmi!!!
+ if (connectionOk)
+ {
+ if (adpRunning)
+ {
+ lgInfo($"Connessione OK: {connectionOk} | adpRunning: {adpRunning}");
+ }
+ }
+ else
+ {
+ lgError("Impossibile procedere, connessione mancante...");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgFatal($"Errore in TryConnect adapter ModBusTCP | szStatusConnection {szStatusConnection}{Environment.NewLine}{exc}");
+ connectionOk = false;
+ needRefresh = true;
+ }
+ }
+ else
+ {
+ // loggo no risposta ping ...
+ connectionOk = false;
+ if (doLog)
+ {
+ lgInfo($"Attenzione: ModBusTCP controllo PING fallito per IP {cIobConf.cncIpAddr}");
+ }
+ }
+ }
+ }
+ // se non è ancora connesso faccio procesisng memoria caso disconnesso...
+ if (!connectionOk)
+ {
+ // processo semafori ed invio...
+ processMemoryDiscon();
+ }
+ }
+
+ ///
+ /// Override disconnessione
+ ///
+ public override void tryDisconnect()
+ {
+ if (connectionOk)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ currPLC.Disconnect();
+ connectionOk = false;
+ lgInfo(szStatusConnection);
+ lgInfo("Effettuata disconnessione adapter ModBusTCP!");
+ }
+ catch (Exception exc)
+ {
+ lgFatal(exc, "Errore nella disconnessione dall'adapter ModBusTCP");
+ }
+ }
+ else
+ {
+ lgError("IMPOSSIBILE effettuare disconnessione ModBusTCP: Connessione non disponibile...");
+ }
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobModbusTCPHam.cs b/IOB-WIN-NEXT/IobModbusTCPHam.cs
new file mode 100644
index 00000000..f98c9cbb
--- /dev/null
+++ b/IOB-WIN-NEXT/IobModbusTCPHam.cs
@@ -0,0 +1,421 @@
+using EasyModbus;
+using IOB_UT_NEXT;
+using MapoSDK;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IOB_WIN_NEXT
+{
+ /* --------------------------------------------------------------------------------
+ * Controlli ModBusTCP COMECA
+ * - protocollo ModBus TCP HAM
+ * - specifico comportamento impianti HAM Pizzaferri
+ *
+ * STRUTTURA MEMORIA a banchi di byte, convertiti successivamente in bit/int/real:
+ * lettura: xxx byte,
+ * scrittura yyy byte
+ * G:\Drive condivisi\30_Clienti\Pizzaferri\Impianti\HAM
+ * *
+ * -------------------------------------------------------------------------------- */
+
+ public class IobModbusTCPHam : IobModbusTCP
+ {
+ #region Public Constructors
+
+ /// Classe base con i metodi x ModBusTCP
+ ///
+ ///
+ ///
+ public IobModbusTCPHam(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("NEW IOB ModBus TCP HAM");
+
+ // provo lettura una prima volta i dati DYN
+ if (currPLC.Connected)
+ {
+ try
+ {
+ processDynData();
+ }
+ catch (Exception exc)
+ { }
+ }
+ }
+
+ #endregion Public Constructors
+
+ #region Protected Properties
+
+ protected bool hasAlarms
+ {
+ get
+ {
+ bool answ = false;
+#if false
+ int numErrors = 0;
+ uint currStatus = 0;
+ if (alarmMaps != null)
+ {
+ // leggo a ciclo le aree degli allarmi CONFIGURATI, se ne trovo --> segnalo allarme...
+ foreach (var item in alarmMaps)
+ {
+ // in primis decremento eventuali blink...
+ item.decreaseBlinkCounter();
+ // banchi in WORD (2 byte) --> scompongo
+ for (int i = 0; i < item.size / 2; i++)
+ {
+ currStatus = S7.Net.Types.Counter.FromByteArray(RawInput.Skip(item.index + 2 * i).Take(2).ToArray());
+ // verifico SE sia variato...
+ if (item.isChanged(i, currStatus))
+ {
+ numErrors++;
+ answ = true;
+ // registro gli allarmi attivi e trasmetto...
+ if (sendAlarmVariations(item.memAddr, i, item.alarmsState[i], currStatus))
+ {
+ // se inviato --> salvo stato da current...
+ item.updStatusVal(i, currStatus);
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ return answ;
+ }
+ }
+
+ #endregion Protected Properties
+
+ #region Private Methods
+
+ private void testRead()
+ {
+ //Ip-Address and Port of Modbus-TCP-Server
+ //currPLC = new ModbusClient(cIobConf.cncIpAddr, 502);
+ ////Connect to Server
+ //currPLC.Connect();
+ //modbusClient.WriteMultipleCoils(4, new bool[] { true, true, true, true, true, true, true, true, true, true }); //Write Coils starting with Address 5
+ //bool[] readCoils = modbusClient.ReadCoils(9, 10); //Read 10 Coils from Server, starting with address 10
+ //int[] readHoldingRegisters = currPLC.ReadHoldingRegisters(0, 34); //Read 10 Holding Registers from Server, starting with Address 1
+
+ int[] readHR1000 = currPLC.ReadHoldingRegisters(0, 100); //Read 10 Holding Registers from Server, starting with Address 1
+
+ //// Console Output
+ //for (int i = 0; i < readCoils.Length; i++)
+ // Console.WriteLine("Value of Coil " + (9 + i + 1) + " " + readCoils[i].ToString());
+
+ for (int i = 0; i < readHR1000.Length / 2; i++)
+ {
+ Console.WriteLine($"Value of HoldingRegister {(i)} | {readHR1000[i]} / {readHR1000[i + 1]}");
+ int[] thisSet = new int[2];
+ Array.Copy(readHR1000, i, thisSet, 0, 2);
+ Console.WriteLine($"Convert val HoldingRegister {(i)} | {ModbusClient.ConvertRegistersToFloat(thisSet)}");
+ }
+ //Console.Write("Press any key to continue . . . ");
+ //Console.ReadKey(true);
+ }
+
+ #endregion Private Methods
+
+ #region Protected Methods
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO/GWMS
+ /// - per lo scopo specifico IN REALTA' non conta lo stato macchina.... ma lo inviamo lo stesso
+ ///
+ protected override void decodeToBaseBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+
+ /* -----------------------------------------------------
+ * bitmap MAPO STANDARD
+ * B0: POWER_ON
+ * B1: RUN
+ * B2: pzCount
+ * B3: allarme
+ *
+ ----------------------------------------------------- */
+
+ var MemInt = new byte[2];
+
+ int byteSignals = 0;
+ // bit 0 (poweron) imposto a 1 SE connected...
+ if (currPLC.Connected)
+ {
+ byteSignals += (1 << 0);
+ }
+
+ // processo dagli stati + gravi...
+ if (hasAlarms)
+ {
+ byteSignals += (1 << 3);
+ }
+ else
+ {
+ byteSignals += (1 << 1);
+ }
+
+ // salvo!
+ B_input = byteSignals;
+ }
+
+ ///
+ /// effettua il setup dei memblock da gestire (NON leggo intera memoria ma tanti blocchi...)
+ ///
+ protected override void setupMemBlocks()
+ {
+ // da calcolare... ora setup cablato...
+ memSetR.Add(1, 34);
+ }
+
+ #endregion Protected Methods
+
+ #region Public Methods
+
+ ///
+ /// Processo i task richiesti e li elimino dalla coda 1:1
+ ///
+ ///
+ public override Dictionary executeTasks(Dictionary task2exe)
+ {
+ lgInfo($"Chiamata executeTasks specifica ModBus TCP HAM: {task2exe.Count} task ricevuti");
+ // Verificare il protocollo: dovrebeb togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ bool taskOk = false;
+ string taskVal = "";
+ // inizio con 1 byte di default
+ byte[] MemBlock = new byte[1];
+ string memAddrWrite = "";
+ if (task2exe != null)
+ {
+#if false
+ // cerco task specifici
+ foreach (var item in task2exe)
+ {
+ taskOk = false;
+ taskVal = "";
+ // converto richiesta in enum...
+ taskType tName = taskType.nihil;
+ Enum.TryParse(item.Key, out tName);
+ // controllo sulla KEY
+ switch (tName)
+ {
+ case taskType.nihil:
+ case taskType.fixStopSetup:
+ case taskType.forceResetPzCount:
+ case taskType.forceSetPzCount:
+ case taskType.setProg:
+ case taskType.sendWatchDogMes2Plc:
+ taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
+ break;
+
+ case taskType.setPzComm:
+ case taskType.setArt:
+ case taskType.setComm:
+ saveProdData(item);
+ int byteSize = 0;
+ // recupero dati da memMap... altrimenti NULLA
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ dataConf currMem = memMap.mMapWrite[item.Key];
+ byteSize = currMem.size;
+ memAddrWrite = currMem.memAddr;
+ MemBlock = new byte[byteSize];
+ if (currMem.tipoMem == plcDataType.String)
+ {
+ saveStringOnMemBlock(ref MemBlock, item.Key, 0, byteSize);
+ }
+ else if (currMem.tipoMem == plcDataType.DInt)
+ {
+ int valDInt = 0;
+ int.TryParse(item.Value, out valDInt);
+ MemBlock = S7.Net.Types.DInt.ToByteArray(valDInt);
+ }
+ else if (currMem.tipoMem == plcDataType.Int)
+ {
+ short valInt = 0;
+ short.TryParse(item.Value, out valInt);
+ MemBlock = S7.Net.Types.Int.ToByteArray(valInt);
+ }
+ }
+ else
+ {
+ lgError($"Errore: non trovata chiave write in memMap.mMapWrite per {item.Key}");
+ }
+ taskVal = item.Value;
+ break;
+
+ case taskType.startSetup:
+ // processo scrittura BIT su DB6.DBDW216
+ MemBlock = new byte[1];
+ MemBlock[0] = (byte)1;
+ memAddrWrite = "DB6.DBDW216";
+ break;
+
+ case taskType.stopSetup:
+ // processo scrittura BIT su DB6.DBDW216
+ MemBlock = new byte[1];
+ MemBlock[0] = (byte)0;
+ memAddrWrite = "DB6.DBDW216";
+ break;
+
+ case taskType.setParameter:
+ // richiedo da URL i parametri WRITE da popolare
+ lgInfo("Chiamata processMemWriteRequests");
+ taskVal = processMemWriteRequests();
+ // se restituiscce "" faccio altra prova...
+ if (string.IsNullOrEmpty(taskVal))
+ {
+ // i parametri me li aspetto come stringa composta paramName|paramvalue
+ if (item.Value.Contains("|"))
+ {
+ string[] paramsJob = item.Value.Split('|');
+ taskVal = $"REQUEST SET PARAMETERS: {paramsJob[0]} --> {paramsJob[1]}";
+ }
+ else
+ {
+ taskVal = $"WRONG REQUEST FOR SET PARAMETERS: {item.Value} doesnt contain pipe for splitting key/value";
+ }
+ }
+ break;
+
+ default:
+ taskVal = "SKIPPED | NO EXEC";
+ break;
+ }
+ // aggiungo task!
+ taskDone.Add(item.Key, taskVal);
+ if (!string.IsNullOrEmpty(memAddrWrite))
+ {
+ // scrivo!
+ taskOk = S7WriteBB(ref MemBlock, memAddrWrite);
+ }
+ if (!taskOk)
+ {
+ lgError($"Errore in S7WriteBB durante executeTasks: {item.Key} | {item.Value}");
+ }
+ }
+#endif
+ }
+ return taskDone;
+ }
+
+ ///
+ /// Override connessione
+ ///
+ public override void tryConnect()
+ {
+ bool doLog = (verboseLog || periodicLog);
+ lgInfo("ModBus TCP HAM: tryConnect step 01");
+ if (!connectionOk)
+ {
+ // SE è necessario refresh...
+ if (needRefresh)
+ {
+ lgInfo("ModBus TCP HAM: tryConnect step 02");
+
+ // reimporto parametri PLC se necessario...
+ setParamPlc();
+ }
+ lgInfo("ModBus TCP HAM: tryConnect step 03");
+
+ // controllo che il ping sia stato tentato almeno pingTestSec fa...
+ if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
+ {
+ if (doLog)
+ {
+ lgInfo("ModBus TCP HAM: ConnKO - tryConnect");
+ }
+ lgInfo("ModBus TCP HAM: tryConnect step 04");
+
+ // in primis salvo data ping...
+ lastPING = DateTime.Now;
+ // se passa il ping faccio il resto...
+ if (testPingMachine == IPStatus.Success)
+ {
+ string szStatusConnection = "ND";
+ try
+ {
+ // ora provo connessione...
+ parentForm.commPlcActive = true;
+ currPLC.Connect();
+ szStatusConnection = "OPEN";
+ parentForm.commPlcActive = false;
+ connectionOk = currPLC.Connected;
+ lgInfo($"StatusConnection: {szStatusConnection}");
+ // refresh stato allarmi!!!
+ if (connectionOk)
+ {
+ if (adpRunning)
+ {
+ lgInfo($"Connessione OK: {connectionOk} | adpRunning: {adpRunning}");
+ }
+ }
+ else
+ {
+ lgError("Impossibile procedere, connessione mancante...");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgFatal($"Errore in TryConnect adapter ModBusTCP | szStatusConnection {szStatusConnection}{Environment.NewLine}{exc}");
+ connectionOk = false;
+ needRefresh = true;
+ }
+ }
+ else
+ {
+ // loggo no risposta ping ...
+ connectionOk = false;
+ if (doLog)
+ {
+ lgInfo($"Attenzione: ModBusTCP controllo PING fallito per IP {cIobConf.cncIpAddr}");
+ }
+ }
+ }
+ }
+ // se non è ancora connesso faccio procesisng memoria caso disconnesso...
+ if (!connectionOk)
+ {
+ // processo semafori ed invio...
+ processMemoryDiscon();
+ }
+ }
+
+ ///
+ /// Override disconnessione
+ ///
+ public override void tryDisconnect()
+ {
+ if (connectionOk)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ currPLC.Disconnect();
+ connectionOk = false;
+ lgInfo(szStatusConnection);
+ lgInfo("Effettuata disconnessione adapter ModBusTCP!");
+ }
+ catch (Exception exc)
+ {
+ lgFatal(exc, "Errore nella disconnessione dall'adapter ModBusTCP");
+ }
+ }
+ else
+ {
+ lgError("IMPOSSIBILE effettuare disconnessione ModBusTCP: Connessione non disponibile...");
+ }
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobSiemens.cs b/IOB-WIN-NEXT/IobSiemens.cs
index 62a86bfa..20ffab30 100644
--- a/IOB-WIN-NEXT/IobSiemens.cs
+++ b/IOB-WIN-NEXT/IobSiemens.cs
@@ -129,7 +129,7 @@ namespace IOB_WIN_NEXT
#region Protected Properties
///
- /// Dizionario delel ultime operazioni dis crittura per OGNI memoria (in modo che fa log ogni x sec...)
+ /// Dizionario delle ultime operazioni di scrittura per OGNI memoria (in modo che fa log ogni x sec...)
///
protected Dictionary lastMemWrite { get; set; } = new Dictionary();
@@ -416,7 +416,7 @@ namespace IOB_WIN_NEXT
}
///
- /// OVerride metodo x scrittura parametri su PLC
+ /// Override metodo x scrittura parametri su PLC
///
///
protected override void plcWriteParams(ref List updatedPar)
diff --git a/IOB-WIN-NEXT/MainForm.cs b/IOB-WIN-NEXT/MainForm.cs
index 71aaeec1..216bcc53 100644
--- a/IOB-WIN-NEXT/MainForm.cs
+++ b/IOB-WIN-NEXT/MainForm.cs
@@ -466,7 +466,10 @@ namespace IOB_WIN_NEXT
try
{
var currForm = (AdapterForm)item;
- numAttivi += currForm.iobObj.IobOnline ? 1 : 0;
+ if (currForm.iobObj != null)
+ {
+ numAttivi += currForm.iobObj.IobOnline ? 1 : 0;
+ }
}
catch
{ }
diff --git a/IOB-WIN-NEXT/packages.config b/IOB-WIN-NEXT/packages.config
index abcb9bfb..5d6bf35d 100644
--- a/IOB-WIN-NEXT/packages.config
+++ b/IOB-WIN-NEXT/packages.config
@@ -1,12 +1,13 @@

-
+
+
-
+
diff --git a/IOB-WIN-NEXT/specialConfig.cs b/IOB-WIN-NEXT/specialConfig.cs
index 6a867dcf..c85e2f94 100644
--- a/IOB-WIN-NEXT/specialConfig.cs
+++ b/IOB-WIN-NEXT/specialConfig.cs
@@ -2,6 +2,52 @@
namespace IOB_WIN_NEXT
{
+ ///
+ /// Implementazione classe connessione ModBus TCP,
+ /// comprensiva dei parametri delle aree di memoria
+ ///
+ public class connParamModBusTCP
+ {
+ #region Public Fields
+
+ ///
+ /// Indirizzo IP del PLC
+ ///
+ public string ipAdrr = "";
+
+ ///
+ /// Base area x lettura
+ ///
+ public string memAddrRead = "";
+
+ ///
+ /// Base area x scrittura
+ ///
+ public string memAddrWrite = "";
+
+ ///
+ /// Size memoria lettura
+ ///
+ public int memSizeRead = 0;
+
+ ///
+ /// Size memoria scrittura
+ ///
+ public int memSizeWrite = 0;
+
+ ///
+ /// Timeout ping
+ ///
+ public int pingMsTimeout = 250;
+
+ ///
+ /// Porta di comunicazione
+ ///
+ public int port;
+
+ #endregion Public Fields
+ }
+
///
/// Implementazione classe connessione SIEMENS con S7.net,
/// comprensiva dei parametri delle aree di memoria