OPC Studio User's Guide and Reference
UAGenericObject Class
Members  Example 



OpcLabs.EasyOpcUA Assembly > OpcLabs.EasyOpc.UA.ComplexData Namespace : UAGenericObject Class
A generic object, used to hold OPC UA complex data.
Object Model
UAGenericObject ClassUAModelNodeDescriptor ClassGenericData ClassUAGenericObject Class
Syntax
'Declaration
 
<ComDefaultInterfaceAttribute(OpcLabs.EasyOpc.UA.ComplexData.ComTypes._UAGenericObject)> 
<ComVisibleAttribute(True)> 
<GuidAttribute("4A00DA64-BA81-474A-B0AC-2014E469A0C8")> 
<TypeConverterAttribute(System.ComponentModel.ExpandableObjectConverter)> 
<TypeDescriptionProviderAttribute(OpcLabs.BaseLib.ComponentModel.Internal.TypeDescriptionProvider`2)> 
<CLSCompliantAttribute(True)> 
<ValueControlAttribute("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.80.82.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=False, 
   Export=True, 
   PageId=10001)> 
<SerializableAttribute()> 
Public NotInheritable Class UAGenericObject 
   Inherits OpcLabs.BaseLib.Info 
   Implements LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.EasyOpc.UA.ComplexData.ComTypes._UAGenericObject, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable 
'Usage
 
Dim instance As UAGenericObject
[ComDefaultInterface(OpcLabs.EasyOpc.UA.ComplexData.ComTypes._UAGenericObject)] 
[ComVisible(true)] 
[Guid("4A00DA64-BA81-474A-B0AC-2014E469A0C8")] 
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)] 
[TypeDescriptionProvider(OpcLabs.BaseLib.ComponentModel.Internal.TypeDescriptionProvider`2)] 
[CLSCompliant(true)] 
[ValueControl("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.80.82.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=false, 
   Export=true, 
   PageId=10001)] 
[Serializable()] 
public sealed class UAGenericObject : OpcLabs.BaseLib.Info, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.EasyOpc.UA.ComplexData.ComTypes._UAGenericObject, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
[ComDefaultInterface(OpcLabs.EasyOpc.UA.ComplexData.ComTypes._UAGenericObject)] 
[ComVisible(true)] 
[Guid("4A00DA64-BA81-474A-B0AC-2014E469A0C8")] 
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)] 
[TypeDescriptionProvider(OpcLabs.BaseLib.ComponentModel.Internal.TypeDescriptionProvider`2)] 
[CLSCompliant(true)] 
[ValueControl("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.80.82.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=false, 
   Export=true, 
   PageId=10001)] 
[Serializable()] 
public ref class UAGenericObject sealed : public OpcLabs.BaseLib.Info, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.EasyOpc.UA.ComplexData.ComTypes._UAGenericObject, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
Remarks

The OPC UA generic object consists of the data itself (OpcLabs.BaseLib.DataTypeModel.GenericData) and optionally its data type ID (OpcLabs.EasyOpc.UA.InformationModel.UAModelNodeDescriptor).

Example

.NET

COM

.NET

COM

// Shows how to read 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 .

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 ReadValue
    {
        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. This is done in the same way as regular reads - just the data 
            // returned is different.
            object value;
            try
            {
                value = client.ReadValue(endpointDescriptor, nodeDescriptor);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Display basic information about what we have read.
            Console.WriteLine(value);


            // We know that this node returns complex data, so we can type cast to UAGenericObject.
            var genericObject = (UAGenericObject) value;

            // The actual data is in the GenericData property of the UAGenericObject.
            //
            // If we want to see the whole hierarchy of the received complex data, we can format it with the "V" (verbose)
            // specifier. In the debugger, you can view the same by displaying the private DebugView property.
            Console.WriteLine();
            Console.WriteLine("{0:V}", genericObject.GenericData);

            // For processing the internals of the data, refer to examples for GenericData and DataType classes.

            // .Int32Value
            var int32Value = ((genericObject.GenericData as StructuredData)
                ?.FieldData["Int32Value"] as PrimitiveData)
                ?.Value as int?;
            Console.WriteLine();
            Console.WriteLine($"Int32Value: {int32Value}");


            // Example output (truncated):
            //
            //(ScalarValueDataType) structured
            //
            //(ScalarValueDataType) structured   
            //  [BooleanValue] (Boolean) primitive; True {System.Boolean}
            //  [ByteStringValue] (ByteString) primitive; System.Byte[] {System.Byte[]}
            //  [ByteValue] (Byte) primitive; 153 {System.Byte}
            //  [DateTimeValue] (DateTime) primitive; 5/11/2013 4:32:00 PM {System.DateTime}
            //  [DoubleValue] (Double) primitive; -8.93178007363702E+27 {System.Double}
            //  [EnumerationValue] (Int32) primitive; 0 {System.Int32}
            //  [ExpandedNodeIdValue] (ExpandedNodeId) structured
            //    [NamespaceURI] (CharArray) primitive; "http://samples.org/UA/memorybuffer/Instance" {System.String}
            //    [NamespaceURISpecified] (Bit) primitive; True {System.Boolean}
            //    [NodeIdType] (NodeIdType) enumeration; 3 (String)
            //    [ServerIndexSpecified] (Bit) primitive; False {System.Boolean}
            //    [String] (StringNodeId) structured
            //      [Identifier] (CharArray) primitive; "????" {System.String}
            //      [NamespaceIndex] (UInt16) primitive; 0 {System.UInt16}
            //  [FloatValue] (Float) primitive; 78.37176 {System.Single}
            //  [GuidValue] (Guid) primitive; 8129cdaf-24d9-8140-64f2-3a6d7a957fd7 {System.Guid}
            //  [Int16Value] (Int16) primitive; 2793 {System.Int16}
            //  [Int32Value] (Int32) primitive; 1133391074 {System.Int32}
            //  [Int64Value] (Int64) primitive; -1039109760798965779 {System.Int64}
            //  [Integer] (Variant) structured
            //    [ArrayDimensionsSpecified] sequence[1]
            //      [0] (Bit) primitive; False {System.Boolean}
            //    [ArrayLengthSpecified] sequence[1]
            //      [0] (Bit) primitive; False {System.Boolean}
            //    [Int64] sequence[1]
            //      [0] (Int64) primitive; 0 {System.Int64}
            //    [VariantType] sequence[6]
            //      [0] (Bit) primitive; False {System.Boolean}
            //      [1] (Bit) primitive; False {System.Boolean}
            //      [2] (Bit) primitive; False {System.Boolean}
            //      [3] (Bit) primitive; True {System.Boolean}
            //      [4] (Bit) primitive; False {System.Boolean}
            //      [5] (Bit) primitive; False {System.Boolean}
            //  [LocalizedTextValue] (LocalizedText) structured
            //    [Locale] (CharArray) primitive; "ko" {System.String}
            //    [LocaleSpecified] (Bit) primitive; True {System.Boolean}
            //    [Reserved1] sequence[6]
            //      [0] (Bit) primitive; False {System.Boolean}
            //      [1] (Bit) primitive; False {System.Boolean}
            //      [2] (Bit) primitive; False {System.Boolean}
            //      [3] (Bit) primitive; False {System.Boolean}
            //      [4] (Bit) primitive; False {System.Boolean}
            //      [5] (Bit) primitive; False {System.Boolean}
            //    [Text] (CharArray) primitive; "? ?? ??+ ??? ??) ?: ???? ?! ?!" {System.String}
            //    [TextSpecified] (Bit) primitive; True {System.Boolean}
            //  [NodeIdValue] (NodeId) structured                                                                               
        }
    }
}
# Shows how to read 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 .
# 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. This is done in the same way as regular reads - just the data
# returned is different.
try:
    value = IEasyUAClientExtension.ReadValue(client, endpointDescriptor, nodeDescriptor)
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Display basic information about what we have read.
print(value)


# We know that this node returns complex data, so we can type cast to UAGenericObject.
genericObject = value

# The actual data is in the GenericData property of the UAGenericObject.
#
# If we want to see the whole hierarchy of the received complex data, we can format it with the "V" (verbose)
# specifier. In the debugger, you can view the same by displaying the private DebugView property.
print()
print(String.Format('{0:V}', genericObject.GenericData))

# For processing the internals of the data, refer to examples for GenericData and DataType classes.

# .Int32Value
structuredData = genericObject.GenericData if isinstance(genericObject.GenericData, StructuredData) else None
fieldData = None if structuredData is None else structuredData.FieldData
fieldValue = None if fieldData is None else fieldData.get_Item('Int32Value')
primitiveData = fieldValue if isinstance(fieldValue, PrimitiveData) else None
int32Value = None if primitiveData is None else primitiveData.Value
print()
print('Int32Value: ', int32Value, sep='')

print()
print('Finished.')
' Shows how to read 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 .

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.ComplexData
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace ComplexData._EasyUAClient

    Friend Class ReadValue

        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. This is done in the same way as regular reads - just the data 
            ' returned is different.
            Dim value As Object
            Try
                value = client.ReadValue(endpointDescriptor, nodeDescriptor)
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Display basic information about what we have read.
            Console.WriteLine(value)


            ' We know that this node returns complex data, so we can type cast to UAGenericObject.
            Dim genericObject = CType(value, UAGenericObject)

            ' The actual data is in the GenericData property of the UAGenericObject.
            '
            ' If we want to see the whole hierarchy of the received complex data, we can format it with the "V" (verbose)
            ' specifier. In the debugger, you can view the same by displaying the private DebugView property.
            Console.WriteLine()
            Console.WriteLine("{0:V}", genericObject.GenericData)

            ' For processing the internals of the data, refer to examples for GenericData and DataType classes.


            ' Example output (truncated):
            '
            '(ScalarValueDataType) structured
            '
            '(ScalarValueDataType) structured   
            '  [BooleanValue] (Boolean) primitive; True {System.Boolean}
            '  [ByteStringValue] (ByteString) primitive; System.Byte[] {System.Byte[]}
            '  [ByteValue] (Byte) primitive; 153 {System.Byte}
            '  [DateTimeValue] (DateTime) primitive; 5/11/2013 4:32:00 PM {System.DateTime}
            '  [DoubleValue] (Double) primitive; -8.93178007363702E+27 {System.Double}
            '  [EnumerationValue] (Int32) primitive; 0 {System.Int32}
            '  [ExpandedNodeIdValue] (ExpandedNodeId) structured
            '    [NamespaceURI] (CharArray) primitive; "http://samples.org/UA/memorybuffer/Instance" {System.String}
            '    [NamespaceURISpecified] (Bit) primitive; True {System.Boolean}
            '    [NodeIdType] (NodeIdType) enumeration; 3 (String)
            '    [ServerIndexSpecified] (Bit) primitive; False {System.Boolean}
            '    [String] (StringNodeId) structured
            '      [Identifier] (CharArray) primitive; "????" {System.String}
            '      [NamespaceIndex] (UInt16) primitive; 0 {System.UInt16}
            '  [FloatValue] (Float) primitive; 78.37176 {System.Single}
            '  [GuidValue] (Guid) primitive; 8129cdaf-24d9-8140-64f2-3a6d7a957fd7 {System.Guid}
            '  [Int16Value] (Int16) primitive; 2793 {System.Int16}
            '  [Int32Value] (Int32) primitive; 1133391074 {System.Int32}
            '  [Int64Value] (Int64) primitive; -1039109760798965779 {System.Int64}
            '  [Integer] (Variant) structured
            '    [ArrayDimensionsSpecified] sequence[1]
            '      [0] (Bit) primitive; False {System.Boolean}
            '    [ArrayLengthSpecified] sequence[1]
            '      [0] (Bit) primitive; False {System.Boolean}
            '    [Int64] sequence[1]
            '      [0] (Int64) primitive; 0 {System.Int64}
            '    [VariantType] sequence[6]
            '      [0] (Bit) primitive; False {System.Boolean}
            '      [1] (Bit) primitive; False {System.Boolean}
            '      [2] (Bit) primitive; False {System.Boolean}
            '      [3] (Bit) primitive; True {System.Boolean}
            '      [4] (Bit) primitive; False {System.Boolean}
            '      [5] (Bit) primitive; False {System.Boolean}
            '  [LocalizedTextValue] (LocalizedText) structured
            '    [Locale] (CharArray) primitive; "ko" {System.String}
            '    [LocaleSpecified] (Bit) primitive; True {System.Boolean}
            '    [Reserved1] sequence[6]
            '      [0] (Bit) primitive; False {System.Boolean}
            '      [1] (Bit) primitive; False {System.Boolean}
            '      [2] (Bit) primitive; False {System.Boolean}
            '      [3] (Bit) primitive; False {System.Boolean}
            '      [4] (Bit) primitive; False {System.Boolean}
            '      [5] (Bit) primitive; False {System.Boolean}
            '    [Text] (CharArray) primitive; "? ?? ??+ ??? ??) ?: ???? ?! ?!" {System.String}
            '    [TextSpecified] (Bit) primitive; True {System.Boolean}
            '  [NodeIdValue] (NodeId) structured                                                                               
        End Sub
    End Class
End Namespace
// Shows how to read 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 .

class procedure ReadValue.Main;
var
  Client: _EasyUAClient;
  EndpointDescriptor: string;
  GenericObject: _UAGenericObject;
  NodeDescriptor: string;
  Value: OleVariant;
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. This is done in the same way as regular reads - just the data
  // returned is different.

  try
    Value := Client.ReadValue(EndpointDescriptor, NodeDescriptor);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  // Display basic information about what we have read.
  WriteLn('value: ', Value);

  // We know that this node returns complex data, so it is a UAGenericObject.
  GenericObject := IUnknown(Value) as _UAGenericObject;

  // The actual data is in the GenericData property of the UAGenericObject.
  //
  // If we want to see the whole hierarchy of the received complex data, we can format it with the "V" (verbose)
  // specifier. In the debugger, you can view the same by displaying the private DebugView property.
  WriteLn;
  WriteLn(GenericObject.GenericData.ToString_2['V', nil]);

  // For processing the internals of the data, refer to examples for GenericData and DataType classes.

  // Example output (truncated):
  //
  //(ScalarValueDataType) structured
  //
  //(ScalarValueDataType) structured
  //  [BooleanValue] (Boolean) primitive; True {System.Boolean}
  //  [ByteStringValue] (ByteString) primitive; System.Byte[] {System.Byte[]}
  //  [ByteValue] (Byte) primitive; 153 {System.Byte}
  //  [DateTimeValue] (DateTime) primitive; 5/11/2013 4:32:00 PM {System.DateTime}
  //  [DoubleValue] (Double) primitive; -8.93178007363702E+27 {System.Double}
  //  [EnumerationValue] (Int32) primitive; 0 {System.Int32}
  //  [ExpandedNodeIdValue] (ExpandedNodeId) structured
  //    [NamespaceURI] (CharArray) primitive; "http://samples.org/UA/memorybuffer/Instance" {System.String}
  //    [NamespaceURISpecified] (Bit) primitive; True {System.Boolean}
  //    [NodeIdType] (NodeIdType) enumeration; 3 (String)
  //    [ServerIndexSpecified] (Bit) primitive; False {System.Boolean}
  //    [String] (StringNodeId) structured
  //      [Identifier] (CharArray) primitive; "????" {System.String}
  //      [NamespaceIndex] (UInt16) primitive; 0 {System.UInt16}
  //  [FloatValue] (Float) primitive; 78.37176 {System.Single}
  //  [GuidValue] (Guid) primitive; 8129cdaf-24d9-8140-64f2-3a6d7a957fd7 {System.Guid}
  //  [Int16Value] (Int16) primitive; 2793 {System.Int16}
  //  [Int32Value] (Int32) primitive; 1133391074 {System.Int32}
  //  [Int64Value] (Int64) primitive; -1039109760798965779 {System.Int64}
  //  [Integer] (Variant) structured
  //    [ArrayDimensionsSpecified] sequence[1]
  //      [0] (Bit) primitive; False {System.Boolean}
  //    [ArrayLengthSpecified] sequence[1]
  //      [0] (Bit) primitive; False {System.Boolean}
  //    [Int64] sequence[1]
  //      [0] (Int64) primitive; 0 {System.Int64}
  //    [VariantType] sequence[6]
  //      [0] (Bit) primitive; False {System.Boolean}
  //      [1] (Bit) primitive; False {System.Boolean}
  //      [2] (Bit) primitive; False {System.Boolean}
  //      [3] (Bit) primitive; True {System.Boolean}
  //      [4] (Bit) primitive; False {System.Boolean}
  //      [5] (Bit) primitive; False {System.Boolean}
  //  [LocalizedTextValue] (LocalizedText) structured
  //    [Locale] (CharArray) primitive; "ko" {System.String}
  //    [LocaleSpecified] (Bit) primitive; True {System.Boolean}
  //    [Reserved1] sequence[6]
  //      [0] (Bit) primitive; False {System.Boolean}
  //      [1] (Bit) primitive; False {System.Boolean}
  //      [2] (Bit) primitive; False {System.Boolean}
  //      [3] (Bit) primitive; False {System.Boolean}
  //      [4] (Bit) primitive; False {System.Boolean}
  //      [5] (Bit) primitive; False {System.Boolean}
  //    [Text] (CharArray) primitive; "? ?? ??+ ??? ??) ?: ???? ?! ?!" {System.String}
  //    [TextSpecified] (Bit) primitive; True {System.Boolean}
  //  [NodeIdValue] (NodeId) structured

end;
// Shows how to read 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 .

// 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. This is done in the same way as regular reads - just the data
// returned is different.

try
{
    $Value = $Client->ReadValue($EndpointDescriptor, $NodeDescriptor);
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}

// Display basic information about what we have read.
printf("Value: %s\n", $Value);

// We know that this node returns complex data, so it is a UAGenericObject.
$GenericObject = $Value;

// The actual data is in the GenericData property of the UAGenericObject.
//
// If we want to see the whole hierarchy of the received complex data, we can format it with the "V" (verbose)
// specifier. In the debugger, you can view the same by displaying the private DebugView property.
printf("\n");
printf("%s\n", $GenericObject->GenericData->ToString_3("V"));

// For processing the internals of the data, refer to examples for GenericData and DataType classes.

// Example output (truncated):
//
//(ScalarValueDataType) structured
//
//(ScalarValueDataType) structured
//  [BooleanValue] (Boolean) primitive; True {System.Boolean}
//  [ByteStringValue] (ByteString) primitive; System.Byte[] {System.Byte[]}
//  [ByteValue] (Byte) primitive; 153 {System.Byte}
//  [DateTimeValue] (DateTime) primitive; 5/11/2013 4:32:00 PM {System.DateTime}
//  [DoubleValue] (Double) primitive; -8.93178007363702E+27 {System.Double}
//  [EnumerationValue] (Int32) primitive; 0 {System.Int32}
//  [ExpandedNodeIdValue] (ExpandedNodeId) structured
//    [NamespaceURI] (CharArray) primitive; "http://samples.org/UA/memorybuffer/Instance" {System.String}
//    [NamespaceURISpecified] (Bit) primitive; True {System.Boolean}
//    [NodeIdType] (NodeIdType) enumeration; 3 (String)
//    [ServerIndexSpecified] (Bit) primitive; False {System.Boolean}
//    [String] (StringNodeId) structured
//      [Identifier] (CharArray) primitive; "????" {System.String}
//      [NamespaceIndex] (UInt16) primitive; 0 {System.UInt16}
//  [FloatValue] (Float) primitive; 78.37176 {System.Single}
//  [GuidValue] (Guid) primitive; 8129cdaf-24d9-8140-64f2-3a6d7a957fd7 {System.Guid}
//  [Int16Value] (Int16) primitive; 2793 {System.Int16}
//  [Int32Value] (Int32) primitive; 1133391074 {System.Int32}
//  [Int64Value] (Int64) primitive; -1039109760798965779 {System.Int64}
//  [Integer] (Variant) structured
//    [ArrayDimensionsSpecified] sequence[1]
//      [0] (Bit) primitive; False {System.Boolean}
//    [ArrayLengthSpecified] sequence[1]
//      [0] (Bit) primitive; False {System.Boolean}
//    [Int64] sequence[1]
//      [0] (Int64) primitive; 0 {System.Int64}
//    [VariantType] sequence[6]
//      [0] (Bit) primitive; False {System.Boolean}
//      [1] (Bit) primitive; False {System.Boolean}
//      [2] (Bit) primitive; False {System.Boolean}
//      [3] (Bit) primitive; True {System.Boolean}
//      [4] (Bit) primitive; False {System.Boolean}
//      [5] (Bit) primitive; False {System.Boolean}
//  [LocalizedTextValue] (LocalizedText) structured
//    [Locale] (CharArray) primitive; "ko" {System.String}
//    [LocaleSpecified] (Bit) primitive; True {System.Boolean}
//    [Reserved1] sequence[6]
//      [0] (Bit) primitive; False {System.Boolean}
//      [1] (Bit) primitive; False {System.Boolean}
//      [2] (Bit) primitive; False {System.Boolean}
//      [3] (Bit) primitive; False {System.Boolean}
//      [4] (Bit) primitive; False {System.Boolean}
//      [5] (Bit) primitive; False {System.Boolean}
//    [Text] (CharArray) primitive; "? ?? ??+ ??? ??) ?: ???? ?! ?!" {System.String}
//    [TextSpecified] (Bit) primitive; True {System.Boolean}
//  [NodeIdValue] (NodeId) structured

Rem This example shows how to read and display data of an attribute (value, timestamps, and status code).
Rem
Rem Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Option Explicit

' Define which server and node we will work with.
Dim endpointDescriptor: endpointDescriptor = _
    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    '"http://opcua.demo-this.com:51211/UA/SampleServer"  
    '"https://opcua.demo-this.com:51212/UA/SampleServer/"
Dim nodeDescriptor: nodeDescriptor = _
    "nsu=http://test.org/UA/Data/ ;i=10239"  ' [ObjectsFolder]/Data.Static.Scalar.StructureValue

' Instantiate the client object.
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")

' Read a node which returns complex data. This is done in the same way as regular reads - just the data 
' returned is different.
On Error Resume Next
Dim Value: Set Value = Client.ReadValue(endpointDescriptor, nodeDescriptor)
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

' Display basic information about what we have read.
WScript.Echo Value


' We know that this node returns complex data, so it is a UAGenericObject.
Dim GenericObject: Set GenericObject = Value

' The actual data is in the GenericData property of the UAGenericObject.
'
' If we want to see the whole hierarchy of the received complex data, we can format it with the "V" (verbose)
' specifier. In the debugger, you can view the same by displaying the private DebugView property.
WScript.Echo
WScript.Echo GenericObject.GenericData.ToString_2("V", Nothing)

' For processing the internals of the data, refer to examples for GenericData and DataType classes.


' Example output (truncated):
'
'(ScalarValueDataType) structured
'
'(ScalarValueDataType) structured   
'  [BooleanValue] (Boolean) primitive; True {System.Boolean}
'  [ByteStringValue] (ByteString) primitive; System.Byte[] {System.Byte[]}
'  [ByteValue] (Byte) primitive; 153 {System.Byte}
'  [DateTimeValue] (DateTime) primitive; 5/11/2013 4:32:00 PM {System.DateTime}
'  [DoubleValue] (Double) primitive; -8.93178007363702E+27 {System.Double}
'  [EnumerationValue] (Int32) primitive; 0 {System.Int32}
'  [ExpandedNodeIdValue] (ExpandedNodeId) structured
'    [NamespaceURI] (CharArray) primitive; "http://samples.org/UA/memorybuffer/Instance" {System.String}
'    [NamespaceURISpecified] (Bit) primitive; True {System.Boolean}
'    [NodeIdType] (NodeIdType) enumeration; 3 (String)
'    [ServerIndexSpecified] (Bit) primitive; False {System.Boolean}
'    [String] (StringNodeId) structured
'      [Identifier] (CharArray) primitive; "????" {System.String}
'      [NamespaceIndex] (UInt16) primitive; 0 {System.UInt16}
'  [FloatValue] (Float) primitive; 78.37176 {System.Single}
'  [GuidValue] (Guid) primitive; 8129cdaf-24d9-8140-64f2-3a6d7a957fd7 {System.Guid}
'  [Int16Value] (Int16) primitive; 2793 {System.Int16}
'  [Int32Value] (Int32) primitive; 1133391074 {System.Int32}
'  [Int64Value] (Int64) primitive; -1039109760798965779 {System.Int64}
'  [Integer] (Variant) structured
'    [ArrayDimensionsSpecified] sequence[1]
'      [0] (Bit) primitive; False {System.Boolean}
'    [ArrayLengthSpecified] sequence[1]
'      [0] (Bit) primitive; False {System.Boolean}
'    [Int64] sequence[1]
'      [0] (Int64) primitive; 0 {System.Int64}
'    [VariantType] sequence[6]
'      [0] (Bit) primitive; False {System.Boolean}
'      [1] (Bit) primitive; False {System.Boolean}
'      [2] (Bit) primitive; False {System.Boolean}
'      [3] (Bit) primitive; True {System.Boolean}
'      [4] (Bit) primitive; False {System.Boolean}
'      [5] (Bit) primitive; False {System.Boolean}
'  [LocalizedTextValue] (LocalizedText) structured
'    [Locale] (CharArray) primitive; "ko" {System.String}
'    [LocaleSpecified] (Bit) primitive; True {System.Boolean}
'    [Reserved1] sequence[6]
'      [0] (Bit) primitive; False {System.Boolean}
'      [1] (Bit) primitive; False {System.Boolean}
'      [2] (Bit) primitive; False {System.Boolean}
'      [3] (Bit) primitive; False {System.Boolean}
'      [4] (Bit) primitive; False {System.Boolean}
'      [5] (Bit) primitive; False {System.Boolean}
'    [Text] (CharArray) primitive; "? ?? ??+ ??? ??) ?: ???? ?! ?!" {System.String}
'    [TextSpecified] (Bit) primitive; True {System.Boolean}
'  [NodeIdValue] (NodeId) structured                                                                               
// 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 .

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 Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# 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.')
' 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 .

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 .

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 .

// 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();
}
Inheritance Hierarchy

System.Object
   OpcLabs.BaseLib.Object2
      OpcLabs.BaseLib.Info
         OpcLabs.EasyOpc.UA.ComplexData.UAGenericObject

Requirements

Target Platforms: .NET Framework: Windows 10 (selected versions), Windows 11 (selected versions), Windows Server 2016, Windows Server 2022; .NET: Linux, macOS, Microsoft Windows

See Also