From 04e2c6e4e252c3cb09dd3b9c11dac1faa811c69e Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 29 Apr 2021 18:01:29 +0200 Subject: [PATCH] OpcUa compila!!! --- IOB-UT/ToMapo.cs | 23 +++- IOB-WIN-NEXT/DATA/CONF/OPC_UA.json | 16 ++- IOB-WIN-NEXT/IobOpcUa.cs | 202 ++++++++++++++++------------- 3 files changed, 143 insertions(+), 98 deletions(-) diff --git a/IOB-UT/ToMapo.cs b/IOB-UT/ToMapo.cs index e6932345..903794c6 100644 --- a/IOB-UT/ToMapo.cs +++ b/IOB-UT/ToMapo.cs @@ -14,11 +14,6 @@ namespace IOB_UT { #region Public Properties - /// - /// Struttura dati x check condizione PowerOn - /// - public diCheckCondition condPowerOn { get; set; } = new diCheckCondition(); - /// /// Struttura dati x check condizione LAVORA / Green /// @@ -102,6 +97,14 @@ namespace IOB_UT /// public class MtcParamConf : BaseParamConf { + #region Public Properties + + /// + /// Struttura dati x check condizione PowerOn + /// + public diCheckCondition condPowerOn { get; set; } = new diCheckCondition(); + + #endregion Public Properties } /// @@ -131,6 +134,16 @@ namespace IOB_UT /// public List condEStop { get; set; } = new List(); + /// + /// Struttura dati x check condizione PowerOn + /// + public List condPowerOn { get; set; } = new List(); + + /// + /// Struttura dati x check condizione READY + /// + public List condReady { get; set; } = new List(); + #endregion Public Properties } } \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/OPC_UA.json b/IOB-WIN-NEXT/DATA/CONF/OPC_UA.json index afcc67d4..dcc5968b 100644 --- a/IOB-WIN-NEXT/DATA/CONF/OPC_UA.json +++ b/IOB-WIN-NEXT/DATA/CONF/OPC_UA.json @@ -7,10 +7,18 @@ "keyProgName": "ncprog", "keyRunMode": "mode", "pingAsPowerOn": true, - "condPowerOn": { - "keyName": "avail", - "targetValue": "AVAILABLE" - }, + "condPowerOn": [ + { + "keyName": "120.00", + "targetValue": "1" + } + ], + "condReady": [ + { + "keyName": "121.00", + "targetValue": "1" + } + ], "condWork": [ { "keyName": "rstat", diff --git a/IOB-WIN-NEXT/IobOpcUa.cs b/IOB-WIN-NEXT/IobOpcUa.cs index d91abafc..0a4315ba 100644 --- a/IOB-WIN-NEXT/IobOpcUa.cs +++ b/IOB-WIN-NEXT/IobOpcUa.cs @@ -126,6 +126,39 @@ namespace IOB_WIN_NEXT } } + /// + /// Indica se abbia stato POWER ON (multicondizione) + /// + protected bool hasPowerOn + { + get + { + return checkMultiCondition(opcUaParams.condPowerOn); + } + } + + /// + /// Indica se abbia stato READY (condizioni varie, es ausiliari OK) + /// + protected bool isReady + { + get + { + return checkMultiCondition(opcUaParams.condReady); + } + } + + /// + /// Indica se abbia stato READY (condizioni varie, es ausiliari OK) + /// + protected bool isWorking + { + get + { + return checkMultiCondition(opcUaParams.condWork); + } + } + /// /// Parametri specifici MTC /// @@ -257,42 +290,23 @@ namespace IOB_WIN_NEXT * B5: emergenza ----------------------------------------------------- */ - // Controllo booleano PING e POWERON... - string currPowerOn = getDataItemValue(opcUaParams.condPowerOn.keyName); // se valido il check ping lo eseguo... altrimenti lo do x buono bool checkPing = !opcUaParams.pingAsPowerOn; if (!checkPing) { checkPing = (testPingMachine == IPStatus.Success); } - // verifico da target value richiesto... - bool checkPowerOn = (currPowerOn == opcUaParams.condPowerOn.targetValue); // bit 0 (poweron) imposto a 1 SE pingo o PowerOn=="ON"... - B_input = (checkPing || checkPowerOn) ? 1 : 0; + B_input = (checkPing || hasPowerOn) ? 1 : 0; // variabili RUN... string currRun = getDataItemValue(opcUaParams.keyRunMode); - // controllo RUN MODE preliminare... CABLATO poiché è GENERALE x MTC - if (currRun == "AUTOMATIC" || currRun == "SEMI_AUTO" || currRun == "SEMI_AUTOMATIC") + if (isWorking) { - int numCond = opcUaParams.condWork.Count; - int numCondOk = 0; - // cerco nell'elenco delle condizioni che indicano lavora se sono ok faccio +1 conteggio...... - foreach (var item in opcUaParams.condWork) - { - if (getDataItemValue(item.keyName) == item.targetValue) - { - numCondOk++; - } - } - // se tutte condizioni rispettate --> lavora! - if (numCond == numCondOk) - { - // RUN = LAVORA! - B_input += (1 << 1); - } + // RUN = LAVORA! + B_input += (1 << 1); } // se ho emergenza premuta --> emergenza! else if (hasEStopTriggered) @@ -304,12 +318,13 @@ namespace IOB_WIN_NEXT { B_input += (1 << 3); } - else + else if (isReady) { // se ho run mode != auto --> manual B_input += (1 << 4); } +#if false DateTime adesso = DateTime.Now; int vFactor = 1; // controllo SE HO dati per fare verifiche... @@ -347,6 +362,7 @@ namespace IOB_WIN_NEXT // imposto veto per vetoSeconds... vetoCheckStatus = adesso.AddSeconds(vetoSeconds * vFactor); } +#endif // log opzionale! if (verboseLog) { @@ -435,7 +451,7 @@ namespace IOB_WIN_NEXT { OpcUaDataItemExt currDataItem; // calcolo parametri - uuid = $"OPC_{dataItem.StartNodeId}"; + uuid = $"OPC_{dataItem.DisplayName}"; // SOLO SE è abilitato il datafiltering... if (enableDataFilter) { @@ -551,95 +567,103 @@ namespace IOB_WIN_NEXT /// /// /// - protected bool checkSaveValue(Opc.Ua.Client.MonitoredItem MonIt, MonitoredItemNotification Notify) + protected bool checkSaveValue(Opc.Ua.Client.MonitoredItem dataItem, MonitoredItemNotification Notify) { bool answ = !enableDataFilter; double oldVal = 0; double newVal = 0; - if (newValue != null) + if (dataItem != null) { - if (isVerboseLog) + if (Notify != null) { - lgInfo($"Richiesta checkSaveSample per {newValue} | id: {newValue.DataItemId} | CDATA: {newValue.CDATA}"); - } - // verifico in memoria se ho l'oggetto condition ed il suo valore.. - if (dataItemMem.ContainsKey(newValue.DataItemId)) - { - MtcDataItemExt currDataItemMem = dataItemMem[newValue.DataItemId]; - // controllo SE SIA scaduto il tempo massimo... - if (Math.Abs(dataItemMem[newValue.DataItemId].valueTimestamp.Subtract(newValue.Timestamp).TotalSeconds) > currDataItemMem.samplePeriod) + if (isVerboseLog) { - answ = true; + lgInfo($"Richiesta checkSaveSample per {dataItem.DisplayName} | id: {dataItem.StartNodeId} | Valore: {Notify.Value}"); } - else + // verifico in memoria se ho l'oggetto condition ed il suo valore.. + string uuid = $"OPC_{dataItem.DisplayName}"; + DateTime adesso = DateTime.Now; + if (dataItemMem.ContainsKey(uuid)) { - // ALTRIMENTI controllo SE diverso - if (dataItemMem[newValue.DataItemId].value != newValue.CDATA) + OpcUaDataItemExt currDataItemMem = dataItemMem[uuid]; + // controllo SE SIA scaduto il tempo massimo... + if (Math.Abs(dataItemMem[uuid].valueTimestamp.Subtract(adesso).TotalSeconds) > currDataItemMem.samplePeriod) { - // controllo SE ho DeadBand... - if (dataItemMem[newValue.DataItemId].thresholdDeadBand > 0) + answ = true; + } + else + { + // ALTRIMENTI controllo SE diverso + if (dataItemMem[uuid].value != $"{Notify.Value}") { - if (isVerboseLog) + // controllo SE ho DeadBand... + if (dataItemMem[uuid].thresholdDeadBand > 0) { - lgInfo($"Test deadband: oldVal: {oldVal} | newVal: {newVal}"); - } - // recupero i valori e testo DeadBand... - double.TryParse(dataItemMem[newValue.DataItemId].value.Replace(".", ","), out oldVal); - double.TryParse(newValue.CDATA.Replace(".", ","), out newVal); - // test deadband! - if (Math.Abs(newVal - oldVal) > dataItemMem[newValue.DataItemId].thresholdDeadBand) - { - // indico da salvare.. - answ = true; + if (isVerboseLog) + { + lgInfo($"Test deadband: oldVal: {oldVal} | newVal: {newVal}"); + } + // recupero i valori e testo DeadBand... + double.TryParse(dataItemMem[uuid].value.Replace(".", ","), out oldVal); + double.TryParse($"{Notify.Value}".Replace(".", ","), out newVal); + // test deadband! + if (Math.Abs(newVal - oldVal) > dataItemMem[uuid].thresholdDeadBand) + { + // indico da salvare.. + answ = true; + } } } } + if (answ) + { + // salvo! + dataItemMem[uuid].value = $"{Notify.Value}"; + dataItemMem[uuid].valueTimestamp = adesso; + } } - if (answ) + else { - // salvo! - dataItemMem[newValue.DataItemId].value = newValue.CDATA; - dataItemMem[newValue.DataItemId].valueTimestamp = newValue.Timestamp; + // registro non trovato da aggiungere... + lgInfo($"DataItem non trovato in checkSaveSample: {dataItem.DisplayName}"); + // provo a creare oggetto in memoria... + try + { + List elencoDataItems = new List(); + int dSamplePeriod = 0; + int threshDBand = 0; + uuid = ""; + var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, dataItem); + // aggiungo + dataItemMem.Add(uuid, currDataItem); + // salvo oggetto x registrazione su server MP-IO + var currMapoDataItem = new machDataItem() + { + uuid = uuid, + Category = DataItemCategory.EVENT, + Name = dataItem.DisplayName, + Type = $"{dataItem.NodeClass}", + SubType = $"{dataItem.StartNodeId}" + }; + // aggiungo + elencoDataItems.Add(currMapoDataItem); + // invio il dataItem serializzato... + sendDataItemsList(elencoDataItems); + } + catch (Exception exc) + { + lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}"); + } } } else { - // registro non trovato da aggiungere... - lgInfo($"DataItem non trovato in checkSaveSample: {newValue.DataItemId}"); - // provo a creare oggetto in memoria... - try - { - List elencoDataItems = new List(); - int dSamplePeriod = 0; - int threshDBand = 0; - string uuid = ""; - var currDataItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, newValue); - // aggiungo - dataItemMem.Add(newValue.DataItemId, currDataItem); - // salvo oggetto x registrazione su server MP-IO - var currMapoDataItem = new machDataItem() - { - uuid = newValue.DataItemId, - Category = (DataItemCategory)newValue.Category, - Name = newValue.Name, - Type = newValue.Type, - SubType = newValue.SubType, - //Units = newValue.Units - }; - // aggiungo - elencoDataItems.Add(currMapoDataItem); - // invio il dataItem serializzato... - sendDataItemsList(elencoDataItems); - } - catch (Exception exc) - { - lgError($"Eccezione in checkSaveSample{Environment.NewLine}{exc}"); - } + lgError("Attenzione: checkSaveItem con Notify null!"); } } else { - lgError("Attenzione: checkSaveItem con newValue null!"); + lgError("Attenzione: checkSaveItem con MonIt null!"); } return answ; }