Gestione null read con errori e disconnessione
This commit is contained in:
@@ -632,6 +632,11 @@ namespace IOB_UT_NEXT
|
||||
/// </summary>
|
||||
public bool UseFullId { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Numero massimo di letture null prima di disconnettere il client
|
||||
/// </summary>
|
||||
public int maxNullRead { get; set; } = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Base del NameSpace usato per le funzionalità di translate (parametri ACT --> SET)
|
||||
/// </summary>
|
||||
|
||||
@@ -533,7 +533,7 @@ namespace IOB_WIN_NEXT.IobOpc
|
||||
}
|
||||
else
|
||||
{
|
||||
lgTrace($"checkAndSend ERROR | MonIt: {MonIt.DisplayName} | NotifyValue Null!!!");
|
||||
lgError($"checkAndSend ERROR | MonIt: {MonIt.DisplayName} | NotifyValue Null!!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1452,7 +1452,7 @@ namespace IOB_WIN_NEXT.IobOpc
|
||||
lgInfo($"Chiamata UAClient con configurazione standard: {application.ApplicationConfiguration.ApplicationName}");
|
||||
string userName = opcUaParams == null || opcUaParams.Identity == null ? "" : opcUaParams.Identity.UserName;
|
||||
string passwd = opcUaParams == null || opcUaParams.Identity == null ? "" : opcUaParams.Identity.Passwd;
|
||||
UA_ref = new UAClient(application.ApplicationConfiguration, cIobConf.codIOB, userName, passwd, isVerboseLog, ClientBase.ValidateResponse);
|
||||
UA_ref = new UAClient(application.ApplicationConfiguration, cIobConf.codIOB, userName, passwd, isVerboseLog, ClientBase.ValidateResponse, opcUaParams.maxNullRead);
|
||||
|
||||
lgInfo($"Chiamata apertura OpcUa Client: {cIobConf.cncIpAddr}:{port}");
|
||||
UA_ref.ServerUrl = $"opc.tcp://{cIobConf.cncIpAddr}:{port}";
|
||||
@@ -1594,6 +1594,8 @@ namespace IOB_WIN_NEXT.IobOpc
|
||||
}
|
||||
}
|
||||
}
|
||||
// gestione ricezione null
|
||||
UA_ref.eh_nullExceed += UA_ref_eh_nullExceed;
|
||||
// gestione eventi change
|
||||
UA_ref.eh_MonItChange += UA_ref_eh_MonItChange;
|
||||
lgInfo("eh_MonItChange event registered");
|
||||
@@ -1614,7 +1616,7 @@ namespace IOB_WIN_NEXT.IobOpc
|
||||
// controllo read error ed eventuale disconnect
|
||||
if (readErrorCurr > readErrorMax)
|
||||
{
|
||||
lgError($"Effettuo disconnessione x superamento errori lettura UA_ref.ReadNode, sleetp 15 sec");
|
||||
lgError($"Effettuo disconnessione x superamento errori lettura UA_ref.ReadNode, sleep {readErrorSleepTime}msec");
|
||||
tryDisconnect();
|
||||
Thread.Sleep(readErrorSleepTime);
|
||||
readErrorCurr = 0;
|
||||
@@ -1622,6 +1624,20 @@ namespace IOB_WIN_NEXT.IobOpc
|
||||
return esitoLink;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ricevuto troppi null --> disconnetto e traccio
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void UA_ref_eh_nullExceed(object sender, int e)
|
||||
{
|
||||
lgError($"Effettuo disconnessione x superamento letture UA_ref.ReadNode a NULL ({e}), sleep {2 * readErrorSleepTime}msec");
|
||||
tryDisconnect();
|
||||
Thread.Sleep(2 * readErrorSleepTime);
|
||||
readErrorCurr = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formatta un dataitem x salvataggio in memoria locale
|
||||
/// </summary>
|
||||
|
||||
+43
-120
@@ -72,8 +72,17 @@ namespace IOB_WIN_NEXT
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the UAClient class.
|
||||
/// </summary>
|
||||
public UAClient(ApplicationConfiguration configuration, string codIOB, string user, string pwd, bool verboseLog, Action<IList, IList> validateResponse)
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="codIOB"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="pwd"></param>
|
||||
/// <param name="verboseLog"></param>
|
||||
/// <param name="validateResponse"></param>
|
||||
/// <param name="maxNullRead">Numero massimo di risposte nulle in browsing prima di disconnettersi</param>
|
||||
public UAClient(ApplicationConfiguration configuration, string codIOB, string user, string pwd, bool verboseLog, Action<IList, IList> validateResponse, int maxNullRead)
|
||||
{
|
||||
currNullReceiv = 0;
|
||||
maxNullAllowed = maxNullRead;
|
||||
m_validateResponse = validateResponse;
|
||||
currIob = codIOB;
|
||||
lg = LogManager.GetCurrentClassLogger();
|
||||
@@ -99,6 +108,11 @@ namespace IOB_WIN_NEXT
|
||||
/// </summary>
|
||||
public event EventHandler<opcUaMonitItemChange> eh_MonItChange;
|
||||
|
||||
/// <summary>
|
||||
/// Evento notifica superamento numero letture null
|
||||
/// </summary>
|
||||
public event EventHandler<int> eh_nullExceed;
|
||||
|
||||
#endregion Public Events
|
||||
|
||||
#region Public Properties
|
||||
@@ -393,8 +407,6 @@ namespace IOB_WIN_NEXT
|
||||
|
||||
try
|
||||
{
|
||||
//#region Read a node by calling the Read Service
|
||||
|
||||
//// build a list of nodes to be read
|
||||
//ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
|
||||
//{
|
||||
@@ -427,10 +439,6 @@ namespace IOB_WIN_NEXT
|
||||
// lgInfo("Read Value = {0} , StatusCode = {1}", result.Value, result.StatusCode);
|
||||
//}
|
||||
|
||||
//#endregion Read a node by calling the Read Service
|
||||
|
||||
#region Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
|
||||
try
|
||||
{
|
||||
DataValue resp = m_session.ReadValue(reqNodeId);
|
||||
@@ -447,8 +455,6 @@ namespace IOB_WIN_NEXT
|
||||
numErrors++;
|
||||
lgTrace($"ReadValue Error | reqNodeId: {reqNodeId} | numErrors: {numErrors}{Environment.NewLine}{exc}");
|
||||
}
|
||||
|
||||
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -466,8 +472,6 @@ namespace IOB_WIN_NEXT
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected int maxErrors = 20;
|
||||
|
||||
/// <summary>
|
||||
/// Read a SINGLE of nodes value (RAW) from Server
|
||||
/// </summary>
|
||||
@@ -507,8 +511,6 @@ namespace IOB_WIN_NEXT
|
||||
return answ;
|
||||
}
|
||||
|
||||
protected int numErrors = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Read a list of nodes from Server
|
||||
/// </summary>
|
||||
@@ -618,83 +620,6 @@ namespace IOB_WIN_NEXT
|
||||
monItList.Add(currMonIt);
|
||||
}
|
||||
|
||||
#if false
|
||||
MonitoredItem IO_120_00_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_120_00_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.00");
|
||||
IO_120_00_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_120_00_MonitoredItem.DisplayName = "IO_120 Variable";
|
||||
IO_120_00_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_120_00_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_120_00_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_120_01_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_120_01_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_120.01");
|
||||
IO_120_01_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_120_01_MonitoredItem.DisplayName = "IO_120_01 Variable";
|
||||
IO_120_01_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_120_01_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_120_01_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_130_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_130_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_130");
|
||||
IO_130_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_130_MonitoredItem.DisplayName = "IO_130 Variable";
|
||||
IO_130_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_130_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_130_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_135_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_135_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_135");
|
||||
IO_135_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_135_MonitoredItem.DisplayName = "IO_135 Variable";
|
||||
IO_135_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_135_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_135_MonitoredItem);
|
||||
|
||||
MonitoredItem IO_140_MonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
IO_140_MonitoredItem.StartNodeId = new NodeId("ns=4;s=IO_140");
|
||||
IO_140_MonitoredItem.AttributeId = Attributes.Value;
|
||||
IO_140_MonitoredItem.DisplayName = "IO_140 Variable";
|
||||
IO_140_MonitoredItem.SamplingInterval = 1000;
|
||||
IO_140_MonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
subscription.AddItem(IO_140_MonitoredItem);
|
||||
|
||||
//MonitoredItem intMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
|
||||
//intMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Int32");
|
||||
//intMonitoredItem.AttributeId = Attributes.Value;
|
||||
//intMonitoredItem.DisplayName = "Int32 Variable";
|
||||
//intMonitoredItem.SamplingInterval = 1000;
|
||||
//intMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(intMonitoredItem);
|
||||
|
||||
//MonitoredItem floatMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// Float Node - Objects\CTT\Scalar\Simulation\Float
|
||||
//floatMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_Float");
|
||||
//floatMonitoredItem.AttributeId = Attributes.Value;
|
||||
//floatMonitoredItem.DisplayName = "Float Variable";
|
||||
//floatMonitoredItem.SamplingInterval = 1000;
|
||||
//floatMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(floatMonitoredItem);
|
||||
|
||||
//MonitoredItem stringMonitoredItem = new MonitoredItem(subscription.DefaultItem);
|
||||
//// String Node - Objects\CTT\Scalar\Simulation\String
|
||||
//stringMonitoredItem.StartNodeId = new NodeId("ns=2;s=Scalar_Simulation_String");
|
||||
//stringMonitoredItem.AttributeId = Attributes.Value;
|
||||
//stringMonitoredItem.DisplayName = "String Variable";
|
||||
//stringMonitoredItem.SamplingInterval = 1000;
|
||||
//stringMonitoredItem.Notification += OnMonitoredItemNotification;
|
||||
|
||||
//subscription.AddItem(stringMonitoredItem);
|
||||
#endif
|
||||
|
||||
// Create the monitored items on Server side
|
||||
subscription.ApplyChanges();
|
||||
lgInfo($"MonitoredItems created for SubscriptionId = {subscription.Id}");
|
||||
@@ -707,7 +632,7 @@ namespace IOB_WIN_NEXT
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a list of nodes to the Server
|
||||
/// Write a list of nodes to the Server
|
||||
/// </summary>
|
||||
/// <param name="node2Write"></param>
|
||||
public void WriteNodes(List<WriteValue> node2Write)
|
||||
@@ -846,32 +771,6 @@ namespace IOB_WIN_NEXT
|
||||
qtyWriteVal.Value.Value = (int)hhmm + 10;
|
||||
nodesToWrite.Add(qtyWriteVal);
|
||||
|
||||
#if false
|
||||
//// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
|
||||
//WriteValue intWriteVal = new WriteValue();
|
||||
//intWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Int32");
|
||||
//intWriteVal.AttributeId = Attributes.Value;
|
||||
//intWriteVal.Value = new DataValue();
|
||||
//intWriteVal.Value.Value = (int)100;
|
||||
//nodesToWrite.Add(intWriteVal);
|
||||
|
||||
//// Float Node - Objects\CTT\Scalar\Scalar_Static\Float
|
||||
//WriteValue floatWriteVal = new WriteValue();
|
||||
//floatWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Float");
|
||||
//floatWriteVal.AttributeId = Attributes.Value;
|
||||
//floatWriteVal.Value = new DataValue();
|
||||
//floatWriteVal.Value.Value = (float)100.5;
|
||||
//nodesToWrite.Add(floatWriteVal);
|
||||
|
||||
//// String Node - Objects\CTT\Scalar\Scalar_Static\String
|
||||
//WriteValue stringWriteVal = new WriteValue();
|
||||
//stringWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_String");
|
||||
//stringWriteVal.AttributeId = Attributes.Value;
|
||||
//stringWriteVal.Value = new DataValue();
|
||||
//stringWriteVal.Value.Value = "String Test";
|
||||
//nodesToWrite.Add(stringWriteVal);
|
||||
#endif
|
||||
|
||||
// Write the node attributes
|
||||
StatusCodeCollection results = null;
|
||||
DiagnosticInfoCollection diagnosticInfos;
|
||||
@@ -907,6 +806,10 @@ namespace IOB_WIN_NEXT
|
||||
|
||||
protected static bool isLogVerbose = false;
|
||||
protected static Logger lg;
|
||||
protected int currNullReceiv = 0;
|
||||
protected int maxErrors = 20;
|
||||
protected int maxNullAllowed = 100;
|
||||
protected int numErrors = 0;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
@@ -1002,12 +905,32 @@ namespace IOB_WIN_NEXT
|
||||
// Log MonitoredItem Notification event
|
||||
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
|
||||
|
||||
// sollevo evento notifica vaziazione MonitoredItem
|
||||
if (eh_MonItChange != null)
|
||||
// verifico se ricevo null, superata soglia genero eccezione
|
||||
if ($"{notification.Value}" == "(null)")
|
||||
{
|
||||
eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
|
||||
currNullReceiv++;
|
||||
}
|
||||
else
|
||||
{
|
||||
currNullReceiv--;
|
||||
currNullReceiv = currNullReceiv > 0 ? currNullReceiv : 0;
|
||||
// sollevo evento notifica vaziazione MonitoredItem
|
||||
if (eh_MonItChange != null)
|
||||
{
|
||||
eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
|
||||
}
|
||||
}
|
||||
lgTrace($"Notification Received | Variable: {monitoredItem.DisplayName} | Value: {notification.Value}");
|
||||
// se ho ricevuto troppi nul --> disconnetto
|
||||
if (currNullReceiv > maxNullAllowed)
|
||||
{
|
||||
if (eh_nullExceed != null)
|
||||
{
|
||||
eh_nullExceed(this, currNullReceiv);
|
||||
}
|
||||
// reset
|
||||
currNullReceiv = 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user