925 lines
35 KiB
C#
925 lines
35 KiB
C#
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;
|
|
using NLog;
|
|
|
|
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 string currIob;
|
|
private readonly Action<IList, IList> m_validateResponse;
|
|
private ApplicationConfiguration m_configuration;
|
|
private Session m_session;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Protected Fields
|
|
|
|
protected static Logger lg;
|
|
protected static bool isLogVerbose = false;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the UAClient class.
|
|
/// </summary>
|
|
public UAClient(ApplicationConfiguration configuration, string codIOB, bool verboseLog, Action<IList, IList> validateResponse)
|
|
{
|
|
m_validateResponse = validateResponse;
|
|
currIob = codIOB;
|
|
lg = LogManager.GetCurrentClassLogger();
|
|
isLogVerbose = verboseLog;
|
|
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:4840";
|
|
|
|
/// <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)
|
|
{
|
|
lgError($"{error.StatusCode} | {error.Code} | {error.LocalizedText}");
|
|
error = error.InnerResult;
|
|
}
|
|
|
|
if (certificateAccepted)
|
|
{
|
|
lgInfo($"Untrusted Certificate accepted. SubjectName = {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));
|
|
}
|
|
lgInfo($"Notification Received | Variable: {monitoredItem.DisplayName} | Value: {notification.Value}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
lgError($"OnMonitoredItemNotification error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void lgError(string message)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = currIob;
|
|
lg.Error(message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere...
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
protected void lgInfo(string message)
|
|
{
|
|
lg.Factory.Configuration.Variables["codIOB"] = currIob;
|
|
if (isLogVerbose)
|
|
{
|
|
lg.Info(message);
|
|
}
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Browse Server nodes
|
|
/// </summary>
|
|
public bool Browse(ushort startNodeNS, uint startNodeVal, List<string> vetoBrowse, ref Dictionary<string, string> nodeIdNameList)
|
|
{
|
|
bool fatto = false;
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("Session not connected!");
|
|
return false;
|
|
}
|
|
|
|
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
|
|
lgInfo($"Browsing {nodeToBrowse} node...");
|
|
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
|
|
|
// Display the results
|
|
lgInfo($"Browse returned {browseResults.Count} results:");
|
|
|
|
foreach (ReferenceDescription result in browseResults)
|
|
{
|
|
lgInfo($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
|
// se NON fa parte dell'elenco dei VETO di filterItems...
|
|
if (!vetoBrowse.Contains($"{result.NodeId}"))
|
|
{
|
|
// se mancasse aggiungo...
|
|
if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
|
|
{
|
|
nodeIdNameList.Add(result.NodeId.ToString(), result.DisplayName.Text);
|
|
}
|
|
}
|
|
}
|
|
fatto = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgError($"Browse Error : {ex.Message}");
|
|
}
|
|
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Browse Server nodes
|
|
/// </summary>
|
|
public bool Browse(string browsePath, List<string> vetoBrowse, ref Dictionary<string, string> nodeIdNameList)
|
|
{
|
|
bool fatto = false;
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("Session not connected!");
|
|
return false;
|
|
}
|
|
|
|
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(browsePath);
|
|
|
|
// Call Browse service
|
|
lgInfo($"Browsing {nodeToBrowse} node...");
|
|
ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
|
|
|
|
// Display the results
|
|
lgInfo($"Browse returned {browseResults.Count} results:");
|
|
|
|
foreach (ReferenceDescription result in browseResults)
|
|
{
|
|
// se veto --> loggo veto
|
|
if (vetoBrowse.Contains($"{result.NodeId}"))
|
|
{
|
|
lgInfo($"| FILTERED --> NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
|
}
|
|
// se NON fa parte dell'elenco dei VETO di filterItems...
|
|
else
|
|
{
|
|
lgInfo($" NodeId = {result.NodeId}, DisplayName = {result.DisplayName.Text}, NodeClass = {result.NodeClass}, Others: {result.BinaryEncodingId} | {result.BrowseName}");
|
|
// se mancasse aggiungo...
|
|
if (!nodeIdNameList.ContainsKey($"{result.NodeId}"))
|
|
{
|
|
nodeIdNameList.Add($"{result.NodeId}", result.DisplayName.Text);
|
|
// se è un nodo object --> faccio sub browse!
|
|
if (result.NodeClass != NodeClass.Variable)
|
|
{
|
|
this.Browse($"{result.NodeId}", vetoBrowse, ref nodeIdNameList);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fatto = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgError($"Browse Error : {ex.Message}");
|
|
}
|
|
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Call UA method
|
|
/// </summary>
|
|
public void CallMethod()
|
|
{
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("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
|
|
lgInfo($"Calling UAMethod for node {methodId} ...");
|
|
outputArguments = m_session.Call(objectId, methodId, inputArguments);
|
|
|
|
// Display results
|
|
lgInfo($"Method call returned {outputArguments.Count} output argument(s):");
|
|
|
|
foreach (var outputArgument in outputArguments)
|
|
{
|
|
lgInfo($" OutputValue = {outputArgument}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
lgInfo($"Method call error: {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)
|
|
{
|
|
lgInfo("Session already connected!");
|
|
}
|
|
else
|
|
{
|
|
lgInfo("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.
|
|
lgInfo($"New Session Created with SessionName = {m_session.SessionName}");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"Create Session Error : {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disconnects the session.
|
|
/// </summary>
|
|
public void Disconnect()
|
|
{
|
|
try
|
|
{
|
|
if (m_session != null)
|
|
{
|
|
lgInfo("Disconnecting...");
|
|
|
|
m_session.Close();
|
|
m_session.Dispose();
|
|
m_session = null;
|
|
|
|
// Log Session Disconnected event
|
|
lgInfo("Session Disconnected.");
|
|
}
|
|
else
|
|
{
|
|
lgInfo("Session not created!");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"Disconnect Error : {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a SINGLE of nodes value from Server
|
|
/// </summary>
|
|
/// <param name="reqNodeId"></param>
|
|
/// <returns></returns>
|
|
public string ReadNode(NodeId reqNodeId)
|
|
{
|
|
string answ = "";
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("Session not connected!");
|
|
return answ;
|
|
}
|
|
|
|
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
|
|
//lgInfo("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)
|
|
//{
|
|
// 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);
|
|
answ = $"{resp.Value}";
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
// Log Error
|
|
lgInfo($"ReadValue Error : {Environment.NewLine}{exc}");
|
|
}
|
|
|
|
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"Read Nodes Error : {ex.Message}.");
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a list of nodes from Server
|
|
/// </summary>
|
|
public void ReadNodes()
|
|
{
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("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
|
|
lgInfo("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)
|
|
{
|
|
lgInfo($"Read Value = {result.Value} , StatusCode = {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
|
|
lgInfo("Reading Value of NamespaceArray node...");
|
|
DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
|
|
// Display the result
|
|
lgInfo($"NamespaceArray Value = {namespaceArray}");
|
|
|
|
#endregion Read the Value attribute of a node by calling the Session.ReadValue method
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"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)
|
|
{
|
|
lgInfo("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();
|
|
lgInfo($"New Subscription created with SubscriptionId = {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();
|
|
lgInfo($"MonitoredItems created for SubscriptionId = {subscription.Id}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
lgInfo($"Subscribe error: {ex.Message}");
|
|
}
|
|
return monItList;
|
|
}
|
|
|
|
/// Write a list of nodes to the Server
|
|
/// </summary>
|
|
public void WriteNodes(List<WriteValue> node2Write)
|
|
{
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("Session not connected!");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Write the configured nodes
|
|
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
|
nodesToWrite.AddRange(node2Write);
|
|
|
|
// Write the node attributes
|
|
StatusCodeCollection results = null;
|
|
DiagnosticInfoCollection diagnosticInfos;
|
|
lgInfo("Writing nodes...");
|
|
|
|
// Call Write Service
|
|
m_session.Write(null,
|
|
nodesToWrite,
|
|
out results,
|
|
out diagnosticInfos);
|
|
|
|
// Validate the response
|
|
m_validateResponse(results, nodesToWrite);
|
|
|
|
// Display the results.
|
|
lgInfo("Write Results :");
|
|
|
|
foreach (StatusCode writeResult in results)
|
|
{
|
|
lgInfo($" {writeResult}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"Write Nodes Error : {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write a list of nodes to the Server
|
|
/// </summary>
|
|
public void WriteSingleNode(WriteValue node2Write)
|
|
{
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("Session not connected!");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Write the configured nodes
|
|
WriteValueCollection nodesToWrite = new WriteValueCollection();
|
|
|
|
nodesToWrite.Add(node2Write);
|
|
|
|
// Write the node attributes
|
|
StatusCodeCollection results = null;
|
|
DiagnosticInfoCollection diagnosticInfos;
|
|
lgInfo("Writing nodes...");
|
|
|
|
// Call Write Service
|
|
m_session.Write(null,
|
|
nodesToWrite,
|
|
out results,
|
|
out diagnosticInfos);
|
|
|
|
// Validate the response
|
|
m_validateResponse(results, nodesToWrite);
|
|
|
|
// Display the results.
|
|
lgInfo("Write Results :");
|
|
|
|
foreach (StatusCode writeResult in results)
|
|
{
|
|
lgInfo(" {writeResult}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"Write Nodes Error : {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write a list of nodes to the Server
|
|
/// </summary>
|
|
public void WriteTestNodes()
|
|
{
|
|
if (m_session == null || m_session.Connected == false)
|
|
{
|
|
lgInfo("Session not connected!");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// scrivo vaslori a caso.. hhmm odierni
|
|
int hhmm = 9876;
|
|
int.TryParse(DateTime.Now.ToString("HHmm"), out hhmm);
|
|
// 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)hhmm - 10;
|
|
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)hhmm;
|
|
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)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;
|
|
lgInfo("Writing nodes...");
|
|
|
|
// Call Write Service
|
|
m_session.Write(null,
|
|
nodesToWrite,
|
|
out results,
|
|
out diagnosticInfos);
|
|
|
|
// Validate the response
|
|
m_validateResponse(results, nodesToWrite);
|
|
|
|
// Display the results.
|
|
lgInfo("Write Results :");
|
|
|
|
foreach (StatusCode writeResult in results)
|
|
{
|
|
lgInfo($" {writeResult}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Log Error
|
|
lgInfo($"Write Nodes Error : {ex.Message}.");
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
} |