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 { /// /// 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. /// public class UAClient { #region Private Fields private readonly string currIob; private readonly Action 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; /// /// The user identity to use when creating the session. /// public IUserIdentity CurrUserIdentity { get; set; } = new UserIdentity(); #endregion Protected Fields #region Public Constructors /// /// Initializes a new instance of the UAClient class. /// public UAClient(ApplicationConfiguration configuration, string codIOB, string user, string pwd, bool verboseLog, Action validateResponse) { m_validateResponse = validateResponse; currIob = codIOB; lg = LogManager.GetCurrentClassLogger(); if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd)) { CurrUserIdentity = new UserIdentity(user, pwd); } else { CurrUserIdentity = new UserIdentity(); } isLogVerbose = verboseLog; 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:4840"; /// /// 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) { lgError($"{error.StatusCode} | {error.Code} | {error.LocalizedText}"); error = error.InnerResult; } if (certificateAccepted) { lgInfo($"Untrusted Certificate accepted. SubjectName = {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)); } lgTrace($"Notification Received | Variable: {monitoredItem.DisplayName} | Value: {notification.Value}"); } catch (Exception ex) { lgError($"OnMonitoredItemNotification error: {ex.Message}"); } } #endregion Private Methods #region Protected Methods /// /// Effettua logging ERROR corretto impostanto anche la variabile IOB prima di scrivere... /// /// protected void lgError(string message) { lg.Factory.Configuration.Variables["codIOB"] = currIob; lg.Error(message); } /// /// Effettua logging INFO corretto impostanto anche la variabile IOB prima di scrivere... /// /// protected void lgInfo(string message) { lg.Factory.Configuration.Variables["codIOB"] = currIob; lg.Info(message); } /// /// Effettua logging DEBUG corretto impostanto anche la variabile IOB prima di scrivere... /// /// protected void lgDebug(string message) { lg.Factory.Configuration.Variables["codIOB"] = currIob; lg.Info(message); } /// /// Effettua logging TRACE corretto impostanto anche la variabile IOB prima di scrivere... /// /// protected void lgTrace(string message) { lg.Factory.Configuration.Variables["codIOB"] = currIob; lg.Trace(message); } #endregion Protected Methods #region Public Methods /// /// Browse Server nodes /// public bool Browse(ushort startNodeNS, uint startNodeVal, List vetoBrowse, ref Dictionary nodeIdNameList) { bool fatto = false; if (m_session == null || m_session.Connected == false) { lgError("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 lgTrace($"Browsing {nodeToBrowse} node..."); ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse); // Display the results lgTrace($"Browse returned {browseResults.Count} results:"); foreach (ReferenceDescription result in browseResults) { lgTrace($" NodeId = {result.NodeId}, TypeId = {result.TypeId}, 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; } /// /// Browse Server nodes /// public bool Browse(string browsePath, List vetoBrowse, ref Dictionary nodeIdNameList) { bool fatto = false; if (m_session == null || m_session.Connected == false) { lgError("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); //nodeToBrowse = ObjectIds.Server; //nodeToBrowse = new NodeId("Calibratrice_L1", 4); //nodeToBrowse = new NodeId("Dati_Mes", 4); //nodeToBrowse = new NodeId(5001, 2); //nodeToBrowse = new NodeId("ns=4;s=NxController"); //nodeToBrowse = new NodeId("ns=4;s=Dati_Mes"); //nodeToBrowse = new NodeId("NxController.GlobalVars", 4); //nodeToBrowse = new NodeId("Dati_Mes", 4); // Call Browse service lgTrace($"Browsing {nodeToBrowse} node..."); ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse); // Display the results lgTrace($"Browse returned {browseResults.Count} results:"); foreach (ReferenceDescription result in browseResults) { // se veto --> loggo veto if (vetoBrowse.Contains($"{result.NodeId}")) { lgTrace($"| 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 { lgTrace($" 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; } /// /// Call UA method /// public void CallMethod() { if (m_session == null || m_session.Connected == false) { lgError("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 outputArguments = null; // Invoke Call service lgDebug($"Calling UAMethod for node {methodId} ..."); outputArguments = m_session.Call(objectId, methodId, inputArguments); // Display results lgDebug($"Method call returned {outputArguments.Count} output argument(s):"); foreach (var outputArgument in outputArguments) { lgDebug($" OutputValue = {outputArgument}"); } } catch (Exception ex) { lgError($"Method call error: {ex.Message}"); } } /// /// Creates a session with the UA server /// public async Task 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, CurrUserIdentity, 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 lgError($"Create Session Error : {ex.Message}"); return false; } } /// /// Disconnects the session. /// 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 { lgError("Session not created!"); } } catch (Exception ex) { // Log Error lgError($"Disconnect Error : {ex.Message}"); } } /// /// Read a SINGLE of nodes value from Server /// /// /// public string ReadNode(NodeId reqNodeId) { string answ = ""; if (m_session == null || m_session.Connected == false) { lgError("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 lgError($"ReadValue Error : {Environment.NewLine}{exc}"); } #endregion Read the Value attribute of a node by calling the Session.ReadValue method } catch (Exception ex) { // Log Error lgError($"Read Nodes Error : {ex.Message}."); } return answ; } /// /// Read a SINGLE of nodes value (RAW) from Server /// /// /// public object ReadNodeRaw(NodeId reqNodeId) { object answ = null; if (m_session == null || m_session.Connected == false) { lgError("Session not connected!"); return answ; } try { #region Read the Value attribute of a node by calling the Session.ReadValue method try { DataValue resp = m_session.ReadValue(reqNodeId); answ = resp; } catch (Exception exc) { // Log Error lgError($"ReadNodeRaw Error 01: {Environment.NewLine}{exc}"); } #endregion Read the Value attribute of a node by calling the Session.ReadValue method } catch (Exception ex) { // Log Error lgError($"ReadNodeRaw Error 02: {ex.Message}."); } return answ; } /// /// Read a list of nodes from Server /// public void ReadNodes() { if (m_session == null || m_session.Connected == false) { lgError("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) { lgTrace($"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 lgTrace("Reading Value of NamespaceArray node..."); DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray); // Display the result lgTrace($"NamespaceArray Value = {namespaceArray}"); #endregion Read the Value attribute of a node by calling the Session.ReadValue method } catch (Exception ex) { // Log Error lgError($"Read Nodes Error : {ex.Message}."); } } /// /// Create Subscription and MonitoredItems for DataChanges /// public List SubscribeToDataChanges(Dictionary DataList) { List monItList = new List(); if (m_session == null || m_session.Connected == false) { lgError("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) { lgError($"Subscribe error: {ex.Message}"); } return monItList; } /// Write a list of nodes to the Server /// public void WriteNodes(List node2Write) { if (m_session == null || m_session.Connected == false) { lgError("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; lgDebug("Writing nodes..."); // Call Write Service m_session.Write(null, nodesToWrite, out results, out diagnosticInfos); // Validate the response m_validateResponse(results, nodesToWrite); // Display the results. lgDebug("Write Results :"); foreach (StatusCode writeResult in results) { lgDebug($" {writeResult}"); } } catch (Exception ex) { // Log Error lgError($"Write Nodes Error : {ex.Message}"); } } /// /// Write a list of nodes to the Server /// public void WriteSingleNode(WriteValue node2Write) { if (m_session == null || m_session.Connected == false) { lgError("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; lgDebug("Writing nodes..."); // Call Write Service m_session.Write(null, nodesToWrite, out results, out diagnosticInfos); // Validate the response m_validateResponse(results, nodesToWrite); // Display the results. lgDebug("Write Results :"); foreach (StatusCode writeResult in results) { lgDebug(" {writeResult}"); } } catch (Exception ex) { // Log Error lgError($"Write Nodes Error : {ex.Message}"); } } /// /// Write a list of nodes to the Server /// public void WriteTestNodes() { if (m_session == null || m_session.Connected == false) { lgError("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; lgDebug("Writing nodes..."); // Call Write Service m_session.Write(null, nodesToWrite, out results, out diagnosticInfos); // Validate the response m_validateResponse(results, nodesToWrite); // Display the results. lgDebug("Write Results :"); foreach (StatusCode writeResult in results) { lgDebug($" {writeResult}"); } } catch (Exception ex) { // Log Error lgError($"Write Nodes Error : {ex.Message}."); } } #endregion Public Methods } }