// Shows how to process generic data type, displaying some of its properties, recursively.
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.
# 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.')
' Shows how to process generic data type, displaying some of its properties, recursively.
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