QuickOPC User's Guide and Reference
UAGenericObject Class
Members  Example 



OpcLabs.EasyOpcUA Assembly > OpcLabs.EasyOpc.UA.Plugins.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.Plugins.ComplexData.ComTypes._UAGenericObject)>
<ComVisibleAttribute(True)>
<GuidAttribute("4A00DA64-BA81-474A-B0AC-2014E469A0C8")>
<TypeConverterAttribute(System.ComponentModel.ExpandableObjectConverter)>
<CLSCompliantAttribute(True)>
<SerializableAttribute()>
Public Class UAGenericObject 
   Inherits OpcLabs.BaseLib.Info
   Implements LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.EasyOpc.UA.Plugins.ComplexData.ComTypes._UAGenericObject, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable 
'Usage
 
Dim instance As UAGenericObject
[ComDefaultInterface(OpcLabs.EasyOpc.UA.Plugins.ComplexData.ComTypes._UAGenericObject)]
[ComVisible(true)]
[Guid("4A00DA64-BA81-474A-B0AC-2014E469A0C8")]
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)]
[CLSCompliant(true)]
[Serializable()]
public class UAGenericObject : OpcLabs.BaseLib.Info, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.EasyOpc.UA.Plugins.ComplexData.ComTypes._UAGenericObject, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
[ComDefaultInterface(OpcLabs.EasyOpc.UA.Plugins.ComplexData.ComTypes._UAGenericObject)]
[ComVisible(true)]
[Guid("4A00DA64-BA81-474A-B0AC-2014E469A0C8")]
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)]
[CLSCompliant(true)]
[Serializable()]
public ref class UAGenericObject : public OpcLabs.BaseLib.Info, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.EasyOpc.UA.Plugins.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).

 

The OPC UA Complex Data extension does not require you to perform OPC operations any differently when complex data is involved. You use the same objects and methods as with the regular data. The only difference is in the data that is being passed to or from the component. When the OPC UA Complex Data extension is enabled (which is by default), complex data returned to you by the methods on the EasyUAClient Class is represented by instances of the UAGenericObject Class, and conversely, if you want to pass complex data to some method on the EasyUAClient Class, you need to prepare an instance of UAGenericObject Class

If the node being read, written or subscribed to represents an array (one- or multi-dimensional), the value passed to or from the component is then an array of UAGenericObject-s. Note that this is different from having a scalar node, and a UAGenericObject with generic data in that itself is an array (a sequence data). Both these options are possible (and sometimes a bit confusing).

The UAGenericObject class

The UAGenericObject Class is used to represent complex data on its way from the server or to the server. It has two basic pieces of information:

Steps to use complex data

Here is what you need to do in order to work with OPC UA complex data.

With the OPC UA Complex Data extension, it is also possible to call OPC UA methods that have complex data in their input arguments, or that return complex data in their output arguments. You will use a usual call to one of the Call methods on the EasyUAClient Class again.

 

 

Example
// Shows how to read complex data with OPC UA Complex Data plug-in.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;
using OpcLabs.EasyOpc.UA.Plugins.ComplexData;

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" (not in .NET Standard)
            // 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.


            // 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.

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';
  //or 'https://opcua.demo-this.com:51212/UA/SampleServer/';
  //or '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.

// Define which server and node we will work with.
$EndpointDescriptor = "http://opcua.demo-this.com:51211/UA/SampleServer";
//or $EndpointDescriptor = "https://opcua.demo-this.com:51212/UA/SampleServer/";
//or $EndpointDescriptor = "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

' Shows how to read complex data with OPC UA Complex Data plug-in.

Imports System
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel
Imports OpcLabs.EasyOpc.UA.Plugins.ComplexData

Namespace UADocExamples.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" (not in .NET Standard)
            ' 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
Rem This example shows how to read and display data of an attribute (value, timestamps, and status code).

Option Explicit

' Define which server and node we will work with.
Dim endpointDescriptor: endpointDescriptor = _
    "http://opcua.demo-this.com:51211/UA/SampleServer"  
'or "https://opcua.demo-this.com:51212/UA/SampleServer/"
'or "opc.tcp://opcua.demo-this.com:51210/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.

using System;
using OpcLabs.BaseLib.DataTypeModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;
using OpcLabs.EasyOpc.UA.Plugins.ComplexData;

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" (not in .NET Standard)
            // 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.

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';
  //or 'https://opcua.demo-this.com:51212/UA/SampleServer/';
  //or '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.

// Define which server and node we will work with.
$EndpointDescriptor = "http://opcua.demo-this.com:51211/UA/SampleServer";
//or $EndpointDescriptor = "https://opcua.demo-this.com:51212/UA/SampleServer/";
//or $EndpointDescriptor = "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.

Imports System
Imports OpcLabs.BaseLib.DataTypeModel
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel
Imports OpcLabs.EasyOpc.UA.Plugins.ComplexData

Namespace UADocExamples.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" (not in .NET Standard)
            ' 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
Inheritance Hierarchy

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

Requirements

Target Platforms: .NET Framework: Windows 7 with SP1, Windows Server 2012; .NET Core: Linux, Microsoft Windows

See Also

Reference

UAGenericObject Members
OpcLabs.EasyOpc.UA.Plugins.ComplexData Namespace