// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// 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 OpcLabs.BaseLib.DataTypeModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.ComplexData;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples.ComplexData._EasyUAClient
{
class WriteValue
{
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=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object.
var client = new EasyUAClient();
// Read a node which returns complex data.
// We know that this node returns complex data, so we can type cast to UAGenericObject.
Console.WriteLine("Reading...");
UAGenericObject genericObject;
try
{
genericObject = (UAGenericObject)client.ReadValue(endpointDescriptor, nodeDescriptor);
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
return;
}
// Modify the data read.
// This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
// data types are sub-types of one common type which the data type of the node. We therefore use the data type
// ID in the returned UAGenericObject to detect which data type has been returned.
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
// We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
// also possible to discover the structure of the data type in the program, and write generic clients that can
// cope with any kind of complex data.
//
// Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
Console.WriteLine("Modifying...");
Console.WriteLine(genericObject.DataTypeId);
if (genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9440")) // ScalarValueDataType
{
// Negate the byte in the "ByteValue" field.
var structuredData = (StructuredData)genericObject.GenericData;
var byteValue = (PrimitiveData)structuredData.FieldData["ByteValue"];
byteValue.Value = (Byte)~((Byte)byteValue.Value);
Console.WriteLine(byteValue.Value);
}
else if (genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9669")) // ArrayValueDataType
{
// Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
var structuredData = (StructuredData)genericObject.GenericData;
var byteValue = (SequenceData)structuredData.FieldData["ByteValue"];
var element0 = (PrimitiveData)byteValue.Elements[0];
var element1 = (PrimitiveData)byteValue.Elements[1];
element0.Value = (Byte)~((Byte)element0.Value);
element1.Value = (Byte)~((Byte)element1.Value);
Console.WriteLine(element0.Value);
Console.WriteLine(element1.Value);
}
// Write the modified complex data back to the node.
// The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
// knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
// as the node has (not a subtype).
Console.WriteLine("Writing...");
try
{
client.WriteValue(endpointDescriptor, nodeDescriptor, genericObject);
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
}
}
}
}
' Shows how to write complex data with OPC UA Complex Data plug-in.
'
' 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
Imports OpcLabs.BaseLib.DataTypeModel
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.ComplexData
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace ComplexData._EasyUAClient
Friend Class WriteValue
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=10239" ' [ObjectsFolder]/Data.Static.Scalar.StructureValue
' Instantiate the client object.
Dim client = New EasyUAClient
' Read a node which returns complex data.
' We know that this node returns complex data, so we can type cast to UAGenericObject.
Console.WriteLine("Reading...")
Dim genericObject As UAGenericObject
Try
genericObject = CType(client.ReadValue(endpointDescriptor, nodeDescriptor), UAGenericObject)
Catch uaException As UAException
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
Exit Sub
End Try
' Modify the data read.
' This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
' data types are sub-types of one common type which the data type of the node. We therefore use the data type
' ID in the returned UAGenericObject to detect which data type has been returned.
' For processing the internals of the data, refer to examples for GenericData and DataType classes.
' We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
' also possible to discover the structure of the data type in the program, and write generic clients that can
' cope with any kind of complex data.
'
' Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
Console.WriteLine("Modifying...")
Console.WriteLine(genericObject.DataTypeId)
If genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9440") Then ' ScalarValueDataType
' Negate the byte in the "ByteValue" field.
Dim structuredData = CType(genericObject.GenericData, StructuredData)
Dim byteValue = CType(structuredData.FieldData("ByteValue"), PrimitiveData)
byteValue.Value = CType(Not CType(byteValue.Value, Byte), Byte)
Console.WriteLine(byteValue.Value)
ElseIf genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9669") Then ' ArrayValueDataType
' Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
Dim structuredData = CType(genericObject.GenericData, StructuredData)
Dim byteValue = CType(structuredData.FieldData("ByteValue"), SequenceData)
Dim element0 = CType(byteValue.Elements(0), PrimitiveData)
Dim element1 = CType(byteValue.Elements(1), PrimitiveData)
element0.Value = CType(Not CType(element0.Value, Byte), Byte)
element1.Value = CType(Not CType(element1.Value, Byte), Byte)
Console.WriteLine(element0.Value)
Console.WriteLine(element1.Value)
End If
' Write the modified complex data back to the node.
' The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
' knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
' as the node has (not a subtype).
Console.WriteLine("Writing...")
Try
client.WriteValue(endpointDescriptor, nodeDescriptor, genericObject)
Catch uaException As UAException
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
Exit Sub
End Try
End Sub
End Class
End Namespace
// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// 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.
class procedure WriteValue.Main;
var
ArrayValueDataType: _UANodeDescriptor;
ByteValue: _PrimitiveData;
ByteValue2: _SequenceData;
Client: _EasyUAClient;
Element0, Element1: _PrimitiveData;
EndpointDescriptor: string;
GenericObject: _UAGenericObject;
NodeDescriptor: string;
ScalarValueDataType: _UANodeDescriptor;
StructuredData: _StructuredData;
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=10239'; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object
Client := CoEasyUAClient.Create;
// Read a node which returns complex data.
// We know that this node returns complex data, so we can type cast to UAGenericObject.
WriteLn('Reading...');
try
GenericObject := _UAGenericObject(IUnknown(Client.ReadValue(EndpointDescriptor, NodeDescriptor)));
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
Exit;
end;
end;
// Modify the data read.
// This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
// data types are sub-types of one common type which the data type of the node. We therefore use the data type
// ID in the returned UAGenericObject to detect which data type has been returned.
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
// We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
// also possible to discover the structure of the data type in the program, and write generic clients that can
// cope with any kind of complex data.
//
// Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
WriteLn('Modifying...');
WriteLn(GenericObject.DataTypeId.ToString);
ScalarValueDataType := CoUANodeDescriptor.Create;
ScalarValueDataType.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=9440'; // ScalarValueDataType
if GenericObject.DataTypeId.NodeDescriptor.Match(ScalarValueDataType) then
begin
// Negate the byte in the "ByteValue" field.
StructuredData := IUnknown(GenericObject.GenericData) as _StructuredData;
ByteValue := IUnknown(StructuredData.FieldData['ByteValue']) as _PrimitiveData;
ByteValue.Value := Byte(not (Byte(byteValue.Value)));
WriteLn(ByteValue.Value);
end
else
begin
ArrayValueDataType := CoUANodeDescriptor.Create;
ArrayValueDataType.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=9669'; // ArrayValueDataType
if GenericObject.DataTypeId.Nodedescriptor.Match(ArrayValueDataType) then
begin
// Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
StructuredData := IUnknown(GenericObject.GenericData) as _StructuredData;
ByteValue2 := IUnknown(StructuredData.FieldData['ByteValue']) as _SequenceData;
Element0 := IUnknown(ByteValue2.Elements[0]) as _PrimitiveData;
Element1 := IUnknown(ByteValue2.Elements[1]) as _PrimitiveData;
Element0.Value := Byte(not (Byte(element0.Value)));
Element1.Value := Byte(not (Byte(element1.Value)));
WriteLn(Element0.Value);
WriteLn(Element1.Value);
end;
end;
// Write the modified complex data back to the node.
// The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
// knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
// as the node has (not a subtype).
WriteLn('Writing...');
try
Client.WriteValue(EndpointDescriptor, NodeDescriptor, GenericObject);
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
Exit;
end;
end;
end;
// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// 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.
// 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=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
// Read a node which returns complex data.
// We know that this node returns complex data, so we can type cast to UAGenericObject.
printf("Reading...\n");
try
{
$GenericObject = $Client->ReadValue($EndpointDescriptor, $NodeDescriptor);
}
catch (com_exception $e)
{
printf("*** Failure: %s\n", $e->getMessage());
Exit();
}
// Modify the data read.
// This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
// data types are sub-types of one common type which the data type of the node. We therefore use the data type
// ID in the returned UAGenericObject to detect which data type has been returned.
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
// We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
// also possible to discover the structure of the data type in the program, and write generic clients that can
// cope with any kind of complex data.
//
// Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
printf("Modifying...\n");
printf("%s\n", $GenericObject->DataTypeId);
$ScalarValueDataType = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
$ScalarValueDataType->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=9440"; // ScalarValueDataType
if ($GenericObject->DataTypeId->NodeDescriptor->Match($ScalarValueDataType)) {
// Negate the byte in the "ByteValue" field.
$StructuredData = $GenericObject->GenericData->AsStructuredData();
$ByteValue = $StructuredData->FieldData["ByteValue"]->AsPrimitiveData();
$ByteValue->Value = ~($ByteValue->Value) & 255;
printf("%s\n", $ByteValue->Value);
}
else {
$ArrayValueDataType = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
$ArrayValueDataType->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=9669"; // ArrayValueDataType
if ($GenericObject->DataTypeId->Nodedescriptor->Match($ArrayValueDataType)) {
// Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
$StructuredData = $GenericObject->GenericData->AsStructuredData();
$ByteValue2 = $StructuredData->FieldData["ByteValue"]->AsSequenceData();
$Element0 = $ByteValue2->Elements[0]->AsPrimitiveData();
$Element1 = $ByteValue2->Elements[1]->AsPrimitiveData();
$Element0->Value = ~($Element0->Value) & 255;
$Element1->Value = ~($Element1->Value) & 255;
printf("%s\n", $Element0->Value);
printf("%s\n", $Element1->Value);
}
}
// Write the modified complex data back to the node.
// The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
// knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
// as the node has (not a subtype).
printf("Writing...\n");
try
{
$Client->WriteValue($EndpointDescriptor, $NodeDescriptor, $GenericObject);
}
catch (com_exception $e)
{
printf("Failure: %s\n", $e->getMessage());
Exit();
}
# Shows how to write complex data with OPC UA Complex Data plug-in.
#
# 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 .NET namespaces.
from System import *
from OpcLabs.BaseLib.DataTypeModel import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *
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.Static.Scalar.StructureValue
nodeDescriptor = UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10239')
# Instantiate the client object.
client = EasyUAClient()
# Read a node which returns complex data.
# We know that this node returns complex data, so we can type cast to UAGenericObject.
try:
print('Reading...')
genericObject = IEasyUAClientExtension.ReadValue(client, endpointDescriptor, nodeDescriptor)
except UAException as uaException:
print('*** Failure: ' + uaException.GetBaseException().Message)
exit()
# Modify the data read.
# This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
# data types are sub-types of one common type which the data type of the node. We therefore use the data type
# ID in the returned UAGenericObject to detect which data type has been returned.
#
# For processing the internals of the data, refer to examples for GenericData and DataType classes.
# We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
# also possible to discover the structure of the data type in the program, and write generic clients that can
# cope with any kind of complex data.
#
# Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
print ('Modifying...')
print(genericObject.DataTypeId)
if genericObject.DataTypeId.NodeDescriptor.Match(UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=9440')): # ScalarValueDataType
# Negate the byte in the "ByteValue" field.
structuredData = genericObject.GenericData
byteValue = structuredData.FieldData.get_Item('ByteValue') # PrimitiveData
byteValue.Value = (~byteValue.Value) & 0xFF
print(byteValue.Value)
elif genericObject.DataTypeId.NodeDescriptor.Match(UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=9669')): # ArrayValueDataType
# Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
structuredData = genericObject.GenericData
byteValue = structuredData.FieldData.get_Item('ByteValue') # SequenceData
element0 = byteValue.Elements.get_Item(0) # PrimitiveData
element1 = byteValue.Elements.get_Item(1) # PrimitiveData
element0.Value = (~element0.Value) & 0xFF
element1.Value = (~element1.Value) & 0xFF
print(element0.Value)
print(element1.Value)
# Write the modified complex data back to the node.
# The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
# knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
# as the node has (not a subtype).
try:
print('Writing...')
IEasyUAClientExtension.WriteValue(client, endpointDescriptor, nodeDescriptor, genericObject)
except UAException as uaException:
print('*** Failure: ' + uaException.GetBaseException().Message)
print()
print('Finished.')
// This example shows different ways of constructing generic data.
//
// 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;
using OpcLabs.BaseLib.DataTypeModel;
namespace UADocExamples.ComplexData._GenericData
{
class _Construction
{
public static void Main1()
{
// Create enumeration data with value of 1.
var enumerationData = new EnumerationData(1);
Console.WriteLine(enumerationData);
// Create opaque data from an array of 2 bytes, specifying its size as 15 bits.
var opaqueData1 = new OpaqueData(new byte[] {0xAA, 0x55}, sizeInBits:15);
Console.WriteLine(opaqueData1);
// Create opaque data from a bit array.
var opaqueData2 = new OpaqueData(new BitArray(new[] { false, true, false, true, false }));
Console.WriteLine(opaqueData2);
// Create primitive data with System.Double value of 180.0.
var primitiveData1 = new PrimitiveData(180.0d);
Console.WriteLine(primitiveData1);
// Create primitive data with System.String value.
var primitiveData2 = new PrimitiveData("Temperature is too high!");
Console.WriteLine(primitiveData2);
// Create sequence data with two elements, using collection initializer syntax.
var sequenceData1 = new SequenceData
{
opaqueData1,
opaqueData2
};
Console.WriteLine(sequenceData1);
// Create the same sequence data, using the Add method.
var sequenceData2 = new SequenceData();
sequenceData2.Elements.Add(opaqueData1);
sequenceData2.Elements.Add(opaqueData2);
Console.WriteLine(sequenceData2);
// Create the same sequence data, using an array (an enumerable) of its elements.
var sequenceData3 = new SequenceData(
new GenericDataCollection(new[] {opaqueData1, opaqueData2}));
Console.WriteLine(sequenceData3);
// Create structured data with two members, using collection initializer syntax.
var structuredData1 = new StructuredData
{
{"Message", primitiveData2},
{"Status", enumerationData}
};
Console.WriteLine(structuredData1);
// Create the same structured data using the Add method.
var structuredData2 = new StructuredData();
structuredData2.Add("Message", primitiveData2);
structuredData2.Add("Status", enumerationData);
Console.WriteLine(structuredData2);
// Create union data.
var unionData1 = new UnionData("DoubleField", primitiveData1);
Console.WriteLine(unionData1);
}
}
}
' This example shows different ways of constructing generic data.
'
' 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
Imports System.Collections
Imports OpcLabs.BaseLib.DataTypeModel
Namespace ComplexData._GenericData
Friend Class _Construction
Public Shared Sub Main1()
' Create enumeration data with value of 1.
Dim enumerationData = New EnumerationData(1)
Console.WriteLine(enumerationData)
' Create opaque data from an array of 2 bytes, specifying its size as 15 bits.
Dim opaqueData1 = New OpaqueData(New Byte() {170, 85}, sizeInBits:=15)
Console.WriteLine(opaqueData1)
' Create opaque data from a bit array.
Dim opaqueData2 = New OpaqueData(New BitArray(New Boolean() {False, True, False, True, False}))
Console.WriteLine(opaqueData2)
' Create primitive data with System.Double value of 180.0.
Dim primitiveData1 = New PrimitiveData(180)
Console.WriteLine(primitiveData1)
' Create primitive data with System.String value.
Dim primitiveData2 = New PrimitiveData("Temperature is too high!")
Console.WriteLine(primitiveData2)
' Create sequence data with two elements, using collection initializer syntax.
Dim sequenceData1 = New SequenceData() From {opaqueData1, opaqueData2}
Console.WriteLine(sequenceData1)
' Create the same sequence data, using the Add method.
Dim sequenceData2 = New SequenceData
sequenceData2.Elements.Add(opaqueData1)
sequenceData2.Elements.Add(opaqueData2)
Console.WriteLine(sequenceData2)
' Create the same sequence data, using an array (an enumerable) of its elements.
Dim sequenceData3 = New SequenceData(New GenericDataCollection(New OpaqueData() {opaqueData1, opaqueData2}))
Console.WriteLine(sequenceData3)
' Create structured data with two members, using collection initializer syntax.
Dim structuredData1 = New StructuredData() From { _
{"Message", primitiveData2}, _
{"Status", enumerationData}}
Console.WriteLine(structuredData1)
' Create the same structured data using the Add method.
Dim structuredData2 = New StructuredData()
structuredData2.Add("Message", primitiveData2)
structuredData2.Add("Status", enumerationData)
Console.WriteLine(structuredData2)
End Sub
End Class
End Namespace
// This example shows different ways of constructing generic data.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// 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.
class procedure _Construction.Main;
var
ByteArray1, ByteArray2: OleVariant;
EnumerationData: _EnumerationData;
OpaqueData1, OpaqueData2: _OpaqueData;
PrimitiveData1, PrimitiveData2: _PrimitiveData;
SequenceData1: _SequenceData;
StructuredData1: _StructuredData;
begin
// Create enumeration data with value of 1.
EnumerationData := CoEnumerationData.Create;
EnumerationData.Value := 1;
WriteLn(EnumerationData.ToString);
// Create opaque data from an array of 2 bytes, specifying its size as 15 bits.
OpaqueData1 := CoOpaqueData.Create;
ByteArray1 := VarArrayCreate([0, 1], varVariant);
ByteArray1[0] := $AA;
ByteArray1[1] := $55;
OpaqueData1.SetByteArrayValue(ByteArray1, 15);
WriteLn(OpaqueData1.ToString);
// Create opaque data from an array of 1 bytes, specifying its size as 5 bits.
OpaqueData2 := CoOpaqueData.Create;
ByteArray2 := VarArrayCreate([0, 0], varVariant);
ByteArray2[0] := $A;
OpaqueData2.SetByteArrayValue(ByteArray2, 5);
WriteLn(OpaqueData2.ToString);
// Create primitive data with System.Double value of 180.0.
PrimitiveData1 := CoPrimitiveData.Create;
PrimitiveData1.Value := 180.0;
WriteLn(PrimitiveData1.ToString);
// Create primitive data with System.String value.
PrimitiveData2 := CoPrimitiveData.Create;
PrimitiveData2.Value := 'Temperature is too high!';
WriteLn(PrimitiveData2.ToString);
// Create sequence data with two elements, using the Add method.
SequenceData1 := CoSequenceData.Create;
SequenceData1.Elements.Add(OpaqueData1);
SequenceData1.Elements.Add(OpaqueData2);
WriteLn(SequenceData1.ToString);
// Create structured data with two members, using the Add method.
StructuredData1 := CoStructuredData.Create;
StructuredData1.Add('Message', PrimitiveData2);
StructuredData1.Add('Status', EnumerationData);
WriteLn(StructuredData1.ToString);
VarClear(ByteArray2);
VarClear(ByteArray1);
end;
// This example shows different ways of constructing generic data.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// 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.
// Create enumeration data with value of 1.
$EnumerationData = new COM("OpcLabs.BaseLib.DataTypeModel.EnumerationData");
$EnumerationData->Value = 1;
printf("%s\n", $EnumerationData);
// Create opaque data from an array of 2 bytes, specifying its size as 15 bits.
$OpaqueData1 = new COM("OpcLabs.BaseLib.DataTypeModel.OpaqueData");
$ByteArray1[0] = 0xAA;
$ByteArray1[1] = 0x55;
$OpaqueData1->SetByteArrayValue($ByteArray1, 15);
printf("%s\n", $OpaqueData1);
// Create opaque data from a bit array.
$OpaqueData2 = new COM("OpcLabs.BaseLib.DataTypeModel.OpaqueData");
$BitArray = $OpaqueData2->Value;
$BitArray->Length = 5;
$BitArray->Set(0, false);
$BitArray->Set(1, true);
$BitArray->Set(2, false);
$BitArray->Set(3, true);
$BitArray->Set(4, false);
printf("%s\n", $OpaqueData2);
// Create primitive data with System.Double value of 180.0.
$PrimitiveData1 = new COM("OpcLabs.BaseLib.DataTypeModel.PrimitiveData");
$PrimitiveData1->Value = 180.0;
printf("%s\n", $PrimitiveData1);
// Create primitive data with System.String value.
$PrimitiveData2 = new COM("OpcLabs.BaseLib.DataTypeModel.PrimitiveData");
$PrimitiveData2->Value = "Temperature is too high!";
printf("%s\n", $PrimitiveData2);
// Create sequence data with two elements, using the Add method.
$SequenceData1 = new COM("OpcLabs.BaseLib.DataTypeModel.SequenceData");
$SequenceData1->Elements->Add($OpaqueData1);
$SequenceData1->Elements->Add($OpaqueData2);
printf("%s\n", $SequenceData1);
// Create structured data with two members, using the Add method.
$StructuredData1 = new COM("OpcLabs.BaseLib.DataTypeModel.StructuredData");
$StructuredData1->Add("Message", $PrimitiveData2);
$StructuredData1->Add("Status", $EnumerationData);
printf("%s\n", $StructuredData1);
Rem This example shows different ways of constructing generic data.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.
Option Explicit
' Create enumeration data with value of 1.
Dim EnumerationData: Set EnumerationData = CreateObject("OpcLabs.BaseLib.DataTypeModel.EnumerationData")
EnumerationData.Value = 1
WScript.Echo EnumerationData
' Create opaque data from an array of 2 bytes, specifying its size as 15 bits.
Dim OpaqueData1: Set OpaqueData1 = CreateObject("OpcLabs.BaseLib.DataTypeModel.OpaqueData")
OpaqueData1.SetByteArrayValue Array(&HAA, &H55), 15
WScript.Echo OpaqueData1
' Create opaque data from a bit array.
Dim OpaqueData2: Set OpaqueData2 = CreateObject("OpcLabs.BaseLib.DataTypeModel.OpaqueData")
Dim BitArray: Set BitArray = OpaqueData2.Value
BitArray.Length = 5
BitArray(0) = False
BitArray(1) = True
BitArray(2) = False
BitArray(3) = True
BitArray(4) = False
WScript.Echo OpaqueData2
' Create primitive data with System.Double value of 180.0.
Dim PrimitiveData1: Set PrimitiveData1 = CreateObject("OpcLabs.BaseLib.DataTypeModel.PrimitiveData")
PrimitiveData1.Value = 180.0
WScript.Echo PrimitiveData1
' Create primitive data with System.String value.
Dim PrimitiveData2: Set PrimitiveData2 = CreateObject("OpcLabs.BaseLib.DataTypeModel.PrimitiveData")
PrimitiveData2.Value = "Temperature is too high!"
WScript.Echo PrimitiveData2
' Create sequence data with two elements, using the Add method.
Dim SequenceData1: Set SequenceData1 = CreateObject("OpcLabs.BaseLib.DataTypeModel.SequenceData")
SequenceData1.Elements.Add OpaqueData1
SequenceData1.Elements.Add OpaqueData2
WScript.Echo SequenceData1
' Create structured data with two members, using the Add method.
Dim StructuredData1: Set StructuredData1 = CreateObject("OpcLabs.BaseLib.DataTypeModel.StructuredData")
StructuredData1.Add "Message", PrimitiveData2
StructuredData1.Add "Status", EnumerationData
WScript.Echo StructuredData1
# This example shows different ways of constructing generic data.
#
# 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 .NET namespaces.
from System import *
from System.Collections import *
from OpcLabs.BaseLib.DataTypeModel import *
# Create enumeration data with value of 1.
enumerationData = EnumerationData(1)
print(enumerationData)
# Create opaque data from an array of 2 bytes, specifying its size as 15 bits.
opaqueData1 = OpaqueData(
[0xAA, 0x55],
15) # sizeInBits
print(opaqueData1)
# Create opaque data from a bit array.
bitArray = BitArray(5)
bitArray[0] = False
bitArray[1] = True
bitArray[2] = False
bitArray[3] = True
bitArray[4] = False
opaqueData2 = OpaqueData(bitArray)
print(opaqueData2)
# Create primitive data with System.Double value of 180.0.
primitiveData1 = PrimitiveData(180.0)
print(primitiveData1)
# Create primitive data with System.String value.
primitiveData2 = PrimitiveData('Temperature is too high!')
print(primitiveData2)
# Create sequence data with two elements, using the Add method.
sequenceData2 = SequenceData()
sequenceData2.Elements.Add(opaqueData1)
sequenceData2.Elements.Add(opaqueData2)
print(sequenceData2)
# Create structured data with two members, using the Add method.
structuredData2 = StructuredData()
structuredData2.Add('Message', primitiveData2)
structuredData2.Add('Status', enumerationData)
print(structuredData2)
# Create union data.
unionData1 = UnionData('DoubleField', primitiveData1)
print(unionData1)
print()
print('Finished.')
// Shows how to process generic data type, displaying some of its properties, recursively.
//
// 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 OpcLabs.BaseLib.DataTypeModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.ComplexData;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples.ComplexData._GenericData
{
class DataTypeKind1
{
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=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object.
var client = new EasyUAClient();
// Read a node. We know that this node returns complex data, so we can type cast to UAGenericObject.
UAGenericObject genericObject;
try
{
genericObject = (UAGenericObject)client.ReadValue(endpointDescriptor, nodeDescriptor);
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
return;
}
// Process the generic data type. We will inspect some of its properties, and dump them.
ProcessGenericData(genericObject.GenericData, maximumDepth: 3);
}
// Process the generic data type. Its structure can sometimes be quite deep, therefore we are limiting the depth
// of the recursion using maximumDepth.
public static void ProcessGenericData(GenericData genericData, int maximumDepth)
{
if (maximumDepth == 0)
return;
Console.WriteLine();
Console.WriteLine("genericData.DataType: {0}", genericData.DataType);
switch (genericData.DataTypeKind)
{
case DataTypeKind.Enumeration:
Console.WriteLine("The generic data is an enumeration.");
var enumerationData = (EnumerationData) genericData;
Console.WriteLine("Its value is {0}.", enumerationData.Value);
// There is also a ValueName that you can inspect (if known).
break;
case DataTypeKind.Opaque:
Console.WriteLine("The generic data is opaque.");
var opaqueData = (OpaqueData) genericData;
Console.WriteLine("Its size is {0} bits.", opaqueData.SizeInBits);
Console.WriteLine("The data bytes are {0}.", BitConverter.ToString(opaqueData.ByteArray));
// Use the Value property (a BitArray) if you need to access the value bit by bit.
break;
case DataTypeKind.Primitive:
Console.WriteLine("The generic data is primitive.");
var primitiveData = (PrimitiveData) genericData;
Console.WriteLine("Its value is \"{0}\".", primitiveData.Value);
break;
case DataTypeKind.Sequence:
Console.WriteLine("The generic data is a sequence.");
var sequenceData = (SequenceData) genericData;
Console.WriteLine("It has {0} elements.", sequenceData.Elements.Count);
Console.WriteLine("A dump of the elements follows.");
foreach (GenericData element in sequenceData.Elements)
ProcessGenericData(element, maximumDepth - 1);
break;
case DataTypeKind.Structured:
Console.WriteLine("The generic data is structured.");
var structuredData = (StructuredData) genericData;
Console.WriteLine("It has {0} field data members.", structuredData.FieldData.Count);
Console.WriteLine("The names of the fields are: {0}.",
String.Join(", ", structuredData.FieldData.Keys));
Console.WriteLine("A dump of each of the fields follows.");
foreach (KeyValuePair<string, GenericData> pair in structuredData.FieldData)
{
Console.WriteLine();
Console.WriteLine("Field name: {0}", pair.Key);
ProcessGenericData(pair.Value, maximumDepth - 1);
}
break;
case DataTypeKind.Union:
Console.WriteLine("The generic data is a union.");
var unionData = (UnionData)genericData;
Console.WriteLine("The name of current field is: {0}", unionData.FieldName);
Console.WriteLine("Current field value is: {0}", unionData.FieldValue);
break;
}
}
}
}
' Shows how to process generic data type, displaying some of its properties, recursively.
'
' 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 OpcLabs.BaseLib.DataTypeModel
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.ComplexData
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace ComplexData._GenericData
Friend Class DataTypeKind1
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=10239" ' [ObjectsFolder]/Data.Static.Scalar.StructureValue
' Instantiate the client object.
Dim client = New EasyUAClient
' Read a node. We know that this node returns complex data, so we can type cast to UAGenericObject.
Dim genericObject As UAGenericObject
Try
genericObject = CType(client.ReadValue(endpointDescriptor, nodeDescriptor), UAGenericObject)
Catch uaException As UAException
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
Exit Sub
End Try
' Process the generic data type. We will inspect some of its properties, and dump them.
ProcessGenericData(genericObject.GenericData, maximumDepth:=2)
End Sub
' Process the generic data type. Its structure can sometimes be quite deep, therefore we are limiting the depth
' of the recursion using maximumDepth.
Public Shared Sub ProcessGenericData(ByVal genericData As GenericData, ByVal maximumDepth As Integer)
If (maximumDepth = 0) Then
Return
End If
Console.WriteLine()
Console.WriteLine("genericData.DataType: {0}", genericData.DataType)
Select Case (genericData.DataTypeKind)
Case DataTypeKind.Enumeration
Console.WriteLine("The generic data is an enumeration.")
Dim enumerationData = CType(genericData, EnumerationData)
Console.WriteLine("Its value is {0}.", enumerationData.Value)
' There is also a ValueName that you can inspect (if known).
Case DataTypeKind.Opaque
Console.WriteLine("The generic data is opaque.")
Dim opaqueData = CType(genericData, OpaqueData)
Console.WriteLine("Its size is {0} bits.", opaqueData.SizeInBits)
Console.WriteLine("The data bytes are {0}.", BitConverter.ToString(opaqueData.ByteArray))
' Use the Value property (a BitArray) if you need to access the value bit by bit.
Case DataTypeKind.Primitive
Console.WriteLine("The generic data is primitive.")
Dim primitiveData = CType(genericData, PrimitiveData)
Console.WriteLine("Its value is ""{0}"".", primitiveData.Value)
Case DataTypeKind.Sequence
Console.WriteLine("The generic data is a sequence.")
Dim sequenceData = CType(genericData, SequenceData)
Console.WriteLine("It has {0} elements.", sequenceData.Elements.Count)
Console.WriteLine("A dump of the elements follows.")
For Each element As GenericData In sequenceData.Elements
ProcessGenericData(element, (maximumDepth - 1))
Next
Case DataTypeKind.Structured
Console.WriteLine("The generic data is structured.")
Dim structuredData = CType(genericData, StructuredData)
Console.WriteLine("It has {0} field data members.", structuredData.FieldData.Count)
Console.WriteLine("The names of the fields are: {0}.", String.Join(", ", structuredData.FieldData.Keys))
Console.WriteLine("A dump of each of the fields follows.")
For Each pair As KeyValuePair(Of String, GenericData) In structuredData.FieldData
Console.WriteLine()
Console.WriteLine("Field name: {0}", pair.Key)
ProcessGenericData(pair.Value, (maximumDepth - 1))
Next
Case DataTypeKind.Union
Console.WriteLine("The generic data is union.")
Dim unionData = CType(genericData, UnionData)
Console.WriteLine("The name of current field is: {0}", unionData.FieldName)
Console.WriteLine("Current field value is: {0}", unionData.FieldValue)
End Select
End Sub
End Class
End Namespace
// Shows how to process generic data type, displaying some of its properties, recursively
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// 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.
class procedure DataTypeKind1.Main;
var
Client: _EasyUAClient;
EndpointDescriptor: string;
GenericObject: _UAGenericObject;
NodeDescriptor: string;
begin
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=10239'; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object
Client := CoEasyUAClient.Create;
// Read a node. We know that this node returns complex data, so we can type cast to UAGenericObject.
try
GenericObject := _UAGenericObject(IUnknown(Client.ReadValue(EndpointDescriptor, NodeDescriptor)));
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
Exit;
end;
end;
// Process the generic data type. We will inspect some of its properties, and dump them.
ProcessGenericData(GenericObject.GenericData, 2);
end;
Function VariantToBytes(Const Value: OleVariant): TBytes;
Var
Size: Integer;
pData: Pointer;
Begin
Size := Succ(VarArrayHighBound(Value, 1) - VarArrayLowBound(Value, 1));
SetLength(Result, Size);
pData := VarArrayLock(Value);
Try
Move(pData^, Pointer(Result)^, Size);
Finally
VarArrayUnlock(Value);
End;
End;
class procedure DatatypeKind1.ProcessGenericData(GenericData: OpcLabs_BaseLib_TLB._GenericData; MaximumDepth: Cardinal);
var
ByteArray: OleVariant;
Count: Cardinal;
Element: OleVariant;
ElementEnumerator: IEnumVARIANT;
EnumerationData: _EnumerationData;
First: boolean;
Keys: string;
OpaqueData: _OpaqueData;
PrimitiveData: _PrimitiveData;
SequenceData: _SequenceData;
StructuredData: _StructuredData;
Value: OpcLabs_BaseLib_TLB._GenericData;
begin
if MaximumDepth = 0 then
Exit;
WriteLn;
WriteLn('genericData.DataType: ', GenericData.DataType.ToString);
case GenericData.DataTypeKind of
DataTypeKind_Enumeration:
begin
WriteLn('The generic data is an enumeration.');
EnumerationData := GenericData as _EnumerationData;
WriteLn(Format('Its value is %s.', [EnumerationData.Value.ToString]));
// There is also a ValueName that you can inspect (if known).
end;
DataTypeKind_Opaque:
begin
WriteLn('The generic data is opaque.');
OpaqueData := GenericData as _OpaqueData;
WriteLn(Format('Its size is %d bits.', [OpaqueData.SizeInBits]));
TVarData(ByteArray).VType := varArray;
TVarData(ByteArray).VArray := PVarArray(OpaqueData.ByteArray);
WriteLn(Format('The data bytes are %s.', [TEncoding.ANSI.GetString(VariantToBytes(ByteArray))]));
// Use the Value property (a BitArray) if you need to access the value bit by bit.
end;
DataTypeKind_Primitive:
begin
WriteLn('The generic data is primitive.');
PrimitiveData := GenericData as _PrimitiveData;
WriteLn(Format('Its value is "%s".', [PrimitiveData.Value]));
end;
DataTypeKind_Sequence:
begin
WriteLn('The generic data is a sequence.');
SequenceData := GenericData as _SequenceData;
WriteLn(Format('It has %s elements.', [SequenceData.Elements.Count.ToString]));
WriteLn('A dump of the elements follows.');
ElementEnumerator := SequenceData.Elements.GetEnumerator;
while (ElementEnumerator.Next(1, Element, Count) = S_OK) do
begin
ProcessGenericData(IUnknown(Element) as OpcLabs_BaseLib_TLB._GenericData, MaximumDepth - 1);
end;
end;
DataTypeKind_Structured:
begin
WriteLn('The generic data is structured.');
StructuredData := GenericData as _StructuredData;
WriteLn(Format('It has %s field data members.', [StructuredData.FieldData.Count.ToString]));
ElementEnumerator := StructuredData.FieldData.GetEnumerator;
Keys := '';
First := True;
while (ElementEnumerator.Next(1, Element, Count) = S_OK) do
begin
if First then
First := False
else
Keys := Keys + ', ';
Keys := Keys + Element.Key;
end;
WriteLn(Format('The names of the fields are: %s.', [Keys]));
WriteLn('A dump of each of the fields follows.');
ElementEnumerator := StructuredData.FieldData.GetEnumerator;
while (ElementEnumerator.Next(1, Element, Count) = S_OK) do
begin
WriteLn;
WriteLn(Format('Field name: %s', [Element.Key]));
Value := IUnknown(Element.Value) as OpcLabs_BaseLib_TLB._GenericData;
ProcessGenericData(Value, MaximumDepth - 1);
end;
end;
end;
end;
# Shows how to process generic data type, displaying some of its properties, recursively.
#
# 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 .NET namespaces.
from System import *
from OpcLabs.BaseLib.DataTypeModel import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *
def processGenericData(genericData, maximumDepth):
if maximumDepth == 0:
print('* Reached maximum depth *')
return
print()
print('genericData.DataType: ', genericData.DataType, sep='')
dataTypeKind = genericData.DataTypeKind
if dataTypeKind == DataTypeKind.Enumeration:
print('The generic data is an enumeration.')
enumerationData = genericData
print('Its value is ', enumerationData.Value, '.', sep='')
# There is also a ValueName that you can inspect (if known).
elif dataTypeKind == DataTypeKind.Opaque:
print('The generic data is opaque.')
opaqueData = genericData
print('Its size is ', opaqueData.SizeInBits, ' bits.', sep='')
print('The data bytes are ', BitConverter.ToString(opaqueData.ByteArray), '.', sep='')
# Use the Value property (a BitArray) if you need to access the value bit by bit.
elif dataTypeKind == DataTypeKind.Primitive:
print('The generic data is primitive.')
primitiveData = genericData
print('Its value is "', primitiveData.Value, '".', sep='')
elif dataTypeKind == DataTypeKind.Sequence:
print('The generic data is a sequence.')
sequenceData = genericData
print('It has ', sequenceData.Elements.Count, ' elements.', sep='')
print('A dump of the elements follows.')
for element in sequenceData.Elements:
processGenericData(element, maximumDepth - 1)
elif dataTypeKind == DataTypeKind.Structured:
print('The generic data is structured.')
structuredData = genericData
print('It has ', structuredData.FieldData.Count, ' field data members.', sep='')
print('The names of the fields are: ', end='')
for i, name in enumerate(structuredData.FieldData.Keys):
if i != 0:
print(', ', end='')
print(name, end='')
print('.')
print('A dump of each of the fields follows.')
for pair in structuredData.FieldData:
print()
print('Field name: ', pair.Key, sep='')
processGenericData(pair.Value, maximumDepth - 1)
elif dataTypeKind == DataTypeKind.Union:
print('The generic data is a union.')
unionData = genericData
print('The name of current field is: ', unionData.FieldName, sep='')
print('Current field value is: ', unionData.FieldValue, end='')
# Define which server and node we will work with.
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.Static.Scalar.StructureValue
nodeDescriptor = UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10239')
# Instantiate the client object.
client = EasyUAClient()
# Read a node. We know that this node returns complex data, so we can type cast to UAGenericObject.
try:
print('Reading...')
genericObject = IEasyUAClientExtension.ReadValue(client, endpointDescriptor, nodeDescriptor)
except UAException as uaException:
print('*** Failure: ' + uaException.GetBaseException().Message)
exit()
print('Reading successful.')
# Process the generic data type. We will inspect some of its properties, and dump them.
processGenericData(genericObject.GenericData, 3)
print()
print('Finished.')