From 79f0ac91cc74446989e8698781a0bb432ad1ee61 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 23 Nov 2024 18:04:33 +0100 Subject: [PATCH 1/2] OPC-UA Siemens Update x gestione SENZA escaped \" (da provare!!!) --- IOB-UT-NEXT/ByteDataConverter.cs | 4 +- IOB-UT-NEXT/ToMapo.cs | 11 ++++ IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json | 20 +++---- IOB-WIN-NEXT/Iob/Generic.cs | 2 +- IOB-WIN-NEXT/IobOpc/OpcUa.cs | 53 ++++++++++++++----- IOB-WIN-NEXT/IobSiemens/SiemensNWSE.cs | 6 +-- .../IobSiemens/SiemensRobotService.cs | 16 +++--- IOB-WIN-NEXT/IobSiemens/SiemensSimec.cs | 4 +- 8 files changed, 78 insertions(+), 38 deletions(-) diff --git a/IOB-UT-NEXT/ByteDataConverter.cs b/IOB-UT-NEXT/ByteDataConverter.cs index a6fbbbd0..15a9c60f 100644 --- a/IOB-UT-NEXT/ByteDataConverter.cs +++ b/IOB-UT-NEXT/ByteDataConverter.cs @@ -36,14 +36,14 @@ namespace IOB_UT_NEXT int bId = 0; if (int.TryParse(sList[3], out bId)) { - this.Bit = bId; + this.Num = bId; } } } public string Product { get; set; } = "ND"; public string Type { get; set; } = "ND"; public int Idx { get; set; } = 0; - public int Bit { get; set; } = 0; + public int Num { get; set; } = 0; } } } diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs index d609cf5f..1cda6736 100644 --- a/IOB-UT-NEXT/ToMapo.cs +++ b/IOB-UT-NEXT/ToMapo.cs @@ -331,6 +331,17 @@ namespace IOB_UT_NEXT /// public Dictionary itemTranslation { get; set; } = new Dictionary(); + /// + /// Separatore configurazione area OPC e subObj in caso di memorie struct speciali + /// + public char kvDelim { get; set; } = '#'; + + /// + /// Separatore definizione aree memoria speciali + /// + public char memDelim { get; set; } = '.'; + + /// /// Nome variabile x EmergencyStop /// diff --git a/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json b/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json index 60bd1ed4..c0934eae 100644 --- a/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json +++ b/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json @@ -2,7 +2,9 @@ "BrowseFullVal": "ns=3;s=\"PV_Exchange_DB_R\"", "BrowseNSIndex": 0, "BrowseValue": 0, - "keyPartCount": "\"Production\"#GEN.Float.0", + "kvDelim": "#", + "memDelim": ".", + "keyPartCount": "Production#GEN.Float.0", "keyPartReq": "", "keyPartId": "", "keyProgName": "", @@ -12,22 +14,22 @@ "maxNullRead": 500, "condWork": [ { - "keyName": "\"Fabric Run\"", + "keyName": "Fabric Run", "bitNum": 0, "targetValue": "1" }, { - "keyName": "\"Enabled\"", + "keyName": "Enabled", "bitNum": 0, "targetValue": "1" }, { - "keyName": "\"Enabled\"", + "keyName": "Enabled", "bitNum": 4, "targetValue": "1" }, { - "keyName": "\"Enabled\"", + "keyName": "Enabled", "bitNum": 5, "targetValue": "1" } @@ -36,12 +38,12 @@ "checkMode": "OR", "checkList": [ { - "keyName": "\"Enabled\"", + "keyName": "Enabled", "bitNum": 4, "targetValue": "1" }, { - "keyName": "\"Enabled\"", + "keyName": "Enabled", "bitNum": 5, "targetValue": "1" } @@ -51,7 +53,7 @@ "checkMode": "AND", "checkList": [ { - "keyName": "\"Enabled\"", + "keyName": "Enabled", "bitNum": 5, "targetValue": "1" } @@ -61,7 +63,7 @@ "checkMode": "OR", "checkList": [ { - "keyName": "\"Fabric Run\"", + "keyName": "Fabric Run", "bitNum": 0, "targetValue": "0" } diff --git a/IOB-WIN-NEXT/Iob/Generic.cs b/IOB-WIN-NEXT/Iob/Generic.cs index fbf15e4b..cdcd53d7 100644 --- a/IOB-WIN-NEXT/Iob/Generic.cs +++ b/IOB-WIN-NEXT/Iob/Generic.cs @@ -3547,7 +3547,7 @@ namespace IOB_WIN_NEXT.Iob } //else //{ - // ActiveAlarmList.Add($"Unknown Bit.{i}"); + // ActiveAlarmList.Add($"Unknown Num.{i}"); //} } } diff --git a/IOB-WIN-NEXT/IobOpc/OpcUa.cs b/IOB-WIN-NEXT/IobOpc/OpcUa.cs index f89e6bf6..4b30a141 100644 --- a/IOB-WIN-NEXT/IobOpc/OpcUa.cs +++ b/IOB-WIN-NEXT/IobOpc/OpcUa.cs @@ -143,14 +143,14 @@ namespace IOB_WIN_NEXT.IobOpc } else { - if (diKey.Contains(kvDelim)) + if (diKey.Contains(opcUaParams.kvDelim)) { - int iPos = opcUaParams.keyPartCount.IndexOf(kvDelim); + int iPos = opcUaParams.keyPartCount.IndexOf(opcUaParams.kvDelim); string kRef = opcUaParams.keyPartCount.Substring(0, iPos); string varDef = opcUaParams.keyPartCount.Substring(iPos + 1); // recupero byte byte[] bArray = getDataItemValueBytes(kRef); - answ = ConvBArr(bArray, varDef, kvSet); + answ = ConvBArr(bArray, varDef, opcUaParams.memDelim); } else { @@ -438,11 +438,7 @@ namespace IOB_WIN_NEXT.IobOpc Dictionary outVal = new Dictionary(); return outVal; } - /// - /// Delimitatore nei key x indicare la parte di configurazione della variabile - /// - private char kvDelim = '#'; - private char kvSet = '.'; + /// /// Effettua vero processing contapezzi /// @@ -458,14 +454,14 @@ namespace IOB_WIN_NEXT.IobOpc { // cerco parametro contapezzi... gest alternativa se è un parametro SPECIALE (con "#") string currPzCount = ""; - if (opcUaParams.keyPartCount.Contains(kvDelim)) + if (opcUaParams.keyPartCount.Contains(opcUaParams.kvDelim)) { - int iPos = opcUaParams.keyPartCount.IndexOf(kvDelim); + int iPos = opcUaParams.keyPartCount.IndexOf(opcUaParams.kvDelim); string kRef = opcUaParams.keyPartCount.Substring(0, iPos); string varDef = opcUaParams.keyPartCount.Substring(iPos + 1); // recupero byte byte[] bArray = getDataItemValueBytes(kRef); - currPzCount = ConvBArr(bArray, varDef, kvSet); + currPzCount = ConvBArr(bArray, varDef, opcUaParams.memDelim); } else { @@ -533,7 +529,7 @@ namespace IOB_WIN_NEXT.IobOpc switch (tVal) { case plcDataType.Boolean: - var boolVal = S7.Net.Types.Boolean.GetValue(bArray[currMem.Idx], currMem.Bit); + var boolVal = S7.Net.Types.Boolean.GetValue(bArray[currMem.Idx], currMem.Num); answ = $"{boolVal}"; break; case plcDataType.Int: @@ -565,7 +561,7 @@ namespace IOB_WIN_NEXT.IobOpc //case plcDataType.RealLH: // break; case plcDataType.String: - answ = S7.Net.Types.String.FromByteArray(bArray.Skip(currMem.Idx).Take(currMem.Bit).ToArray()); + answ = S7.Net.Types.String.FromByteArray(bArray.Skip(currMem.Idx).Take(currMem.Num).ToArray()); break; //case plcDataType.HLPInt: // break; @@ -949,6 +945,28 @@ namespace IOB_WIN_NEXT.IobOpc { accodaFLog(sVal, qEncodeFLog(descr, currVal)); //accodaFLog(sVal, qEncodeFLog(descr, $"{NotifyValue}")); + + // calcolo eventuali variazioni dati "collegati" in memRead/memWrite... + if (memMap.mMapRead != null && memMap.mMapRead.Count > 0) + { + // elenco aree collegate... + var listRelated = memMap.mMapRead.Where(x => x.Value.memAddr.Contains(uuid)); + if (listRelated != null && listRelated.Count() > 0) + { + foreach (var item in listRelated) + { + // ciclo e calcolo valore + var rByte= dataItemMem[uuid].rawByte; + string convVal = ConvBArr(rByte, item.Value.memAddr, opcUaParams.memDelim); + // metto in array currData... + upsertKey(item.Key, convVal); + } + } + } + if (memMap.mMapWrite != null && memMap.mMapWrite.Count > 0) + { + + } } else { @@ -1339,6 +1357,15 @@ namespace IOB_WIN_NEXT.IobOpc { answ = fullCode.Replace(opcUaParams.BaseIdMask, ""); } + // tolgo eventuali caratteri speciali mappati... + // se c'è gestione fix nomi sistemo... + if (opcUaParams.DictOpcNameReplace.Count > 0) + { + foreach (var item in opcUaParams.DictOpcNameReplace) + { + answ = answ.Replace(item.Key, item.Value); + } + } // trimmo spazi x ridurre dimensione se > 50... if (answ.Length > 50) { diff --git a/IOB-WIN-NEXT/IobSiemens/SiemensNWSE.cs b/IOB-WIN-NEXT/IobSiemens/SiemensNWSE.cs index 33d0c4cf..2dd2313f 100644 --- a/IOB-WIN-NEXT/IobSiemens/SiemensNWSE.cs +++ b/IOB-WIN-NEXT/IobSiemens/SiemensNWSE.cs @@ -29,10 +29,10 @@ namespace IOB_WIN_NEXT.IobSiemens * STRUTTURA MEMORIA DB101: (scrittura) 14byte, solo 2 impiegati x ora * NB: segnali da tenere attivi ALMENO 3 secondi x farli recepire * - * B0.0 Bit Azzeramento volume acqua OSMOSI - * B0.1 Bit Azzeramento volume acqua DEPURAZIONE + * B0.0 Num Azzeramento volume acqua OSMOSI + * B0.1 Num Azzeramento volume acqua DEPURAZIONE * - * B1.7 Bit Attivazione modo DEMO (0 = disattivato) + * B1.7 Num Attivazione modo DEMO (0 = disattivato) * * -------------------------------------------------------------------------------- */ diff --git a/IOB-WIN-NEXT/IobSiemens/SiemensRobotService.cs b/IOB-WIN-NEXT/IobSiemens/SiemensRobotService.cs index 637bc879..7740687e 100644 --- a/IOB-WIN-NEXT/IobSiemens/SiemensRobotService.cs +++ b/IOB-WIN-NEXT/IobSiemens/SiemensRobotService.cs @@ -20,14 +20,14 @@ namespace IOB_WIN_NEXT.IobSiemens * * * DB15 - * B0.0 Bit PowerOn - * B0.1 Bit Run - * B0.2 Bit Contapezzi - * B0.3 Bit Allarme - * B0.4 Bit Manuale - * B0.5 Bit MagOutPieno - * B0.6 Bit MagInVuoto - * B0.7 Bit EmergenzaArmata (0=triggered,premuta) + * B0.0 Num PowerOn + * B0.1 Num Run + * B0.2 Num Contapezzi + * B0.3 Num Allarme + * B0.4 Num Manuale + * B0.5 Num MagOutPieno + * B0.6 Num MagInVuoto + * B0.7 Num EmergenzaArmata (0=triggered,premuta) * Contapezzi DInt 2 * PezziRiman DInt 6 * diff --git a/IOB-WIN-NEXT/IobSiemens/SiemensSimec.cs b/IOB-WIN-NEXT/IobSiemens/SiemensSimec.cs index 60843c29..c5e2f7a0 100644 --- a/IOB-WIN-NEXT/IobSiemens/SiemensSimec.cs +++ b/IOB-WIN-NEXT/IobSiemens/SiemensSimec.cs @@ -24,7 +24,7 @@ namespace IOB_WIN_NEXT.IobSiemens * CodComm Array[0..9] of Char DBB20..29 * CodProgr Array[0..9] of Char DBB30..39 * - * DB29 blocco dati letto dal MES Byte Bit + * DB29 blocco dati letto dal MES Byte Num * CicloOn Bool 0 0 * MacchOn Bool 0 1 * ManualeOn Bool 0 2 @@ -210,7 +210,7 @@ namespace IOB_WIN_NEXT.IobSiemens * B5: emergenza (1=attiva/premuta, 0=armed) * * - BIT di stato - * DB29 blocco dati letto dal MES Byte Bit + * DB29 blocco dati letto dal MES Byte Num * CicloOn Bool 0 0 * MacchOn Bool 0 1 * ManualeOn Bool 0 2 From 9ff0e8aae9befd72c976eb0e150bc4556b29c638 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 25 Nov 2024 09:35:08 +0100 Subject: [PATCH 2/2] Rama Siemens: - Update decodifica altri valori contatori --- IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json | 33 +++++---- IOB-WIN-NEXT/IobOpc/OpcUa.cs | 77 ++++++++++++++++---- 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json b/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json index c0934eae..a4ff689b 100644 --- a/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json +++ b/IOB-WIN-NEXT/DATA/CONF/Tend_RAMA_100_47.json @@ -4,7 +4,7 @@ "BrowseValue": 0, "kvDelim": "#", "memDelim": ".", - "keyPartCount": "Production#GEN.Float.0", + "keyPartCount": "PV_Exchange_DB_R.Production#GEN.Float.0", "keyPartReq": "", "keyPartId": "", "keyProgName": "", @@ -14,22 +14,22 @@ "maxNullRead": 500, "condWork": [ { - "keyName": "Fabric Run", + "keyName": "PV_Exchange_DB_R.Fabric Run", "bitNum": 0, "targetValue": "1" }, { - "keyName": "Enabled", + "keyName": "PV_Exchange_DB_R.Enabled", "bitNum": 0, "targetValue": "1" }, { - "keyName": "Enabled", + "keyName": "PV_Exchange_DB_R.Enabled", "bitNum": 4, "targetValue": "1" }, { - "keyName": "Enabled", + "keyName": "PV_Exchange_DB_R.Enabled", "bitNum": 5, "targetValue": "1" } @@ -38,12 +38,12 @@ "checkMode": "OR", "checkList": [ { - "keyName": "Enabled", + "keyName": "PV_Exchange_DB_R.Enabled", "bitNum": 4, "targetValue": "1" }, { - "keyName": "Enabled", + "keyName": "PV_Exchange_DB_R.Enabled", "bitNum": 5, "targetValue": "1" } @@ -53,7 +53,7 @@ "checkMode": "AND", "checkList": [ { - "keyName": "Enabled", + "keyName": "PV_Exchange_DB_R.Enabled", "bitNum": 5, "targetValue": "1" } @@ -63,7 +63,7 @@ "checkMode": "OR", "checkList": [ { - "keyName": "Fabric Run", + "keyName": "PV_Exchange_DB_R.Fabric Run", "bitNum": 0, "targetValue": "0" } @@ -77,7 +77,7 @@ "checkMode": "AND", "checkList": [ { - "keyName": "\"Alarms\"", + "keyName": "PV_Exchange_DB_R.Alarms", "bitNum": 0, "targetValue": "1" } @@ -96,7 +96,10 @@ "ns=3;s=\"PV_Exchange_DB_R\".\"Enabled\"", "ns=3;s=\"PV_Exchange_DB_R\".\"Fabric Run\"", "ns=3;s=\"PV_Exchange_DB_R\".\"Production\"", - "ns=3;s=\"PV_Exchange_DB_R\".\"Alarms\"" + "ns=3;s=\"PV_Exchange_DB_R\".\"Alarms\"", + "ns=3;s=\"SP_Exchange_DB_R\".\"Enabling\"", + "ns=3;s=\"SP_Exchange_DB_R\".\"Fabric Enabling\"", + "ns=3;s=\"SP_Exchange_DB_R\".\"Fabric Speed\"" ], "filterItemsNodeId": [ "ns=2;s=RamosaETN21.RamosaCJ2._Hints", @@ -226,7 +229,7 @@ "OPC_Prod_PartMetCount": { "name": "OPC_Prod_PartMetCount", "description": "Contatore Metri Parziale", - "memAddr": "\"Production\"#GEN.Float.0", + "memAddr": "PV_Exchange_DB_R.Production#GEN.Float.0", "tipoMem": "FloatABCD", "index": 1, "size": 1, @@ -240,7 +243,7 @@ "OPC_Prod_TotMetCount": { "name": "OPC_Prod_TotMetCount", "description": "Contatore Metri Totale", - "memAddr": "\"Production\"#GEN.Float.4", + "memAddr": "PV_Exchange_DB_R.Production#GEN.Float.4", "tipoMem": "FloatABCD", "index": 1, "size": 1, @@ -254,7 +257,7 @@ "OPC_Prod_TotHourCount": { "name": "OPC_Prod_TotHourCount", "description": "Contatore Ore Totale", - "memAddr": "\"Production\"#GEN.Float.8", + "memAddr": "PV_Exchange_DB_R.Production#GEN.Float.8", "tipoMem": "FloatABCD", "index": 1, "size": 1, @@ -274,7 +277,7 @@ "MemConfWrite": "", "MaxVal": 9999 }, - "BaseIdMask": "\"PV_Exchange_DB_R\".", + "BaseIdMask": "", "DictOpcNameReplace": { "\"": "" } diff --git a/IOB-WIN-NEXT/IobOpc/OpcUa.cs b/IOB-WIN-NEXT/IobOpc/OpcUa.cs index 4b30a141..d73a7009 100644 --- a/IOB-WIN-NEXT/IobOpc/OpcUa.cs +++ b/IOB-WIN-NEXT/IobOpc/OpcUa.cs @@ -891,6 +891,40 @@ namespace IOB_WIN_NEXT.IobOpc return changed; } + /// + /// Fix stringa da versione "raw " a "bonificata" + /// + /// + /// + internal string stringFixOpcUaName(string origName) + { + string answ = origName; + // se ho dizionari di sostituzione caratteri sistemo! + if (opcUaParams.DictOpcNameReplace.Count > 0) + { + // cerco nel dizionario LUT di traduzione + if (DictOpcFixKeys.ContainsKey(origName)) + { + answ = DictOpcFixKeys[origName]; + } + else + { + // altrimenti sitemo e metto in dizionario + foreach (var item in opcUaParams.DictOpcNameReplace) + { + answ = answ.Replace(item.Key, item.Value); + } + DictOpcFixKeys.Add(origName, answ); + } + } + return answ; + } + + /// + /// Dizionario chiavi OpcUa bonificate da char non standard + /// + internal Dictionary DictOpcFixKeys { get; set; } = new Dictionary(); + /// /// Verifica ed invia variazioni DAL FORMATO RAW data (byte[]) /// @@ -923,7 +957,10 @@ namespace IOB_WIN_NEXT.IobOpc string descr = ""; DateTime locTStamp = DateTime.Now; descr = itemTranslation("OPC", uuid); - sVal = $"Change 02: {locTStamp.ToString()} | descr: {descr} | Id: {MonIt.StartNodeId} | Val: {currVal}"; + // calcolo nomi "bonificati" + string startNodeId = stringFixOpcUaName($"{MonIt.StartNodeId}"); + string displayName = stringFixOpcUaName($"{MonIt.DisplayName}"); + sVal = $"Change 02: {locTStamp.ToString()} | descr: {descr} | Id: {startNodeId} | Val: {currVal}"; lgDebug(sVal); // verifico se salvare @@ -933,7 +970,7 @@ namespace IOB_WIN_NEXT.IobOpc // cerco filtro ANCHE PER solo display name x contains... if (!isFiltered) { - isFiltered = opcUaParams.fluxLogVetoContains.Contains(uuid) || opcUaParams.fluxLogVetoContains.Contains(MonIt.DisplayName); + isFiltered = opcUaParams.fluxLogVetoContains.Contains(uuid) || opcUaParams.fluxLogVetoContains.Contains(displayName); } if (isFiltered) { @@ -950,22 +987,40 @@ namespace IOB_WIN_NEXT.IobOpc if (memMap.mMapRead != null && memMap.mMapRead.Count > 0) { // elenco aree collegate... - var listRelated = memMap.mMapRead.Where(x => x.Value.memAddr.Contains(uuid)); + var listRelated = memMap.mMapRead.Where(x => x.Value.memAddr.Contains(uuid)).ToList(); if (listRelated != null && listRelated.Count() > 0) { foreach (var item in listRelated) { // ciclo e calcolo valore - var rByte= dataItemMem[uuid].rawByte; - string convVal = ConvBArr(rByte, item.Value.memAddr, opcUaParams.memDelim); + var rByte = dataItemMem[uuid].rawByte; + int iPos = item.Value.memAddr.IndexOf(opcUaParams.kvDelim); + string varDef = item.Value.memAddr.Substring(iPos + 1); + string convVal = ConvBArr(rByte, varDef, opcUaParams.memDelim); // metto in array currData... upsertKey(item.Key, convVal); + accodaFLog($"mMapRead | {item.Key} | {convVal}", qEncodeFLog(item.Key, convVal)); } } } if (memMap.mMapWrite != null && memMap.mMapWrite.Count > 0) { - + // elenco aree collegate... + var listRelated = memMap.mMapWrite.Where(x => x.Value.memAddr.Contains(uuid)).ToList(); + if (listRelated != null && listRelated.Count() > 0) + { + foreach (var item in listRelated) + { + // ciclo e calcolo valore + var rByte = dataItemMem[uuid].rawByte; + int iPos = item.Value.memAddr.IndexOf(opcUaParams.kvDelim); + string varDef = item.Value.memAddr.Substring(iPos + 1); + string convVal = ConvBArr(rByte, varDef, opcUaParams.memDelim); + // metto in array currData... + upsertKey(item.Key, convVal); + accodaFLog($"mMapRead | {item.Key} | {convVal}", qEncodeFLog(item.Key, convVal)); + } + } } } else @@ -1357,15 +1412,7 @@ namespace IOB_WIN_NEXT.IobOpc { answ = fullCode.Replace(opcUaParams.BaseIdMask, ""); } - // tolgo eventuali caratteri speciali mappati... - // se c'è gestione fix nomi sistemo... - if (opcUaParams.DictOpcNameReplace.Count > 0) - { - foreach (var item in opcUaParams.DictOpcNameReplace) - { - answ = answ.Replace(item.Key, item.Value); - } - } + answ = stringFixOpcUaName(answ); // trimmo spazi x ridurre dimensione se > 50... if (answ.Length > 50) {