PicoOPC User's Guide and Reference
Reading a Node

One or more OPC UA nodes can be read using the Read method of the Client object.

The first argument to this method specifies the maximum age of the values to be read, in milliseconds (this can be an integer, or the language binding may use a more appropriate type to represent the duration). Use 0 to read a new value from the data source. Use -1 (or a corresponding value, defined in the language binding) to get a cached value.

The second argument to the Read method is an array of nodes and their attributes to read. Each element of the array is of the ReadValueId type. Each ReadValueId contains primarily the NodeId of the node you want to read (see Node Identification for more details). In addition, it has the ID of the attribute you want to read (in the AttributeId property, defaults to the Value attribute), and an index range (in the IndexRange property, for array element extraction). You can set these parameters differently from the defaults when creating the NodeId, if you need to. Consult the OPC UA specifications for the syntax of semantics of the index range.

The method returns an array of attribute data values (the DataValue type). The positions (indexes) of elements in the result array correspond to those in the input array of ReadValueId-s. Remember that the actual value is only valid when the status code (in the StatusCode property of the DataValue) indicates so (see Operation Model for more details).

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

using System;
using OpcLabs.PicoOpc.UA;

namespace ConsoleApp._Client
{
    partial class Read
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new Client();

            try
            {
                try
                {
                    // Connect to the server.
                    Console.WriteLine();
                    Console.WriteLine("Connecting...");
                    client.Connect(new Uri("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"));

                    // Read a node.
                    Console.WriteLine();
                    Console.WriteLine("Reading...");
                    var nodeId = new NodeId(10221, namespaceIndex:2);
                    DataValue dataValue = client.Read(TimeSpan.Zero, new[] { new ReadValueId(nodeId) })[0];

                    // Display the result.
                    Console.WriteLine();
                    Console.WriteLine($"Status code: 0x{dataValue.StatusCode:X8}");
                    Console.WriteLine($"Server timestamp: {DateTime.FromFileTimeUtc(dataValue.ServerTimestamp)}");
                    Console.WriteLine($"Source timestamp: {DateTime.FromFileTimeUtc(dataValue.SourceTimestamp)}");
                    if (dataValue.StatusCode == 0)
                    {
                        Console.WriteLine($"Built-in type: {dataValue.Variant.BuiltInType}");
                        Console.WriteLine($"Is array: {dataValue.Variant.IsArray}");
                        Console.WriteLine($"Value: {dataValue.Variant.Value}");
                    }
                }
                finally
                {
                    if (client.IsConnected)
                    {
                        // Disconnect from the server.
                        Console.WriteLine();
                        Console.WriteLine("Disconnecting...");
                        client.Disconnect();
                    }
                }
            }
            catch (AggregateException aggregateException)
            {
                Console.WriteLine("*** Failure: {0}", aggregateException.GetBaseException().Message);
            }
        }
    }
}

If the actual value is an array, reading is no different. You just need to extract the element values, possibly type-casting them on the way, as in the following example. 

// This example shows how to read an attribute that is an array.

using System;
using System.Linq;
using OpcLabs.PicoOpc.UA;

namespace ConsoleApp._Client
{
    partial class Read
    {
        public static void Array()
        {
            // Instantiate the client object.
            var client = new Client();

            try
            {
                try
                {
                    // Connect to the server.
                    Console.WriteLine();
                    Console.WriteLine("Connecting...");
                    client.Connect(new Uri("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"));

                    // Read a node.
                    Console.WriteLine();
                    Console.WriteLine("Reading...");
                    var nodeId = new NodeId(10305, namespaceIndex:2);
                    DataValue dataValue = client.Read(TimeSpan.Zero, new[] { new ReadValueId(nodeId) })[0];

                    // Display the result.
                    Console.WriteLine();
                    Console.WriteLine($"Status code: 0x{dataValue.StatusCode:X8}");
                    Console.WriteLine($"Server timestamp: {DateTime.FromFileTimeUtc(dataValue.ServerTimestamp)}");
                    Console.WriteLine($"Source timestamp: {DateTime.FromFileTimeUtc(dataValue.SourceTimestamp)}");
                    if (dataValue.StatusCode == 0)
                    {
                        Console.WriteLine($"Built-in type: {dataValue.Variant.BuiltInType}");
                        Console.WriteLine($"Is array: {dataValue.Variant.IsArray}");
                        Console.WriteLine($"Value: {dataValue.Variant.Value}");
                        Console.WriteLine();
                        Int32[] intArray = ((object[]) dataValue.Variant.Value).Cast<Int32>().ToArray();
                        foreach (Int32 element in intArray)
                            Console.WriteLine($"Element: {element}");
                    }
                }
                finally
                {
                    if (client.IsConnected)
                    {
                        // Disconnect from the server.
                        Console.WriteLine();
                        Console.WriteLine("Disconnecting...");
                        client.Disconnect();
                    }
                }
            }
            catch (AggregateException aggregateException)
            {
                Console.WriteLine("*** Failure: {0}", aggregateException.GetBaseException().Message);
            }
        }
    }
}

The above examples were a bit simplified due to the fact that we have only read one node in the Read method call. The following example show the full power of the method, with multiple nodes being read at once. 

// This example shows how to read data of multiple nodes or attributes at once.

using System;
using OpcLabs.PicoOpc.UA;

namespace ConsoleApp._Client
{
    partial class Read
    {
        public static void Multiple()
        {
            // Instantiate the client object.
            var client = new Client();

            try
            {
                try
                {
                    // Connect to the server.
                    Console.WriteLine();
                    Console.WriteLine("Connecting...");
                    client.Connect(new Uri("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"));

                    // Read attributes.
                    Console.WriteLine();
                    Console.WriteLine("Reading...");
                    DataValue[] dataValueArray = client.Read(TimeSpan.Zero, new[]
                    {
                        new ReadValueId(new NodeId(10845, namespaceIndex:2)),
                        new ReadValueId(new NodeId(10853, namespaceIndex:2)),
                        new ReadValueId(new NodeId(10855, namespaceIndex:2))
                    });

                    // Display the results.
                    Console.WriteLine();
                    foreach (DataValue dataValue in dataValueArray)
                        if (dataValue.StatusCode == 0)
                            Console.WriteLine($"Value: {dataValue.Variant.Value}");
                    else
                            Console.WriteLine($"*** Status not good: 0x{dataValue.StatusCode:X8}");
                }
                finally
                {
                    if (client.IsConnected)
                    {
                        // Disconnect from the server.
                        Console.WriteLine();
                        Console.WriteLine("Disconnecting...");
                        client.Disconnect();
                    }
                }
            }
            catch (AggregateException aggregateException)
            {
                Console.WriteLine("*** Failure: {0}", aggregateException.GetBaseException().Message);
            }
        }
    }
}
See Also