Update gestione IOB-WIN x start OpcUa method

This commit is contained in:
Samuele Locatelli
2021-04-29 17:10:43 +02:00
parent 2221844098
commit c9d3eaf300
9 changed files with 1475 additions and 103 deletions
@@ -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
/// <summary>
/// Elenco degli items da monitorare come risultato del browse iniziale
/// </summary>
private static Dictionary<string, string> selectedItemList = new Dictionary<string, string>();
#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<Opc.Ua.Client.MonitoredItem> subscribedItems = uaClient.SubscribeToDataChanges(selectedItemList);
// Wait for some DataChange notifications from MonitoredItems
await Task.Delay(20_000 * 3 * 15);
@@ -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
{
/// <summary>
/// Evento per incapsulare dati x refresh pagina
/// </summary>
public class opcUaMonitItemChange : EventArgs
{
#region Private Fields
/// <summary>
/// Monitored Item da notificare
/// </summary>
private readonly MonitoredItem _monitoredItem;
/// <summary>
/// Valore notifica
/// </summary>
private readonly MonitoredItemNotification _notification;
#endregion Private Fields
#region Public Constructors
/// <summary>
/// salvataggio obj
/// </summary>
/// <param name="newObject"></param>
public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
{
_monitoredItem = monitoredItem;
_notification = notification;
}
#endregion Public Constructors
#region Public Properties
/// <summary>
/// Proprietà lettura del MonitoredItem
/// </summary>
public MonitoredItem CurrMonitoredItem
{
get { return _monitoredItem; }
}
/// <summary>
/// Proprietà lettura della notifica
/// </summary>
public MonitoredItemNotification CurrNotify
{
get { return _notification; }
}
#endregion Public Properties
}
/// <summary>
/// OPC UA Client with examples of basic functionality.
/// </summary>
@@ -53,12 +108,6 @@ namespace Quickstarts.ConsoleReferenceClient
#endregion Private Fields
#region Protected Fields
protected Dictionary<string, string> DataList = new Dictionary<string, string>();
#endregion Protected Fields
#region Public Constructors
/// <summary>
@@ -74,6 +123,15 @@ namespace Quickstarts.ConsoleReferenceClient
#endregion Public Constructors
#region Public Events
/// <summary>
/// Evento notifica variazione MonitoredItem
/// </summary>
public event EventHandler<opcUaMonitItemChange> eh_MonItChange;
#endregion Public Events
#region Public Properties
/// <summary>
@@ -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
/// <summary>
/// Browse Server nodes
/// </summary>
public void Browse()
public Dictionary<string, string> Browse(ushort startNodeNS, uint startNodeVal)
{
Dictionary<string, string> nodeIdNameList = new Dictionary<string, string>();
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;
}
/// <summary>
@@ -399,7 +447,7 @@ namespace Quickstarts.ConsoleReferenceClient
/// <summary>
/// Create Subscription and MonitoredItems for DataChanges
/// </summary>
public List<MonitoredItem> SubscribeToDataChanges()
public List<MonitoredItem> SubscribeToDataChanges(Dictionary<string, string> DataList)
{
List<MonitoredItem> monItList = new List<MonitoredItem>();
if (m_session == null || m_session.Connected == false)
@@ -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
{
/// <summary>
/// Evento per incapsulare dati x refresh pagina
/// </summary>
public class opcUaMonitItemChange : EventArgs
{
#region Private Fields
/// <summary>
/// Monitored Item da notificare
/// </summary>
private readonly MonitoredItem _monitoredItem;
/// <summary>
/// Valore notifica
/// </summary>
private readonly MonitoredItemNotification _notification;
#endregion Private Fields
#region Public Constructors
/// <summary>
/// salvataggio obj
/// </summary>
/// <param name="newObject"></param>
public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
{
_monitoredItem = monitoredItem;
_notification = notification;
}
#endregion Public Constructors
#region Public Properties
/// <summary>
/// Proprietà lettura del MonitoredItem
/// </summary>
public MonitoredItem CurrMonitoredItem
{
get { return _monitoredItem; }
}
/// <summary>
/// Proprietà lettura della notifica
/// </summary>
public MonitoredItemNotification CurrNotify
{
get { return _notification; }
}
#endregion Public Properties
}
/// <summary>
/// OPC UA Client with examples of basic functionality.
/// </summary>
internal class UAClient
{
#region Private Fields
private readonly IOutput m_output;
private readonly Action<IList, IList> m_validateResponse;
private ApplicationConfiguration m_configuration;
private Session m_session;
#endregion Private Fields
#region Public Constructors
/// <summary>
/// Initializes a new instance of the UAClient class.
/// </summary>
public UAClient(ApplicationConfiguration configuration, IOutput output, Action<IList, IList> validateResponse)
{
m_validateResponse = validateResponse;
m_output = output;
m_configuration = configuration;
m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
}
#endregion Public Constructors
#region Public Events
/// <summary>
/// Evento notifica variazione MonitoredItem
/// </summary>
public event EventHandler<opcUaMonitItemChange> eh_MonItChange;
#endregion Public Events
#region Public Properties
/// <summary>
/// Gets or sets the server URL.
/// </summary>
public string ServerUrl { get; set; } = "opc.tcp://localhost:62541/Quickstarts/ReferenceServer";
/// <summary>
/// Gets the client session.
/// </summary>
public Session Session => m_session;
#endregion Public Properties
#region Private Methods
/// <summary>
/// Handles the certificate validation event.
/// This event is triggered every time an untrusted certificate is received from the server.
/// </summary>
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;
}
/// <summary>
/// Handle DataChange notifications from Server
/// </summary>
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
/// <summary>
/// Browse Server nodes
/// </summary>
public Dictionary<string, string> Browse(ushort startNodeNS, uint startNodeVal)
{
Dictionary<string, string> nodeIdNameList = new Dictionary<string, string>();
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;
}
/// <summary>
/// Call UA method
/// </summary>
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<object> outputArguments = null;
// Invoke Call service
m_output.WriteLine("Calling UAMethod for node {0} ...", methodId);
outputArguments = m_session.Call(objectId, methodId, inputArguments);
// Display results
m_output.WriteLine("Method call returned {0} output argument(s):", outputArguments.Count);
foreach (var outputArgument in outputArguments)
{
m_output.WriteLine(" OutputValue = {0}", outputArgument.ToString());
}
}
catch (Exception ex)
{
m_output.WriteLine("Method call error: {0}", ex.Message);
}
}
/// <summary>
/// Creates a session with the UA server
/// </summary>
public async Task<bool> ConnectAsync()
{
try
{
if (m_session != null && m_session.Connected == true)
{
m_output.WriteLine("Session already connected!");
}
else
{
m_output.WriteLine("Connecting...");
// Get the endpoint by connecting to server's discovery endpoint.
// Try to find the first endopint without security.
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
// Create the session
Session session = await Session.Create(
m_configuration,
endpoint,
false,
false,
m_configuration.ApplicationName,
30 * 60 * 1000,
new UserIdentity(),
null
);
// Assign the created session
if (session != null && session.Connected)
{
m_session = session;
}
// Session created successfully.
m_output.WriteLine($"New Session Created with SessionName = {m_session.SessionName}");
}
return true;
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Create Session Error : {ex.Message}");
return false;
}
}
/// <summary>
/// Disconnects the session.
/// </summary>
public void Disconnect()
{
try
{
if (m_session != null)
{
m_output.WriteLine("Disconnecting...");
m_session.Close();
m_session.Dispose();
m_session = null;
// Log Session Disconnected event
m_output.WriteLine("Session Disconnected.");
}
else
{
m_output.WriteLine("Session not created!");
}
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Disconnect Error : {ex.Message}");
}
}
/// <summary>
/// Read a list of nodes from Server
/// </summary>
public void ReadNodes()
{
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
return;
}
try
{
#region Read a node by calling the Read Service
// build a list of nodes to be read
ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
{
// Value of ServerStatus
new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
// BrowseName of ServerStatus_StartTime
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
// Value of ServerStatus_StartTime
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
};
// Read the node attributes
m_output.WriteLine("Reading nodes...");
// Call Read Service
m_session.Read(
null,
0,
TimestampsToReturn.Both,
nodesToRead,
out DataValueCollection resultsValues,
out DiagnosticInfoCollection diagnosticInfos);
// Validate the results
m_validateResponse(resultsValues, nodesToRead);
// Display the results.
foreach (DataValue result in resultsValues)
{
m_output.WriteLine("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
// Read Server NamespaceArray
m_output.WriteLine("Reading Value of NamespaceArray node...");
DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
// Display the result
m_output.WriteLine($"NamespaceArray Value = {namespaceArray}");
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Read Nodes Error : {ex.Message}.");
}
}
/// <summary>
/// Create Subscription and MonitoredItems for DataChanges
/// </summary>
public List<MonitoredItem> SubscribeToDataChanges(Dictionary<string, string> DataList)
{
List<MonitoredItem> monItList = new List<MonitoredItem>();
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
return monItList;
}
try
{
// Create a subscription for receiving data change notifications
// Define Subscription parameters
Subscription subscription = new Subscription(m_session.DefaultSubscription);
subscription.DisplayName = "Steamware Console Subscription";
subscription.PublishingEnabled = true;
subscription.PublishingInterval = 1000;
m_session.AddSubscription(subscription);
// Create the subscription on Server side
subscription.Create();
m_output.WriteLine("New Subscription created with SubscriptionId = {0}.", subscription.Id);
// Create MonitoredItems for data changes
foreach (var item in DataList)
{
MonitoredItem currMonIt = new MonitoredItem(subscription.DefaultItem);
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
currMonIt.StartNodeId = new NodeId(item.Key);
currMonIt.AttributeId = Attributes.Value;
currMonIt.DisplayName = item.Value;
currMonIt.SamplingInterval = 1000;
currMonIt.Notification += OnMonitoredItemNotification;
subscription.AddItem(currMonIt);
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();
m_output.WriteLine("MonitoredItems created for SubscriptionId = {0}.", subscription.Id);
}
catch (Exception ex)
{
m_output.WriteLine("Subscribe error: {0}", ex.Message);
}
return monItList;
}
/// <summary>
/// Write a list of nodes to the Server
/// </summary>
public void WriteNodes()
{
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
return;
}
try
{
// Write the configured nodes
WriteValueCollection nodesToWrite = new WriteValueCollection();
// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
WriteValue commWriteVal = new WriteValue();
commWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
commWriteVal.AttributeId = Attributes.Value;
commWriteVal.Value = new DataValue();
commWriteVal.Value.Value = (int)111;
nodesToWrite.Add(commWriteVal);
WriteValue artWriteVal = new WriteValue();
artWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
artWriteVal.AttributeId = Attributes.Value;
artWriteVal.Value = new DataValue();
artWriteVal.Value.Value = (int)222;
nodesToWrite.Add(artWriteVal);
WriteValue qtyWriteVal = new WriteValue();
qtyWriteVal.NodeId = new NodeId("ns=4;s=IO_153");
qtyWriteVal.AttributeId = Attributes.Value;
qtyWriteVal.Value = new DataValue();
qtyWriteVal.Value.Value = (int)333;
nodesToWrite.Add(qtyWriteVal);
//// 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);
// Write the node attributes
StatusCodeCollection results = null;
DiagnosticInfoCollection diagnosticInfos;
m_output.WriteLine("Writing nodes...");
// Call Write Service
m_session.Write(null,
nodesToWrite,
out results,
out diagnosticInfos);
// Validate the response
m_validateResponse(results, nodesToWrite);
// Display the results.
m_output.WriteLine("Write Results :");
foreach (StatusCode writeResult in results)
{
m_output.WriteLine(" {0}", writeResult);
}
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Write Nodes Error : {ex.Message}.");
}
}
#endregion Public Methods
}
}
+2 -2
View File
@@ -114,12 +114,12 @@ namespace IOB_UT
/// <summary>
/// Indice NS da cui fare il browse dei file
/// </summary>
public uint BrowseNSIndex { get; set; } = 4;
public ushort BrowseNSIndex { get; set; } = 4;
/// <summary>
/// ID del nodo da cui partire x il browse di identificazione nodi iniziale
/// </summary>
public ushort BrowseValue { get; set; } = 5001;
public uint BrowseValue { get; set; } = 5001;
/// <summary>
/// Struttura dati x check condizione Errore
+3
View File
@@ -118,6 +118,9 @@
<Reference Include="Opc.Ua.Client, Version=1.4.365.0, Culture=neutral, PublicKeyToken=bfa7a73c5cf4b6e8, processorArchitecture=MSIL">
<HintPath>..\packages\OPCFoundation.NetStandard.Opc.Ua.Client.1.4.365.48\lib\net462\Opc.Ua.Client.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Configuration, Version=1.4.365.0, Culture=neutral, PublicKeyToken=bfa7a73c5cf4b6e8, processorArchitecture=MSIL">
<HintPath>..\packages\OPCFoundation.NetStandard.Opc.Ua.Configuration.1.4.365.48\lib\net462\Opc.Ua.Configuration.dll</HintPath>
</Reference>
<Reference Include="Opc.Ua.Core, Version=1.4.365.0, Culture=neutral, PublicKeyToken=bfa7a73c5cf4b6e8, processorArchitecture=MSIL">
<HintPath>..\packages\OPCFoundation.NetStandard.Opc.Ua.Core.1.4.365.48\lib\net462\Opc.Ua.Core.dll</HintPath>
</Reference>
+41 -62
View File
@@ -98,22 +98,6 @@ namespace IOB_WIN_NEXT
// leggo il file...
loadOpcUaConf(jsonFileName);
}
// !!!FARE FIXME TODO Spostare DOPO connect
// faccio un primo browse dei dati...
selectedItemList = UA_ref.Browse(opcUaParams.BrowseNSIndex, opcUaParams.BrowseValue);
// sottoscrivo a rilevazione cambio dati
List<Opc.Ua.Client.MonitoredItem> subscribedItems = UA_ref.SubscribeToDataChanges(selectedItemList);
// aggiungo come DataItems
int dSamplePeriod = 0;
int threshDBand = 0;
string uuid = "";
foreach (var item in subscribedItems)
{
OpcUaDataItemExt newItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, item);
dataItemMem.Add(uuid, newItem);
}
}
#endregion Public Constructors
@@ -437,55 +421,54 @@ namespace IOB_WIN_NEXT
/// Vera connessione ad MTC
/// </summary>
/// <returns></returns>
private short doConnect()
private async Task<short> doConnect()
{
IOutput console = new ConsoleOutput();
short esitoLink = 0;
// reset memoria dataItem..
dataItemMem = new Dictionary<string, MtcDataItemExt>();
dataItemMem = new Dictionary<string, OpcUaDataItemExt>();
// predisposizione conf oggetto di comunicazione MTC
short port = 5000;
short.TryParse(cIobConf.cncPort, out port);
// test probe!
try
{
var probe = new Probe($"http://{cIobConf.cncIpAddr}:{port}").Execute();
// se valido loggo!
if (probe != null)
{
lgInfo($"Effettuata correttamente PROBE per device MTC all'URL {probe.Url} | vers: {probe.Version} | send: {probe.Header.Sender}");
lgInfo($"---------------- Elenco Devices ----------------");
// loggo devices principali...
logDevicesList(probe.Devices);
}
}
catch (Exception exc)
{
lgError($"Eccezione durante test probe:{Environment.NewLine}{exc}");
}
// attendo 1 sec...
Thread.Sleep(1000);
// ora avvio
try
{
lgInfo($"Chiamata apertura MTC Client: {cIobConf.cncIpAddr}:{port}");
UA_ref = new MTConnectClient($"http://{cIobConf.cncIpAddr}:{port}");
lgInfo("Start init OpcUa Client");
// Define the UA Client application
ApplicationInstance application = new ApplicationInstance();
application.ApplicationName = "Steamware IOB-WIN Client";
application.ApplicationType = ApplicationType.Client;
// gestire init da con + browse e discovery post connessione
// load the application configuration.
await application.LoadApplicationConfiguration("ConsoleReferenceClient.Config.xml", silent: false);
// check the application certificate.
await application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0);
// chiamare --> checkAndSend(e.CurrMonitoredItem, e.CurrNotify, true);
lgInfo($"Chiamata UAClient con configurazione standard: {application.ApplicationConfiguration.ApplicationName}");
UA_ref = new UAClient(application.ApplicationConfiguration, console, ClientBase.ValidateResponse);
// gestire eventi change
lgInfo($"Chiamata apertura OpcUa Client: {cIobConf.cncIpAddr}:{port}");
UA_ref.ServerUrl = $"opc.tcp://{cIobConf.cncIpAddr}:{port}";
bool connected = await UA_ref.ConnectAsync();
if (connected)
{
// faccio un primo browse dei dati...
selectedItemList = UA_ref.Browse(opcUaParams.BrowseNSIndex, opcUaParams.BrowseValue);
// sottoscrivo a rilevazione cambio dati
List<Opc.Ua.Client.MonitoredItem> subscribedItems = UA_ref.SubscribeToDataChanges(selectedItemList);
// aggiungo come DataItems
int dSamplePeriod = 0;
int threshDBand = 0;
string uuid = "";
foreach (var item in subscribedItems)
{
OpcUaDataItemExt newItem = formatDataItem(ref dSamplePeriod, ref threshDBand, ref uuid, item);
dataItemMem.Add(uuid, newItem);
}
// gestione eventi change
UA_ref.eh_MonItChange += UA_ref_eh_MonItChange;
}
UA_ref.eh_MonItChange += UA_ref_eh_MonItChange;
// Subscribe to the Event handlers to receive the MTConnect documents
UA_ref.ProbeReceived += DevicesSuccessful;
UA_ref.CurrentReceived += CurrentSuccessful;
UA_ref.SampleReceived += StreamsSuccessful;
// attendo 1 sec...
Thread.Sleep(1000);
UA_ref.Start();
esitoLink = 1;
// fix tempi!
@@ -897,15 +880,6 @@ namespace IOB_WIN_NEXT
}
}
/// <summary>
/// Ricevuta modifica come stream da campionamenti ricevuti
/// </summary>
/// <param name="document"></param>
protected void StreamsSuccessful(MTConnectStreams.Document document)
{
checkAndSend(document, false);
}
#endregion Protected Methods
#region Public Methods
@@ -1040,7 +1014,12 @@ namespace IOB_WIN_NEXT
{
// ora provo connessione...
parentForm.commPlcActive = true;
short esitoLink = doConnect();
var task = Task.Run(async () =>
{
return await doConnect();
});
short esitoLink = task.Result; // use returned result from async method here
lgInfo($"szStatusConnection OpcUa, esitoLink: {esitoLink}");
parentForm.commPlcActive = false;
connectionOk = true;
+4 -5
View File
@@ -179,7 +179,7 @@ namespace IOB_WIN_NEXT
/// <summary>
/// Browse Server nodes
/// </summary>
public Dictionary<string, string> Browse(uint startNodeNS, ushort startNodeVal)
public Dictionary<string, string> Browse(ushort startNodeNS, uint startNodeVal)
{
Dictionary<string, string> nodeIdNameList = new Dictionary<string, string>();
if (m_session == null || m_session.Connected == false)
@@ -200,7 +200,7 @@ namespace IOB_WIN_NEXT
//NodeId nodeToBrowse = ObjectIds.Server;
//NodeId nodeToBrowse = new NodeId("ns=4,i=5001");
NodeId nodeToBrowse = new NodeId(startNodeNS, startNodeVal);
NodeId nodeToBrowse = new NodeId(startNodeVal, startNodeNS);
// Call Browse service
m_output.WriteLine("Browsing {0} node...", nodeToBrowse);
@@ -211,8 +211,7 @@ namespace IOB_WIN_NEXT
foreach (ReferenceDescription result in browseResults)
{
m_output.WriteLine($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.NodeClass} | {result.NodeId} | {result.BinaryEncodingId} | {result.BrowseName}");
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);
}
}
@@ -641,4 +640,4 @@ namespace IOB_WIN_NEXT
#endregion Public Methods
}
}
}
+643
View File
@@ -0,0 +1,643 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using Opc.Ua;
using Opc.Ua.Client;
namespace IOB_WIN_NEXT
{
/// <summary>
/// Evento per incapsulare dati x refresh pagina
/// </summary>
public class opcUaMonitItemChange : EventArgs
{
#region Private Fields
/// <summary>
/// Monitored Item da notificare
/// </summary>
private readonly MonitoredItem _monitoredItem;
/// <summary>
/// Valore notifica
/// </summary>
private readonly MonitoredItemNotification _notification;
#endregion Private Fields
#region Public Constructors
/// <summary>
/// salvataggio obj
/// </summary>
/// <param name="newObject"></param>
public opcUaMonitItemChange(MonitoredItem monitoredItem, MonitoredItemNotification notification)
{
_monitoredItem = monitoredItem;
_notification = notification;
}
#endregion Public Constructors
#region Public Properties
/// <summary>
/// Proprietà lettura del MonitoredItem
/// </summary>
public MonitoredItem CurrMonitoredItem
{
get { return _monitoredItem; }
}
/// <summary>
/// Proprietà lettura della notifica
/// </summary>
public MonitoredItemNotification CurrNotify
{
get { return _notification; }
}
#endregion Public Properties
}
/// <summary>
/// OPC UA Client with examples of basic functionality.
/// </summary>
public class UAClient
{
#region Private Fields
private readonly IOutput m_output;
private readonly Action<IList, IList> m_validateResponse;
private ApplicationConfiguration m_configuration;
private Session m_session;
#endregion Private Fields
#region Public Constructors
/// <summary>
/// Initializes a new instance of the UAClient class.
/// </summary>
public UAClient(ApplicationConfiguration configuration, IOutput output, Action<IList, IList> validateResponse)
{
m_validateResponse = validateResponse;
m_output = output;
m_configuration = configuration;
m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
}
#endregion Public Constructors
#region Public Events
/// <summary>
/// Evento notifica variazione MonitoredItem
/// </summary>
public event EventHandler<opcUaMonitItemChange> eh_MonItChange;
#endregion Public Events
#region Public Properties
/// <summary>
/// Gets or sets the server URL.
/// </summary>
public string ServerUrl { get; set; } = "opc.tcp://localhost:62541/Quickstarts/ReferenceServer";
/// <summary>
/// Gets the client session.
/// </summary>
public Session Session => m_session;
#endregion Public Properties
#region Private Methods
/// <summary>
/// Handles the certificate validation event.
/// This event is triggered every time an untrusted certificate is received from the server.
/// </summary>
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;
}
/// <summary>
/// Handle DataChange notifications from Server
/// </summary>
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
/// <summary>
/// Browse Server nodes
/// </summary>
public Dictionary<string, string> Browse(ushort startNodeNS, uint startNodeVal)
{
Dictionary<string, string> nodeIdNameList = new Dictionary<string, string>();
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;
}
/// <summary>
/// Call UA method
/// </summary>
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<object> outputArguments = null;
// Invoke Call service
m_output.WriteLine("Calling UAMethod for node {0} ...", methodId);
outputArguments = m_session.Call(objectId, methodId, inputArguments);
// Display results
m_output.WriteLine("Method call returned {0} output argument(s):", outputArguments.Count);
foreach (var outputArgument in outputArguments)
{
m_output.WriteLine(" OutputValue = {0}", outputArgument.ToString());
}
}
catch (Exception ex)
{
m_output.WriteLine("Method call error: {0}", ex.Message);
}
}
/// <summary>
/// Creates a session with the UA server
/// </summary>
public async Task<bool> ConnectAsync()
{
try
{
if (m_session != null && m_session.Connected == true)
{
m_output.WriteLine("Session already connected!");
}
else
{
m_output.WriteLine("Connecting...");
// Get the endpoint by connecting to server's discovery endpoint.
// Try to find the first endopint without security.
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
// Create the session
Session session = await Session.Create(
m_configuration,
endpoint,
false,
false,
m_configuration.ApplicationName,
30 * 60 * 1000,
new UserIdentity(),
null
);
// Assign the created session
if (session != null && session.Connected)
{
m_session = session;
}
// Session created successfully.
m_output.WriteLine($"New Session Created with SessionName = {m_session.SessionName}");
}
return true;
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Create Session Error : {ex.Message}");
return false;
}
}
/// <summary>
/// Disconnects the session.
/// </summary>
public void Disconnect()
{
try
{
if (m_session != null)
{
m_output.WriteLine("Disconnecting...");
m_session.Close();
m_session.Dispose();
m_session = null;
// Log Session Disconnected event
m_output.WriteLine("Session Disconnected.");
}
else
{
m_output.WriteLine("Session not created!");
}
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Disconnect Error : {ex.Message}");
}
}
/// <summary>
/// Read a list of nodes from Server
/// </summary>
public void ReadNodes()
{
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
return;
}
try
{
#region Read a node by calling the Read Service
// build a list of nodes to be read
ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
{
// Value of ServerStatus
new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
// BrowseName of ServerStatus_StartTime
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
// Value of ServerStatus_StartTime
new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
};
// Read the node attributes
m_output.WriteLine("Reading nodes...");
// Call Read Service
m_session.Read(
null,
0,
TimestampsToReturn.Both,
nodesToRead,
out DataValueCollection resultsValues,
out DiagnosticInfoCollection diagnosticInfos);
// Validate the results
m_validateResponse(resultsValues, nodesToRead);
// Display the results.
foreach (DataValue result in resultsValues)
{
m_output.WriteLine("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
// Read Server NamespaceArray
m_output.WriteLine("Reading Value of NamespaceArray node...");
DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
// Display the result
m_output.WriteLine($"NamespaceArray Value = {namespaceArray}");
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Read Nodes Error : {ex.Message}.");
}
}
/// <summary>
/// Create Subscription and MonitoredItems for DataChanges
/// </summary>
public List<MonitoredItem> SubscribeToDataChanges(Dictionary<string, string> DataList)
{
List<MonitoredItem> monItList = new List<MonitoredItem>();
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
return monItList;
}
try
{
// Create a subscription for receiving data change notifications
// Define Subscription parameters
Subscription subscription = new Subscription(m_session.DefaultSubscription);
subscription.DisplayName = "Steamware IOB-WIN Subscription";
subscription.PublishingEnabled = true;
subscription.PublishingInterval = 1000;
m_session.AddSubscription(subscription);
// Create the subscription on Server side
subscription.Create();
m_output.WriteLine("New Subscription created with SubscriptionId = {0}.", subscription.Id);
// Create MonitoredItems for data changes
foreach (var item in DataList)
{
MonitoredItem currMonIt = new MonitoredItem(subscription.DefaultItem);
// Int32 Node - Objects\CTT\Scalar\Simulation\Int32
currMonIt.StartNodeId = new NodeId(item.Key);
currMonIt.AttributeId = Attributes.Value;
currMonIt.DisplayName = item.Value;
currMonIt.SamplingInterval = 1000;
currMonIt.Notification += OnMonitoredItemNotification;
subscription.AddItem(currMonIt);
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();
m_output.WriteLine("MonitoredItems created for SubscriptionId = {0}.", subscription.Id);
}
catch (Exception ex)
{
m_output.WriteLine("Subscribe error: {0}", ex.Message);
}
return monItList;
}
/// <summary>
/// Write a list of nodes to the Server
/// </summary>
public void WriteNodes()
{
if (m_session == null || m_session.Connected == false)
{
m_output.WriteLine("Session not connected!");
return;
}
try
{
// Write the configured nodes
WriteValueCollection nodesToWrite = new WriteValueCollection();
// Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
WriteValue commWriteVal = new WriteValue();
commWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
commWriteVal.AttributeId = Attributes.Value;
commWriteVal.Value = new DataValue();
commWriteVal.Value.Value = (int)111;
nodesToWrite.Add(commWriteVal);
WriteValue artWriteVal = new WriteValue();
artWriteVal.NodeId = new NodeId("ns=4;s=IO_151");
artWriteVal.AttributeId = Attributes.Value;
artWriteVal.Value = new DataValue();
artWriteVal.Value.Value = (int)222;
nodesToWrite.Add(artWriteVal);
WriteValue qtyWriteVal = new WriteValue();
qtyWriteVal.NodeId = new NodeId("ns=4;s=IO_153");
qtyWriteVal.AttributeId = Attributes.Value;
qtyWriteVal.Value = new DataValue();
qtyWriteVal.Value.Value = (int)333;
nodesToWrite.Add(qtyWriteVal);
//// 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);
// Write the node attributes
StatusCodeCollection results = null;
DiagnosticInfoCollection diagnosticInfos;
m_output.WriteLine("Writing nodes...");
// Call Write Service
m_session.Write(null,
nodesToWrite,
out results,
out diagnosticInfos);
// Validate the response
m_validateResponse(results, nodesToWrite);
// Display the results.
m_output.WriteLine("Write Results :");
foreach (StatusCode writeResult in results)
{
m_output.WriteLine(" {0}", writeResult);
}
}
catch (Exception ex)
{
// Log Error
m_output.WriteLine($"Write Nodes Error : {ex.Message}.");
}
}
#endregion Public Methods
}
}
+1
View File
@@ -16,6 +16,7 @@
<package id="NLog" version="4.6.8" targetFramework="net40-client" requireReinstallation="true" />
<package id="OmronFinsTCP.Net" version="3.0.0.0" targetFramework="net40-client" />
<package id="OPCFoundation.NetStandard.Opc.Ua.Client" version="1.4.365.48" targetFramework="net462" />
<package id="OPCFoundation.NetStandard.Opc.Ua.Configuration" version="1.4.365.48" targetFramework="net462" />
<package id="OPCFoundation.NetStandard.Opc.Ua.Core" version="1.4.365.48" targetFramework="net462" />
<package id="OPCFoundation.NetStandard.Opc.Ua.Security.Certificates" version="1.4.365.48" targetFramework="net462" />
<package id="Portable.BouncyCastle" version="1.8.10" targetFramework="net462" />