To subscribe to complex data information, call one of the Subscribe methods on the EasyUAClient Class as usual. When complex data is returned by the client, a DataChangeNotification Event or EventNotification Event will be raised (or a corresponding callback will be made). The value in the event arguments will be of type UAGenericObject Class, and you will process its contents.
How precisely you process the received generic data depends on the application. In general, there can be two usage cases:
- Your application knows the type of the data to expect. In this case, you can hard-code this knowledge into the application. For example, if you know that the received data is a structure that has a field called "Temperature". You would type-cast the received data to StructuredData, and from the FieldData collection, you will get an element indexed by a string "Temperature". This can then be an instance of PrimitiveData Class, containing the temperature value in its Value Property. For more information, see Working with generic data.
- Your application does not know the type of the data to expect. This requires more coding, but is also perfectly doable. You will be accessing the generic data information similarly to the above case, but in a more generic way. The GenericData Class gives you a DataType Property, and the DataType object contained in this property gives you the metadata needed. For more information, see Working with data types.
The example below shows how to subscribe to OPC UA complex data and display the incoming values.
.NET
// Shows how to subscribe to complex data with OPC UA Complex Data plug-in.
using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples.ComplexData._EasyUAClient
{
class SubscribeDataChange
{
public static void Main1()
{
// Define which server and node we will work with.
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/"
UANodeDescriptor nodeDescriptor =
"nsu=http://test.org/UA/Data/ ;i=10867"; // [ObjectsFolder]/Data.Dynamic.Scalar.StructureValue
// Instantiate the client object and hook the event handler.
var client = new EasyUAClient();
client.DataChangeNotification += client_DataChangeNotification;
// Subscribe to a node which returns complex data. This is done in the same way as regular subscribes - just
// the data returned is different.
Console.WriteLine("Subscribing...");
client.SubscribeDataChange(endpointDescriptor, nodeDescriptor, samplingInterval:1000);
Console.WriteLine("Processing data change events for 20 seconds...");
System.Threading.Thread.Sleep(20 * 1000);
Console.WriteLine("Unsubscribing...");
client.UnsubscribeAllMonitoredItems();
Console.WriteLine("Waiting for 5 seconds...");
System.Threading.Thread.Sleep(5 * 1000);
// Unhook the event handler.
client.DataChangeNotification -= client_DataChangeNotification;
// Example output:
//
//Subscribing...
//Processing data change events for 20 seconds...
//(ScalarValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ScalarValueDataType) structured
//(ScalarValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ScalarValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ScalarValueDataType) structured
//(ScalarValueDataType) structured
//(ScalarValueDataType) structured
//Unsubscribing...
//Waiting for 5 seconds...
}
static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e)
{
// Display value
if (e.Succeeded)
Console.WriteLine("Value: {0}", e.AttributeData.Value);
else
Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief);
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
}
}
}
# Shows how to subscribe to complex data with OPC UA Complex Data plug-in.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time
# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *
def dataChangeNotification(sender, e):
# Display value.
if e.Succeeded:
print('Value: ', e.AttributeData.Value, sep='')
else:
print('*** Failure: ', e.ErrorMessageBrief, sep='')
#
# For processing the internals of the data, refer to examples for GenericData and DataType classes.
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/'
# [ObjectsFolder]/Data.Dynamic.Scalar.StructureValue
nodeDescriptor = UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10867')
# Instantiate the client object and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification
# Subscribe to a node which returns complex data. This is done in the same way as regular subscribes - just
# the data returned is different.
print('Subscribing...')
IEasyUAClientExtension.SubscribeDataChange(client,
endpointDescriptor,
nodeDescriptor,
1000) # samplingInterval
print('Processing data change events for 30 seconds...')
time.sleep(30)
print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()
print('Waiting for 5 seconds...')
time.sleep(5)
# Unhook the event handler.
client.DataChangeNotification -= dataChangeNotification
print('Finished.')
' Shows how to subscribe to complex data with OPC UA Complex Data plug-in.
Imports System
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace ComplexData._EasyUAClient
Friend Class SubscribeDataChange
Public Shared Sub Main1()
' 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/"
' Define which node we will work with.
Dim nodeDescriptor As UANodeDescriptor = _
"nsu=http://test.org/UA/Data/ ;i=10867" ' [ObjectsFolder]/Data.Dynamic.Scalar.StructureValue
' Instantiate the client object and hook the event handler.
Dim client = New EasyUAClient
AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification
' Subscribe to a node which returns complex data. This is done in the same way as regular subscribes - just
' the data returned is different.
Console.WriteLine("Subscribing...")
client.SubscribeDataChange(endpointDescriptor, nodeDescriptor, samplingInterval:=1000)
Console.WriteLine("Processing data change events for 20 seconds...")
Threading.Thread.Sleep((20 * 1000))
Console.WriteLine("Unsubscribing...")
client.UnsubscribeAllMonitoredItems()
Console.WriteLine("Waiting for 5 seconds...")
Threading.Thread.Sleep((5 * 1000))
' Unhook the event handler.
RemoveHandler client.DataChangeNotification, AddressOf client_DataChangeNotification
' Example output:
'
'Subscribing...
'Processing data change events for 20 seconds...
'(ScalarValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ScalarValueDataType) structured
'(ScalarValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ScalarValueDataType) structured
'(ArrayValueDataType) structured
'(ArrayValueDataType) structured
'(ScalarValueDataType) structured
'(ScalarValueDataType) structured
'(ScalarValueDataType) structured
'Unsubscribing...
'Waiting for 5 seconds...
End Sub
Private Shared Sub client_DataChangeNotification(sender As Object, e As EasyUADataChangeNotificationEventArgs)
' Display value
If e.Succeeded Then
Console.WriteLine("Value: {0}", e.AttributeData.Value)
Else
Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief)
End If
' For processing the internals of the data, refer to examples for GenericData and DataType classes.
End Sub
End Class
End Namespace
COM
// Shows how to subscribe to complex data with OPC UA Complex Data plug-in.
type
TClientEventHandlers33 = class
procedure OnDataChangeNotification(
ASender: TObject;
sender: OleVariant;
const eventArgs: _EasyUADataChangeNotificationEventArgs);
end;
procedure TClientEventHandlers33.OnDataChangeNotification(
ASender: TObject;
sender: OleVariant;
const eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
// Display value
if eventArgs.Succeeded then
WriteLn('Value: ', eventArgs.AttributeData.Value.ToString)
else
WriteLn('*** Failure: ', eventArgs.ErrorMessageBrief);
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
end;
class procedure SubscribeDataChange.Main;
var
Client: TEasyUAClient;
ClientEventHandlers: TClientEventHandlers33;
EndpointDescriptor: string;
NodeDescriptor: string;
begin
// Define which server and node we will work with.
EndpointDescriptor :=
//'http://opcua.demo-this.com:51211/UA/SampleServer';
//'https://opcua.demo-this.com:51212/UA/SampleServer/';
'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
NodeDescriptor := 'nsu=http://test.org/UA/Data/ ;i=10867'; // [ObjectsFolder]/Data.Dynamic.Scalar.StructureValue
// Instantiate the client object and hook events
Client := TEasyUAClient.Create(nil);
ClientEventHandlers := TClientEventHandlers33.Create;
Client.OnDataChangeNotification := ClientEventHandlers.OnDataChangeNotification;
// Subscribe to a node which returns complex data. This is done in the same way as regular subscribes - just
// the data returned is different.
WriteLn('Subscribing...');
Client.SubscribeDataChange(EndpointDescriptor, NodeDescriptor, 1000);
WriteLn('Processing data change events for 20 seconds...');
PumpSleep(20*1000);
WriteLn('Unsubscribing...');
Client.UnsubscribeAllMonitoredItems;
WriteLn('Waiting for 5 seconds...');
PumpSleep(5*1000);
WriteLn('Finished.');
FreeAndNil(Client);
FreeAndNil(ClientEventHandlers);
// Example output:
//
//Subscribing...
//Processing data change events for 20 seconds...
//(ScalarValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ScalarValueDataType) structured
//(ScalarValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ScalarValueDataType) structured
//(ArrayValueDataType) structured
//(ArrayValueDataType) structured
//(ScalarValueDataType) structured
//(ScalarValueDataType) structured
//(ScalarValueDataType) structured
//Unsubscribing...
//Waiting for 5 seconds...
end;
// Shows how to subscribe to complex data with OPC UA Complex Data plug-in.
class ClientEvents {
function DataChangeNotification($Sender, $E)
{
// Display value
if ($E->Succeeded)
printf("Value: %s\n", $E->AttributeData->Value);
else
printf("*** Failure : %s\n", $E->ErrorMessageBrief);
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
}
}
// Define which server and node we will work with.
$EndpointDescriptor =
//"http://opcua.demo-this.com:51211/UA/SampleServer";
//"https://opcua.demo-this.com:51212/UA/SampleServer/";
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
$NodeDescriptor = "nsu=http://test.org/UA/Data/ ;i=10867"; // [ObjectsFolder]/Data.Dynamic.Scalar.StructureValue
// Instantiate the client object and hook events
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
$ClientEvents = new ClientEvents();
com_event_sink($Client, $ClientEvents, "DEasyUAClientEvents");
// Subscribe to a node which returns complex data. This is done in the same way as regular subscribes - just
// the data returned is different.
printf("Subscribing...\n");
$Client->SubscribeDataChange($EndpointDescriptor, $NodeDescriptor, 1000);
printf("Processing data change events for 20 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 20);
printf("Unsubscribing...\n");
$Client->UnsubscribeAllMonitoredItems;
printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);
Complex data is also supported and can also be returned in notifications for OPC UA Alarms&Conditions, i.e. in event arguments of type EasyUAEventNotificationEventArgs, used in the EventNotification Event .
See Also