QuickOPC User's Guide and Reference
DAReadItemArguments Class
Members 



View with Navigation Tools
OpcLabs.EasyOpcClassic Assembly > OpcLabs.EasyOpc.DataAccess.OperationModel Namespace : DAReadItemArguments Class
Holds information necessary to read an OPC item, such OPC server and item descriptor, and read parameters.
Object Model
DAReadItemArguments ClassDAReadParameters ClassDAItemDescriptor ClassDAReadParameters ClassServerDescriptor Class
Syntax
'Declaration
 
<CLSCompliantAttribute(True)>
<ComDefaultInterfaceAttribute(OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAReadItemArguments)>
<ComVisibleAttribute(True)>
<GuidAttribute("B5DACA52-2B85-4278-81BD-CA4F3386B4FF")>
<TypeConverterAttribute(System.ComponentModel.ExpandableObjectConverter)>
<ValueControlAttribute("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.63.115.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=False, 
   Export=True, 
   PageId=10001)>
<SerializableAttribute()>
Public NotInheritable Class DAReadItemArguments 
   Inherits DAItemArguments
   Implements LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAItemArguments, OpcLabs.EasyOpc.DataAccess.OperationModel.ComTypes._DAReadItemArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable 
 
'Usage
 
Dim instance As DAReadItemArguments
Remarks

 

In OPC Data Access, reading data from OPC items is one of the most common tasks. The OPC server generally provides current data for any OPC item in form of a Value, Timestamp and Quality combination (VTQ).

A single item

If you want to read the current VTQ from a specific OPC item, call the ReadItem method. You pass in individual arguments for machine name, server class, ItemID, and an optional data type. You will receive back a DAVtq object holding the current value, timestamp, and quality of the OPC item. The ReadItem method returns the current VTQ, regardless of the quality. You may receive an Uncertain or even Bad quality (and no usable data value), and your code needs to deal with such situations accordingly.

// This example shows how to read a single item, and display its value, timestamp and quality.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadItem
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            DAVtq vtq;
            try
            {
                vtq = client.ReadItem("", "OPCLabs.KitServer.2", "Simulation.Random");
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            Console.WriteLine("Vtq: {0}", vtq);
        }
    }
}

In QuickOPC.NET, you can also pass ServerDescriptor and DAItemDescriptor objects in place of individual arguments to the ReadItem method.

// This example shows how to read a single item using a browse path, and display its value, timestamp and quality.

using System;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadItem
    {
        public static void BrowsePath()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            DAVtq vtq;
            try
            {
                vtq = client.ReadItem(
                    new ServerDescriptor("", "OPCLabs.KitServer.2"),
                    new DAItemDescriptor(null, "/Simulation/Random"));
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            Console.WriteLine("Vtq: {0}", vtq);
        }
    }
}

 

Multiple items

For reading VTQs of multiple items simultaneously in an efficient manner, call the ReadMultipleItems method (instead of multiple ReadItem calls in a loop). You will receive back an array of DAVtqResult objects.

In QuickOPC.NET, you can pass in a ServerDescriptor object and an array of DAItemDescriptor objects, or an array of DAItemArguments objects, to the ReadMultipleItems method.

Example 1

// This example shows how to read 4 items at once, and display their values, timestamps and qualities.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadMultipleItems
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            DAVtqResult[] vtqResults = client.ReadMultipleItems("OPCLabs.KitServer.2",
                new DAItemDescriptor[]
                    {
                        "Simulation.Random", "Trends.Ramp (1 min)", "Trends.Sine (1 min)", "Simulation.Register_I4"
                    });

            for (int i = 0; i < vtqResults.Length; i++)
            {
                Debug.Assert(vtqResults[i] != null);

                if (vtqResults[i].Succeeded)
                    Console.WriteLine("vtqResults[{0}].Vtq: {1}", i, vtqResults[i].Vtq);
                else
                    Console.WriteLine("vtqResults[{0}] *** Failure: {1}", i, vtqResults[i].ErrorMessageBrief);
            }
        }
    }
}

Example 2

// This example repeatedly reads a large number of items.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadMultipleItems
    {
        private const int RepeatCount = 10;
        private const int NumberOfItems = 1000;

        public static void ManyRepeat()
        {
            Console.WriteLine("Creating array of arguments...");
            var arguments = new DAReadItemArguments[NumberOfItems];
            for (int i = 0; i < NumberOfItems; i++)
            {
                int copy = (i / 100) + 1;
                int phase = i % 100;
                string itemId = FormattableString.Invariant($"Simulation.Incrementing.Copy_{copy}.Phase_{phase}");
                Console.WriteLine(itemId);

                var readItemArguments = new DAReadItemArguments("OPCLabs.KitServer.2", itemId);
                arguments[i] = readItemArguments;
            }

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

            for (int iRepeat = 1; iRepeat <= RepeatCount; iRepeat++)
            {
                Console.WriteLine("Reading items...");
                DAVtqResult[] vtqResults = client.ReadMultipleItems(arguments);

                int successCount = 0;
                foreach (DAVtqResult vtqResult in vtqResults)
                    if (vtqResult.Succeeded)
                        successCount++;
                Console.WriteLine($"Success count: {successCount}");
            }
        }
    }
}

Example 3

// This example shows how to read 4 items at once synchronously, and display their values, timestamps and qualities.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadMultipleItems
    {
        public static void Synchronous()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            // Specify that only synchronous method is allowed. By default, both synchronous and asynchronous methods are
            // allowed, and the component picks a suitable method automatically. Disallowing asynchronous method leaves
            // only the synchronous method available for selection.
            client.InstanceParameters.Mode.AllowAsynchronousMethod = false;

            DAVtqResult[] vtqResults = client.ReadMultipleItems("OPCLabs.KitServer.2",
                new DAItemDescriptor[]
                    {
                        "Simulation.Random", "Trends.Ramp (1 min)", "Trends.Sine (1 min)", "Simulation.Register_I4"
                    });

            for (int i = 0; i < vtqResults.Length; i++)
            {
                Debug.Assert(vtqResults[i] != null);

                if (vtqResults[i].Succeeded)
                    Console.WriteLine("vtqResult[{0}].Vtq: {1}", i, vtqResults[i].Vtq);
                else
                    Console.WriteLine("vtqResult[{0}] *** Failure: {1}", i, vtqResults[i].ErrorMessageBrief);
            }
        }

        
        // Example output:
        //
        //vtqResult[0].Vtq: 0.00125125888851588 { System.Double} @2020-04-10T15:29:20.642; GoodNonspecific(192)
        //vtqResult[1].Vtq: 0.344052940607071 {System.Double} @2020-04-10T15:29:20.643; GoodNonspecific(192)
        //vtqResult[2].Vtq: 0.830410616568378 {System.Double} @2020-04-10T15:29:20.643; GoodNonspecific(192)
        //vtqResult[3].Vtq: 0 {System.Int32} @1601-01-01T00:00:00.000; GoodNonspecific(192)
    }
}

Example 4

Rem This example shows how to read 2 items (first valid, second invalid), test for success of each read and display either 
Rem the DAVtq or the Exception.

Option Explicit

Dim ReadItemArguments1: Set ReadItemArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments1.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments1.ItemDescriptor.ItemID = "Simulation.Random"

Dim ReadItemArguments2: Set ReadItemArguments2 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments2.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments2.ItemDescriptor.ItemID = "UnknownItem"

Dim arguments(1)
Set arguments(0) = ReadItemArguments1
Set arguments(1) = ReadItemArguments2

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
Dim results: results = Client.ReadMultipleItems(arguments)

Dim i: For i = LBound(results) To UBound(results)
    Dim VtqResult: Set VtqResult = results(i)
    If VtqResult.Succeeded Then
        WScript.Echo "results(" & i & ").Vtq.ToString(): " & VtqResult.Vtq.ToString()
    Else
        WScript.Echo "results(" & i & ") *** Failure: " & VtqResult.ErrorMessageBrief
    End If
Next

Example 5

Rem This example attempts to read 3 items (first valid, second invalid, third valid again), and display their values, 
Rem timestamps and qualities. Without testing for a success, a run-time error occurs when accessing the Vtq property
Rem of a failed result.

Option Explicit

Dim ReadItemArguments1: Set ReadItemArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments1.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments1.ItemDescriptor.ItemID = "Simulation.Random"

Dim ReadItemArguments2: Set ReadItemArguments2 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments2.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments2.ItemDescriptor.ItemID = "UnknownItem"

Dim ReadItemArguments3: Set ReadItemArguments3 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments3.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments3.ItemDescriptor.ItemID = "Trends.Ramp (1 min)"

Dim arguments(2)
Set arguments(0) = ReadItemArguments1
Set arguments(1) = ReadItemArguments2
Set arguments(2) = ReadItemArguments3

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
Dim results: results = Client.ReadMultipleItems(arguments)

Dim i: For i = LBound(results) To UBound(results)
    ' This is an anti-example - you should not access the Vtq property without testing the success first!
    WScript.Echo "results(" & i & ").Vtq.ToString(): " & results(i).Vtq.ToString()
Next

Read parameters

In QuickOPC.NET, you can use the optional argument of type DAReadParameters, and then set the ValueAge property in it to control how “old” may be the values you receive by reading from OPC items.  With the DataSource property, you can also specify that you want values from the device, or from cache. You can also use the pre-defined DAReadParameters.CacheSource and DAReadParameters.DeviceSource constants to specify the read parameters. There are also overloads of ReadXXXX methods that accept an integer valueAge argument.

Some OPC-DA (Data Access) servers only support older versions of the OPC specifications, which do not allow specifying the value age by a number; they only support reading from the cache, and reading from the device. With such servers, QuickOPC may emulate this functionality by providing a value from its internal (client-side) cache, when it is fresh enough, and performing a read from the device otherwise.

In .NET languages, there is an implicit conversion operator from Int32 to DAReadParameters, which means that you can simply use the number of milliseconds that represents the value age in place of any argument that expects the read parameters (the DAReadParameters object). There is also a FromInt32 Method which has the same functionality as this conversion operator.

In addition, there is also an implicit conversion from the DADataSource Enumeration to DAReadParameters. You can therefore use the enumeration members such as DADataSource.Cache or DADataSource.Device in place of the read parameters. The FromDADataSource Method has the same functionality as this conversion operator. 

The default setting of read parameters, which specifies a non-zero value age, 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 value age that is appropriate for particular read operation in your application, if the default behavior is not what you want.

Reading from the device (or using very short value age) is, however, an ineffective practice that is discouraged, and should only be used when absolutely necessary.

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

 Include: Examples - OPC Data Access - Read a single item from the device
// This example shows how to read a single item from the device, and display its value, timestamp and quality.

using System;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadItem
    {
        public static void DeviceSource()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            Console.WriteLine("Reading item...");
            DAVtq vtq;
            try
            {
                // DADataSource enumeration:
                // Selects the data source for OPC reads (from device, from OPC cache, or dynamically determined).
                // The data source (memory, OPC cache or OPC device) selection is based on the desired value age and
                // current status of data received from the server.

                vtq = client.ReadItem("OPCLabs.KitServer.2", "Simulation.Random", DADataSource.Device);
            }
            catch (OpcException opcException)
            {
                Console.WriteLine("*** Failure: {0}", opcException.GetBaseException().Message);
                return;
            }

            Console.WriteLine("Vtq: {0}", vtq);
        }
    }
}
// This example shows how to read 4 items from the device, and display their values, timestamps and qualities.

using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess._EasyDAClient
{
    partial class ReadMultipleItems
    {
        public static void DeviceSource()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            // DADataSource enumeration:
            // Selects the data source for OPC reads (from device, from OPC cache, or dynamically determined).
            // The data source (memory, OPC cache or OPC device) selection will be based on the desired value age and
            // current status of data received from the server.

            DAVtqResult[] vtqResults = client.ReadMultipleItems(
                new []
                    {
                        new DAReadItemArguments("OPCLabs.KitServer.2", "Simulation.Random", DADataSource.Device),
                        new DAReadItemArguments("OPCLabs.KitServer.2", "Trends.Ramp (1 min)", DADataSource.Device),
                        new DAReadItemArguments("OPCLabs.KitServer.2", "Trends.Sine (1 min)", DADataSource.Device),
                        new DAReadItemArguments("OPCLabs.KitServer.2", "Simulation.Register_I4", DADataSource.Device)
                    });

            for (int i = 0; i < vtqResults.Length; i++)
            {
                Debug.Assert(vtqResults[i] != null);

                if (vtqResults[i].Succeeded)
                    Console.WriteLine("vtqResult[{0}].Vtq: {1}", i, vtqResults[i].Vtq);
                else
                    Console.WriteLine("vtqResult[{0}] *** Failure: {1}", i, vtqResults[i].ErrorMessageBrief);
            }
        }


        // Example output:
        //
        //vtqResult[0].Vtq: 0.00125125888851588 { System.Double} @2020-04-10T12:44:16.250; GoodNonspecific(192)
        //vtqResult[1].Vtq: 0.270812898874283 {System.Double} @2020-04-10T12:44:16.248; GoodNonspecific(192)
        //vtqResult[2].Vtq: 0.991434340167834 {System.Double} @2020-04-10T12:44:16.250; GoodNonspecific(192)
        //vtqResult[3].Vtq: 0 {System.Int32} @1601-01-01T00:00:00.000; GoodNonspecific(192)
    }
}

 

Inheritance Hierarchy

System.Object
   OpcLabs.BaseLib.Object2
      OpcLabs.BaseLib.Info
         OpcLabs.BaseLib.OperationModel.OperationArguments
            OpcLabs.EasyOpc.DataAccess.OperationModel.DAItemArguments
               OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments

Requirements

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

See Also

Reference

DAReadItemArguments Members
OpcLabs.EasyOpc.DataAccess.OperationModel Namespace
DAItemArguments Class
DAReadParameters Class