diff --git a/IOB-UT-NEXT/BitConditionCheck.cs b/IOB-UT-NEXT/BitConditionCheck.cs
new file mode 100644
index 00000000..94899773
--- /dev/null
+++ b/IOB-UT-NEXT/BitConditionCheck.cs
@@ -0,0 +1,89 @@
+namespace IOB_UT_NEXT
+{
+ public class BitConditionCheck
+ {
+ #region Public Constructors
+
+ ///
+ /// Inizializza un oggetto da usare per testing bit condition
+ ///
+ /// Nome della chiave registrata
+ /// Configuraizone nel formato BaseAddr.BitNum=ValOk
+ public BitConditionCheck(string keyName, string rawConf)
+ {
+ Logging.Instance.Info($"Init BitConditionCheck | {keyName} | {rawConf}");
+ KeyName = keyName;
+ RawVal = rawConf;
+ string sVal = "";
+ int valDecoded = 0;
+ // check preliminare
+ if (rawConf.Contains(".") && rawConf.Contains("="))
+ {
+ // splitto per "="...
+ var splitCond = rawConf.Split('=');
+ sVal = splitCond[1];
+ int.TryParse(sVal, out valDecoded);
+ ValOk = valDecoded;
+ // il restante splitto per "."
+ var splitMem = splitCond[0].Split('.');
+ // BaseAddr
+ sVal = splitMem[0];
+ int.TryParse(sVal, out valDecoded);
+ BaseAddr = valDecoded;
+ // BitNum
+ sVal = splitMem[1];
+ int.TryParse(sVal, out valDecoded);
+ BitNum = valDecoded;
+ }
+ }
+
+ ///
+ /// Inizializza un oggetto fake/empty
+ ///
+ public BitConditionCheck()
+ {
+ Logging.Instance.Info("Init empty BitConditionCheck");
+ }
+
+ ///
+ /// Inizializza un oggetto solo per key
+ ///
+ /// Nome della chiave registrata
+ public BitConditionCheck(string keyName)
+ {
+ Logging.Instance.Info($"Init BitConditionCheck | {keyName}");
+ KeyName = keyName;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ ///
+ /// Indirizzo base x memoria da testare come bit condition
+ ///
+ public int BaseAddr { get; set; } = 0;
+
+ ///
+ /// Numero bit da impiegare
+ ///
+ public int BitNum { get; set; } = 0;
+
+ ///
+ /// Valore chiave
+ ///
+ public string KeyName { get; set; } = "";
+
+ ///
+ /// Valore raw decodificato
+ ///
+ public string RawVal { get; set; } = "";
+
+ ///
+ /// Valore target che porta a condizione OK = true
+ ///
+ public int ValOk { get; set; } = 0;
+
+ #endregion Public Properties
+ }
+}
\ No newline at end of file
diff --git a/IOB-UT-NEXT/IOB-UT-NEXT.csproj b/IOB-UT-NEXT/IOB-UT-NEXT.csproj
index 2507531e..e74a2d2f 100644
--- a/IOB-UT-NEXT/IOB-UT-NEXT.csproj
+++ b/IOB-UT-NEXT/IOB-UT-NEXT.csproj
@@ -141,10 +141,12 @@
+
+
diff --git a/IOB-UT-NEXT/plcMemMapExt.cs b/IOB-UT-NEXT/plcMemMapExt.cs
new file mode 100644
index 00000000..3b582347
--- /dev/null
+++ b/IOB-UT-NEXT/plcMemMapExt.cs
@@ -0,0 +1,14 @@
+using MapoSDK;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IOB_UT_NEXT
+{
+ public class plcMemMapExt : plcMemMap
+ {
+ public Dictionary optMemPar { get; set; } = new Dictionary();
+ }
+}
diff --git a/IOB-WIN-NEXT/DATA/CONF/3026.json b/IOB-WIN-NEXT/DATA/CONF/3026.json
index 6488f32b..2ecd5729 100644
--- a/IOB-WIN-NEXT/DATA/CONF/3026.json
+++ b/IOB-WIN-NEXT/DATA/CONF/3026.json
@@ -1,36 +1,36 @@
{
"mMapWrite": {
-
+
},
"mMapRead": {
- "StatusWord": {
- "name": "StatusWord",
- "description": "Word di Status",
- "memAddr": "40002",
- "tipoMem": "Int",
- "index": 2,
- "size": 1,
- "func": "POINT",
- "period": 90,
- "factor": 1,
- "minVal": 0,
- "maxVal": 65536,
- "unit": "BMap"
- },
- "StatusDetWord": {
- "name": "StatusDetWord",
- "description": "Word di Status",
- "memAddr": "40005",
- "tipoMem": "Int",
- "index": 5,
- "size": 1,
- "func": "POINT",
- "period": 90,
- "factor": 1,
- "minVal": 0,
- "maxVal": 65536,
- "unit": "BMap"
- },
+ //"StatusWord": {
+ // "name": "StatusWord",
+ // "description": "Word di Status",
+ // "memAddr": "40002",
+ // "tipoMem": "Int",
+ // "index": 2,
+ // "size": 1,
+ // "func": "POINT",
+ // "period": 90,
+ // "factor": 1,
+ // "minVal": 0,
+ // "maxVal": 65536,
+ // "unit": "BMap"
+ //},
+ //"StatusDetWord": {
+ // "name": "StatusDetWord",
+ // "description": "Word di Status",
+ // "memAddr": "40005",
+ // "tipoMem": "Int",
+ // "index": 5,
+ // "size": 1,
+ // "func": "POINT",
+ // "period": 90,
+ // "factor": 1,
+ // "minVal": 0,
+ // "maxVal": 65536,
+ // "unit": "BMap"
+ //},
"FreqInverter": {
"name": "FreqInverter",
"description": "Frequenza Inverter",
@@ -101,5 +101,10 @@
"maxVal": 999999999,
"unit": "A"
}
+ },
+ "optMemPar": {
+ "AutoBitCond": "40002.14=1",
+ "EStopBitCond": "40002.9=0",
+ "WorkBitCond": "40002.0=1"
}
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs
index 138aadbe..917d5d04 100644
--- a/IOB-WIN-NEXT/IobGeneric.cs
+++ b/IOB-WIN-NEXT/IobGeneric.cs
@@ -174,7 +174,7 @@ namespace IOB_WIN_NEXT
///
/// Struttura memoria PLC x lettura/scrittura da JSON file
///
- public plcMemMap memMap;
+ public plcMemMapExt memMap;
///
/// Minimo numero di px da inviare in blocco
@@ -5191,8 +5191,9 @@ namespace IOB_WIN_NEXT
lgInfoStartup($"File json PARAMETRI composto da {jsonData.Length} caratteri");
try
{
- memMap = JsonConvert.DeserializeObject(jsonData);
+ memMap = JsonConvert.DeserializeObject(jsonData);
setupMemMap();
+ setupOptMemPar();
}
catch (Exception exc)
{
@@ -5246,6 +5247,47 @@ namespace IOB_WIN_NEXT
lgInfoStartup("DONE loadMemConf");
}
+ ///
+ /// Dizionario condizioni di check (opzionali) da usare x valori controllo bitmap (es ModBUs TCP Imax)
+ ///
+ protected Dictionary OptCheckConditions { get; set; } = new Dictionary();
+
+ protected virtual void setupOptMemPar()
+ {
+ // verifica se siano necessari configuraizoni speciali dalla optMemPar (es per ricerca condizioni status bolleane come ModbusTCP...)
+ if (memMap.optMemPar != null && memMap.optMemPar.Count > 0)
+ {
+ // cerco condizioni speciali x Auto, Estop, Work.. devono essere *BitCond
+ var listPar2add = memMap.optMemPar.Where(x => x.Key.EndsWith("BitCond")).ToList();
+ if (listPar2add != null && listPar2add.Count > 0)
+ {
+ foreach (var item in listPar2add)
+ {
+ addCheckCondition(item.Key, item.Value);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Aggiunge in setup memoria la checkCondition ricevuta già "decodificata"
+ ///
+ /// Chiave da aggiungere
+ /// Valore da decodificare e poi aggiungere
+ private void addCheckCondition(string ompKey, string ompVal)
+ {
+ var newCond = new BitConditionCheck(ompVal);
+ // cerco x aggiornare o aggiungere...
+ if (OptCheckConditions.ContainsKey(ompKey))
+ {
+ OptCheckConditions[ompKey] = newCond;
+ }
+ else
+ {
+ OptCheckConditions.Add(ompKey, newCond);
+ }
+ }
+
///
/// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
///
@@ -6689,6 +6731,9 @@ namespace IOB_WIN_NEXT
}
#endregion Private Methods
+
+
+
}
///
diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs
index 21a5f25c..1bedd686 100644
--- a/IOB-WIN-NEXT/IobModbusTCP.cs
+++ b/IOB-WIN-NEXT/IobModbusTCP.cs
@@ -27,7 +27,7 @@ namespace IOB_WIN_NEXT
{
lgInfo("NEW IOB ModBus TCP");
DateTime adesso = DateTime.Now;
- memMap = new plcMemMap();
+ memMap = new plcMemMapExt();
if (IOBConf != null)
{
// gestione invio ritardato contapezzi
diff --git a/IOB-WIN-NEXT/IobModbusTCPImaxAeromec.cs b/IOB-WIN-NEXT/IobModbusTCPImaxAeromec.cs
index 563e88e3..5dce5300 100644
--- a/IOB-WIN-NEXT/IobModbusTCPImaxAeromec.cs
+++ b/IOB-WIN-NEXT/IobModbusTCPImaxAeromec.cs
@@ -43,51 +43,8 @@ namespace IOB_WIN_NEXT
#endregion Public Constructors
- #region Protected Methods
+ #region Protected Properties
- ///
- /// Restituisce status di emergenza
- ///
- protected bool EStop
- {
- get
- {
- bool answ = false;
- int currStatus = 0;
- // hard coded
- int statusReg = 40002;
- // deve avere allarmi (è un allarme EStop)
- if (hasAlarms())
- {
- int[] listInt = new int[2];
- listInt = HoldingRegisterLUT[statusReg];
- currStatus = ModbusClient.ConvertRegistersToInt(listInt);
- // hard coded il 9° bit a zero
- answ = ((currStatus & (1 << 9)) == 0);
- }
- return answ;
- }
- }
-
- ///
- /// Restituisce status di LAVORA, hard coded
- ///
- protected bool Work
- {
- get
- {
- bool answ = false;
- int currStatus = 0;
- // hard coded
- int statusReg = 40002;
- int[] listInt = new int[2];
- listInt = HoldingRegisterLUT[statusReg];
- currStatus = ModbusClient.ConvertRegistersToInt(listInt);
- // hard coded il 5° bit
- answ = ((currStatus & (1 << 0)) > 0);
- return answ;
- }
- }
///
/// Restituisce status di AUTOmatico, hard coded
///
@@ -95,6 +52,8 @@ namespace IOB_WIN_NEXT
{
get
{
+ return testCondition("WorkBitCond");
+#if false
bool answ = false;
int currStatus = 0;
// hard coded
@@ -105,9 +64,49 @@ namespace IOB_WIN_NEXT
// hard coded il 5° bit
answ = ((currStatus & (1 << 14)) > 0);
return answ;
+#endif
}
}
+ ///
+ /// Restituisce status di ESTOP triggered (triggered = premuta, altrimenti armed)
+ ///
+ protected bool EStopTriggered
+ {
+ get
+ {
+ return testCondition("EStopBitCond");
+ }
+ }
+
+ ///
+ /// Restituisce status di LAVORA, hard coded
+ ///
+ protected bool Work
+ {
+ get
+ {
+ return testCondition("WorkBitCond");
+#if false
+
+ bool answ = false;
+ int currStatus = 0;
+ // hard coded
+ int statusReg = 40002;
+ int[] listInt = new int[2];
+ listInt = HoldingRegisterLUT[statusReg];
+ currStatus = ModbusClient.ConvertRegistersToInt(listInt);
+ // hard coded il 5° bit
+ answ = ((currStatus & (1 << 0)) > 0);
+ return answ;
+#endif
+ }
+ }
+
+ #endregion Protected Properties
+
+ #region Protected Methods
+
///
/// Effettua decodifica aree memoria alla bitmap usata x MAPO
///
@@ -137,26 +136,32 @@ namespace IOB_WIN_NEXT
{
byteSignals += (1 << 0);
}
- // processo dagli stati + gravi...
- if (!EStop)
+ if (HoldingRegisterLUT != null && HoldingRegisterLUT.Count > 0)
{
- byteSignals += (1 << 7);
- }
+ // se emergenza NON premuta (triggered) indico OK (armata...)
+ if (!EStopTriggered)
+ {
+ byteSignals += (1 << 7);
+ }
- // processo dagli stati + gravi...
- if (hasAlarms())
- {
- byteSignals += (1 << 3);
+ // processo dagli stati + gravi...
+ if (hasAlarms())
+ {
+ byteSignals += (1 << 3);
+ }
+ if (Work)
+ {
+ byteSignals += (1 << 1);
+ }
+ if (!Auto)
+ {
+ byteSignals += (1 << 4);
+ }
}
- if (Work)
+ else
{
- byteSignals += (1 << 1);
+ lgInfo("HoldingRegisterLUT vuoto!");
}
- if (!Auto)
- {
- byteSignals += (1 << 4);
- }
-
// salvo!
B_input = byteSignals;
@@ -190,6 +195,31 @@ namespace IOB_WIN_NEXT
lgTrace("-------------------- Completato test lettura {baseAddr} --------------------");
}
+ ///
+ /// Testa la condition modbus da LUT + configurazione
+ ///
+ ///
+ ///
+ private bool testCondition(string cKey)
+ {
+ bool answ = false;
+ if (OptCheckConditions.ContainsKey(cKey))
+ {
+ int currStatus = 0;
+ int[] listInt = new int[2];
+ listInt = HoldingRegisterLUT[OptCheckConditions[cKey].BaseAddr];
+ currStatus = ModbusClient.ConvertRegistersToInt(listInt);
+ // hard coded il 9° bit a zero
+ answ = ((currStatus & (1 << OptCheckConditions[cKey].BitNum)) == OptCheckConditions[cKey].ValOk);
+ lgTrace($"testCondition for {cKey} | BaseAddr: {OptCheckConditions[cKey].BaseAddr} | BitNum: {OptCheckConditions[cKey].BitNum} | ValOk: {OptCheckConditions[cKey].ValOk}");
+ }
+ else
+ {
+ lgTrace($"testCondition error: {cKey} not found");
+ }
+ return answ;
+ }
+
private void testRead()
{
foreach (var item in memSetR)
diff --git a/IOB-WIN-NEXT/IobModbusTCPZetapack.cs b/IOB-WIN-NEXT/IobModbusTCPZetapack.cs
index 99699781..754ca2ac 100644
--- a/IOB-WIN-NEXT/IobModbusTCPZetapack.cs
+++ b/IOB-WIN-NEXT/IobModbusTCPZetapack.cs
@@ -55,7 +55,7 @@ namespace IOB_WIN_NEXT
bool answ = false;
int currStatus = 0;
// hard coded
- int statusReg = 40003;
+ int statusReg = 40002;
// deve avere allarmi (è un allarme EStop)
if (hasAlarms())
{
@@ -79,7 +79,7 @@ namespace IOB_WIN_NEXT
bool answ = false;
int currStatus = 0;
// hard coded
- int statusReg = 40003;
+ int statusReg = 40002;
int[] listInt = new int[2];
listInt = HoldingRegisterLUT[statusReg];
currStatus = ModbusClient.ConvertRegistersToInt(listInt);
@@ -98,7 +98,7 @@ namespace IOB_WIN_NEXT
bool answ = false;
int currStatus = 0;
// hard coded
- int statusReg = 40003;
+ int statusReg = 40002;
int[] listInt = new int[2];
listInt = HoldingRegisterLUT[statusReg];
currStatus = ModbusClient.ConvertRegistersToInt(listInt);
@@ -137,26 +137,32 @@ namespace IOB_WIN_NEXT
{
byteSignals += (1 << 0);
}
- // processo dagli stati + gravi...
- if (!EStop)
+ if (HoldingRegisterLUT != null && HoldingRegisterLUT.Count > 0)
{
- byteSignals += (1 << 7);
- }
+ // processo dagli stati + gravi...
+ if (!EStop)
+ {
+ byteSignals += (1 << 7);
+ }
- // processo dagli stati + gravi...
- if (hasAlarms())
- {
- byteSignals += (1 << 3);
+ // processo dagli stati + gravi...
+ if (hasAlarms())
+ {
+ byteSignals += (1 << 3);
+ }
+ if (Work)
+ {
+ byteSignals += (1 << 1);
+ }
+ if (!Auto)
+ {
+ byteSignals += (1 << 4);
+ }
}
- if (Work)
+ else
{
- byteSignals += (1 << 1);
+ lgInfo("HoldingRegisterLUT vuoto!");
}
- if (!Auto)
- {
- byteSignals += (1 << 4);
- }
-
// salvo!
B_input = byteSignals;
diff --git a/IOB-WIN-NEXT/IobOpcUa.cs b/IOB-WIN-NEXT/IobOpcUa.cs
index 1b6369a6..122d0268 100644
--- a/IOB-WIN-NEXT/IobOpcUa.cs
+++ b/IOB-WIN-NEXT/IobOpcUa.cs
@@ -1176,7 +1176,7 @@ namespace IOB_WIN_NEXT
opcUaParams = JsonConvert.DeserializeObject(jsonData);
lgDebug($"Decodifica aree OpcUaParamConf: trovati {opcUaParams.paramsEndThresh.Count} valori paramsEndThresh");
// sistemo se ci sono dati memMap...
- memMap = new plcMemMap();
+ memMap = new plcMemMapExt();
if (opcUaParams.mMapWrite != null)
{
memMap.mMapWrite = opcUaParams.mMapWrite;
@@ -1186,6 +1186,7 @@ namespace IOB_WIN_NEXT
memMap.mMapRead = opcUaParams.mMapRead;
}
setupMemMap();
+ setupOptMemPar();
}
catch (Exception exc)
{
diff --git a/IOB-WIN-NEXT/IobSiemens.cs b/IOB-WIN-NEXT/IobSiemens.cs
index 103901c6..7b061e4e 100644
--- a/IOB-WIN-NEXT/IobSiemens.cs
+++ b/IOB-WIN-NEXT/IobSiemens.cs
@@ -79,7 +79,7 @@ namespace IOB_WIN_NEXT
///
public IobSiemens(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
- memMap = new plcMemMap();
+ memMap = new plcMemMapExt();
writePre = true;
if (IOBConf.optPar.ContainsKey("WRITE_PRE"))
{