diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 82854520..095afc33 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -269,6 +269,11 @@ namespace IOB_UT_NEXT
///
ND,
+ ///
+ /// Adapter ModBus TCP
+ ///
+ MODBUS_TCP,
+
///
/// Adapter MTConnect
///
diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs
index b559c19d..7a318db4 100644
--- a/IOB-UT-NEXT/ToMapo.cs
+++ b/IOB-UT-NEXT/ToMapo.cs
@@ -188,6 +188,84 @@ namespace IOB_UT_NEXT
#endregion Public Methods
}
+ ///
+ /// Struttura della conf memoria ModBus
+ ///
+ public class BaseModbusConf
+ {
+ #region Public Enums
+
+ public enum DataType
+ {
+ ND = 0,
+ Bit,
+ Int,
+ Real
+ }
+
+ public enum MemDirection
+ {
+ R,
+ W
+ }
+
+ public enum MemType
+ {
+ ND = 0,
+ DiscreteInput = 1,
+ Coil = 2,
+ InputRegister = 3,
+ HoldingRegister = 4
+ }
+
+ #endregion Public Enums
+
+ #region Public Properties
+
+ ///
+ /// Elenco aree memoria mobdus
+ ///
+ public List MemoryList { get; set; } = new List();
+
+ #endregion Public Properties
+
+ #region Public Classes
+
+ ///
+ /// struttura di base memoria ModBus
+ ///
+ public class ModbusMemArea
+ {
+ #region Public Properties
+
+ public ushort BaseAddr { get; set; } = 0;
+ public string RawAddr { get; set; } = "";
+ public ushort Size { get; set; } = 2;
+ public MemType Type { get; set; } = MemType.ND;
+
+ public List VarList { get; set; } = new List();
+
+ #endregion Public Properties
+ }
+
+ public class VarConf
+ {
+ #region Public Properties
+
+ public MemDirection Direction { get; set; } = MemDirection.R;
+ public ushort MemAddr { get; set; } = 0;
+ public string Name { get; set; } = "ND";
+ public int RangeMax { get; set; } = 0;
+ public int RangeMin { get; set; } = 0;
+ public ushort Size { get; set; } = 2;
+ public DataType Type { get; set; } = DataType.ND;
+
+ #endregion Public Properties
+ }
+
+ #endregion Public Classes
+ }
+
///
/// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect, OPC-UA, ...)
///
diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs
index d319f5b8..9445b21a 100644
--- a/IOB-WIN-NEXT/AdapterForm.cs
+++ b/IOB-WIN-NEXT/AdapterForm.cs
@@ -1186,6 +1186,11 @@ namespace IOB_WIN_NEXT
start.Enabled = true;
break;
+ case tipoAdapter.MODBUS_TCP:
+ iobObj = new IobModbusTCP(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..04480fbe
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini
@@ -0,0 +1,72 @@
+;Configurazione IOB-WIN
+[IOB]
+;Impianto COMECA per Pizzaferri
+CNCTYPE=MODBUS_TCP
+PING_MS_TIMEOUT=500
+
+[MACHINE]
+VENDOR=HAM
+MODEL=HAM
+
+[CNC]
+IP=hampizzaferri.dyndns.org
+PORT=502
+;CPUTYPE=S71500
+;RACK=0
+;SLOT=0
+
+[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=DB85.DBB0
+ADDR_WRITE=DB85.DBB280
+SIZE_READ=280
+SIZE_WRITE=32
+
+
+[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=FALSE
+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=20
+
+; conf parametri memoria READ/WRITE
+PARAM_CONF=PIZ03.json
+
+NO_PING=TRUE
+; conf aree allarme
+ALARM_CONF=PIZ03_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..a28052db
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04.json
@@ -0,0 +1,247 @@
+{
+ "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": {
+ "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
+ },
+ "Level": {
+ "name": "LT15",
+ "description": "Livello Serbatoio",
+ "memAddr": "DB85.DBB16",
+ "tipoMem": "Real",
+ "index": 16,
+ "size": 4,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "PressBH": {
+ "name": "PT01",
+ "description": "Pressione Linea CNG",
+ "memAddr": "DB85.DBB20",
+ "tipoMem": "Real",
+ "index": 20,
+ "size": 4,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "PressBL": {
+ "name": "PT100",
+ "description": "Pressione Riduttrice",
+ "memAddr": "DB85.DBB24",
+ "tipoMem": "Real",
+ "index": 24,
+ "size": 4,
+ "func": "MAX",
+ "period": 60,
+ "factor": 1
+ },
+ "MainPress": {
+ "name": "PT16",
+ "description": "Pressione Serbatoio",
+ "memAddr": "DB85.DBB28",
+ "tipoMem": "Real",
+ "index": 28,
+ "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..2f20c6bc
--- /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..feee01e5 100644
--- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
+++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
@@ -83,6 +83,9 @@
..\CncLib\ExtLib\CndexLinkDotNet.dll
+
+ ..\packages\EasyModbusTCP.5.6.0\lib\net40\EasyModbus.dll
+
False
ExtLib\krcc.dll
@@ -172,6 +175,7 @@
+
@@ -347,12 +351,21 @@
Always
+
+ Always
+
+
+ Always
+
Always
Always
+
+ Always
+
Always
diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs
new file mode 100644
index 00000000..6be7f7c8
--- /dev/null
+++ b/IOB-WIN-NEXT/IobModbusTCP.cs
@@ -0,0 +1,116 @@
+using EasyModbus;
+using IOB_UT_NEXT;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IOB_WIN_NEXT
+{
+ public class IobModbusTCP : IobGeneric
+ {
+ #region Protected Fields
+
+ protected string serverIp = "hampizzaferri.dyndns.org";
+
+ #endregion Protected Fields
+
+ //protected string serverIp = "127.0.0.1";
+
+ #region Public Constructors
+
+ /// Classe base con i metodi x Siemens
+ ///
+ ///
+ ///
+ public IobModbusTCP(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("NEW IOB ModBus TCP");
+
+ testRead();
+ }
+
+ #endregion Public Constructors
+
+ #region Private Methods
+
+ private void testConf()
+ {
+ BaseModbusConf.VarConf var01 = new BaseModbusConf.VarConf()
+ {
+ Name = "Giacenza Serbatoio",
+ Type = BaseModbusConf.DataType.Real,
+ MemAddr = 1,
+ Size = 2,
+ Direction = BaseModbusConf.MemDirection.R,
+ RangeMin = 0,
+ RangeMax = 100
+ };
+ BaseModbusConf.VarConf var02 = new BaseModbusConf.VarConf()
+ {
+ Name = "Pressione Serbatoio",
+ Type = BaseModbusConf.DataType.Real,
+ MemAddr = 3,
+ Size = 2,
+ Direction = BaseModbusConf.MemDirection.R,
+ RangeMin = 0,
+ RangeMax = 25
+ };
+ List memList01 = new List();
+ memList01.Add(var01);
+ memList01.Add(var02);
+ BaseModbusConf.ModbusMemArea block01 = new BaseModbusConf.ModbusMemArea()
+ {
+ RawAddr = "40001",
+ Type = BaseModbusConf.MemType.HoldingRegister,
+ BaseAddr = 1,
+ Size = 50,
+ VarList = memList01
+ };
+ List DemoMem = new List();
+ DemoMem.Add(block01);
+
+ // creo un area di memoria
+ BaseModbusConf demoConf = new BaseModbusConf()
+ {
+ MemoryList = DemoMem
+ };
+ // salvo conf con json x compilare...
+ var rawData = JsonConvert.SerializeObject(demoConf);
+ }
+
+ private void testRead()
+ {
+ //Ip-Address and Port of Modbus-TCP-Server
+ ModbusClient modbusClient = new ModbusClient(serverIp, 502);
+ //Connect to Server
+ modbusClient.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 = modbusClient.ReadHoldingRegisters(0, 34); //Read 10 Holding Registers from Server, starting with Address 1
+
+ int[] readHR1000 = modbusClient.ReadHoldingRegisters(0, 100); //Read 10 Holding Registers from Server, starting with Address 1
+
+ //Disconnect from Server
+ modbusClient.Disconnect();
+
+ //// 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 < readHoldingRegisters.Length; i++)
+ {
+ Console.WriteLine("Value of HoldingRegister " + (i + 1) + " " + readHoldingRegisters[i].ToString());
+ int[] thisSet = new int[2];
+ Array.Copy(readHoldingRegisters, i, thisSet, 0, 2);
+ Console.WriteLine("Convert val HoldingRegister " + (i + 1) + " " + ModbusClient.ConvertRegistersToFloat(thisSet));
+ }
+ Console.Write("Press any key to continue . . . ");
+ Console.ReadKey(true);
+ }
+
+ #endregion Private Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/packages.config b/IOB-WIN-NEXT/packages.config
index abcb9bfb..4e1386f8 100644
--- a/IOB-WIN-NEXT/packages.config
+++ b/IOB-WIN-NEXT/packages.config
@@ -1,6 +1,7 @@
+