QuickOPC User's Guide and Reference
OPC UA Index Range Lists
Fundamentals > Identifying Information in OPC UA Client-Server > OPC UA Index Range Lists

OPC Unified Architecture has support for single- and multidimensional arrays in data values. In addition, it is also possible to work with (read, write, subscribe to) only a subset of an array, so that the whole (potentially large) array does not have to be transferred between the OPC server and OPC client.

QuickOPC-UA uses Index Range Lists (UAIndexRangeList objects) to control which parts of array value should be accessed. An index range list can be used to identify the whole array, a single element of a structure or an array, or a single range of indexes for arrays. Index Range List is basically a list of individual Index Ranges (UAIndexRange objects), each containing a range for a single dimension of an array.

There is an implicit conversion from an integer (Int32) to a UAIndexRange, so if your language (such as C#) supports implicit conversions, an index range containing just a single element can be written simply as the element index, without explicitly constructing the UAIndexRange object.

Besides constructing the UAIndexRangeList from individual UAIndexRange objects, it is also possible to specify the index range list by parsing a string, using static UAIndexRangeList.TryParse method.

Examples of index range strings:

Dimensions are separated by commas. A minimum and maximum value, separated by a colon, denotes a range of index. If the colon is missing, only a single for an index is selected. An empty string denotes the whole array.

One-dimensional index range lists can be easily constructed using the UAIndexRangeList.OneDimension static method, passing it either the single index, or minimum and maximum indices.

UAIndexRangeList can be given as IndexRangeList property of the UAAttributeArguments object (and derived objects, such as UAReadArguments, UAWriteArguments, UAWriteValueArguments, and EasyUAMonitoredItemArguments). You can then pass this object to a corresponding method on the main EasyUAClient object.

// This example shows how to read a range of values from an array.

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

namespace UADocExamples._UAIndexRangeList
{
    class Usage
    {
        public static void ReadValue()
        {
            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/"

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

            // Obtain the value, indicating that just the elements 2 to 4 should be returned
            object value;
            try
            {
                value = client.ReadValue(
                    new UAReadArguments(
                        endpointDescriptor,
                        "nsu=http://test.org/UA/Data/;ns=2;i=10305",
                        UAIndexRangeList.OneDimension(2, 4)));
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Cast to typed array
            var arrayValue = (Int32[]) value;

            // Display results
            for (int i = 0; i < 3; i++)
                Console.WriteLine("arrayValue[{0}]: {1}", i, arrayValue[i]);


            // Example output:
            //arrayValue[0]: 180410224
            //arrayValue[1]: 1919239969
            //arrayValue[2]: 1700185172
        }
    }
}
// This example shows how to read a range of values from an array.

class procedure Usage.ReadValue;
var
  Client: _EasyUAClient;
  EndpointDescriptor: string;
  ReadArguments1: _UAReadArguments;
  Arguments, Results: OleVariant;
  I: Cardinal;
  IndexRange: _UAIndexRange;
  IndexRangeList: OpcLabs_EasyOpcUA_TLB._UAIndexRangeList;
  ArrayValue: OleVariant;
  Value: Integer;
  ValueResult: _ValueResult;
begin
  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';

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

  // Prepare the arguments, indicating that just the elements 2 to 4 should be returned.
  IndexRangeList := CoUAIndexRangeList.Create;
  IndexRange := CoUAIndexRange.Create;
  IndexRange.Minimum := 2;
  IndexRange.Maximum := 4;
  IndexRangeList.Add(IndexRange);

  ReadArguments1 := CoUAReadArguments.Create;
  ReadArguments1.EndpointDescriptor.UrlString := EndpointDescriptor;
  ReadArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;ns=2;i=10305';
  ReadArguments1.IndexRangeList := IndexRangeList;

  Arguments := VarArrayCreate([0, 0], varVariant);
  Arguments[0] := ReadArguments1;

  // Obtain value.
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.ReadMultipleValues(Arguments));

  ValueResult := IInterface(Results[0]) as _ValueResult;
  if not ValueResult.Succeeded then
    begin
      WriteLn(' *** Failure: ', ValueResult.Exception.GetBaseException.Message);
      Exit;
    end;

  // Display results
  ArrayValue := ValueResult.Value;
  for I := VarArrayLowBound(ArrayValue, 1) to VarArrayHighBound(ArrayValue, 1) do
  begin
      Value := ArrayValue[I];
      WriteLn('arrayValue[', I, ']: ', Value);
  end;

  // Example output:
  //arrayValue[0]: 180410224
  //arrayValue[1]: 1919239969
  //arrayValue[2]: 1700185172
end;
// This example shows how to read a range of values from an array.

$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";

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

// Prepare the arguments, indicating that just the elements 2 to 4 should be returned.
$IndexRangeList = new COM("OpcLabs.EasyOpc.UA.UAIndexRangeList");
$IndexRange = new COM("OpcLabs.EasyOpc.UA.UAIndexRange");
$IndexRange->Minimum = 2;
$IndexRange->Maximum = 4;
$IndexRangeList->Add($IndexRange);

$ReadArguments1 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments1->EndpointDescriptor->UrlString = $EndpointDescriptor;
$ReadArguments1->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/;ns=2;i=10305";
$ReadArguments1->IndexRangeList = $IndexRangeList;

$arguments[0] = $ReadArguments1;

// Obtain value.
$results = $Client->ReadMultipleValues($arguments);

$ValueResult = $results[0];

if (!$ValueResult->Succeeded) {
    printf("*** Failure: %s\n", $ValueResult->ErrorMessageBrief);
    Exit();
}

// Display results
$ArrayValue = $ValueResult->Value;
for ($i = 0; $i <= 2; $i++)
{
    printf("arrayValue[d]s\n", $i, $ArrayValue[$i]);
}

// Example output:
//arrayValue[0]: 180410224
//arrayValue[1]: 1919239969
//arrayValue[2]: 1700185172

' This example shows how to read a range of values from an array.

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

Namespace UADocExamples._UAIndexRangeList
    Friend Class Usage
        Public Shared Sub ReadValue()

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

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

            ' Obtain the value, indicating that just the elements 2 to 4 should be returned
            Dim value As Object
            Try
                value = client.ReadValue( _
                    New UAReadArguments( _
                        endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/;i=10305", _
                        UAIndexRangeList.OneDimension(2, 4)))
                ' or "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Cast to typed array
            Dim arrayValue = DirectCast(value, Int32())

            ' Display results
            For i = 0 To 2
                Console.WriteLine("arrayValue[{0}]: {1}", i, arrayValue(i))
            Next
        End Sub
    End Class
End Namespace
Rem This example shows how to read a range of values from an array.

Option Explicit

Dim endpointDescriptor
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"

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

' Prepare the arguments, indicating that just the elements 2 to 4 should be returned.
Dim IndexRangeList: Set IndexRangeList = CreateObject("OpcLabs.EasyOpc.UA.UAIndexRangeList")
Dim IndexRange: Set IndexRange = CreateObject("OpcLabs.EasyOpc.UA.UAIndexRange")
IndexRange.Minimum = 2
IndexRange.Maximum = 4
IndexRangeList.Add IndexRange
'
Dim ReadArguments1: Set ReadArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments1.EndpointDescriptor.UrlString = endpointDescriptor
ReadArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/;ns=2;i=10305"
ReadArguments1.IndexRangeList = IndexRangeList

Dim arguments(0)
Set arguments(0) = ReadArguments1

' Obtain the value.
Dim results: results = Client.ReadMultipleValues(arguments)
Dim ValueResult: Set ValueResult = results(0)
If Not ValueResult.Succeeded Then
    WScript.Echo "*** Failure: " & ValueResult.Exception.GetBaseException().Message
    WScript.Quit
End If
' VBScript can only handle well arrays of VARIANTs; most other COM tool will be able to use simply the .Value property.
Dim arrayValue: arrayValue = ValueResult.RegularizedValue

' Display results
Dim i: For i = 0 To 2
    WScript.Echo "arrayValue[" & i & "]: " & arrayValue(i)
Next


' Example output:
'arrayValue[0]: 180410224
'arrayValue[1]: 1919239969
'arrayValue[2]: 1700185172

 

 

See Also