diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs b/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs
index 759e1695..7bb08cd0 100644
--- a/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs
@@ -28,6 +28,7 @@
* ======================================================================*/
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
using Opc.Ua;
using Opc.Ua.Configuration;
@@ -36,6 +37,15 @@ namespace Quickstarts.ConsoleReferenceClient
{
public static class Program
{
+ #region Private Fields
+
+ ///
+ /// Elenco degli items da monitorare come risultato del browse iniziale
+ ///
+ private static Dictionary selectedItemList = new Dictionary();
+
+ #endregion Private Fields
+
#region Public Methods
public static async Task Main(string[] args)
@@ -73,10 +83,29 @@ namespace Quickstarts.ConsoleReferenceClient
// Run tests for available methods.
uaClient.ReadNodes();
uaClient.WriteNodes();
- uaClient.Browse();
- //uaClient.CallMethod();
- uaClient.SubscribeToDataChanges();
+ console.WriteLine("Please enter NodeId Value (enter for next option) (ex: ns=4,i=5001)");
+ console.WriteLine("Please enter INT Value (ex: 5001 --> i=5001)");
+ string valIn01 = Console.ReadLine();
+ console.WriteLine("Please enter Namespace index (ex: 4 --> ns=4)");
+ string valIn02 = Console.ReadLine();
+ uint iValue = 5001;
+ ushort nsVal = 4;
+ if (!string.IsNullOrEmpty(valIn01))
+ {
+ uint.TryParse(valIn01, out iValue);
+ }
+ if (!string.IsNullOrEmpty(valIn02))
+ {
+ ushort.TryParse(valIn02, out nsVal);
+ }
+ selectedItemList = uaClient.Browse(nsVal, iValue);
+ console.WriteLine("Press ENTER to continue...");
+ Console.ReadLine();
+
+ //uaClient.CallMethod();
+ List subscribedItems = uaClient.SubscribeToDataChanges(selectedItemList);
+
// Wait for some DataChange notifications from MonitoredItems
await Task.Delay(20_000 * 3 * 15);
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs b/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs
index cbef3e62..72e09fa2 100644
--- a/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs
@@ -31,11 +31,66 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
+using System.Collections;
using Opc.Ua;
using Opc.Ua.Client;
namespace Quickstarts.ConsoleReferenceClient
{
+ ///
+ /// Evento per incapsulare dati x refresh pagina
+ ///
+ public class opcUaMonitItemChange : EventArgs
+ {
+ #region Private Fields
+
+ ///
+ /// Monitored Item da notificare
+ ///
+ private readonly MonitoredItem _monitoredItem;
+
+ ///
+ /// Valore notifica
+ ///
+ private readonly MonitoredItemNotification _notification;
+
+ #endregion Private Fields
+
+ #region Public Constructors
+
+ ///
+ /// salvataggio obj
+ ///
+ ///
+ public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
+ {
+ _monitoredItem = monitoredItem;
+ _notification = notification;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ ///
+ /// Proprietà lettura del MonitoredItem
+ ///
+ public MonitoredItem CurrMonitoredItem
+ {
+ get { return _monitoredItem; }
+ }
+
+ ///
+ /// Proprietà lettura della notifica
+ ///
+ public MonitoredItemNotification CurrNotify
+ {
+ get { return _notification; }
+ }
+
+ #endregion Public Properties
+ }
+
///
/// OPC UA Client with examples of basic functionality.
///
@@ -53,12 +108,6 @@ namespace Quickstarts.ConsoleReferenceClient
#endregion Private Fields
- #region Protected Fields
-
- protected Dictionary DataList = new Dictionary();
-
- #endregion Protected Fields
-
#region Public Constructors
///
@@ -74,6 +123,15 @@ namespace Quickstarts.ConsoleReferenceClient
#endregion Public Constructors
+ #region Public Events
+
+ ///
+ /// Evento notifica variazione MonitoredItem
+ ///
+ public event EventHandler eh_MonItChange;
+
+ #endregion Public Events
+
#region Public Properties
///
@@ -128,6 +186,12 @@ namespace Quickstarts.ConsoleReferenceClient
{
// Log MonitoredItem Notification event
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
+
+ // sollevo evento notifica vaziazione MonitoredItem
+ if (eh_MonItChange != null)
+ {
+ eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
+ }
m_output.WriteLine("Notification Received for Variable \"{0}\" and Value = {1}.", monitoredItem.DisplayName, notification.Value);
}
catch (Exception ex)
@@ -143,12 +207,13 @@ namespace Quickstarts.ConsoleReferenceClient
///
/// Browse Server nodes
///
- public void Browse()
+ public Dictionary Browse(ushort startNodeNS, uint startNodeVal)
{
+ Dictionary nodeIdNameList = new Dictionary();
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
- return;
+ return nodeIdNameList;
}
try
@@ -161,25 +226,9 @@ namespace Quickstarts.ConsoleReferenceClient
browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
- NodeId nodeToBrowse = ObjectIds.Server;
+ //NodeId nodeToBrowse = ObjectIds.Server;
//NodeId nodeToBrowse = new NodeId("ns=4,i=5001");
-
- m_output.WriteLine("Please enter NodeId Value (enter for next option) (ex: ns=4,i=5001)");
- m_output.WriteLine("Please enter INT Value (ex: 5001 --> i=5001)");
- string valIn01 = Console.ReadLine();
- m_output.WriteLine("Please enter Namespace index (ex: 4 --> ns=4)");
- string valIn02 = Console.ReadLine();
- uint iValue = 5001;
- ushort nsVal = 4;
- if (!string.IsNullOrEmpty(valIn01))
- {
- uint.TryParse(valIn01, out iValue);
- }
- if (!string.IsNullOrEmpty(valIn02))
- {
- ushort.TryParse(valIn02, out nsVal);
- }
- nodeToBrowse = new NodeId(iValue, nsVal);
+ NodeId nodeToBrowse = new NodeId(startNodeVal, startNodeNS);
// Call Browse service
m_output.WriteLine("Browsing {0} node...", nodeToBrowse);
@@ -191,17 +240,16 @@ namespace Quickstarts.ConsoleReferenceClient
foreach (ReferenceDescription result in browseResults)
{
m_output.WriteLine($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
- DataList.Add(result.NodeId.ToString(), result.DisplayName.Text);
+ nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
}
-
- m_output.WriteLine("Press ENTER to continue...");
- Console.ReadLine();
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Browse Error : {ex.Message}.");
}
+
+ return nodeIdNameList;
}
///
@@ -399,7 +447,7 @@ namespace Quickstarts.ConsoleReferenceClient
///
/// Create Subscription and MonitoredItems for DataChanges
///
- public List SubscribeToDataChanges()
+ public List SubscribeToDataChanges(Dictionary DataList)
{
List monItList = new List();
if (m_session == null || m_session.Connected == false)
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs.bak b/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs.bak
new file mode 100644
index 00000000..11cd47d7
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs.bak
@@ -0,0 +1,670 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Opc.Ua;
+using Opc.Ua.Client;
+
+namespace Quickstarts.ConsoleReferenceClient
+{
+ ///
+ /// Evento per incapsulare dati x refresh pagina
+ ///
+ public class opcUaMonitItemChange : EventArgs
+ {
+ #region Private Fields
+
+ ///
+ /// Monitored Item da notificare
+ ///
+ private readonly MonitoredItem _monitoredItem;
+
+ ///
+ /// Valore notifica
+ ///
+ private readonly MonitoredItemNotification _notification;
+
+ #endregion Private Fields
+
+ #region Public Constructors
+
+ ///
+ /// salvataggio obj
+ ///
+ ///
+ public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
+ {
+ _monitoredItem = monitoredItem;
+ _notification = notification;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Properties
+
+ ///
+ /// Proprietà lettura del MonitoredItem
+ ///
+ public MonitoredItem CurrMonitoredItem
+ {
+ get { return _monitoredItem; }
+ }
+
+ ///
+ /// Proprietà lettura della notifica
+ ///
+ public MonitoredItemNotification CurrNotify
+ {
+ get { return _notification; }
+ }
+
+ #endregion Public Properties
+ }
+
+ ///
+ /// OPC UA Client with examples of basic functionality.
+ ///
+ internal class UAClient
+ {
+ #region Private Fields
+
+ private readonly IOutput m_output;
+
+ private readonly Action m_validateResponse;
+
+ private ApplicationConfiguration m_configuration;
+
+ private Session m_session;
+
+ #endregion Private Fields
+
+ #region Public Constructors
+
+ ///
+ /// Initializes a new instance of the UAClient class.
+ ///
+ public UAClient(ApplicationConfiguration configuration, IOutput output, Action validateResponse)
+ {
+ m_validateResponse = validateResponse;
+ m_output = output;
+ m_configuration = configuration;
+ m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Events
+
+ ///
+ /// Evento notifica variazione MonitoredItem
+ ///
+ public event EventHandler eh_MonItChange;
+
+ #endregion Public Events
+
+ #region Public Properties
+
+ ///
+ /// Gets or sets the server URL.
+ ///
+ public string ServerUrl { get; set; } = "opc.tcp://localhost:62541/Quickstarts/ReferenceServer";
+
+ ///
+ /// Gets the client session.
+ ///
+ public Session Session => m_session;
+
+ #endregion Public Properties
+
+ #region Private Methods
+
+ ///
+ /// Handles the certificate validation event.
+ /// This event is triggered every time an untrusted certificate is received from the server.
+ ///
+ private void CertificateValidation(CertificateValidator sender, CertificateValidationEventArgs e)
+ {
+ bool certificateAccepted = true;
+
+ // ****
+ // Implement a custom logic to decide if the certificate should be
+ // accepted or not and set certificateAccepted flag accordingly.
+ // The certificate can be retrieved from the e.Certificate field
+ // ***
+
+ ServiceResult error = e.Error;
+ while (error != null)
+ {
+ m_output.WriteLine(error);
+ error = error.InnerResult;
+ }
+
+ if (certificateAccepted)
+ {
+ m_output.WriteLine("Untrusted Certificate accepted. SubjectName = {0}", e.Certificate.SubjectName);
+ }
+
+ e.AcceptAll = certificateAccepted;
+ }
+
+ ///
+ /// Handle DataChange notifications from Server
+ ///
+ private void OnMonitoredItemNotification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
+ {
+ try
+ {
+ // Log MonitoredItem Notification event
+ MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
+
+ // sollevo evento notifica vaziazione MonitoredItem
+ if (eh_MonItChange != null)
+ {
+ eh_MonItChange(this, new opcUaMonitItemChange(monitoredItem, notification));
+ }
+ m_output.WriteLine("Notification Received for Variable \"{0}\" and Value = {1}.", monitoredItem.DisplayName, notification.Value);
+ }
+ catch (Exception ex)
+ {
+ m_output.WriteLine("OnMonitoredItemNotification error: {0}", ex.Message);
+ }
+ }
+
+ #endregion Private Methods
+
+ #region Public Methods
+
+ ///
+ /// Browse Server nodes
+ ///
+ public Dictionary Browse(ushort startNodeNS, uint startNodeVal)
+ {
+ Dictionary nodeIdNameList = new Dictionary();
+ if (m_session == null || m_session.Connected == false)
+ {
+ m_output.WriteLine("Session not connected!");
+ return nodeIdNameList;
+ }
+
+ try
+ {
+ // Create a Browser object
+ Browser browser = new Browser(m_session);
+
+ // Set browse parameters
+ browser.BrowseDirection = BrowseDirection.Forward;
+ browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
+ browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
+
+ //NodeId nodeToBrowse = ObjectIds.Server;
+ //NodeId nodeToBrowse = new NodeId("ns=4,i=5001");
+ NodeId nodeToBrowse = new NodeId(startNodeVal, startNodeNS);
+
+ // Call Browse service
+ m_output.WriteLine("Browsing {0} node...", nodeToBrowse);
+ ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
+
+ // Display the results
+ m_output.WriteLine("Browse returned {0} results:", browseResults.Count);
+
+ 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);
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ m_output.WriteLine($"Browse Error : {ex.Message}.");
+ }
+
+ return nodeIdNameList;
+ }
+
+ ///
+ /// Call UA method
+ ///
+ public void CallMethod()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ m_output.WriteLine("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Define the UA Method to call
+ // Parent node - Objects\CTT\Methods
+ // Method node - Objects\CTT\Methods\Add
+ NodeId objectId = new NodeId("ns=2;s=Methods");
+ NodeId methodId = new NodeId("ns=2;s=Methods_Add");
+
+ // Define the method parameters
+ // Input argument requires a Float and an UInt32 value
+ object[] inputArguments = new object[] { (float)10.5, (uint)10 };
+ IList