diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 99e1da4b..52a04d7f 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -294,6 +294,16 @@ namespace IOB_UT_NEXT
///
OpcUa,
+ ///
+ /// Adapter OPC-UA CMS
+ ///
+ OpcUaCMS,
+
+ ///
+ /// Adapter OPC-UA SCM
+ ///
+ OpcUaSCM,
+
///
/// Adapter OPC-UA per Ewon
///
diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs
index 267045c7..369cdd1c 100644
--- a/IOB-UT-NEXT/ToMapo.cs
+++ b/IOB-UT-NEXT/ToMapo.cs
@@ -458,6 +458,16 @@ namespace IOB_UT_NEXT
///
public Dictionary mMapWrite { get; set; } = new Dictionary();
+ ///
+ /// Elenco dei SOLI item sottoscritti (se vuoto TUTTI)
+ ///
+ public List subscribedItems { get; set; } = new List();
+
+ ///
+ /// Elenco dei NodeId da ignorare intesi come interi rami (se vuoto NON filtro)
+ ///
+ public List filterItemsNodeId { get; set; } = new List();
+
#endregion Public Properties
}
}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs
index 4af037c8..ece6dab5 100644
--- a/IOB-WIN-NEXT/AdapterForm.cs
+++ b/IOB-WIN-NEXT/AdapterForm.cs
@@ -1211,6 +1211,12 @@ namespace IOB_WIN_NEXT
start.Enabled = true;
break;
+ case tipoAdapter.OpcUaCMS:
+ case tipoAdapter.OpcUaSCM:
+ iobObj = new IobOpcUaCMS(this, IOBConf);
+ start.Enabled = true;
+ break;
+
case tipoAdapter.OpcUaEwon:
iobObj = new IobOpcUaEwon(this, IOBConf);
start.Enabled = true;
diff --git a/IOB-WIN-NEXT/DATA/CONF/FP_TR2.ini b/IOB-WIN-NEXT/DATA/CONF/FP_TR2.ini
new file mode 100644
index 00000000..67f19087
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/FP_TR2.ini
@@ -0,0 +1,74 @@
+;Configurazione IOB-WIN
+[IOB]
+;Centro di lavoro OpcUa
+CNCTYPE=OpcUaCMS
+;CNCTYPE=OpcUa
+PING_MS_TIMEOUT=500
+
+[MACHINE]
+VENDOR=CMS
+MODEL=Eidos
+
+[CNC]
+IP=192.168.2.12
+PORT=62541
+;IP=192.168.250.53
+;PORT=4840
+GETPRGNAME=true
+
+[SERVER]
+MPIP=http://192.168.2.252
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/sendReboot.aspx?idxMacchina=
+CMD_ODL_STARTED=/IOB/getCurrOdlStart/
+CMD_FORCLE_SPLIT_ODL=/IOB/forceSplitOdlFull/
+CMD_IDLE_TIME=/IOB/getIdlePeriod/
+
+[MEMORY]
+ADDR_READ=DB9999.DBB0
+ADDR_WRITE=DB9999.DBB0
+SIZE_READ=0
+SIZE_WRITE=0
+;BIT0=CONN
+;BIT1=DB60.DBB1
+;BIT2=PZCOUNT.STD.DB700.DBW22
+;BIT3=DB60.DBB3
+;BIT4=DB60.DBB4
+
+
+[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]
+AUTO_CHANGE_ODL=true
+CHANGE_ODL_MODE=PZCOUNT_RESET
+PZCOUNT_MODE=OPC
+DISABLE_PZCOUNT=FALSE
+ENABLE_SEND_PZC_BLOCK=TRUE
+MIN_SEND_PZC_BLOCK=0
+MAX_SEND_PZC_BLOCK=100
+ENABLE_DYN_DATA=FALSE
+FORCE_DYN_DATA=TRUE
+ENABLE_DATA_FILTER=TRUE
+ENABLE_CLI_RESTART=TRUE
+; conf parametri memoria READ/WRITE
+OPC_PARAM_CONF=FP_TR2.json
+
+[BRANCH]
+NAME=master
diff --git a/IOB-WIN-NEXT/DATA/CONF/FP_TR2.json b/IOB-WIN-NEXT/DATA/CONF/FP_TR2.json
new file mode 100644
index 00000000..c7d34b51
--- /dev/null
+++ b/IOB-WIN-NEXT/DATA/CONF/FP_TR2.json
@@ -0,0 +1,83 @@
+{
+ "BrowseFullVal": "ns=2;s=Machine",
+ "BrowseNSIndex": 2,
+ "BrowseValue": 0,
+ "keyPartCount": "ProductionProcesses/01/Programs/01/RepsDone",
+ "keyPartReq": "ProductionProcesses/01/Programs/01/RepsTarget",
+ "keyPartId": "",
+ "keyProgName": "ProductionProcesses/01/Programs/01/Name",
+ "keyRunMode": "Status",
+ "pingAsPowerOn": true,
+ "condWork": [
+ {
+ "keyName": "Status",
+ "targetValue": "EXE"
+ }
+ ],
+ "condPowerOn": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "Power",
+ "targetValue": "true"
+ }
+ ]
+ },
+ "condReady": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "Status",
+ "targetValue": "READY"
+ }
+ ]
+ },
+ "condManual": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "Status",
+ "targetValue": "MDI"
+ }
+ ]
+ },
+ "condEStop": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "Emergency",
+ "targetValue": "false"
+ }
+ ]
+ },
+ "condError": {
+ "checkMode": "AND",
+ "checkList": [
+ {
+ "keyName": "Alarm",
+ "targetValue": "true"
+ }
+ ]
+ },
+ "condCountEnabled": {
+ "checkMode": "AND",
+ "checkList": []
+ },
+ "fluxLogVeto": [
+ "L2p1CommonVariable"
+ ],
+ "itemTranslation": {
+ "avail": "Machine Available",
+ "rstat": "Execution Mode",
+ "mode": "Controller Mode",
+ "ncprog": "Program Name",
+ "IO_150": "Qta Prodotta (metri)",
+ "lpremain": "Qta Richiesta",
+ "fdovrd": "PATH FEED OVERRIDE",
+ "rovrd": "PATH RAPID OVERRIDE"
+ },
+ "filterItemsNodeId": [
+ "ns=2;s=Machine/Axes",
+ "ns=2;s=Machine/OperatingGroups"
+ ]
+}
\ 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 5370415f..735286f9 100644
--- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini
@@ -71,6 +71,5 @@ CLI_INST=SteamWareSim
;STARTLIST=OPC_UA
;STARTLIST=SIM_PIZ03
;STARTLIST=FOV062
-STARTLIST=3013
-
+STARTLIST=FP_TR2
MAXCNC=10
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
index 879b7028..f42062ec 100644
--- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
+++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj
@@ -182,6 +182,7 @@
+
@@ -340,6 +341,12 @@
Always
+
+ Always
+
+
+ Always
+
Always
diff --git a/IOB-WIN-NEXT/IobOpcUa.cs b/IOB-WIN-NEXT/IobOpcUa.cs
index 526cee7c..b9665ce3 100644
--- a/IOB-WIN-NEXT/IobOpcUa.cs
+++ b/IOB-WIN-NEXT/IobOpcUa.cs
@@ -86,7 +86,7 @@ namespace IOB_WIN_NEXT
{
bool.TryParse(getOptPar("ENABLE_DATA_FILTER"), out enableDataFilter);
}
- // gestione restart MTC client...
+ // gestione restart OpcUa client...
if (!string.IsNullOrEmpty(getOptPar("ENABLE_CLI_RESTART")))
{
bool.TryParse(getOptPar("ENABLE_CLI_RESTART"), out enableCliRestart);
@@ -316,15 +316,50 @@ namespace IOB_WIN_NEXT
if (connected)
{
// faccio un primo browse dei dati...
+ Dictionary nodeIdNameList = new Dictionary();
if (!string.IsNullOrEmpty(opcUaParams.BrowseFullVal))
{
- selectedItemList = UA_ref.Browse(opcUaParams.BrowseFullVal);
+ UA_ref.Browse(opcUaParams.BrowseFullVal, opcUaParams.filterItemsNodeId, ref nodeIdNameList);
}
else
{
- selectedItemList = UA_ref.Browse(opcUaParams.BrowseNSIndex, opcUaParams.BrowseValue);
+ UA_ref.Browse(opcUaParams.BrowseNSIndex, opcUaParams.BrowseValue, opcUaParams.filterItemsNodeId, ref nodeIdNameList);
}
- // sottoscrivo a rilevazione cambio dati
+ // loggo elenco degli item sottocrivibili...
+ lgInfo("---------- AVAILABLE FOR SUBSCRIBE ----------");
+ foreach (var item in nodeIdNameList)
+ {
+ lgInfo(item.Key);
+ }
+ lgInfo("---------- END LIST ----------");
+
+ // se ho un insieme non vuoto degli item sottoscritti carico solo quelli
+ if (opcUaParams.subscribedItems != null && opcUaParams.subscribedItems.Count > 0)
+ {
+ // cerco e aggiungo SOLO quelle indicati
+ foreach (var currItem in opcUaParams.subscribedItems)
+ {
+ if (nodeIdNameList.ContainsKey(currItem))
+ {
+ selectedItemList.Add(currItem, nodeIdNameList[currItem]);
+ }
+ }
+ }
+ // altrimenti tutti!
+ else
+ {
+ selectedItemList = nodeIdNameList;
+ }
+
+ // loggo elenco degli item sottocrivibili...
+ lgInfo("---------- SUBSCRIBED NODES ----------");
+ foreach (var item in nodeIdNameList)
+ {
+ lgInfo(item.Key);
+ }
+ lgInfo("---------- END LIST ----------");
+
+ // sottoscrivo a rilevazione cambio dati solo l'incrocio degli insiemi
List subscribedItems = UA_ref.SubscribeToDataChanges(selectedItemList);
// aggiungo come DataItems
int dSamplePeriod = 0;
@@ -735,37 +770,39 @@ namespace IOB_WIN_NEXT
{
string jsonFullPath = $"{Application.StartupPath}/DATA/CONF/{fileName}";
lgInfo($"Apertura file {jsonFullPath}");
- StreamReader reader = new StreamReader(jsonFullPath);
- string jsonData = reader.ReadToEnd().Replace("\n", "").Replace("\r", "");
- if (!string.IsNullOrEmpty(jsonData))
+ using (StreamReader reader = new StreamReader(jsonFullPath))
{
- lgInfo($"File json composto da {jsonData.Length} caratteri");
- try
+ string jsonData = reader.ReadToEnd().Replace("\n", "").Replace("\r", "");
+ if (!string.IsNullOrEmpty(jsonData))
{
- opcUaParams = JsonConvert.DeserializeObject(jsonData);
- lgInfo($"Decodifica aree OpcUaParamConf: trovati {opcUaParams.paramsEndThresh.Count} valori paramsEndThresh");
- // sistemo se ci sono dati memMap...
- memMap = new plcMemMap();
- if (opcUaParams.mMapWrite != null)
+ lgInfo($"File json composto da {jsonData.Length} caratteri");
+ try
{
- memMap.mMapWrite = opcUaParams.mMapWrite;
+ opcUaParams = JsonConvert.DeserializeObject(jsonData);
+ lgInfo($"Decodifica aree OpcUaParamConf: trovati {opcUaParams.paramsEndThresh.Count} valori paramsEndThresh");
+ // sistemo se ci sono dati memMap...
+ memMap = new plcMemMap();
+ if (opcUaParams.mMapWrite != null)
+ {
+ memMap.mMapWrite = opcUaParams.mMapWrite;
+ }
+ if (opcUaParams.mMapRead != null)
+ {
+ memMap.mMapRead = opcUaParams.mMapRead;
+ }
+ setupMemMap();
}
- if (opcUaParams.mMapRead != null)
+ catch (Exception exc)
{
- memMap.mMapRead = opcUaParams.mMapRead;
+ lgError($"Eccezione in decodifica conf json OPC-UA:{Environment.NewLine}{exc}");
}
- setupMemMap();
}
- catch (Exception exc)
+ else
{
- lgError($"Eccezione in decodifica conf json OPC-UA:{Environment.NewLine}{exc}");
+ lgError("Errore in loadOpcUaConf: file json vuoto!");
}
}
- else
- {
- lgError("Errore in loadOpcUaConf: file json vuoto!");
- }
- reader.Dispose();
+ //reader.Dispose();
}
#endregion Protected Methods
diff --git a/IOB-WIN-NEXT/IobOpcUaCMS.cs b/IOB-WIN-NEXT/IobOpcUaCMS.cs
new file mode 100644
index 00000000..c30e24bb
--- /dev/null
+++ b/IOB-WIN-NEXT/IobOpcUaCMS.cs
@@ -0,0 +1,372 @@
+using MapoSDK;
+using Newtonsoft.Json;
+using Opc.Ua;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IOB_WIN_NEXT
+{
+ public class IobOpcUaCMS : IobOpcUa
+ {
+ #region Protected Fields
+
+ ///
+ /// Modalità cambio ODL
+ ///
+ protected string CHANGE_ODL_MODE = "";
+
+ protected bool testDone = false;
+
+ #endregion Protected Fields
+
+ #region Public Constructors
+
+ ///
+ /// Estende l'init della classe base, impiegando il pacchetto Nuget OPC-UA foundation con la gestione specifica per CMS/SCM (es. Eidos termoformatrice)
+ /// https://github.com/OPCFoundation/UA-.NETStandard
+ ///
+ ///
+ ///
+ public IobOpcUaCMS(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ // inizializzo classe base...
+ if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE")))
+ {
+ CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE");
+ }
+
+ // impostazioni specifiche OpcUA SCM
+ }
+
+ #endregion Public Constructors
+
+ #region Protected Methods
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ ///
+ protected override void decodeToBaseBitmap()
+ {
+ DateTime adesso = DateTime.Now;
+ // init a zero...
+ B_input = 0;
+
+ /* -----------------------------------------------------
+ * STATE MACHINE 60 STD / SIMULA
+ *------------------------------------------------------
+ * bitmap MAPO
+ * B0: POWER_ON
+ * B1: RUN
+ * B2: pzCount
+ * B3: allarme
+ * B4: manuale
+ * B5: SlowTC (NON gestito qui)
+ * B6: warm-up / cool-down (NON GESTITO ?!?)
+ * B7: emergenza
+ ---------------------------------------------------- */
+
+ // se valido il check ping lo eseguo... altrimenti lo do x buono
+ bool checkPing = !opcUaParams.pingAsPowerOn;
+ string currRun = "";
+ if (!checkPing)
+ {
+ checkPing = (testPingMachine == IPStatus.Success);
+ }
+ // bit 0 (poweron) imposto a 1 SE pingo + PowerOn=="ON"...
+ bool powerOnOk = checkPing && hasPowerOn;
+ // procedo SOLO SE mi da ping OK...
+ if (checkPing)
+ {
+ B_input = powerOnOk ? 1 : 0;
+
+ // variabili RUN...
+ currRun = getDataItemValue(opcUaParams.keyRunMode);
+
+ // salvo running come = working...
+ isRunning = isWorking;
+
+ // se ho emergenza premuta --> emergenza!
+ if (hasEStopArmed)
+ {
+ B_input += (1 << 7);
+ }
+ //// se ho emergenza premuta --> emergenza!
+ //if (isWarmUpCoolDown)
+ //{
+ // B_input += (1 << 6);
+ //}
+ // se ho almeno 1 allarme E NON SONO IN AUTO --> ALARM!
+ if (hasError)
+ {
+ B_input += (1 << 3);
+ }
+ if (isWorking)
+ {
+ // RUN = LAVORA!
+ B_input += (1 << 1);
+ }
+ else if (powerOnOk && (!isReady || isManual))
+ {
+ // se NON ready --> manual
+ B_input += (1 << 4);
+ }
+ }
+
+ // controllo se sono poweroff e se non ho dati buoni da > 2 minuti --> disconnetto
+ if (adesso.Subtract(lastCurrent).TotalMinutes > 5)
+ {
+ tryDisconnect();
+ }
+
+ // solo se non ho veto check
+ int vFactor = 2;
+ if (vetoCheckStatus < adesso)
+ {
+ lgInfo($"Stato variabili checkPing: {testPingMachine}");
+ // imposto veto per vetoSeconds...
+ vetoCheckStatus = adesso.AddSeconds(vetoSeconds * vFactor);
+ }
+
+ // log opzionale!
+ if (verboseLog)
+ {
+ lgInfo($"Trasformazione checkPing: {checkPing} | hasPowerOn: {hasPowerOn} | B_input: {B_input} | currRun = {currRun}");
+ }
+ }
+
+ ///
+ /// Effettua vera scrittura parametri
+ ///
+ ///
+ protected override void plcWriteParams(ref List updatedPar)
+ {
+#if false
+ if (!testDone)
+ {
+ try
+ {
+ if (UA_ref != null)
+ {
+ UA_ref.WriteTestNodes();
+ testDone = true;
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in WriteTestNodes{Environment.NewLine}{exc}");
+ }
+ }
+#endif
+
+ dataConf currMem = null;
+ int byteSize = 0;
+ string memAddrWrite = "";
+ string serObj = "";
+ if (updatedPar != null)
+ {
+ List nodes2Write = new List();
+ // controllo i parametri... ne gestisco 4...
+ foreach (var item in updatedPar)
+ {
+ try
+ {
+ memAddrWrite = "";
+ int valInt = 0;
+ double valReal = 0;
+ // cerco in area memMapWrite...
+ if (memMap.mMapWrite.ContainsKey(item.uid))
+ {
+ // recupero!
+ currMem = memMap.mMapWrite[item.uid];
+ byteSize = currMem.size;
+ memAddrWrite = currMem.memAddr;
+
+ WriteValue commWriteVal = new WriteValue();
+ commWriteVal.NodeId = new NodeId(currMem.memAddr);
+ commWriteVal.AttributeId = Attributes.Value;
+ commWriteVal.Value = new DataValue();
+ commWriteVal.Value.Value = item.reqValue;
+
+ // faccio preliminarmente upsertKey...
+ upsertKey(currMem.name, currMem.value);
+ serObj = JsonConvert.SerializeObject(item);
+ lgInfo($"Inizio processing plcWriteParams per {currMem.name} | valore richiesto {currMem.value}");
+ lgInfo($"---------------{Environment.NewLine}UPDATED PARAM:{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
+ serObj = JsonConvert.SerializeObject(currMem);
+ lgInfo($"---------------{Environment.NewLine}MEMORY CONTENT:{Environment.NewLine}{serObj}{Environment.NewLine}---------------");
+
+ switch (currMem.tipoMem)
+ {
+ case plcDataType.Boolean:
+ break;
+
+ case plcDataType.Int:
+ case plcDataType.DInt:
+ case plcDataType.Word:
+ case plcDataType.DWord:
+ int.TryParse(item.reqValue, out valInt);
+ commWriteVal.Value.Value = valInt;
+ memAddrWrite = currMem.memAddr;
+ break;
+
+ case plcDataType.Real:
+ double.TryParse(item.reqValue, out valReal);
+ commWriteVal.Value.Value = valReal;
+ break;
+
+ case plcDataType.String:
+
+ // verifico caso speciale: se è art/comm scrivo AFFIANCATE...
+ if (item.uid == "setArt" | item.uid == "setComm")
+ {
+ // accodo commessa + articolo con padding secondo lunghezza...
+ string codArt = "";
+ if (currProdData.ContainsKey("setArt"))
+ {
+ codArt = string.IsNullOrEmpty(currProdData["setArt"]) ? "" : currProdData["setArt"];
+ }
+ string codComm = "";
+ if (currProdData.ContainsKey("setComm"))
+ {
+ codComm = string.IsNullOrEmpty(currProdData["setComm"]) ? "" : currProdData["setComm"];
+ }
+ // padding...
+ codArt = codArt.PadRight(20, ' ');
+ codComm = codComm.PadRight(20, ' ');
+ commWriteVal.Value.Value = $"{codComm}{codArt}";
+ }
+ break;
+
+ default:
+ break;
+ }
+ lgInfo($"---------------{Environment.NewLine}OPC-UA data:{Environment.NewLine}NodeId: {commWriteVal.NodeId}{Environment.NewLine}Value: {commWriteVal.Value.Value}{Environment.NewLine}---------------");
+
+ if (!string.IsNullOrEmpty(memAddrWrite))
+ {
+ nodes2Write.Add(commWriteVal);
+ }
+ 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}");
+ }
+ }
+
+ if (nodes2Write.Count > 0)
+ {
+ UA_ref.WriteNodes(nodes2Write);
+ }
+ }
+ }
+
+ #endregion Protected Methods
+
+ #region Public Methods
+
+ ///
+ /// Processo i task richiesti e li elimino dalla coda 1:1
+ ///
+ ///
+ public override Dictionary executeTasks(Dictionary task2exe)
+ {
+ // uso metodo base x ora
+ return base.executeTasks(task2exe);
+ }
+
+ ///
+ /// Effettua vero processing contapezzi
+ ///
+ public override void processContapezzi()
+ {
+ if (utils.CRB("enableContapezzi"))
+ {
+ // check condizione validazione
+ if (checkMultiCondition(opcUaParams.condCountEnabled.checkList, opcUaParams.condCountEnabled.checkMode) || opcUaParams.condCountEnabled.checkList.Count == 0)
+ {
+ // cerco parametro contapezzi...
+ string currPzCount = getDataItemValue(opcUaParams.keyPartCount);
+
+ // se ho un contapezzi... processo...
+ if (!string.IsNullOrEmpty(currPzCount))
+ {
+ int newVal = -1;
+ bool fatto = Int32.TryParse(currPzCount, out newVal);
+
+ if (fatto)
+ {
+ // gestione decremento contapezzi: viene "messo via" solo SE c'è un effettivo decremento contapezzi...
+ if (newVal < contapezziPLC)
+ {
+ pzCountResetted = true;
+ // incremento contatore richiesta
+ countKeyRichiesta = countKeyRichiesta + 1;
+ // log
+ lgInfo("Contapezzi resettato (PLC) --> pzCountResetted = true");
+ }
+
+ // salvo nuovo valore contapezziPLC
+ contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
+ }
+ else
+ {
+ lgError($"Errore in decodifica valore contapezzi, valore rilevato: {currPzCount}");
+ }
+ }
+ else
+ {
+ lgError("Errore in decodifica valore contapezzi, valore vuoto!");
+ }
+ }
+
+ if (CHANGE_ODL_MODE == "PZCOUNT_RESET")
+ {
+ // controllo comunque, se è ZERO il contapezzi, e sul server è maggiore il valore x ODL e NON abilitato il trigger reset --> abilito trigger...
+ if (!pzCountResetted && contapezziPLC == 0 && contapezziIOB > 0)
+ {
+ pzCountResetted = true;
+ // incremento contatore richiesta
+ countKeyRichiesta = countKeyRichiesta + 1;
+ // log
+ lgInfo("Contapezzi resettato (PLC==0 e IOB>PLC) --> pzCountResetted = true");
+ }
+ }
+ }
+ }
+
+ ///
+ /// Effettua reset del contapezzi, NON POSSIBILE in questa versione
+ ///
+ ///
+ public override bool resetcontapezziPLC()
+ {
+ bool answ = false;
+ return answ;
+ }
+
+ ///
+ /// Effettua IMPOSTAZIONE FORZATA del contapezzi, NON POSSIBILE in questa versione
+ ///
+ ///
+ public override bool setcontapezziPLC(int newPzCount)
+ {
+ bool answ = false;
+ return answ;
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/IOB-WIN-NEXT/IobOpcUaEwon.cs b/IOB-WIN-NEXT/IobOpcUaEwon.cs
index a280dd4e..b6c452c2 100644
--- a/IOB-WIN-NEXT/IobOpcUaEwon.cs
+++ b/IOB-WIN-NEXT/IobOpcUaEwon.cs
@@ -33,7 +33,7 @@ namespace IOB_WIN_NEXT
///
public IobOpcUaEwon(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
- // inizializzo calsse base...
+ // inizializzo classe base...
if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE")))
{
CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE");
diff --git a/IOB-WIN-NEXT/IobSiemensTorri.cs b/IOB-WIN-NEXT/IobSiemensTorri.cs
index c0b8cc75..153b4057 100644
--- a/IOB-WIN-NEXT/IobSiemensTorri.cs
+++ b/IOB-WIN-NEXT/IobSiemensTorri.cs
@@ -17,6 +17,12 @@ namespace IOB_WIN_NEXT
* mod: 2019.04.06: aggiunta indicazione (IOB--> PLC) di stato setup su DB701.B0.4
* -------------------------------------------------------------------------------- */
+ #region Protected Fields
+
+ protected Dictionary lastReadAlarms = new Dictionary();
+
+ #endregion Protected Fields
+
#region Public Constructors
///
@@ -32,6 +38,50 @@ namespace IOB_WIN_NEXT
#endregion Public Constructors
+ #region Private Methods
+
+ private int checkAlarmBank(string memAddrAlarms)
+ {
+ int trovato = 0;
+ uint valDW = 0;
+ var MemBlockPZ = new byte[4];
+ bool fatto = S7ReadBB(ref MemBlockPZ, memAddrAlarms, 4);
+ //if (fatto)
+ //{
+ valDW = S7.Net.Types.DWord.FromByteArray(MemBlockPZ.ToArray());
+ // se <> 0 --> log e accodo a dynData
+ if (valDW != 0)
+ {
+ string key = $"MTH_ALARM_{memAddrAlarms}_{valDW}";
+ var biteVal = baseUtils.binaryForm(valDW);
+ lgInfo($"Stato allarmi rilevati: {key} | {valDW} | {biteVal}");
+ // accodo a dictionary
+ string almMsg = $"{DateTime.Now} | val {valDW} | {biteVal}";
+ // se non ci fosse aggiungo
+ if (!lastReadAlarms.ContainsKey(key))
+ {
+ lastReadAlarms.Add(key, almMsg);
+ }
+ trovato++;
+ }
+ //}
+ return trovato;
+ }
+
+ private void checkAlarms()
+ {
+ // leggo i banchi allarmi : cablato D700.DBDW2 --> D700 DBDW14, sono 4 banchi a 32 bit da verificare
+
+ int trovati = 0;
+ // ciclo nei 4 banchi...
+ trovati += checkAlarmBank("DB700.DBDW2");
+ trovati += checkAlarmBank("DB700.DBDW6");
+ trovati += checkAlarmBank("DB700.DBDW10");
+ trovati += checkAlarmBank("DB700.DBDW14");
+ }
+
+ #endregion Private Methods
+
#region Protected Methods
///
@@ -208,48 +258,6 @@ namespace IOB_WIN_NEXT
}
}
- private void checkAlarms()
- {
- // leggo i banchi allarmi : cablato D700.DBDW2 --> D700 DBDW14, sono 4 banchi a 32 bit da verificare
-
- int trovati = 0;
- // ciclo nei 4 banchi...
- trovati += checkAlarmBank("DB700.DBDW2");
- trovati += checkAlarmBank("DB700.DBDW6");
- trovati += checkAlarmBank("DB700.DBDW10");
- trovati += checkAlarmBank("DB700.DBDW14");
- }
-
- private int checkAlarmBank(string memAddrAlarms)
- {
- int trovato = 0;
- uint valDW = 0;
- var MemBlockPZ = new byte[4];
- bool fatto = S7ReadBB(ref MemBlockPZ, memAddrAlarms, 4);
- //if (fatto)
- //{
- valDW = S7.Net.Types.DWord.FromByteArray(MemBlockPZ.ToArray());
- // se <> 0 --> log e accodo a dynData
- if (valDW != 0)
- {
- string key = $"MTH_ALARM_{memAddrAlarms}_{valDW}";
- var biteVal = baseUtils.binaryForm(valDW);
- lgInfo($"Stato allarmi rilevati: {key} | {valDW} | {biteVal}");
- // accodo a dictionary
- string almMsg = $"{DateTime.Now} | val {valDW} | {biteVal}";
- // se non ci fosse aggiungo
- if (!lastReadAlarms.ContainsKey(key))
- {
- lastReadAlarms.Add(key, almMsg);
- }
- trovato++;
- }
- //}
- return trovato;
- }
-
- protected Dictionary lastReadAlarms = new Dictionary();
-
#endregion Protected Methods
#region Public Methods
@@ -291,6 +299,7 @@ namespace IOB_WIN_NEXT
break;
case taskType.fixStopSetup:
+ MemBlock[0] = 0;
taskVal = "VALUE DB701.0.4 --> 0";
lgInfo($"Chiamata fixStopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
break;
@@ -302,6 +311,7 @@ namespace IOB_WIN_NEXT
break;
case taskType.stopSetup:
+ MemBlock[0] = 0;
taskVal = "VALUE DB701.0.4 --> 0";
lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
break;
diff --git a/IOB-WIN-NEXT/UAClient.cs b/IOB-WIN-NEXT/UAClient.cs
index 5ea7e49f..dc99903e 100644
--- a/IOB-WIN-NEXT/UAClient.cs
+++ b/IOB-WIN-NEXT/UAClient.cs
@@ -180,13 +180,13 @@ namespace IOB_WIN_NEXT
///
/// Browse Server nodes
///
- public Dictionary Browse(ushort startNodeNS, uint startNodeVal)
+ public bool Browse(ushort startNodeNS, uint startNodeVal, List vetoBrowse, ref Dictionary nodeIdNameList)
{
- Dictionary nodeIdNameList = new Dictionary();
+ bool fatto = false;
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
- return nodeIdNameList;
+ return false;
}
try
@@ -213,8 +213,17 @@ namespace IOB_WIN_NEXT
foreach (ReferenceDescription result in browseResults)
{
m_output.WriteLine($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
- nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
+ // se NON fa parte dell'elenco dei VETO di filterItems...
+ if (!vetoBrowse.Contains($"{result.NodeId}"))
+ {
+ // se mancasse aggiungo...
+ if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
+ {
+ nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
+ }
+ }
}
+ fatto = true;
}
catch (Exception ex)
{
@@ -222,19 +231,19 @@ namespace IOB_WIN_NEXT
m_output.WriteLine($"Browse Error : {ex.Message}.");
}
- return nodeIdNameList;
+ return fatto;
}
///
/// Browse Server nodes
///
- public Dictionary Browse(string browsePath)
+ public bool Browse(string browsePath, List vetoBrowse, ref Dictionary nodeIdNameList)
{
- Dictionary nodeIdNameList = new Dictionary();
+ bool fatto = false;
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
- return nodeIdNameList;
+ return false;
}
try
@@ -260,9 +269,27 @@ namespace IOB_WIN_NEXT
foreach (ReferenceDescription result in browseResults)
{
+ // se veto --> loggo veto
+ if (vetoBrowse.Contains($"{result.NodeId}"))
+ {
+ m_output.WriteLine($"| FILTERED --> NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
+ }
+ // se NON fa parte dell'elenco dei VETO di filterItems...
+ else {
m_output.WriteLine($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
- nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
+ // se mancasse aggiungo...
+ if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
+ {
+ nodeIdNameList.Add($"{result.NodeId}", result.DisplayName.Text);
+ // se è un nodo object --> faccio sub browse!
+ if (result.NodeClass != NodeClass.Variable)
+ {
+ this.Browse($"{result.NodeId}",vetoBrowse, ref nodeIdNameList);
+ }
+ }
+ }
}
+ fatto = true;
}
catch (Exception ex)
{
@@ -270,7 +297,7 @@ namespace IOB_WIN_NEXT
m_output.WriteLine($"Browse Error : {ex.Message}.");
}
- return nodeIdNameList;
+ return fatto;
}
///