OpcUa compila!!!

This commit is contained in:
Samuele Locatelli
2021-04-29 18:01:29 +02:00
parent 34e72d8ff4
commit 04e2c6e4e2
3 changed files with 143 additions and 98 deletions
+18 -5
View File
@@ -14,11 +14,6 @@ namespace IOB_UT
{
#region Public Properties
/// <summary>
/// Struttura dati x check condizione PowerOn
/// </summary>
public diCheckCondition condPowerOn { get; set; } = new diCheckCondition();
/// <summary>
/// Struttura dati x check condizione LAVORA / Green
/// </summary>
@@ -102,6 +97,14 @@ namespace IOB_UT
/// </summary>
public class MtcParamConf : BaseParamConf
{
#region Public Properties
/// <summary>
/// Struttura dati x check condizione PowerOn
/// </summary>
public diCheckCondition condPowerOn { get; set; } = new diCheckCondition();
#endregion Public Properties
}
/// <summary>
@@ -131,6 +134,16 @@ namespace IOB_UT
/// </summary>
public List<diCheckCondition> condEStop { get; set; } = new List<diCheckCondition>();
/// <summary>
/// Struttura dati x check condizione PowerOn
/// </summary>
public List<diCheckCondition> condPowerOn { get; set; } = new List<diCheckCondition>();
/// <summary>
/// Struttura dati x check condizione READY
/// </summary>
public List<diCheckCondition> condReady { get; set; } = new List<diCheckCondition>();
#endregion Public Properties
}
}
+12 -4
View File
@@ -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",
+113 -89
View File
@@ -126,6 +126,39 @@ namespace IOB_WIN_NEXT
}
}
/// <summary>
/// Indica se abbia stato POWER ON (multicondizione)
/// </summary>
protected bool hasPowerOn
{
get
{
return checkMultiCondition(opcUaParams.condPowerOn);
}
}
/// <summary>
/// Indica se abbia stato READY (condizioni varie, es ausiliari OK)
/// </summary>
protected bool isReady
{
get
{
return checkMultiCondition(opcUaParams.condReady);
}
}
/// <summary>
/// Indica se abbia stato READY (condizioni varie, es ausiliari OK)
/// </summary>
protected bool isWorking
{
get
{
return checkMultiCondition(opcUaParams.condWork);
}
}
/// <summary>
/// Parametri specifici MTC
/// </summary>
@@ -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
/// </summary>
/// <param name="newValue"></param>
/// <returns></returns>
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<machDataItem> elencoDataItems = new List<machDataItem>();
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<machDataItem> elencoDataItems = new List<machDataItem>();
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;
}