QuickOPC User's Guide and Reference
Reading Attributes of OPC UA Nodes
Development Models > Imperative Programming Model > Imperative Programming Model for OPC Data (Classic and UA) > Obtaining Information (OPC Data) > Reading Attributes of OPC UA Nodes
In This Topic

In OPC UA Data Access, reading data from attributes of OPC nodes is one of the most common tasks. The OPC server generally provides data for any OPC attribute in form of a Value, Timestamps and Status Code combination (see chapter “OPC Attribute Data”).

A single node and attribute

If you want to read the current attribute data from an attribute of an OPC node, call the Read method. You pass in individual arguments for the endpoint descriptor and the node ID. You will receive back a UAAttributeData object holding the current value, timestamps, and status code for the specified OPC node and attribute. The Read method returns the current attribute data, regardless of the actual status code. You may receive an Uncertain or even Bad status (and no usable data value), and your code needs to deal with such situations accordingly.

.NET 

// This example shows how to read and display data of an attribute (value, timestamps, and status code).

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

namespace UADocExamples._EasyUAClient
{
    partial class Read
    {
        public static void Main1()
        {
            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/"

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Obtain attribute data. By default, the Value attribute of a node will be read.
            UAAttributeData attributeData;
            try
            {
                attributeData = client.Read(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853");
            }
            catch (UAException uaException)
            {
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}");
                return;
            }

            // Display results
            Console.WriteLine($"Value: {attributeData.Value}");
            Console.WriteLine($"ServerTimestamp: {attributeData.ServerTimestamp}");
            Console.WriteLine($"SourceTimestamp: {attributeData.SourceTimestamp}");
            Console.WriteLine($"StatusCode: {attributeData.StatusCode}");

            // Example output:
            //
            //Value: -2.230064E-31
            //ServerTimestamp: 11/6/2011 1:34:30 PM
            //SourceTimestamp: 11/6/2011 1:34:30 PM
            //StatusCode: Good
        }
    }
}
# This example shows how to read and display data of an attribute (value, timestamps, and status code).

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.UA
using namespace OpcLabs.EasyOpc.UA.OperationModel

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll"

[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/"

# Instantiate the client object.
$client = New-Object EasyUAClient

# Obtain attribute data. By default, the Value attribute of a node will be read.
try {
    $attributeData = $client.Read($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853")
}
catch [UAException] {
    Write-Host "*** Failure: $($PSItem.Exception.GetBaseException().Message)"
    return
}

# Display results
Write-Host "Value: $($attributeData.Value)"
Write-Host "ServerTimestamp: $($attributeData.ServerTimestamp)"
Write-Host "SourceTimestamp: $($attributeData.SourceTimestamp)"
Write-Host "StatusCode: $($attributeData.StatusCode)"


# Example output:
#
#Value: -2.230064E-31
#ServerTimestamp: 11/6/2011 1:34:30 PM
#SourceTimestamp: 11/6/2011 1:34:30 PM
#StatusCode: Good

# This example shows how to read and display data of an attribute (value, timestamps, and status code).

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Instantiate the client object.
client = EasyUAClient()

# Obtain attribute data. By default, the Value attribute of a node will be read.
try:
    attributeData = IEasyUAClientExtension.Read(client,
UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'))
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Display results.
print('Value: ', attributeData.Value)
print('ServerTimestamp: ', attributeData.ServerTimestamp)
print('SourceTimestamp: ', attributeData.SourceTimestamp)
print('StatusCode: ', attributeData.StatusCode)


# Example output:
#
#Value: -2.230064E-31
#ServerTimestamp: 11/6/2011 1:34:30 PM
#SourceTimestamp: 11/6/2011 1:34:30 PM
#StatusCode: Good

' This example shows how to read and display data of an attribute (value, timestamps, and status code).

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

Namespace _EasyUAClient
    Friend Class Read
        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/"

            ' Instantiate the client object
            Dim client = New EasyUAClient()

            ' Obtain attribute data. By default, the Value attribute of a node will be read.
            Dim attributeData As UAAttributeData
            Try
                attributeData = client.Read(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853")
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Display results
            Console.WriteLine("Value: {0}", attributeData.Value)
            Console.WriteLine("ServerTimestamp: {0}", attributeData.ServerTimestamp)
            Console.WriteLine("SourceTimestamp: {0}", attributeData.SourceTimestamp)
            Console.WriteLine("StatusCode: {0}", attributeData.StatusCode)

            ' Example output:
            '
            'Value: -2.230064E-31
            'ServerTimestamp: 11/6/2011 1:34:30 PM
            'SourceTimestamp: 11/6/2011 1:34:30 PM
            'StatusCode: Good
        End Sub
    End Class
End Namespace

COM 

// This example shows how to read and display data of an attribute (value, timestamps, and status code).

#include "stdafx.h"    // Includes "QuickOpc.h", and other commonly used files
#include "Read.h"

namespace _EasyUAClient
{
    void Read::Main()
    {
        // Initialize the COM library
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        {
            // Instantiate the client object
            _EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

            // Obtain attribute data. By default, the Value attribute of a node will be read.
            _UAAttributeDataPtr AttributeDataPtr = ClientPtr->Read(
                //L"http://opcua.demo-this.com:51211/UA/SampleServer", 
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
                L"nsu=http://test.org/UA/Data/ ;i=10853");
    
            // Display results
            _variant_t vString;
            vString.ChangeType(VT_BSTR, &AttributeDataPtr->Value);
            _tprintf(_T("Value: %s\n"), (LPCTSTR)CW2CT((_bstr_t)vString));
            vString.ChangeType(VT_BSTR, &_variant_t(AttributeDataPtr->ServerTimestamp, VT_DATE));
            _tprintf(_T("ServerTimestamp: %s\n"), (LPCTSTR)CW2CT((_bstr_t)vString));
            vString.ChangeType(VT_BSTR, &_variant_t(AttributeDataPtr->SourceTimestamp, VT_DATE));
            _tprintf(_T("SourceTimestamp: %s\n"), (LPCTSTR)CW2CT((_bstr_t)vString));
            _tprintf(_T("StatusCode: %s\n"), (LPCTSTR)CW2CT(AttributeDataPtr->StatusCode->ToString));

            // Example output:
            //
            //Value: -2.230064E-31
            //ServerTimestamp: 11/6/2011 1:34:30 PM
            //SourceTimestamp: 11/6/2011 1:34:30 PM
            //StatusCode: Good

        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}
// This example shows how to read and display data of an attribute (value,
// timestamps, and status code).

class procedure Read.Main;
var
  Client: EasyUAClient;
  AttributeData: _UAAttributeData;
begin
  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  // Obtain attribute data. By default, the Value attribute of a node will be
  // read.
  AttributeData := Client.Read_(
    //'http://opcua.demo-this.com:51211/UA/SampleServer',
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer',
    'nsu=http://test.org/UA/Data/ ;i=10853');

  // Display results
  WriteLn('Value: ', AttributeData.Value);
  WriteLn('ServerTimestamp: ', DateTimeToStr(AttributeData.ServerTimestamp));
  WriteLn('SourceTimestamp: ', DateTimeToStr(AttributeData.SourceTimestamp));
  WriteLn('StatusCode: ', AttributeData.StatusCode.ToString);

  // Example output:
  //
  //Value: -2.230064E-31
  //ServerTimestamp: 11/6/2011 1:34:30 PM
  //SourceTimestamp: 11/6/2011 1:34:30 PM
  //StatusCode: Good
end;
// This example shows how to read and display data of an attribute (value,
// timestamps, and status code).

class procedure Read.Main;
var
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  AttributeData: _UAAttributeData;
begin
  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  // Obtain attribute data. By default, the Value attribute of a node will be
  // read.
  try
    AttributeData := Client.Read(
      //'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',
      'nsu=http://test.org/UA/Data/ ;i=10853');
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  // Display results
  WriteLn('Value: ', AttributeData.Value);
  WriteLn('ServerTimestamp: ', DateTimeToStr(AttributeData.ServerTimestamp));
  WriteLn('SourceTimestamp: ', DateTimeToStr(AttributeData.SourceTimestamp));
  WriteLn('StatusCode: ', AttributeData.StatusCode.ToString);

  // Example output:
  //
  //Value: -2.230064E-31
  //ServerTimestamp: 11/6/2011 1:34:30 PM
  //SourceTimestamp: 11/6/2011 1:34:30 PM
  //StatusCode: Good
end;
// This example shows how to read and display data of an attribute (value, timestamps, and status code).

// Instantiate the client object
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");

// Obtain attribute data. By default, the Value attribute of a node will be read.
try
{
    $AttributeData = $Client->Read(
        //"http://opcua.demo-this.com:51211/UA/SampleServer", 
        "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", 
        "nsu=http://test.org/UA/Data/ ;i=10853");
}
catch (com_exception $e)
{
    printf("*** Failure: %s\n", $e->getMessage());
    Exit();
}

// Display results
printf("Value: %s\n", $AttributeData->Value);
printf("ServerTimestamp: %s\n", $AttributeData->ServerTimestamp);
printf("SourceTimestamp: %s\n", $AttributeData->SourceTimestamp);
printf("StatusCode: %s\n", $AttributeData->StatusCode);

// Example output:
//
//Value: -2.230064E-31
//ServerTimestamp: 11/6/2011 1:34:30 PM
//SourceTimestamp: 11/6/2011 1:34:30 PM
//StatusCode: Good

// This example shows how to read and display data of an attribute (value, timestamps, and status code).

mle_outputtext.Text = ""

// Instantiate the client object
OLEObject client
client = CREATE OLEObject
client.ConnectToNewObject("OpcLabs.EasyOpc.UA.EasyUAClient")

// Obtain attribute data. By default, the Value attribute of a node will be read.
OLEObject attributeData
TRY
    attributeData = client.Read("http://opcua.demo-this.com:51211/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853")        // or "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
CATCH (OLERuntimeError oleRuntimeError)
    mle_outputtext.Text = mle_outputtext.Text + "*** Failure: " + oleRuntimeError.Description + "~r~n"
    RETURN
END TRY

// Display results
mle_outputtext.Text = mle_outputtext.Text + "Value: " + String(attributeData.value) + "~r~n"
mle_outputtext.Text = mle_outputtext.Text + "ServerTimestamp: " + String(attributeData.ServerTimestamp) + "~r~n"
mle_outputtext.Text = mle_outputtext.Text + "SourceTimestamp: " + String(attributeData.SourceTimestamp) + "~r~n"
mle_outputtext.Text = mle_outputtext.Text + "StatusCode: " + String(attributeData.StatusCode) + "~r~n"

// Example output:
//
//Value: -2.230064E-31
//ServerTimestamp: 11/6/2011 1:34:30 PM
//SourceTimestamp: 11/6/2011 1:34:30 PM
//StatusCode: Good

# This example shows how to read and display data of an attribute (value, timestamps, and status code).

# The Python for Windows (pywin32) extensions package is needed. Install it using "pip install pypiwin32".
# CAUTION: We now recommend using Python.NET package instead. Full set of examples with Python.NET is available!
import win32com.client
from pywintypes import com_error

# Instantiate the client object
client = win32com.client.Dispatch('OpcLabs.EasyOpc.UA.EasyUAClient') 

# Obtain attribute data. By default, the Value attribute of a node will be read.
try:
    attributeData = client.Read('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer',
                                'nsu=http://test.org/UA/Data/ ;i=10853')
except com_error as e:
    print('*** Failure: ' + e.args[2][1] + ': ' + e.args[2][2])
    exit()

# Display results
print('Value: ', attributeData.Value)
print('ServerTimestamp: ', attributeData.ServerTimestamp)
print('SourceTimestamp: ', attributeData.SourceTimestamp)
print('StatusCode: ', attributeData.StatusCode)

# Example output:
#
#Value: -2.230064E-31
#ServerTimestamp: 11/6/2011 1:34:30 PM
#SourceTimestamp: 11/6/2011 1:34:30 PM
#StatusCode: Good

Rem This example shows how to read and display data of an attribute (value, timestamps, and status code).

Public Sub Read_Main_Command_Click()
    OutputText = ""

    ' Instantiate the client object
    Dim Client As New EasyUAClient

    ' Obtain attribute data. By default, the Value attribute of a node will be read.
    On Error Resume Next
    Dim AttributeData As UAAttributeData
    Set AttributeData = Client.Read("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", _
                                    "nsu=http://test.org/UA/Data/ ;i=10853")
    If Err.Number <> 0 Then
        OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
        Exit Sub
    End If
    On Error GoTo 0

    ' Display results
    OutputText = OutputText & "Value: " & AttributeData.value & vbCrLf
    OutputText = OutputText & "ServerTimestamp: " & AttributeData.ServerTimestamp & vbCrLf
    OutputText = OutputText & "SourceTimestamp: " & AttributeData.SourceTimestamp & vbCrLf
    OutputText = OutputText & "StatusCode: " & AttributeData.StatusCode & vbCrLf

    ' Example output:
    '
    'Value: -2.230064E-31
    'ServerTimestamp: 11/6/2011 1:34:30 PM
    'SourceTimestamp: 11/6/2011 1:34:30 PM
    'StatusCode: Good
End Sub
Rem This example shows how to read and display data of an attribute (value, timestamps, and status code).

Option Explicit

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

' Obtain attribute data. By default, the Value attribute of a node will be read.
On Error Resume Next
Dim AttributeData: Set AttributeData = Client.Read("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", _
                                                   "nsu=http://test.org/UA/Data/ ;i=10853")
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
    WScript.Quit
End If
On Error Goto 0

' Display results
WScript.Echo "Value: " & AttributeData.Value
WScript.Echo "ServerTimestamp: " & AttributeData.ServerTimestamp
WScript.Echo "SourceTimestamp: " & AttributeData.SourceTimestamp
WScript.Echo "StatusCode: " & AttributeData.StatusCode

' Example output:
'
'Value: -2.230064E-31
'ServerTimestamp: 11/6/2011 1:34:30 PM
'SourceTimestamp: 11/6/2011 1:34:30 PM
'StatusCode: Good

Tools

:: This example shows how to read and display data of an attribute (value, timestamps, and status code).

:: Invoke the OPC UA client.
uaClient

:: Obtain attribute data and display results. By default, the Value attribute of a node will be read.
read opc.tcp://opcua.demo-this.com:51210/UA/SampleServer "nsu=http://test.org/UA/Data/ ;i=10853"

 

If the attribute ID is not specified in the method call, the method will read from the Value attribute. There are also other overloads of the Read method that allow you to pass in the arguments in a different way, and with more information in them. For example, you can pass in a UANodeArguments object, and an attribute ID.

Multiple nodes or attributes

For reading attribute data of multiple attributes (of the same node or of different nodes) simultaneously in an efficient manner, call the ReadMultiple method (instead of multiple Read calls in a loop). You pass in an array of UAReadArguments objects, and you will receive back an array of UAAttributeDataResult objects.

.NET

// This example shows how to read data (value, timestamps, and status code) of 3 attributes at once. In this example,
// we are reading a Value attribute of 3 different nodes, but the method can also be used to read multiple attributes
// of the same node.

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

namespace UADocExamples._EasyUAClient
{
    partial class ReadMultiple
    {
        public static void Main1()
        {
            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/"

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Obtain attribute data. By default, the Value attributes of the nodes will be read.
            UAAttributeDataResult[] attributeDataResultArray = client.ReadMultiple(new[]
                {
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845"),
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853"),
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855")
                });

            // Display results.
            foreach (UAAttributeDataResult attributeDataResult in attributeDataResultArray)
            {
                if (attributeDataResult.Succeeded)
                    Console.WriteLine($"AttributeData: {attributeDataResult.AttributeData}");
                else
                    Console.WriteLine($"*** Failure: {attributeDataResult.ErrorMessageBrief}");
            }
        }

        // Example output:
        //
        //AttributeData: 51 {Int16} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
        //AttributeData: -1993984 {Single} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
        //AttributeData: Yellow% Dragon Cat) White Blue Dog# Green Banana- {String} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good            
    }
}
# This example shows how to read data (value, timestamps, and status code) of 3 attributes at once. In this example,
# we are reading a Value attribute of 3 different nodes, but the method can also be used to read multiple attributes
# of the same node.

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.UA
using namespace OpcLabs.EasyOpc.UA.OperationModel

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll"

[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/"

# Instantiate the client object.
$client = New-Object EasyUAClient

# Obtain attribute data. By default, the Value attributes of the nodes will be read.
$attributeDataResultArray = $client.ReadMultiple(@(
        (New-Object UAReadArguments($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845")), 
        (New-Object UAReadArguments($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853")), 
        (New-Object UAReadArguments($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855"))
    ))

foreach ($attributeDataResult in $attributeDataResultArray) {
    if ($attributeDataResult.Succeeded) {
        Write-Host "AttributeData: $($attributeDataResult.AttributeData)"
    }
    else {
        Write-Host "*** Failure: $($attributeDataResult.ErrorMessageBrief)"
    }
}


# Example output:
#
#AttributeData: 51 {Int16} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
#AttributeData: -1993984 {Single} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
#AttributeData: Yellow% Dragon Cat) White Blue Dog# Green Banana- {String} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good            

# This example shows how to read data (value, timestamps, and status code) of 3 attributes at once. In this example,
# we are reading a Value attribute of 3 different nodes, but the method can also be used to read multiple attributes
# of the same node.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


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

# Instantiate the client object.
client = EasyUAClient()

# Obtain attribute data. By default, the Value attributes of the nodes will be read.
attributeDataResultArray = client.ReadMultiple([
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845')),
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853')),
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855')),
    ])

# Display results.
for attributeDataResult in attributeDataResultArray:
    if attributeDataResult.Succeeded:
        print('AttributeData: ', attributeDataResult.AttributeData, sep='')
    else:
        print('*** Failure: ', attributeDataResult.ErrorMessageBrief, sep='')

print()
print('Finished.')
' This example shows how to read data (value, timestamps, and status code) of 3 attributes at once. In this example,
' we are reading a Value attribute of 3 different nodes, but the method can also be used to read multiple attributes
' of the same node.

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

Namespace _EasyUAClient
    Partial Friend Class ReadMultiple
        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/"

            ' Instantiate the client object
            Dim client = New EasyUAClient()

            ' Obtain attribute data. By default, the Value attributes of the nodes will be read.
            Dim attributeDataResultArray() As UAAttributeDataResult = client.ReadMultiple(New UAReadArguments() _
               {
                   New UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845"),
                   New UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853"),
                   New UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855")
               })

            ' Display results
            For Each attributeDataResult As UAAttributeDataResult In attributeDataResultArray
                If attributeDataResult.Succeeded Then
                    Console.WriteLine("AttributeData: {0}", attributeDataResult.AttributeData)
                Else
                    Console.WriteLine("*** Failure: {0}", attributeDataResult.ErrorMessageBrief)
                End If
            Next attributeDataResult

            ' Example output:
            '
            'AttributeData: 51 {System.Int16} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
            'AttributeData: -1993984 {System.Single} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
            'AttributeData: Yellow% Dragon Cat) White Blue Dog# Green Banana- {System.String} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good            
        End Sub
    End Class
End Namespace

COM

// This example shows how to read the attributes of 4 OPC-UA nodes at once, and display the results.

#include "stdafx.h"    // Includes "QuickOpc.h", and other commonly used files
#include <atlsafe.h>
#include "ReadMultiple.h"

namespace _EasyUAClient
{
    void ReadMultiple::Main()
    {
        // Initialize the COM library
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        {
            _UAReadArgumentsPtr ReadArguments1Ptr(_uuidof(UAReadArguments));
            ReadArguments1Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments1Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10853";

            _UAReadArgumentsPtr ReadArguments2Ptr(_uuidof(UAReadArguments));
            ReadArguments2Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments2Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10845";

            _UAReadArgumentsPtr ReadArguments3Ptr(_uuidof(UAReadArguments));
            ReadArguments3Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments3Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10304";

            _UAReadArgumentsPtr ReadArguments4Ptr(_uuidof(UAReadArguments));
            ReadArguments4Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments4Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10389";

            CComSafeArray<VARIANT> arguments(4);
            arguments.SetAt(0, _variant_t((IDispatch*)ReadArguments1Ptr));
            arguments.SetAt(1, _variant_t((IDispatch*)ReadArguments2Ptr));
            arguments.SetAt(2, _variant_t((IDispatch*)ReadArguments3Ptr));
            arguments.SetAt(3, _variant_t((IDispatch*)ReadArguments4Ptr));
            CComVariant vArguments(arguments);

            // Instantiate the client object
            _EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

            // Obtain values. By default, the Value attributes of the nodes will be read.
            CComSafeArray<VARIANT> results;
            results.Attach(ClientPtr->ReadMultiple(&vArguments));
            
            // Display results
            for (int i = results.GetLowerBound(); i <= results.GetUpperBound(); i++)
            {
                _UAAttributeDataResultPtr ResultPtr = results[i];

                _variant_t vString;
                vString.ChangeType(VT_BSTR, &_variant_t((IDispatch*)ResultPtr->AttributeData));
                _tprintf(_T("results(d).AttributeDatas\n"), i, (LPCTSTR)CW2CT((_bstr_t)vString));
            }
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}
// This example shows how to read the attributes of 4 OPC-UA nodes at once, and
// display the results.

class procedure ReadMultiple.Main;
var
  Arguments: OleVariant;
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  I: Cardinal;
  ReadArguments1, ReadArguments2, ReadArguments3, ReadArguments4: _UAReadArguments;
  Result: _UAAttributeDataResult;
  Results: OleVariant;
begin
  ReadArguments1 := CoUAReadArguments.Create;
  ReadArguments1.EndpointDescriptor.UrlString := 
    //'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';
  ReadArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';

  ReadArguments2 := CoUAReadArguments.Create;
  ReadArguments2.EndpointDescriptor.UrlString := 
    //'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';
  ReadArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845';

  ReadArguments3 := CoUAReadArguments.Create;
  ReadArguments3.EndpointDescriptor.UrlString := 
    //'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';
  ReadArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10304';

  ReadArguments4 := CoUAReadArguments.Create;
  ReadArguments4.EndpointDescriptor.UrlString := 
    //'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';
  ReadArguments4.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10389';

  Arguments := VarArrayCreate([0, 3], varVariant);
  Arguments[0] := ReadArguments1;
  Arguments[1] := ReadArguments2;
  Arguments[2] := ReadArguments3;
  Arguments[3] := ReadArguments4;

  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  // Perform the operation
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.ReadMultiple(Arguments));

  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
    Result := IInterface(Results[I]) as _UAAttributeDataResult;
    if Result.Succeeded then
      WriteLn('results(', I, ').AttributeData: ', Result.AttributeData.ToString)
    else
      WriteLn('results(', I, ') *** Failure: ', Result.ErrorMessageBrief);
  end;

  VarClear(Results);
  VarClear(Arguments);
end;
// This example shows how to read the attributes of 4 OPC-UA nodes at once, and display the results.

$ReadArguments1 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments1->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments1->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853";

$ReadArguments2 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments2->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments2->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845";

$ReadArguments3 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments3->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments3->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10304";

$ReadArguments4 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments4->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments4->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10389";

$arguments[0] = $ReadArguments1;
$arguments[1] = $ReadArguments2;
$arguments[2] = $ReadArguments3;
$arguments[3] = $ReadArguments4;

// Instantiate the client object
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");

// Perform the operation
$results = $Client->ReadMultiple($arguments);

// Display results
for ($i = 0; $i < count($results); $i++)
{
    $attributeDataResult = $results[$i];
    if ($attributeDataResult->Succeeded)
        printf("results[d].AttributeDatas\n", $i, $attributeDataResult->AttributeData);
    else
        printf("results[d]: *** Failures\n", $i, $attributeDataResult->ErrorMessageBrief);
}
// This example shows how to read data (value, timestamps, and status code) of 3 attributes at once. In this example,
// we are reading a Value attribute of 3 different nodes, but the method can also be used to read multiple attributes
// of the same node.

mle_outputtext.Text = ""

// Instantiate the client object
OLEObject client
client = CREATE OLEObject
client.ConnectToNewObject("OpcLabs.EasyOpc.UA.EasyUAClient")

// Prepare arguments. By default, the Value attributes of the nodes will be read.

OLEObject readArguments1
readArguments1 = CREATE OLEObject
readArguments1.ConnectToNewObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
readArguments1.EndpointDescriptor.UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer"
readArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845"

OLEObject readArguments2
readArguments2 = CREATE OLEObject
readArguments2.ConnectToNewObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
readArguments2.EndpointDescriptor.UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer"
readArguments2.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"

OLEObject readArguments3
readArguments3 = CREATE OLEObject
readArguments3.ConnectToNewObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
readArguments3.EndpointDescriptor.UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer"
readArguments3.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855"

OLEObject readArgumentsList
readArgumentsList = CREATE OLEObject
readArgumentsList.ConnectToNewObject("OpcLabs.BaseLib.Collections.ElasticVector")
readArgumentsList.Add(readArguments1)
readArgumentsList.Add(readArguments2)
readArgumentsList.Add(readArguments3)

// Obtain attribute data. 
OLEObject attributeDataResultList
attributeDataResultList = client.ReadList(readArgumentsList)

// Display results
Int i
FOR i = 0 TO attributeDataResultList.Count - 1
    OLEObject attributeDataResult
    attributeDataResult = attributeDataResultList.Item[i]
    IF attributeDataResult.Succeeded THEN
        mle_outputtext.Text = mle_outputtext.Text + "AttributeData: " + String(attributeDataResult.AttributeData) + "~r~n"
    ELSE
        mle_outputtext.Text = mle_outputtext.Text + "*** Failure: " + attributeDataResult.ErrorMessageBrief + "~r~n"
    END IF    
NEXT

// Example output:
//
//AttributeData: 51 {System.Int16} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
//AttributeData: -1993984 {System.Single} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
//AttributeData: Yellow% Dragon Cat) White Blue Dog# Green Banana- {System.String} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good            

Rem This example shows how to read the attributes of 4 OPC-UA nodes at once, and
Rem display the results.

Public Sub ReadMultiple_Main_Command_Click()
    OutputText = ""

    Dim readArguments1 As New UAReadArguments
    readArguments1.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    readArguments1.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10853"

    Dim ReadArguments2 As New UAReadArguments
    ReadArguments2.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ReadArguments2.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10845"

    Dim ReadArguments3 As New UAReadArguments
    ReadArguments3.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ReadArguments3.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10304"

    Dim ReadArguments4 As New UAReadArguments
    ReadArguments4.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ReadArguments4.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10389"

    Dim arguments(3) As Variant
    Set arguments(0) = readArguments1
    Set arguments(1) = ReadArguments2
    Set arguments(2) = ReadArguments3
    Set arguments(3) = ReadArguments4

    ' Instantiate the client object
    Dim Client As New EasyUAClient

    ' Obtain values. By default, the Value attributes of the nodes will be read.
    Dim results() As Variant
    results = Client.ReadMultiple(arguments)

    ' Display results
    Dim i: For i = LBound(results) To UBound(results)
        Dim Result As UAAttributeDataResult: Set Result = results(i)
        If Result.Succeeded Then
            OutputText = OutputText & "results(" & i & ").AttributeData: " & Result.AttributeData & vbCrLf
        Else
            OutputText = OutputText & "results(" & i & ") *** Failure: " & Result.ErrorMessageBrief & vbCrLf
        End If
    Next
End Sub
Rem This example shows how to read the attributes of 4 OPC-UA nodes at once, and display the results.

Option Explicit

Dim ReadArguments1: Set ReadArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments1.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"

Dim ReadArguments2: Set ReadArguments2 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments2.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments2.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845"

Dim ReadArguments3: Set ReadArguments3 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments3.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments3.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10304"

Dim ReadArguments4: Set ReadArguments4 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments4.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments4.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10389"

Dim arguments(3)
Set arguments(0) = ReadArguments1
Set arguments(1) = ReadArguments2
Set arguments(2) = ReadArguments3
Set arguments(3) = ReadArguments4

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

' Perform the operation
Dim results: results = Client.ReadMultiple(arguments)

' Display results
Dim i: For i = LBound(results) To UBound(results)
    Dim AttributeDataResult: Set AttributeDataResult = results(i)
    If AttributeDataResult.Succeeded Then
        WScript.Echo "results(" & i & ").AttributeData: " & AttributeDataResult.AttributeData
    Else
        WScript.Echo "results(" & i & ") *** Failure: " & AttributeDataResult.ErrorMessageBrief
    End If
Next

 

Reading properties

OPC “Classic” has separate functions for reading so-called OPC properties. OPC properties contain additional information related to a node. In OPC Unified Architecture, properties are accessed in the same way as other information. That is, if you have a node ID (obtained e.g. by browsing) of a property, you can use one of the ReadXXXX methods described in this chapter to get a value (or some other attribute) of that property.

Read parameters

The details of how the read will be performed are specified using the read parameters object (UAReadParameters class). In the most generic case, all arguments for the read method are contained in the UAReadArguments object, and the read parameters are in its ReadParameters property. There are, however, many extension methods for reading, and some of the accept the UAReadParameters object as an argument directly.

Maximum age

It is possible to specify the maximum age of the value to be read. In order to do that, set the MaximumAge property of the read parameters to the appropriate number of milliseconds. The MaximumAge property corresponds to the maxAge parameter in the OPC UA Read Service request, and you can read more details about it here: Table 53 - Read Service Parameters.

By default, the read parameters are set to UAReadParameters.FromCache, which denotes reading from the (OPC server) cache (and using the default encoding), and corresponds to MaximumAge equal to the CacheMaximumAge constant (Int32.MaxValue). Setting the read parameters to UAReadParameters.FromDevice will cause the server to read from the device (data source), and use the default encoding. Reading from the device is achieved by setting the MaximumAge to the DeviceMaximumAge constant (which is, in fact, zero).

For choosing a specific maximum age (in milliseconds), set the MaximumAge property to a value between zero and Int32.MaxValue. In .NET languages, there is an implicit conversion operator from Double to UAReadParameters, which means that you can simply use the number of milliseconds that represents the maximum age in place of any argument that expects the read parameters (the UAReadParameters object). There is also a FromDouble Method which has the same functionality as the conversion operator.

The default setting of read parameters, which specifies reading from the cache, may sometimes "bite" you, if you expect to receive an up-to-date value from the data source. Furthermore, you may even receive a "bad quality" indication with some first reads, because the (OPC server) cache is not yet filled with valid data. Make sure to specify the proper maximum age for the read operation, if the default behavior is not what you want. The default cannot be set to reading from the device (data source), because reading from the device (or using very short maximum age) is an ineffective practice that is discouraged, and should only be used when absolutely necessary. And, choosing a concrete number of milliseconds as a default for the maximum age would be sub-optimal, because the application requirements differ greatly, and there is no maximum age that "fits them all".

Be aware that it is physically impossible for any system to always obtain fully up-to-date values all the time. 

// This example shows how to read data from the device (data source) and display a value, timestamps, and status code.

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

namespace UADocExamples._EasyUAClient
{
    partial class Read
    {
        public static void FromDevice()
        {
            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/"

            // Instantiate the client object
            var client = new EasyUAClient();

            // Obtain attribute data. By default, the Value attribute of a node will be read.
            // The parameters specify reading from the device (data source), which may be slow but provides the very latest
            // data.
            UAAttributeData attributeData;
            try
            {
                attributeData = client.Read(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 
                    UAReadParameters.FromDevice);
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Display results
            Console.WriteLine("Value: {0}", attributeData.Value);
            Console.WriteLine("ServerTimestamp: {0}", attributeData.ServerTimestamp);
            Console.WriteLine("SourceTimestamp: {0}", attributeData.SourceTimestamp);
            Console.WriteLine("StatusCode: {0}", attributeData.StatusCode);

            // Example output:
            //
            //Value: -2.230064E-31
            //ServerTimestamp: 11/6/2011 1:34:30 PM
            //SourceTimestamp: 11/6/2011 1:34:30 PM
            //StatusCode: Good
        }
    }
}
# This example shows how to read data from the device (data source) and display a value, timestamps, and status code.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Instantiate the client object.
client = EasyUAClient()

# Obtain attribute data. By default, the Value attribute of a node will be read.
# The parameters specify reading from the device (data source), which may be slow but provides the very latest
# data.
try:
    attributeData = IEasyUAClientExtension.Read(client,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAReadParameters.FromDevice)
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Display results.
print('Value: ', attributeData.Value)
print('ServerTimestamp: ', attributeData.ServerTimestamp)
print('SourceTimestamp: ', attributeData.SourceTimestamp)
print('StatusCode: ', attributeData.StatusCode)

 

// This example shows how to read data value of 3 nodes at once, from the device (data source).

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

namespace UADocExamples._EasyUAClient
{
    partial class ReadMultiple
    {
        public static void FromDevice()
        {
            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/"

            // Instantiate the client object
            var client = new EasyUAClient();

            // Obtain attribute data. By default, the Value attributes of the nodes will be read.
            // The parameters specify reading from the device (data source), which may be slow but provides the very latest
            // data.
            UAAttributeDataResult[] attributeDataResultArray = client.ReadMultiple(new[]
                {
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 
                        UAReadParameters.FromDevice),
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 
                        UAReadParameters.FromDevice),
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 
                        UAReadParameters.FromDevice)
                });

            // Display results
            foreach (UAAttributeDataResult attributeDataResult in attributeDataResultArray)
            {
                if (attributeDataResult.Succeeded)
                    Console.WriteLine("AttributeData: {0}", attributeDataResult.AttributeData);
                else
                    Console.WriteLine("*** Failure: {0}", attributeDataResult.ErrorMessageBrief);
            }
        }

        // Example output:
        //
        //AttributeData: 51 {System.Int16} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
        //AttributeData: -1993984 {System.Single} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good
        //AttributeData: Yellow% Dragon Cat) White Blue Dog# Green Banana- {System.String} @11/6/2011 1:49:19 PM @11/6/2011 1:49:19 PM; Good            
    }
}
# This example shows how to read data value of 3 nodes at once, from the device (data source).

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


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

# Instantiate the client object.
client = EasyUAClient()

# Obtain attribute data. By default, the Value attributes of the nodes will be read.
# The parameters specify reading from the device (data source), which may be slow but provides the very latest
# data.
attributeDataResultArray = client.ReadMultiple([
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
                    UAReadParameters.FromDevice),
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
                    UAReadParameters.FromDevice),
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
                    UAReadParameters.FromDevice),
    ])

# Display results.
for attributeDataResult in attributeDataResultArray:
    if attributeDataResult.Succeeded:
        print('AttributeData: ', attributeDataResult.AttributeData, sep='')
    else:
        print('*** Failure: ', attributeDataResult.ErrorMessageBrief, sep='')

print()
print('Finished.')

Encoding

The read parameters also allow you to select the encoding that will be used to transfer the value (e.g. binary, or XML). This is done using the EncodingName Property of the read parameters, which is a UAQualifiedName. The default is a null qualified name, which means that the encoding will be selected automatically. If you want a specific encoding be used (and the OPC server supports it), you can set this property to e.g. UABrowseNames.DefaultBinary or UABrowseNames.DefaultXml. In .NET languages, there is an implicit conversion operator from UAQualifiedName to UAReadParameters, which means that you can simply use the browse name of the encoding in place of any argument that expects the read parameters (the UAReadParameters object). There is also a FromUAQualifiedName Method which has the same functionality as the conversion operator.

The encoding setting is normally an implementation detail that is handled automatically between the OPC client and the OPC server, and it is rarely set manually.

Using browse paths

.NET

// This example shows how to read the attributes of 4 OPC-UA nodes specified by browse paths at once, and display the
// results.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Navigation.Parsing;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    partial class ReadMultiple
    {
        public static void BrowsePath()
        {
            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/"

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Instantiate the browse path parser.
            var browsePathParser = new UABrowsePathParser {DefaultNamespaceUriString = "http://test.org/UA/Data/"};

            // Prepare arguments.
            // Note: Add error handling around the following statement if the browse paths are not guaranteed to be
            // syntactically valid.
            var readArgumentsArray = new[]
            {
                new UAReadArguments(endpointDescriptor, 
                    browsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue")),
                new UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue")),
                new UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Static/Array/UInt16Value")),
                new UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Static/UserScalar/Int32Value"))
            };

            // Obtain attribute data.
            UAAttributeDataResult[] attributeDataResultArray = client.ReadMultiple(readArgumentsArray);

            // Display results.
            for (int i = 0; i < attributeDataResultArray.Length; i++)
            {
                UAAttributeDataResult attributeDataResult = attributeDataResultArray[i];
                if (attributeDataResult.Succeeded)
                    Console.WriteLine($"results[{i}].AttributeData: {attributeDataResult.AttributeData}");
                else
                    Console.WriteLine($"results[{i}] *** Failure: {attributeDataResult.ErrorMessageBrief}");
            }
        }

        // Example output:
        //results[0].AttributeData: 4.187603E+21 {Single} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
        //results[1].AttributeData: -98 {Int16} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
        //results[2].AttributeData: [58] {38240, 11129, 64397, 22845, 30525, ...} {Int32[]} @2019-11-09T14:00:07.543 @@2019-11-09T14:05:46.268; Good
        //results[3].AttributeData: 1280120396 {Int32} @2019-11-09T14:00:07.590 @@2019-11-09T14:05:46.268; Good
    }
}
# This example shows how to read the attributes of 4 OPC-UA nodes specified by browse paths at once, and display the
# results.

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.UA
using namespace OpcLabs.EasyOpc.UA.Navigation.Parsing
using namespace OpcLabs.EasyOpc.UA.OperationModel

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll"

[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/"

# Instantiate the client object.
$client = New-Object EasyUAClient

# Instantiate the browse path parser.
$browsePathParser = New-Object UABrowsePathParser -Property @{DefaultNamespaceUriString = "http://test.org/UA/Data/"}

# Prepare arguments.
# Note: Add error handling around the following statement if the browse paths are not guaranteed to be
## syntactically valid.
$readArgumentsArray = @(
        (New-Object UAReadArguments($endpointDescriptor, 
            $browsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue"))),
        (New-Object UAReadArguments($endpointDescriptor,
            $browsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue"))),
        (New-Object UAReadArguments($endpointDescriptor,
            $browsePathParser.Parse("[ObjectsFolder]/Data/Static/Array/UInt16Value"))),
        (New-Object UAReadArguments($endpointDescriptor,
            $browsePathParser.Parse("[ObjectsFolder]/Data/Static/UserScalar/Int32Value")))
    )

# Obtain attribute data.
$attributeDataResultArray = $client.ReadMultiple($readArgumentsArray)

for ($i = 0; $i -lt $attributeDataResultArray.Length; $i++) {
    $attributeDataResult = $attributeDataResultArray[$i]
    if ($attributeDataResult.Succeeded) {
        Write-Host "results[$($i)].AttributeData: $($attributeDataResult.AttributeData)"
    }
    else {
        Write-Host "results[$($i)]: *** Failure: $($attributeDataResult.ErrorMessageBrief)"
    }
}


# Example output:
#
#results[0].AttributeData: 4.187603E+21 {Single} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
#results[1].AttributeData: -98 {Int16} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
#results[2].AttributeData: [58] {38240, 11129, 64397, 22845, 30525, ...} {Int32[]} @2019-11-09T14:00:07.543 @@2019-11-09T14:05:46.268; Good
#results[3].AttributeData: 1280120396 {Int32} @2019-11-09T14:00:07.590 @@2019-11-09T14:05:46.268; Good

# This example shows how to read the attributes of 4 OPC-UA nodes specified by browse paths at once, and display the
# results.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.Navigation.Parsing 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/'

# Instantiate the client object.
client = EasyUAClient()

# Instantiate the browse path parser.
browsePathParser = UABrowsePathParser()
browsePathParser.DefaultNamespaceUriString = 'http://test.org/UA/Data/'

# Prepare arguments.
# Note: Add error handling around the following statement if the browse paths are not guaranteed to be
# syntactically valid.
readArgumentsArray = [
    UAReadArguments(endpointDescriptor,
                    UANodeDescriptor(browsePathParser.Parse('[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue'))),
    UAReadArguments(endpointDescriptor,
                    UANodeDescriptor(browsePathParser.Parse('[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue'))),
    UAReadArguments(endpointDescriptor,
                    UANodeDescriptor(browsePathParser.Parse('[ObjectsFolder]/Data/Static/Array/UInt16Value'))),
    UAReadArguments(endpointDescriptor,
                    UANodeDescriptor(browsePathParser.Parse('[ObjectsFolder]/Data/Static/UserScalar/Int32Value'))),
    ]

# Obtain attribute data.
attributeDataResultArray = client.ReadMultiple(readArgumentsArray)

# Display results.
for i, attributeDataResult in enumerate(attributeDataResultArray):
    if attributeDataResult.Succeeded:
        print('results[', i, '].AttributeData: ', attributeDataResult.AttributeData, sep='')
    else:
        print('results[', i, '] *** Failure: ', attributeDataResult.ErrorMessageBrief, sep='')

print()
print('Finished.')
' This example shows how to read the attributes of 4 OPC-UA nodes specified by browse paths at once, and display the
' results.

Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.Navigation.Parsing
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace _EasyUAClient
    Partial Friend Class ReadMultiple
        Public Shared Sub BrowsePath()

            ' 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/"

            ' Instantiate the client object
            Dim client = New EasyUAClient()

            Dim browsePathParser = New UABrowsePathParser()
            browsePathParser.DefaultNamespaceUriString = "http://test.org/UA/Data/"

            ' Prepare arguments
            ' Note: Add error handling around the following statement if the browse paths are Not guaranteed to be
            ' syntactically valid.
            Dim readArgumentsArray = New UAReadArguments() _
            {
                New UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue")),
                New UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue")),
                New UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Static/Array/UInt16Value")),
                New UAReadArguments(endpointDescriptor,
                    browsePathParser.Parse("[ObjectsFolder]/Data/Static/UserScalar/Int32Value"))
            }


            ' Obtain attribute data. By default, the Value attributes of the nodes will be read.
            Dim resultArray() As UAAttributeDataResult = client.ReadMultiple(readArgumentsArray)

            ' Display results
            For i As Integer = 0 To resultArray.Length - 1
                Dim attributeDataResult As UAAttributeDataResult = resultArray(i)
                If attributeDataResult.Succeeded Then
                    Console.WriteLine("results[{0}].AttributeData: {1}", i, attributeDataResult.AttributeData)
                Else
                    Console.WriteLine("results[{0}]: *** Failure: {1}", i, attributeDataResult.ErrorMessageBrief)
                End If
            Next i

            ' Example output:
            'results[0].AttributeData 4.187603E+21 {System.Single} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
            'results[1].AttributeData: -98 {System.Int16} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
            'results[2].AttributeData: [58] {38240, 11129, 64397, 22845, 30525, ...} {System.Int32[]} @2019-11-09T14:00:07.543 @@2019-11-09T14:05:46.268; Good
            'results[3].AttributeData: 1280120396 {System.Int32} @2019-11-09T14:00:07.590 @@2019-11-09T14:05:46.268; Good
        End Sub
    End Class
End Namespace

COM

// This example shows how to read the attributes of 4 OPC-UA nodes specified
// by browse paths at once, and display the results.

class procedure ReadMultiple.BrowsePath;
var
  Arguments: OleVariant;
  BrowsePathParser: _UABrowsePathParser;
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  I: Cardinal;
  ReadArguments1, ReadArguments2, ReadArguments3, ReadArguments4: _UAReadArguments;
  Result: _UAAttributeDataResult;
  Results: OleVariant;
begin
  BrowsePathParser := CoUABrowsePathParser.Create;
  BrowsePathParser.DefaultNamespaceUriString := 'http://test.org/UA/Data/';

  ReadArguments1 := CoUAReadArguments.Create;
  ReadArguments1.EndpointDescriptor.UrlString := 
    //'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';
  //  Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
  ReadArguments1.NodeDescriptor.BrowsePath := BrowsePathParser.Parse('[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue');

  ReadArguments2 := CoUAReadArguments.Create;
  ReadArguments2.EndpointDescriptor.UrlString := 
    //'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';
  //  Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
  ReadArguments2.NodeDescriptor.BrowsePath := BrowsePathParser.Parse('[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue');

  ReadArguments3 := CoUAReadArguments.Create;
  ReadArguments3.EndpointDescriptor.UrlString := 
    //'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';
  //  Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
  ReadArguments3.NodeDescriptor.BrowsePath := BrowsePathParser.Parse('[ObjectsFolder]/Data/Static/Array/UInt16Value');

  ReadArguments4 := CoUAReadArguments.Create;
  ReadArguments4.EndpointDescriptor.UrlString := 
    //'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';
  //  Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
  ReadArguments4.NodeDescriptor.BrowsePath := BrowsePathParser.Parse('[ObjectsFolder]/Data/Static/UserScalar/Int32Value');

  Arguments := VarArrayCreate([0, 3], varVariant);
  Arguments[0] := ReadArguments1;
  Arguments[1] := ReadArguments2;
  Arguments[2] := ReadArguments3;
  Arguments[3] := ReadArguments4;

  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  // Perform the operation
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.ReadMultiple(Arguments));

  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
    Result := IInterface(Results[I]) as _UAAttributeDataResult;
    if Result.Succeeded then
      WriteLn('results[', I, '].AttributeData: ', Result.AttributeData.ToString)
    else
      WriteLn('results[', I, '] *** Failure: ', Result.ErrorMessageBrief);
  end;

  VarClear(Results);
  VarClear(Arguments);

  // Example output:
  //results[0].AttributeData: 4.187603E+21 {System.Single} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
  //results[1].AttributeData: -98 {System.Int16} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
  //results[2].AttributeData: [58] {38240, 11129, 64397, 22845, 30525, ...} {System.Int32[]} @2019-11-09T14:00:07.543 @@2019-11-09T14:05:46.268; Good
  //results[3].AttributeData: 1280120396 {System.Int32} @2019-11-09T14:00:07.590 @@2019-11-09T14:05:46.268; Good

end;
// This example shows how to read the attributes of 4 OPC-UA nodes specified by browse paths at once, and display the results.

$BrowsePathParser = new COM("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser");
$BrowsePathParser->DefaultNamespaceUriString = "http://test.org/UA/Data/";

$ReadArguments1 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments1->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments1->NodeDescriptor->BrowsePath = $BrowsePathParser->Parse("[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue");

$ReadArguments2 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments2->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments2->NodeDescriptor->BrowsePath = $BrowsePathParser->Parse("[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue");

$ReadArguments3 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments3->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments3->NodeDescriptor->BrowsePath = $BrowsePathParser->Parse("[ObjectsFolder]/Data/Static/Array/UInt16Value");

$ReadArguments4 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments4->EndpointDescriptor->UrlString = 
    //"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";
$ReadArguments4->NodeDescriptor->BrowsePath = $BrowsePathParser->Parse("[ObjectsFolder]/Data/Static/UserScalar/Int32Value");

$arguments[0] = $ReadArguments1;
$arguments[1] = $ReadArguments2;
$arguments[2] = $ReadArguments3;
$arguments[3] = $ReadArguments4;

// Instantiate the client object
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");

// Perform the operation
$results = $Client->ReadMultiple($arguments);

// Display results
for ($i = 0; $i < count($results); $i++)
{
    $attributeDataResult = $results[$i];
    if ($attributeDataResult->Succeeded)
        printf("results[d].AttributeDatas\n", $i, $attributeDataResult->AttributeData);
    else
        printf("results[d]: *** Failures\n", $i, $attributeDataResult->ErrorMessageBrief);
}
Rem This example shows how to read the attributes of 4 OPC-UA nodes specified
Rem by browse paths at once, and display the results.

Public Sub ReadMultiple_BrowsePath_Command_Click()
    OutputText = ""

    Dim BrowsePathParser As New UABrowsePathParser
    BrowsePathParser.DefaultNamespaceUriString = "http://test.org/UA/Data/"

    Dim readArguments1 As New UAReadArguments
    readArguments1.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
    Set readArguments1.nodeDescriptor.browsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue")

    Dim ReadArguments2 As New UAReadArguments
    ReadArguments2.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
    Set ReadArguments2.nodeDescriptor.browsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue")

    Dim ReadArguments3 As New UAReadArguments
    ReadArguments3.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
    Set ReadArguments3.nodeDescriptor.browsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Static/Array/UInt16Value")

    Dim ReadArguments4 As New UAReadArguments
    ReadArguments4.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
    Set ReadArguments4.nodeDescriptor.browsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Static/UserScalar/Int32Value")

    Dim arguments(3) As Variant
    Set arguments(0) = readArguments1
    Set arguments(1) = ReadArguments2
    Set arguments(2) = ReadArguments3
    Set arguments(3) = ReadArguments4

    ' Instantiate the client object
    Dim Client As New EasyUAClient

    ' Obtain values. By default, the Value attributes of the nodes will be read.
    Dim results() As Variant
    results = Client.ReadMultiple(arguments)

    ' Display results
    Dim i: For i = LBound(results) To UBound(results)
        Dim Result As UAAttributeDataResult: Set Result = results(i)
        If Result.Succeeded Then
            OutputText = OutputText & "results(" & i & ").AttributeData: " & Result.AttributeData & vbCrLf
        Else
            OutputText = OutputText & "results(" & i & ") *** Failure: " & Result.ErrorMessageBrief & vbCrLf
        End If
    Next
    
    ' Example output:
    'results(0).AttributeData: 4.187603E+21 {System.Single} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
    'results(1).AttributeData: -98 {System.Int16} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
    'results(2).AttributeData: [58] {38240, 11129, 64397, 22845, 30525, ...} {System.Int32[]} @2019-11-09T14:00:07.543 @@2019-11-09T14:05:46.268; Good
    'results(3).AttributeData: 1280120396 {System.Int32} @2019-11-09T14:00:07.590 @@2019-11-09T14:05:46.268; Good
End Sub
Rem This example shows how to read the attributes of 4 OPC-UA nodes specified by browse paths at once, and display the 
Rem results.

Option Explicit

Dim BrowsePathParser: Set BrowsePathParser = CreateObject("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser")
BrowsePathParser.DefaultNamespaceUriString = "http://test.org/UA/Data/"

Dim ReadArguments1: Set ReadArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments1.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
ReadArguments1.NodeDescriptor.BrowsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/FloatValue")

Dim ReadArguments2: Set ReadArguments2 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments2.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
ReadArguments2.NodeDescriptor.BrowsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Dynamic/Scalar/SByteValue")

Dim ReadArguments3: Set ReadArguments3 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments3.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
ReadArguments3.NodeDescriptor.BrowsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Static/Array/UInt16Value")

Dim ReadArguments4: Set ReadArguments4 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments4.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' Note: Add error handling around the following statement if the browse path is not guaranteed to be syntactically valid.
ReadArguments4.NodeDescriptor.BrowsePath = BrowsePathParser.Parse("[ObjectsFolder]/Data/Static/UserScalar/Int32Value")

Dim arguments(3)
Set arguments(0) = ReadArguments1
Set arguments(1) = ReadArguments2
Set arguments(2) = ReadArguments3
Set arguments(3) = ReadArguments4

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

' Perform the operation
Dim results: results = Client.ReadMultiple(arguments)

' Display results
Dim i: For i = LBound(results) To UBound(results)
    Dim AttributeDataResult: Set AttributeDataResult = results(i)
    If AttributeDataResult.Succeeded Then
        WScript.Echo "results[" & i & "].AttributeData: " & AttributeDataResult.AttributeData
    Else
        WScript.Echo "results[" & i & "] *** Failure: " & AttributeDataResult.ErrorMessageBrief
    End If
Next

' Example output:
'results[0].AttributeData: 4.187603E+21 {System.Single} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
'results[1].AttributeData: -98 {System.Int16} @2019-11-09T14:05:46.268 @@2019-11-09T14:05:46.268; Good
'results[2].AttributeData: [58] {38240, 11129, 64397, 22845, 30525, ...} {System.Int32[]} @2019-11-09T14:00:07.543 @@2019-11-09T14:05:46.268; Good
'results[3].AttributeData: 1280120396 {System.Int32} @2019-11-09T14:00:07.590 @@2019-11-09T14:05:46.268; Good

Advanced

If you access some node or nodes repeatedly, it might be possible to improve the performance of it by (pre-)registering the node or nodes with the server. The performance improvement will only occur if the target OPC UA server supports the necessary node registration services. For more information, see OPC UA Node Registration Service.

See Also

Examples - OPC Unified Architecture

OPC UA Online Reference