// This example shows how to store current state of the subscribed monitored items in a dictionary.
// each change.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
using System;
using System.Collections.Generic;
using System.Threading;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples._EasyUAClient
{
partial class SubscribeMultipleMonitoredItems
{
public static void StoreInDictionary()
{
UAEndpointDescriptor endpointDescriptor =
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
// or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
// or "https://opcua.demo-this.com:51212/UA/SampleServer/"
// Instantiate the client object and hook events.
using (var client = new EasyUAClient())
{
client.DataChangeNotification += client_DataChangeNotification_StoreInDictionary;
Console.WriteLine("Subscribing...");
client.SubscribeMultipleMonitoredItems(new[]
{
new EasyUAMonitoredItemArguments(null, endpointDescriptor,
"nsu=http://test.org/UA/Data/ ;i=10845", 1000),
new EasyUAMonitoredItemArguments(null, endpointDescriptor,
"nsu=http://test.org/UA/Data/ ;i=10853", 1000),
new EasyUAMonitoredItemArguments(null, endpointDescriptor,
"nsu=http://test.org/UA/Data/ ;i=10855", 1000)
});
Console.WriteLine("Processing monitored item changed events for 1 minute...");
int startTickCount = Environment.TickCount;
do
{
Thread.Sleep(5 * 1000);
// Each 5 seconds, display the current state of the monitored items we have subscribed to.
lock (_serialize)
{
Console.WriteLine();
foreach (KeyValuePair<UANodeDescriptor, UAAttributeDataResult> pair in _attributeDataResultDictionary)
{
UANodeDescriptor nodeDescriptor = pair.Key;
UAAttributeDataResult attributeDataResult = pair.Value;
Console.WriteLine($"{nodeDescriptor}: {attributeDataResult}");
}
// The code above shows how you can process the complete contents of the dictionary. In other
// scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
// by indexing the dictionary by the node descriptor of the monitored item you are interested in.
}
} while (Environment.TickCount < startTickCount + 60 * 1000);
Console.WriteLine("Unsubscribing...");
}
Console.WriteLine("Finished.");
}
static void client_DataChangeNotification_StoreInDictionary(object sender, EasyUADataChangeNotificationEventArgs e)
{
lock (_serialize)
// Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
// key which is the node descriptor of the monitored item this data change notification is for.
_attributeDataResultDictionary[e.Arguments.NodeDescriptor] = (UAAttributeDataResult)e;
}
// Holds last known state of each subscribed monitored item.
private static readonly Dictionary<UANodeDescriptor, UAAttributeDataResult> _attributeDataResultDictionary =
new Dictionary<UANodeDescriptor, UAAttributeDataResult>();
// Synchronization object used to prevent simultaneous access to the dictionary.
private static readonly object _serialize = new object();
}
}
' This example shows how to store current state of the subscribed monitored items in a dictionary.
' each change.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.
Imports System.Threading
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace _EasyUAClient
Partial Friend Class SubscribeMultipleMonitoredItems
Public Shared Sub StoreInDictionary()
' Define which server we will work with.
Dim endpointDescriptor As UAEndpointDescriptor =
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
' or "https://opcua.demo-this.com:51212/UA/SampleServer/"
' Instantiate the client object.
Using client = New EasyUAClient()
AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification_StoreInDictionary
Console.WriteLine("Subscribing...")
client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() {
New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor,
"nsu=http://test.org/UA/Data/ ;i=10845", 1000),
New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor,
"nsu=http://test.org/UA/Data/ ;i=10853", 1000),
New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor,
"nsu=http://test.org/UA/Data/ ;i=10855", 1000)
})
Console.WriteLine("Processing monitored item changed events for 1 minute...")
Dim startTickCount As Integer = Environment.TickCount
Do
Thread.Sleep(5 * 1000)
' Each 5 seconds, display the current state of the monitored items we have subscribed to.
SyncLock _serialize
Console.WriteLine()
For Each pair As KeyValuePair(Of UANodeDescriptor, UAAttributeDataResult) In _attributeDataResultDictionary
Dim nodeDescriptor As UANodeDescriptor = pair.Key
Dim attributeDataResult As UAAttributeDataResult = pair.Value
Console.WriteLine($"{nodeDescriptor}: {attributeDataResult}")
Next
' The code above shows how you can process the complete contents of the dictionary. In other
' scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
' by indexing the dictionary by the node descriptor of the monitored item you are interested in.
End SyncLock
Loop While Environment.TickCount < startTickCount + 60 * 1000
Console.WriteLine("Unsubscribing...")
End Using
Console.WriteLine("Finished.")
End Sub
Private Shared Sub client_DataChangeNotification_StoreInDictionary(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
SyncLock _serialize
' Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
' key which is the node descriptor of the monitored item this data change notification is for.
_attributeDataResultDictionary(e.Arguments.NodeDescriptor) = CType(e, UAAttributeDataResult)
End SyncLock
' Display value
If e.Succeeded Then
Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value)
Else
Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief)
End If
End Sub
' Holds last known state of each subscribed monitores item.
Private Shared ReadOnly _attributeDataResultDictionary As New Dictionary(Of UANodeDescriptor, UAAttributeDataResult)
' Synchronization object used to prevent simultaneous access to the dictionary.
Private Shared ReadOnly _serialize As New Object
End Class
End Namespace
# This example shows how to store current state of the subscribed monitored items in a dictionary.
# each change.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import threading
import time
# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *
lock = threading.Lock()
attributeDataResultDictionary = {}
# Data change notification event handler.
def dataChangeNotification(sender, eventArgs):
global lock
global attributeDataResultDictionary
with lock:
# Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
# key which is the node descriptor of the monitored item this data change notification is for.
attributeDataResultDictionary[eventArgs.Arguments.NodeDescriptor] = EasyUADataChangeNotificationEventArgs.ToUAAttributeDataResult(eventArgs)
endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'
# Instantiate the client object.
client = EasyUAClient()
# Hook events.
client.DataChangeNotification += dataChangeNotification
print('Subscribing...')
client.SubscribeMultipleMonitoredItems([
EasyUAMonitoredItemArguments(
None,
endpointDescriptor,
UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
UAMonitoringParameters(1000)),
EasyUAMonitoredItemArguments(
None,
endpointDescriptor,
UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
UAMonitoringParameters(1000)),
EasyUAMonitoredItemArguments(
None,
endpointDescriptor,
UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
UAMonitoringParameters(1000)),
])
print('Processing data change events for 1 minute...')
endTime = time.time() + 60
while time.time() < endTime:
time.sleep(5)
#
# Each 5 seconds, display the current state of the monitored items we have subscribed to.
with lock:
print()
print('Current state of the monitored items:')
for nodeDescriptor, attributeDataResult in attributeDataResultDictionary.items():
print(nodeDescriptor, ': ', attributeDataResult, sep='')
#
# The code above shows how you can process the complete contents of the dictionary. In other
# scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
# by indexing the dictionary by the node descriptor of the monitored item you are interested in.
print()
print('Unsubscribing all monitored items...')
client.UnsubscribeAllMonitoredItems()
print('Waiting for 5 seconds...')
time.sleep(5)
print('Finished.')