QuickOPC User's Guide and Reference
EasyUAMonitoredItemArguments Class
Members  Example 



OpcLabs.EasyOpcUA Assembly > OpcLabs.EasyOpc.UA.OperationModel Namespace : EasyUAMonitoredItemArguments Class
Holds all arguments needed to subscribe to a monitored item in an OPC-UA server, possibly including a callback method.
Object Model
EasyUAMonitoredItemArguments ClassUAEndpointDescriptor ClassUAIndexRangeList ClassUAIndexRange ClassUAMonitoringParameters ClassUANodeDescriptor ClassUASubscriptionParameters Class
Syntax
'Declaration
 
<CLSCompliantAttribute(True)>
<ComDefaultInterfaceAttribute(OpcLabs.EasyOpc.UA.OperationModel.ComTypes._EasyUAMonitoredItemArguments)>
<ComVisibleAttribute(True)>
<GuidAttribute("014F8522-306C-4E1B-9A8C-7E940AB94A3E")>
<TypeConverterAttribute(System.ComponentModel.ExpandableObjectConverter)>
<ValueControlAttribute("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.72.465.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=False, 
   Export=True, 
   PageId=10001)>
<SerializableAttribute()>
Public Class EasyUAMonitoredItemArguments 
   Inherits UAMonitoredItemArguments
   Implements LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._EasyUAMonitoredItemArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UAAttributeArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UAMonitoredItemArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UANodeArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable 
'Usage
 
Dim instance As EasyUAMonitoredItemArguments
[CLSCompliant(true)]
[ComDefaultInterface(OpcLabs.EasyOpc.UA.OperationModel.ComTypes._EasyUAMonitoredItemArguments)]
[ComVisible(true)]
[Guid("014F8522-306C-4E1B-9A8C-7E940AB94A3E")]
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)]
[ValueControl("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.72.465.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=false, 
   Export=true, 
   PageId=10001)]
[Serializable()]
public class EasyUAMonitoredItemArguments : UAMonitoredItemArguments, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._EasyUAMonitoredItemArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UAAttributeArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UAMonitoredItemArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UANodeArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
[CLSCompliant(true)]
[ComDefaultInterface(OpcLabs.EasyOpc.UA.OperationModel.ComTypes._EasyUAMonitoredItemArguments)]
[ComVisible(true)]
[Guid("014F8522-306C-4E1B-9A8C-7E940AB94A3E")]
[TypeConverter(System.ComponentModel.ExpandableObjectConverter)]
[ValueControl("OpcLabs.BaseLib.Forms.Common.ObjectSerializationControl, OpcLabs.BaseLibForms, Version=5.72.465.1, Culture=neutral, PublicKeyToken=6faddca41dacb409", 
   DefaultReadWrite=false, 
   Export=true, 
   PageId=10001)]
[Serializable()]
public ref class EasyUAMonitoredItemArguments : public UAMonitoredItemArguments, LINQPad.ICustomMemberProvider, OpcLabs.BaseLib.ComTypes._Info, OpcLabs.BaseLib.ComTypes._Object2, OpcLabs.BaseLib.OperationModel.ComTypes._OperationArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._EasyUAMonitoredItemArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UAAttributeArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UAMonitoredItemArguments, OpcLabs.EasyOpc.UA.OperationModel.ComTypes._UANodeArguments, System.ICloneable, System.Runtime.Serialization.ISerializable, System.Xml.Serialization.IXmlSerializable  
Remarks

 

General

Subscription is initiated by calling one of the  SubscribeMonitoredItemSubscribeDataChange, or  SubscribeMultipleMonitoredItems method. For any significant change in the subscribed item, your application will receive the  DataChangeNotification event notification, described further below. Obviously, you first need to hook up event handler for that event, and in order to prevent event loss, you should do it before subscribing. Alternatively, you can pass a callback method into the SubscribeMonitoredItem, SubscribeDataChange or SubscribeMultipleMonitoredItems call.

Some items may be changing quite frequently, and receiving all changes that are generated is not desirable for performance reasons; there are also physical limitations to the event throughput in the system. You may also want to influence the amount of received information, or control how and how often the information is delivered. QuickOPC-UA has two sets of parameters for this: subscription parameters and monitoring parameters.

Subscription parameters (can be fully contained in  UASubscriptionParameters object) influence the information delivery. Main subscription parameters are the relative priority, and publishing interval (in milliseconds). The publishing interval defines the cyclic rate that the subscription is requested to return notifications to the client.

Monitoring parameters (can be fully contained in UAMonitoringParameters object) influence which information is delivered to the client. Main monitoring parameters are the data change filter (optional), size of monitored item queue, and sampling interval (in milliseconds; it is the fastest rate at which the monitored items should be accessed and evaluated).

The data change filter, if present, is contained in the UADataChangeFilter object, and defines the conditions under which a data change notification should be reported and, optionally, a deadband for value changes where no notification is generated. The Trigger property selects whether a notification is generated only when the status code associated with the value changes, or either the status code or the value change, or if any of the status code, value, or a source timestamp change. The DeadbandType property determines the type of deadband used, and can either select no deadband, absolute deadband, or percent deadband.

There are implicit conversions available from System.Double and UADataChangeTrigger to UADataChangeFilter. This allows the developer to simply use the absolute deadband, or the trigger selection, in place of any data change filter.

In order to make the settings of various parameters easier, QuickOPC-UA allows you to omit the specification of publishing interval in subscription parameters by leaving it at zero (the default). In this case, the component will calculate the publishing interval by dividing the sampling interval by the so-called automatic publishing factor (EasyUAClient.SharedParameters.EngineParameters.AutomaticPublishingFactor) with a default pre-set by the component. The resulting value is limited by the value of EasyUAClient.SharedParameters.EngineParameters.FastestAutomaticPublishingInterval property. This algorithm should determine a suitable publishing interval in the most common cases.

A single node and attribute

If you want to subscribe to a specific value in OPC address space, call the SubscribeDataChange or SubscribeMonitoredItem method. These methods have number of overloads, but in its simplest form, only three arguments are necessary: an endpoint descriptor, node ID, and a sampling interval. Other callbacks allow you to specify e.g. the callback method, a user-defined state object, absolute deadband value, or pass in a full set of parameters using EasyUAMonitoredItemArguments object. The SubscribeDataChange and SubscribeMonitoredItem methods return a subscription handle that you can later use to change the subscription parameters, or unsubscribe.

It is common to pass in a State argument of type Object. When the monitored item’s value changes, the State argument is then passed to the DataChangeNotification event handler (or your callback method) in the EasyUADataChangeNotificationEventArgs.Arguments object. 

The State argument is typically used to provide some sort of correlation between objects in your application, and the event notifications. For example, if you are programming an HMI application and you want the event handler to update the control that displays the item’s value, you may want to set the State argument to the control object itself. When the event notification arrives, you simply update the control indicated by the State property of EasyUADataChangeNotificationEventArgs.Arguments, without having to look it up by Node Id or so. See Use the state instead of handles to identify subscribed entities.

.NET

// This example shows how to subscribe to changes of a single monitored item and display the value of the item with each
// change.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeDataChange
    {
        public static void Overload1()
        {
            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 and hook events.
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification;

            Console.WriteLine("Subscribing...");
            client.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000);

            Console.WriteLine("Processing data change events for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Display value.
            if (e.Succeeded)
                Console.WriteLine($"Value: {e.AttributeData.Value}");
            else
                Console.WriteLine($"*** Failure: {e.ErrorMessageBrief}");
        }
    }
}
# This example shows how to subscribe to changes of a single monitored item and display the value of the item with each
# change.

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

# 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

# Data change notification handler
Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { 
    # Display value.
    if ($EventArgs.Succeeded) {
        Write-Host "Value: $($EventArgs.AttributeData.Value)"
    }
    else {
        Write-Host "*** Failure: $($EventArgs.ErrorMessageBrief)"
    }
}

Write-Host "Subscribing..."
$client.SubscribeDataChange($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000)

Write-Host "Processing data change events for 20 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 20) {    
    Start-Sleep -Seconds 1
}

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."
# This example shows how to subscribe to changes of a single monitored item and display the value of the item with each
# change.

# 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 *


def dataChangeNotification(sender, e):
    # Display value.
    if e.Succeeded:
        print('Value: ', e.AttributeData.Value, sep='')
    else:
        print('*** Failure: ', e.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
IEasyUAClientExtension.SubscribeDataChange(client,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
    1000)

print('Processing data change events for 20 seconds...')
time.sleep(20)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of a single monitored item and display the value of the item with each change.

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

Namespace _EasyUAClient
    Friend Class SubscribeDataChange
        Public Shared Sub Overload1()

            ' 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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification

            Console.WriteLine("Subscribing...")
            client.SubscribeDataChange(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000)

            Console.WriteLine("Processing monitored item changed events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Display value
            If e.Succeeded Then
                Console.WriteLine("Value: {0}", e.AttributeData.Value)
            Else
                Console.WriteLine("*** Failure: {0}", e.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace

COM

// This example shows how to subscribe to changes of a single monitored item and display each change.

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

namespace _EasyUAClient
{
    // CEasyUAClientEvents

    class CEasyUAClientEvents : public IDispEventImpl<1, CEasyUAClientEvents>
    {
    public:
    BEGIN_SINK_MAP(CEasyUAClientEvents)
        // Event handlers must have the __stdcall calling convention
        SINK_ENTRY(1, DISPID_EASYUACLIENTEVENTS_DATACHANGENOTIFICATION, &CEasyUAClientEvents::DataChangeNotification)
    END_SINK_MAP()

    public:
        // The handler for EasyUAClient.DataChangeNotification event
        STDMETHOD(DataChangeNotification)(VARIANT varSender, _EasyUADataChangeNotificationEventArgs* pEventArgs)
        {
            // Display the data
            // Remark: Production code would check EventArgsPtr->Exception before accessing EventArgsPtr->AttributeData.
            _UAAttributeDataPtr AttributeDataPtr(pEventArgs->AttributeData);
            _tprintf(_T("%s\n"), (LPCTSTR)CW2CT(AttributeDataPtr->ToString));

            return S_OK;
        }
    };



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

            // Hook events
            CEasyUAClientEvents* pClientEvents = new CEasyUAClientEvents();
            AtlGetObjectSourceInterface(ClientPtr, &pClientEvents->m_libid, &pClientEvents->m_iid, 
                &pClientEvents->m_wMajorVerNum, &pClientEvents->m_wMinorVerNum);
            pClientEvents->m_iid = _uuidof(DEasyUAClientEvents);
            pClientEvents->DispEventAdvise(ClientPtr, &pClientEvents->m_iid);

            //
            _tprintf(_T("Subscribing...\n"));
            ClientPtr->SubscribeDataChange(
                //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",
                1000);

            _tprintf(_T("Processing monitored item changed events for 1 minute...\n"));
            Sleep(60*1000);

            // Unhook events
            pClientEvents->DispEventUnadvise(ClientPtr, &pClientEvents->m_iid);
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}
// This example shows how to subscribe to changes of a single monitored item
// and display each change.

type
  TClientEventHandlers = class
    procedure OnDataChangeNotification(
      Sender: TObject;
      sender0: OleVariant;
      eventArgs: _EasyUADataChangeNotificationEventArgs);
  end;

procedure TClientEventHandlers.OnDataChangeNotification(
  Sender: TObject;
  sender0: OleVariant;
  eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
  // Display the data
  // Remark: Production code would check eventArgs.Exception before accessing
  // eventArgs.AttributeData.
    WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ': ',
    eventArgs.AttributeData.ToString);
end;

class procedure SubscribeDataChange.Main;
var
  Client: EasyUAClient;
  EvsClient: TEvsEasyUAClient;
  ClientEventHandlers: TClientEventHandlers;
begin
  // Instantiate the client object and hook events
  EvsClient := TEvsEasyUAClient.Create(nil);
  Client := EvsClient.ComServer;
  ClientEventHandlers := TClientEventHandlers.Create;
  EvsClient.OnDataChangeNotification := @ClientEventHandlers.OnDataChangeNotification;

  WriteLn('Subscribing...');
  Client.SubscribeDataChange(
    //'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',
    1000);

  WriteLn('Processing data change events for 1 minute...');
  PumpSleep(60*1000);
end;
// This example shows how to subscribe to changes of a single monitored item
// and display each change.

type
  TClientEventHandlers121 = class
    procedure OnDataChangeNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUADataChangeNotificationEventArgs);
  end;

procedure TClientEventHandlers121.OnDataChangeNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
  // Display the data
  if eventArgs.Succeeded then
      WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ': ',
      eventArgs.AttributeData.ToString)
  else
      WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ' *** Failure: ',
      eventArgs.ErrorMessageBrief);
end;

class procedure SubscribeDataChange.Main;
var
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers121;
begin
  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers121.Create;
  Client.OnDataChangeNotification := ClientEventHandlers.OnDataChangeNotification;

  WriteLn('Subscribing...');
  Client.SubscribeDataChange(
      //'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',
    1000);

  WriteLn('Processing data change events for 1 minute...');
  PumpSleep(60*1000);

  WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;

  WriteLn('Waiting for 5 seconds...');
  PumpSleep(5*1000);

  WriteLn('Finished.');
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;
// This example shows how to subscribe to changes of a single monitored item and display each change.

class ClientEvents {
    function DataChangeNotification($Sender, $E)
    {
        // Display the data
        if ($E->Succeeded)
        printf("%s\n", $E->AttributeData);
        else
        printf("*** Failure : %s\n", $E->ErrorMessageBrief);
    }
}



// Instantiate the client object and hook events
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
$ClientEvents = new ClientEvents();
com_event_sink($Client, $ClientEvents, "DEasyUAClientEvents");

printf("Subscribing...\n");
$Client->SubscribeDataChange(
    //"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", 
    1000);

printf("Processing monitored item changed events for 1 minute...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 60);
Rem This example shows how to subscribe to changes of a single monitored item and display each change.

' The client object, with events
'Public WithEvents Client1 As EasyUAClient

Public Sub SubscribeDataChange_Main_Command_Click()
    OutputText = ""
    
    Set Client1 = New EasyUAClient

    OutputText = OutputText & "Subscribing..." & vbCrLf
    Call Client1.SubscribeDataChange("opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853", 1000)

    OutputText = OutputText & "Processing data changed notification events for 1 minute..." & vbCrLf
    Pause 60000

    OutputText = OutputText & "Unsubscribing..." & vbCrLf
    Client1.UnsubscribeAllMonitoredItems

    OutputText = OutputText & "Waiting for 5 seconds..." & vbCrLf
    Pause 5000

    OutputText = OutputText & "Finished." & vbCrLf
    Set Client1 = Nothing
End Sub

Public Sub Client1_DataChangeNotification(ByVal sender As Variant, ByVal eventArgs As EasyUADataChangeNotificationEventArgs)
    ' Display the data
    If eventArgs.Exception Is Nothing Then
        OutputText = OutputText & eventArgs.AttributeData & vbCrLf
    Else
        OutputText = OutputText & eventArgs.ErrorMessageBrief & vbCrLf
    End If
End Sub
Rem This example shows how to subscribe to changes of a single monitored item and display each change.

Option Explicit

' Instantiate the client object and hook events
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")
WScript.ConnectObject Client, "Client_"

WScript.Echo "Subscribing..."
Client.SubscribeDataChange "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer", "nsu=http://test.org/UA/Data/ ;i=10853", 1000

WScript.Echo "Processing monitored item changed events for 1 minute..."
WScript.Sleep 60*1000



Sub Client_DataChangeNotification(Sender, e)
    ' Display the data
    Dim display: If e.Exception Is Nothing Then display = e.AttributeData Else display = e.ErrorMessageBrief
    WScript.Echo display
End Sub

 

Multiple nodes or attributes

To subscribe to multiple items simultaneously in an efficient manner, call the SubscribeMultipleMonitoredItems method (instead of multiple SubscribeDataChange or SubscribeMonitoredItem calls in a loop). You receive back an array of subscription handles. You pass in an array of EasyUAMonitoredItemArguments objects (each containing information for a single subscription to be made), to the SubscribeMultipleMonitoredItems method.

.NET

// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
// each change.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        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 and hook events.
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification_Main1;

            Console.WriteLine("Subscribing...");
            client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                });

            Console.WriteLine("Processing monitored item changed events for 10 seconds...");
            System.Threading.Thread.Sleep(10 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification_Main1(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Display value.
            if (e.Succeeded)
                Console.WriteLine($"{e.Arguments.NodeDescriptor}: {e.AttributeData.Value}");
            else
                Console.WriteLine($"{e.Arguments.NodeDescriptor} *** Failure: {e.ErrorMessageBrief}");
        }
    }
}
# This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
# each change.

#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

# Data change notification handler
Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { 
    # Display value.
    if ($EventArgs.Succeeded) {
        Write-Host "$($EventArgs.Arguments.NodeDescriptor): $($EventArgs.AttributeData.Value)"
    }
    else {
        Write-Host "$($EventArgs.Arguments.NodeDescriptor) *** Failure: $($EventArgs.ErrorMessageBrief)"
    }
}

Write-Host "Subscribing..."
$handleArray = $client.SubscribeMultipleMonitoredItems(@(
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10845")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10853")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10855")),
        1000))
    ))

Write-Host
Write-Host "Processing monitored item changed events for 10 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 10) {    
    Start-Sleep -Seconds 1
}

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."
# This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item
# with each change.

# 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 *


def dataChangeNotification(sender, e):
    # Display value.
    if e.Succeeded:
        print(e.Arguments.NodeDescriptor, ': ', e.AttributeData.Value, sep='')
    else:
        print(e.Arguments.NodeDescriptor, ' *** Failure: ', e.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
client.SubscribeMultipleMonitoredItems([
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
        UAMonitoringParameters(1000)),
    ])

print('Processing data change events for 10 seconds...')
time.sleep(10)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
' each change.

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

Namespace _EasyUAClient
    Partial Friend Class SubscribeMultipleMonitoredItems
        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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification

            Console.WriteLine("Subscribing...")
            client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _
                { _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 1000), _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000), _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _
                } _
             )

            Console.WriteLine("Processing monitored item changed events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Display value
            If e.Succeeded Then
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value)
            Else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace

COM

// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with
// each change.

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

namespace _EasyUAClient
{
    // CEasyUAClientEvents

    class CEasyUAClientEvents : public IDispEventImpl<1, CEasyUAClientEvents>
    {
    public:
    BEGIN_SINK_MAP(CEasyUAClientEvents)
        // Event handlers must have the __stdcall calling convention
        SINK_ENTRY(1, DISPID_EASYUACLIENTEVENTS_DATACHANGENOTIFICATION, &CEasyUAClientEvents::DataChangeNotification)
    END_SINK_MAP()

    public:
        // The handler for EasyUAClient.DataChangeNotification event
        STDMETHOD(DataChangeNotification)(VARIANT varSender, _EasyUADataChangeNotificationEventArgs* pEventArgs)
        {
            // Display the data
            _tprintf(_T("%s: "), (LPCTSTR)CW2CT(pEventArgs->Arguments->NodeDescriptor->ToString));
            // Remark: Production code would check EventArgsPtr->Exception before accessing EventArgsPtr->AttributeData.
            _UAAttributeDataPtr AttributeDataPtr(pEventArgs->AttributeData);
            _tprintf(_T("%s\n"), (LPCTSTR)CW2CT(AttributeDataPtr->ToString));

            return S_OK;
        }
    };



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

            // Hook events
            CEasyUAClientEvents* pClientEvents = new CEasyUAClientEvents();
            AtlGetObjectSourceInterface(ClientPtr, &pClientEvents->m_libid, &pClientEvents->m_iid, 
                &pClientEvents->m_wMajorVerNum, &pClientEvents->m_wMinorVerNum);
            pClientEvents->m_iid = _uuidof(DEasyUAClientEvents);
            pClientEvents->DispEventAdvise(ClientPtr, &pClientEvents->m_iid);

            //
            _tprintf(_T("Subscribing...\n"));

            _UAMonitoringParametersPtr MonitoringParametersPtr(_uuidof(UAMonitoringParameters));
            MonitoringParametersPtr->SamplingInterval = 1000;

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

            _UAMonitoredItemArgumentsPtr MonitoringArguments2Ptr(_uuidof(EasyUAMonitoredItemArguments));
            MonitoringArguments2Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            MonitoringArguments2Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10853";
            MonitoringArguments2Ptr->MonitoringParameters = MonitoringParametersPtr;

            _UAMonitoredItemArgumentsPtr MonitoringArguments3Ptr(_uuidof(EasyUAMonitoredItemArguments));
            MonitoringArguments3Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            MonitoringArguments3Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10855";
            MonitoringArguments3Ptr->MonitoringParameters = MonitoringParametersPtr;

            CComSafeArray<VARIANT> arguments(3);
            arguments.SetAt(0, _variant_t((IDispatch*)MonitoringArguments1Ptr));
            arguments.SetAt(1, _variant_t((IDispatch*)MonitoringArguments2Ptr));
            arguments.SetAt(2, _variant_t((IDispatch*)MonitoringArguments3Ptr));
            CComVariant vArguments(arguments);

            CComSafeArray<VARIANT> handles;
            handles.Attach(ClientPtr->SubscribeMultipleMonitoredItems(&vArguments));

            for (int i = handles.GetLowerBound(); i <= handles.GetUpperBound(); i++)
            {
                _variant_t vString;
                vString.ChangeType(VT_BSTR, &_variant_t(handles[i]));
                _tprintf(_T("handleArray(d)s\n"), i, (LPCTSTR)CW2CT((_bstr_t)vString));
            }

            _tprintf(_T("Processing monitored item changed events for 10 seconds...\n"));
            Sleep(10*1000);

            _tprintf(_T("Unsubscribing...\n"));
            ClientPtr->UnsubscribeAllMonitoredItems();

            _tprintf(_T("Waiting for 5 seconds...\n"));
            Sleep(5*1000);

            // Unhook events
            pClientEvents->DispEventUnadvise(ClientPtr, &pClientEvents->m_iid);
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}
// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
// each change.

{
type
  TClientEventHandlers = class
    procedure OnDataChangeNotification(
      Sender: TObject;
      sender0: OleVariant;
      eventArgs: _EasyUADataChangeNotificationEventArgs);
  end;

procedure TClientEventHandlers.OnDataChangeNotification(
  Sender: TObject;
  sender0: OleVariant;
  eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
  // Display the data
  // Remark: Production code would check eventArgs.Exception before accessing
  // eventArgs.AttributeData.
    WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ': ',
    eventArgs.AttributeData.ToString);
end;
}

class procedure SubscribeMultipleMonitoredItems.Main;
var
  Arguments: OleVariant;
  EvsClient: TEvsEasyUAClient;
  Client: EasyUAClient;
  ClientEventHandlers: TClientEventHandlers;
  Handle: Cardinal;
  HandleArray: OleVariant;
  I: Cardinal;
  MonitoredItemArguments1, MonitoredItemArguments2, MonitoredItemArguments3:
    _EasyUAMonitoredItemArguments;
  MonitoringParameters: _UAMonitoringParameters;
begin
  // Instantiate the client object and hook events
  EvsClient := TEvsEasyUAClient.Create(nil);
  Client := EvsClient.ComServer;
  ClientEventHandlers := TClientEventHandlers.Create;
  EvsClient.OnDataChangeNotification := @ClientEventHandlers.OnDataChangeNotification;

  WriteLn('Subscribing...');
  MonitoringParameters := CoUAMonitoringParameters.Create;
  MonitoringParameters.SamplingInterval := 1000;
  MonitoredItemArguments1 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments1.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845';
  MonitoredItemArguments1.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments2 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments2.EndpointDescriptor.UrlString := 
      //'http://opcua.demo-this.com:51211/UA/SampleServer';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';
  MonitoredItemArguments2.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments3 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments3.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10855';
  MonitoredItemArguments3.MonitoringParameters := MonitoringParameters;
  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := MonitoredItemArguments1;
  Arguments[1] := MonitoredItemArguments2;
  Arguments[2] := MonitoredItemArguments3;

  TVarData(HandleArray).VType := varArray or varVariant;
  TVarData(HandleArray).VArray := PVarArray(
    Client.SubscribeMultipleMonitoredItems(PSafeArray(TVarData(Arguments).VArray)));

  for I := VarArrayLowBound(HandleArray, 1) to VarArrayHighBound(HandleArray, 1) do
  begin
      Handle := Cardinal(HandleArray[I]);
      WriteLn('HandleArray[', I, ']: ', Handle);
  end;

  WriteLn('Processing monitored item changed events for 10 seconds...');
  PumpSleep(10*1000);

  WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;

  WriteLn('Waiting for 5 seconds...');
  Sleep(5*1000);

  WriteLn('Finished...');
end;
// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
// each change.

type
  TClientEventHandlers123 = class
    procedure OnDataChangeNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUADataChangeNotificationEventArgs);
  end;

procedure TClientEventHandlers123.OnDataChangeNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
  // Display the data
  if eventArgs.Succeeded then
      WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ': ',
      eventArgs.AttributeData.ToString)
  else
      WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ' *** Failure: ',
      eventArgs.ErrorMessageBrief);
end;

class procedure SubscribeMultipleMonitoredItems.Main;
var
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers123;
  Handle: Cardinal;
  HandleArray: OleVariant;
  I: Cardinal;
  MonitoredItemArguments1, MonitoredItemArguments2, MonitoredItemArguments3:
    _EasyUAMonitoredItemArguments;
  MonitoringParameters: _UAMonitoringParameters;
begin
  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers123.Create;
  Client.OnDataChangeNotification := ClientEventHandlers.OnDataChangeNotification;

  WriteLn('Subscribing...');
  MonitoringParameters := CoUAMonitoringParameters.Create;
  MonitoringParameters.SamplingInterval := 1000;
  MonitoredItemArguments1 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments1.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';
  MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845';
  MonitoredItemArguments1.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments2 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments2.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';
  MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';
  MonitoredItemArguments2.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments3 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments3.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';
  MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10855';
  MonitoredItemArguments3.MonitoringParameters := MonitoringParameters;
  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := MonitoredItemArguments1;
  Arguments[1] := MonitoredItemArguments2;
  Arguments[2] := MonitoredItemArguments3;

  TVarData(HandleArray).VType := varArray or varVariant;
  TVarData(HandleArray).VArray := PVarArray(
    Client.SubscribeMultipleMonitoredItems(Arguments));

  for I := VarArrayLowBound(HandleArray, 1) to VarArrayHighBound(HandleArray, 1) do
  begin
      Handle := Cardinal(HandleArray[I]);
      WriteLn('HandleArray[', I, ']: ', Handle);
  end;

  WriteLn('Processing monitored item changed events for 10 seconds...');
  PumpSleep(10*1000);

  WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;

  WriteLn('Waiting for 5 seconds...');
  Sleep(5*1000);

  WriteLn('Finished.');
  VarClear(HandleArray);
  VarClear(Arguments);
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;
// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
// each change.

class ClientEvents {
    function DataChangeNotification($Sender, $E)
    {
        // Display the data
        if ($E->Succeeded)
            printf(" s\n", $E->Arguments->NodeDescriptor, $E->AttributeData);
        else
            printf("s *** Failures\n", $E->Arguments->NodeDescriptor, $E->ErrorMessageBrief);
    }
}



// Instantiate the client object and hook events
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
$ClientEvents = new ClientEvents();
com_event_sink($Client, $ClientEvents, "DEasyUAClientEvents");

printf("Subscribing...\n");
$MonitoringParameters = new COM("OpcLabs.EasyOpc.UA.UAMonitoringParameters");
$MonitoringParameters->SamplingInterval = 1000;
$MonitoredItemArguments1 = new COM("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments");
$MonitoredItemArguments1->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";
$MonitoredItemArguments1->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845";
$MonitoredItemArguments1->MonitoringParameters = $MonitoringParameters;
$MonitoredItemArguments2 = new COM("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments");
$MonitoredItemArguments2->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";
$MonitoredItemArguments2->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853";
$MonitoredItemArguments2->MonitoringParameters = $MonitoringParameters;
$MonitoredItemArguments3 = new COM("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments");
$MonitoredItemArguments3->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";
$MonitoredItemArguments3->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855";
$MonitoredItemArguments3->MonitoringParameters = $MonitoringParameters;
$arguments[0] = $MonitoredItemArguments1;
$arguments[1] = $MonitoredItemArguments2;
$arguments[2] = $MonitoredItemArguments3;
$handleArray = $Client->SubscribeMultipleMonitoredItems($arguments);

for ($i = 0; $i < count($handleArray); $i++)
{
    printf("handleArray[d]d\n", $i, $handleArray[$i]);
}

printf("Processing monitored item changed events for 10 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 10);

printf("Unsubscribing...\n");
$Client->UnsubscribeAllMonitoredItems;

printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);
Rem This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with
Rem each change.

' The client object, with events
'Public WithEvents Client2 As EasyUAClient

Public Sub SubscribeMultipleMonitoredItems_Main_Command_Click()
    OutputText = ""

    Set Client2 = New EasyUAClient

    OutputText = OutputText & "Subscribing..." & vbCrLf
    Dim MonitoringParameters As New UAMonitoringParameters
    MonitoringParameters.SamplingInterval = 1000
    
    Dim MonitoredItemArguments1 As New EasyUAMonitoredItemArguments
    MonitoredItemArguments1.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    MonitoredItemArguments1.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10845"
    Set MonitoredItemArguments1.MonitoringParameters = MonitoringParameters
    MonitoredItemArguments1.SetState ("Item1")
    
    Dim MonitoredItemArguments2 As New EasyUAMonitoredItemArguments
    MonitoredItemArguments2.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    MonitoredItemArguments2.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10853"
    Set MonitoredItemArguments2.MonitoringParameters = MonitoringParameters
    MonitoredItemArguments2.SetState ("Item2")
    
    Dim MonitoredItemArguments3 As New EasyUAMonitoredItemArguments
    MonitoredItemArguments3.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    MonitoredItemArguments3.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10855"
    Set MonitoredItemArguments3.MonitoringParameters = MonitoringParameters
    MonitoredItemArguments3.SetState ("Item3")
    
    Dim arguments(2) As Variant
    Set arguments(0) = MonitoredItemArguments1
    Set arguments(1) = MonitoredItemArguments2
    Set arguments(2) = MonitoredItemArguments3
    Dim handleArray As Variant
    handleArray = Client2.SubscribeMultipleMonitoredItems(arguments)

    Dim i As Long: For i = LBound(handleArray) To UBound(handleArray)
        OutputText = OutputText & "handleArray(" & i & "): " & handleArray(i) & vbCrLf
    Next

    OutputText = OutputText & "Processing monitored item changed events for 10 seconds..." & vbCrLf
    Pause 10000

    OutputText = OutputText & "Unsubscribing..." & vbCrLf
    Call Client2.UnsubscribeAllMonitoredItems

    OutputText = OutputText & "Waiting for 5 seconds..." & vbCrLf
    Pause 5000

    Set Client2 = Nothing
    OutputText = OutputText & "Finished." & vbCrLf
End Sub

Public Sub Client2_DataChangeNotification(ByVal sender As Variant, ByVal eventArgs As EasyUADataChangeNotificationEventArgs)
    ' Display the data
    If eventArgs.Exception Is Nothing Then
        OutputText = OutputText & "[" & eventArgs.arguments.State & "] " & eventArgs.arguments.nodeDescriptor & ": " & eventArgs.AttributeData & vbCrLf
    Else
        OutputText = OutputText & "[" & eventArgs.arguments.State & "] " & eventArgs.arguments.nodeDescriptor & ": " & eventArgs.ErrorMessageBrief & vbCrLf
    End If
End Sub
Rem This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
Rem each change.

Option Explicit

' Instantiate the client object and hook events
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")
WScript.ConnectObject Client, "Client_"

WScript.Echo "Subscribing..."
Dim MonitoringParameters: Set MonitoringParameters = CreateObject("OpcLabs.EasyOpc.UA.UAMonitoringParameters")
MonitoringParameters.SamplingInterval = 1000
Dim MonitoredItemArguments1: Set MonitoredItemArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments")
MonitoredItemArguments1.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845"
MonitoredItemArguments1.MonitoringParameters = MonitoringParameters
Dim MonitoredItemArguments2: Set MonitoredItemArguments2 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments")
MonitoredItemArguments2.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"
MonitoredItemArguments2.MonitoringParameters = MonitoringParameters
Dim MonitoredItemArguments3: Set MonitoredItemArguments3 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments")
MonitoredItemArguments3.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855"
MonitoredItemArguments3.MonitoringParameters = MonitoringParameters
Dim arguments(2)
Set arguments(0) = MonitoredItemArguments1
Set arguments(1) = MonitoredItemArguments2
Set arguments(2) = MonitoredItemArguments3
Dim handleArray: handleArray = Client.SubscribeMultipleMonitoredItems(arguments)

Dim i: For i = LBound(handleArray) To UBound(handleArray)
    WScript.Echo "handleArray(" & i & "): " & handleArray(i)
Next

WScript.Echo "Processing monitored item changed events for 10 seconds..."
WScript.Sleep 10 * 1000

WScript.Echo "Unsubscribing..."
Client.UnsubscribeAllMonitoredItems

WScript.Echo "Waiting for 5 seconds..."
WScript.Sleep 5 * 1000



Sub Client_DataChangeNotification(Sender, e)
    ' Display the data
    Dim display: If e.Exception Is Nothing Then display = e.AttributeData Else display = e.ErrorMessageBrief
    WScript.Echo e.Arguments.NodeDescriptor & ":" & display
End Sub

 

// This example shows how to subscribe to changes of all data variables under a specified object in OPC UA address space.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        public static void AllInObject()
        {
            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 and hook events
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification_AllInObject;

            // Obtain variables under "Scalar" node
            Console.WriteLine("Browsing...");
            UANodeElementCollection nodeElementCollection;
            try
            {
                nodeElementCollection = client.BrowseDataVariables(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;ns=2;i=10787");
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Create array with monitored item arguments
            EasyUAMonitoredItemArguments[] monitoredItemArgumentsArray = nodeElementCollection
                .Select(element => new EasyUAMonitoredItemArguments(null, endpointDescriptor, element))
                .ToArray();

            Console.WriteLine("Subscribing...");
            client.SubscribeMultipleMonitoredItems(monitoredItemArgumentsArray);

            Console.WriteLine("Processing monitored item changed events for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);
        }

        static void client_DataChangeNotification_AllInObject(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Display value
            if (e.Succeeded)
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value);
            else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief);
        }
    }
}
# This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item
# with each change.

# 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 *


def dataChangeNotification(sender, e):
    # Display value.
    if e.Succeeded:
        print(e.Arguments.NodeDescriptor, ': ', e.AttributeData.Value, sep='')
    else:
        print(e.Arguments.NodeDescriptor, ' *** Failure: ', e.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

# Obtain variables under "Scalar" node.
print('Browsing...')
try:
    nodeElementCollection = IEasyUAClientExtension.BrowseDataVariables(client,
        endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;ns=2;i=10787'))
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Create array with monitored item arguments.
monitoredItemArgumentsArray = list(map(
    lambda element: EasyUAMonitoredItemArguments(None, endpointDescriptor, element.ToUANodeDescriptor()),
    nodeElementCollection))

print('Subscribing...')
client.SubscribeMultipleMonitoredItems(monitoredItemArgumentsArray)

print('Processing data change events for 20 seconds...')
time.sleep(20)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of all data variables under a specified object in OPC UA address space.

Imports System.Linq
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace _EasyUAClient
    Partial Friend Class SubscribeMultipleMonitoredItems
        Public Shared Sub AllInObject()

            ' 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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification_AllInObject

            ' Obtain variables under "Scalar" node
            Console.WriteLine("Subscribing...")
            Dim nodeElementCollection As UANodeElementCollection
            Try
                nodeElementCollection = client.BrowseDataVariables(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;ns=2;i=10787")
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Create array with monitored item arguments

            Dim monitoredItemArgumentsArray() As EasyUAMonitoredItemArguments = nodeElementCollection.Select(Function(element) New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, element)).ToArray()

            Console.WriteLine("Subscribing...")
            client.SubscribeMultipleMonitoredItems(monitoredItemArgumentsArray)

            Console.WriteLine("Processing monitored item changed events for 20 seconds...")
            Threading.Thread.Sleep(20 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification_AllInObject(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Display value
            If e.Succeeded Then
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value)
            Else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace

 

// This example shows how to store current state of the subscribed monitored items in a dictionary.
// each change.

using System;
using System.Collections.Generic;
using System.Threading;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        public static void StoreInDictionary()
        {
            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 and hook events.
            using (var client = new EasyUAClient())
            {
                client.DataChangeNotification += client_DataChangeNotification_StoreInDictionary;

                Console.WriteLine("Subscribing...");
                client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor,
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor,
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor,
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                });

                Console.WriteLine("Processing monitored item changed events for 1 minute...");
                int startTickCount = Environment.TickCount;
                do
                {
                    Thread.Sleep(5 * 1000);

                    // Each 5 seconds, display the current state of the monitored items we have subscribed to.
                    lock (_serialize)
                    {
                        Console.WriteLine();
                        foreach (KeyValuePair<UANodeDescriptor, UAAttributeDataResult> pair in _attributeDataResultDictionary)
                        {
                            UANodeDescriptor nodeDescriptor = pair.Key;
                            UAAttributeDataResult attributeDataResult = pair.Value;
                            Console.WriteLine($"{nodeDescriptor}: {attributeDataResult}");
                        }

                        // The code above shows how you can process the complete contents of the dictionary. In other
                        // scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
                        // by indexing the dictionary by the node descriptor of the monitored item you are interested in.
                    }
                } while (Environment.TickCount < startTickCount + 60 * 1000);

                Console.WriteLine("Unsubscribing...");
            }

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification_StoreInDictionary(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            lock (_serialize)
                // Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
                // key which is the node descriptor of the monitored item this data change notification is for.
                _attributeDataResultDictionary[e.Arguments.NodeDescriptor] = (UAAttributeDataResult)e;
        }

        // Holds last known state of each subscribed monitored item.
        private static readonly Dictionary<UANodeDescriptor, UAAttributeDataResult> _attributeDataResultDictionary =
            new Dictionary<UANodeDescriptor, UAAttributeDataResult>();

        // Synchronization object used to prevent simultaneous access to the dictionary.
        private static readonly object _serialize = new object();
    }
}
# This example shows how to store current state of the subscribed monitored items in a dictionary.
# each change.

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

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


lock = threading.Lock()
attributeDataResultDictionary = {}

# Data change notification event handler.
def dataChangeNotification(sender, eventArgs):
    global lock
    global attributeDataResultDictionary
    with lock:
        # Convert the event arguments to a UAAttributeData result object, and store it in the dictionary under the
        # key which is the node descriptor of the monitored item this data change notification is for.
        attributeDataResultDictionary[eventArgs.Arguments.NodeDescriptor] = EasyUADataChangeNotificationEventArgs.ToUAAttributeDataResult(eventArgs)


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()
# Hook events.
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
client.SubscribeMultipleMonitoredItems([
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
        UAMonitoringParameters(1000)),
    ])

print('Processing data change events for 1 minute...')
endTime = time.time() + 60
while time.time() < endTime:
    time.sleep(5)
    #
    # Each 5 seconds, display the current state of the monitored items we have subscribed to.
    with lock:
        print()
        print('Current state of the monitored items:')
        for nodeDescriptor, attributeDataResult in attributeDataResultDictionary.items():
            print(nodeDescriptor, ': ', attributeDataResult, sep='')
        #
        # The code above shows how you can process the complete contents of the dictionary. In other
        # scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
        # by indexing the dictionary by the node descriptor of the monitored item you are interested in.

print()
print('Unsubscribing all monitored items...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')

 

Common considerations

If you are only interested in certain kinds of changes in the monitored item, or need to reduce the amount of incoming notifications by specifying a deadband, use OPC UA Data Change Filter.

Note: It is NOT an error to subscribe to the same item twice (or more times), even with precisely same parameters. You will receive separate subscription handles, and with regard to your application, this situation will look no different from subscribing to different items. Internally, however, the subscription made to the OPC server might be optimized (merged together), depending on other parameters and circumstances.

Differences between various OPC UA subscription methods

OPC UA has one underlying mechanism for subscriptions, and the mechanism is further differentiated by the arguments used and the types of notifications generated. The general subscription mechanism refers to "monitored items", and in the current OPC UA version, the monitored item can represent two types of subscriptions: a subscription to either data changes, or events. The distinction is made by the type of filter specified with the subscription (in its monitoring parameters): It is either a data change filter, or an event filter. Depending on which type of subscription (filter) the monitored item uses, either data change notifications, or event notifications, are generated by the subscription.

Subscription methods that have "MonitoredItem" in their name are the most general ones. They allow you to create either data change or event subscriptions, depending on the data you pass in.

Subscription methods that have "DataChange" in their name are designed to create data change subscriptions only. Because of this specialization, they can have simplified set of arguments that makes most sense with data change subscriptions. These methods, however, do not do anything new as far as OPC UA subscriptions go: They just call the SubscribeMultipleMonitoredItems method internally, creating the generalized input arguments for it as needed.

Subscription methods that have "Event" in their name are designed to create event subscriptions only. Because of this specialization, they can have simplified set of arguments that makes most sense with event subscriptions. These methods, however, also do not do anything new as far as OPC UA subscriptions go: They just call the SubscribeMultipleMonitoredItems method internally, creating the generalized input arguments for it as needed.

You can use the more specialized methods if they provide the functionality you need, and give shorter code. In some cases, the more advanced functionality might be missing from the specialized methods, and in that case you should use the generalized methods and assemble the input arguments yourself.

More examples

The example below logs OPC Unified Architecture data changes into an XML file.

The main program:

// Logs OPC Unified Architecture data changes into an XML file.

using System;
using System.Diagnostics;
using System.Xml;
using System.Xml.Serialization;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UAXmlLogger
{
    class Program
    {
        static void Main()
        {
            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/"

            Console.WriteLine("Starting up...");
            var xmlSerializer = new XmlSerializer(typeof(EasyUADataChangeNotificationEventArgs));
            var xmlWriter = XmlWriter.Create("UAData.xml", new XmlWriterSettings
            {
                Indent = true,
                CloseOutput = true
            });
            // The root element can have any name you need, but the name below also allows reading the log back as .NET array
            xmlWriter.WriteStartElement("ArrayOfEasyUADataChangeNotificationEventArgs");

            Console.WriteLine("Logging data for 30 seconds...");
            int handle = EasyUAClient.SharedInstance.SubscribeDataChange(endpointDescriptor, 
                "nsu=http://test.org/UA/Data/ ;i=10853", 
                samplingInterval:100,
               (_, eventArgs) =>
               {
                   Debug.Assert(!(eventArgs is null));
                   Console.Write(".");
                   xmlSerializer.Serialize(xmlWriter, eventArgs);
               });
            System.Threading.Thread.Sleep(30 * 1000);

            Console.WriteLine();
            Console.WriteLine("Shutting down...");
            EasyUAClient.SharedInstance.UnsubscribeMonitoredItem(handle);
            xmlWriter.WriteEndElement();    // not really necessary - XmlWriter would write the end tag for us anyway
            xmlWriter.Close();

            Console.WriteLine("Finished.");
        }
    }
}

 

 

 

Example

.NET

.NET

COM

.NET

.NET

COM

.NET

.NET

// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
// each change.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        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 and hook events.
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification_Main1;

            Console.WriteLine("Subscribing...");
            client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                });

            Console.WriteLine("Processing monitored item changed events for 10 seconds...");
            System.Threading.Thread.Sleep(10 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification_Main1(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Display value.
            if (e.Succeeded)
                Console.WriteLine($"{e.Arguments.NodeDescriptor}: {e.AttributeData.Value}");
            else
                Console.WriteLine($"{e.Arguments.NodeDescriptor} *** Failure: {e.ErrorMessageBrief}");
        }
    }
}
# This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
# each change.

#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

# Data change notification handler
Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { 
    # Display value.
    if ($EventArgs.Succeeded) {
        Write-Host "$($EventArgs.Arguments.NodeDescriptor): $($EventArgs.AttributeData.Value)"
    }
    else {
        Write-Host "$($EventArgs.Arguments.NodeDescriptor) *** Failure: $($EventArgs.ErrorMessageBrief)"
    }
}

Write-Host "Subscribing..."
$handleArray = $client.SubscribeMultipleMonitoredItems(@(
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10845")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10853")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10855")),
        1000))
    ))

Write-Host
Write-Host "Processing monitored item changed events for 10 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 10) {    
    Start-Sleep -Seconds 1
}

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."
# This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item
# with each change.

# 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 *


def dataChangeNotification(sender, e):
    # Display value.
    if e.Succeeded:
        print(e.Arguments.NodeDescriptor, ': ', e.AttributeData.Value, sep='')
    else:
        print(e.Arguments.NodeDescriptor, ' *** Failure: ', e.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
client.SubscribeMultipleMonitoredItems([
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        endpointDescriptor,
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
        UAMonitoringParameters(1000)),
    ])

print('Processing data change events for 10 seconds...')
time.sleep(10)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
' each change.

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

Namespace _EasyUAClient
    Partial Friend Class SubscribeMultipleMonitoredItems
        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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification

            Console.WriteLine("Subscribing...")
            client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _
                { _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 1000), _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000), _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _
                } _
             )

            Console.WriteLine("Processing monitored item changed events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Display value
            If e.Succeeded Then
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value)
            Else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace
// This example shows how to obtain parameters of certain monitored item subscription.

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

namespace UADocExamples._EasyUAClient
{
    class GetMonitoredItemArguments
    {
        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 and hook events.
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification;

            Console.WriteLine("Subscribing...");
            int[] handleArray = client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                });

            Console.WriteLine("Getting monitored item arguments...");
            EasyUAMonitoredItemArguments monitoredItemArguments =
                client.GetMonitoredItemArguments(handleArray[2]);
            Console.WriteLine($"NodeDescriptor: {monitoredItemArguments.NodeDescriptor}");
            Console.WriteLine($"SamplingInterval: {monitoredItemArguments.MonitoringParameters.SamplingInterval}");
            Console.WriteLine($"PublishingInterval: {monitoredItemArguments.SubscriptionParameters.PublishingInterval}");

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Your code would do the processing here.
        }


        // Example output:
        //
        //Subscribing...
        //Getting monitored item arguments...
        //NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10855"
        //SamplingInterval: 1000
        //PublishingInterval: 0
        //Waiting for 5 seconds...
        //Unsubscribing...
        //Waiting for 5 seconds...
        //Finished.

    }
}
# This example shows how to obtain parameters of certain monitored item subscription.

#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

# Data change notification handler
Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { 
    # Your code would do the processing here.
}

Write-Host "Subscribing..."
$handleArray = $client.SubscribeMultipleMonitoredItems(@(
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10845")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10853")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10855")),
        1000))
    ))

Write-Host "Getting monitored item arguments..."
$monitoredItemArguments = $client.GetMonitoredItemArguments($handleArray[2])
Write-Host "NodeDescriptor: $($monitoredItemArguments.NodeDescriptor)"
Write-Host "SamplingInterval: $($monitoredItemArguments.MonitoringParameters.SamplingInterval)"
Write-Host "PublishingInterval: $($monitoredItemArguments.SubscriptionParameters.PublishingInterval)"

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."


# Example output:
#
#Subscribing...
#Getting monitored item arguments...
#NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10855"
#SamplingInterval: 1000
#PublishingInterval: 0
#Waiting for 5 seconds...
#Unsubscribing...
#Waiting for 5 seconds...
#Finished.
# This example shows how to obtain parameters of certain monitored item subscription.

# 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 *


def dataChangeNotification(sender, e):
    # Your code would do the processing here.
    pass


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
handleArray = client.SubscribeMultipleMonitoredItems([
    EasyUAMonitoredItemArguments(
        None,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
        UAMonitoringParameters(1000)),
    ])

print('Getting monitored item arguments...')
monitoredItemArguments = client.GetMonitoredItemArguments(handleArray[2])
print('NodeDescriptor: ', monitoredItemArguments.NodeDescriptor, sep='')
print('SamplingInterval: ', monitoredItemArguments.MonitoringParameters.SamplingInterval, sep='')
print('PublishingInterval: ', monitoredItemArguments.SubscriptionParameters.PublishingInterval, sep='')

print('Waiting for 5 seconds...')
time.sleep(5)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to obtain parameters of certain monitored item subscription.

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

Namespace _EasyUAClient
    Friend Class GetMonitoredItemArguments
        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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification

            Console.WriteLine("Subscribing...")
            Dim handleArray() As Integer = client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _
               { _
                   New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 1000), _
                   New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000), _
                   New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _
               } _
            )

            Console.WriteLine("Getting monitored item arguments...")
            Dim monitoredItemArguments As EasyUAMonitoredItemArguments = client.GetMonitoredItemArguments(handleArray(2))
            Console.WriteLine("NodeDescriptor: {0}", monitoredItemArguments.NodeDescriptor)
            Console.WriteLine("SamplingInterval: {0}", monitoredItemArguments.MonitoringParameters.SamplingInterval)
            Console.WriteLine("PublishingInterval: {0}", monitoredItemArguments.SubscriptionParameters.PublishingInterval)

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Your code would do the processing here
        End Sub
    End Class
End Namespace
// This example shows how to obtain parameters of certain monitored item subscription.

type
  TClientEventHandlers115 = class
    procedure Client_DataChangeNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUADataChangeNotificationEventArgs);
  end;

procedure TClientEventHandlers115.Client_DataChangeNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
  // Your code would do the processing here
end;

class procedure GetMonitoredItemArguments.Main;
var
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers115;
  HandleArray: OleVariant;
  MonitoredItemArguments1, MonitoredItemArguments2, MonitoredItemArguments3:
    _EasyUAMonitoredItemArguments;
  MonitoredItemArguments: _EasyUAMonitoredItemArguments;
begin
  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers115.Create;
  Client.OnDataChangeNotification := ClientEventHandlers.Client_DataChangeNotification;

  WriteLn('Subscribing...');
  MonitoredItemArguments1 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments1.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';
  MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845';
  MonitoredItemArguments2 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments2.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';
  MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';
  MonitoredItemArguments3 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments3.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';
  MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10855';

  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := MonitoredItemArguments1;
  Arguments[1] := MonitoredItemArguments2;
  Arguments[2] := MonitoredItemArguments3;

  TVarData(HandleArray).VType := varArray or varVariant;
  TVarData(HandleArray).VArray := PVarArray(
    Client.SubscribeMultipleMonitoredItems(Arguments));

  WriteLn('Getting monitored item arguments...');
  MonitoredItemArguments := Client.GetMonitoredItemArguments(HandleArray[2]);

  WriteLn('NodeDescriptor: ', MonitoredItemArguments.NodeDescriptor.ToString);
  WriteLn('SamplingInterval: ', MonitoredItemArguments.MonitoringParameters.ToString);
  WriteLn('PublishingInterval: ', MonitoredItemArguments.SubscriptionParameters.ToString);

  WriteLn('Waiting for 5 seconds...');
  PumpSleep(5*1000);

  WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;

  WriteLn('Waiting for 5 seconds...');
  Sleep(5*1000);

  WriteLn('Finished.');
  
  VarClear(HandleArray);
  VarClear(Arguments);
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;
// This example shows how to obtain dictionary of parameters of all monitored item subscriptions.

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

namespace UADocExamples._EasyUAClient
{
    class GetMonitoredItemArgumentsDictionary
    {
        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 and hook events.
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification;

            Console.WriteLine("Subscribing...");
            client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000),
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                });

            Console.WriteLine("Getting monitored item arguments dictionary...");
            EasyUAMonitoredItemArgumentsDictionary monitoredItemArgumentsDictionary =
                client.GetMonitoredItemArgumentsDictionary();

            foreach (EasyUAMonitoredItemArguments monitoredItemArguments in monitoredItemArgumentsDictionary.Values)
            {
                Console.WriteLine();
                Console.WriteLine($"NodeDescriptor: {monitoredItemArguments.NodeDescriptor}");
                Console.WriteLine($"SamplingInterval: {monitoredItemArguments.MonitoringParameters.SamplingInterval}");
                Console.WriteLine($"PublishingInterval: {monitoredItemArguments.SubscriptionParameters.PublishingInterval}");
            }

            Console.WriteLine();
            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void client_DataChangeNotification(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Your code would do the processing here.
        }


        // Example output:
        //
        //Subscribing...
        //Getting monitored item arguments dictionary...
        //
        //NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10845"
        //SamplingInterval: 1000
        //PublishingInterval: 0
        //
        //NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10853"
        //SamplingInterval: 1000
        //PublishingInterval: 0
        //
        //NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10855"
        //SamplingInterval: 1000
        //PublishingInterval: 0
        //
        //Waiting for 5 seconds...
        //Unsubscribing...
        //Waiting for 5 seconds...
        //Finished.
    }
}
# This example shows how to obtain dictionary of parameters of all monitored item subscriptions.

#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

# Data change notification handler
Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { 
    # Your code would do the processing here.
}

Write-Host "Subscribing..."
$handleArray = $client.SubscribeMultipleMonitoredItems(@(
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10845")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10853")), 
        1000)),
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10855")),
        1000))
    ))

Write-Host "Getting monitored item arguments dictionary..."
$monitoredItemArgumentsDictionary = $client.GetMonitoredItemArgumentsDictionary()

foreach ($monitoredItemArguments in $monitoredItemArgumentsDictionary.Values) {
    Write-Host
    Write-Host "NodeDescriptor: $($monitoredItemArguments.NodeDescriptor)"
    Write-Host "SamplingInterval: $($monitoredItemArguments.MonitoringParameters.SamplingInterval)"
    Write-Host "PublishingInterval: $($monitoredItemArguments.SubscriptionParameters.PublishingInterval)"
}

Write-Host
Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."


# Example output:
#
#Subscribing...
#Getting monitored item arguments dictionary...
#
#NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10845"
#SamplingInterval: 1000
#PublishingInterval: 0
#
#NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10853"
#SamplingInterval: 1000
#PublishingInterval: 0
#
#NodeDescriptor: NodeId="nsu=http://test.org/UA/Data/ ;i=10855"
#SamplingInterval: 1000
#PublishingInterval: 0
#
#Waiting for 5 seconds...
#Unsubscribing...
#Waiting for 5 seconds...
#Finished.
# This example shows how to obtain dictionary of parameters of all monitored item subscriptions.

# 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 *


def dataChangeNotification(sender, e):
    # Your code would do the processing here.
    pass


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
handleArray = client.SubscribeMultipleMonitoredItems([
    EasyUAMonitoredItemArguments(
        None,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
        UAMonitoringParameters(1000)),
    EasyUAMonitoredItemArguments(
        None,
        UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
        UAMonitoringParameters(1000)),
    ])

print('Getting monitored item arguments dictionary...')
monitoredItemArgumentsDictionary = client.GetMonitoredItemArgumentsDictionary()

for monitoredItemArguments in monitoredItemArgumentsDictionary.Values:
    print()
    print('NodeDescriptor: ', monitoredItemArguments.NodeDescriptor, sep='')
    print('SamplingInterval: ', monitoredItemArguments.MonitoringParameters.SamplingInterval, sep='')
    print('PublishingInterval: ', monitoredItemArguments.SubscriptionParameters.PublishingInterval, sep='')

print()
print('Waiting for 5 seconds...')
time.sleep(5)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to obtain dictionary of parameters of all monitored item subscriptions.

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

Namespace _EasyUAClient
    Friend Class GetMonitoredItemArgumentsDictionary
        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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification

            Console.WriteLine("Subscribing...")
            client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _
                { _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845", 1000), _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853", 1000), _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _
                } _
             )

            Console.WriteLine("Getting monitored item arguments dictionary...")
            Dim monitoredItemArgumentsDictionary As EasyUAMonitoredItemArgumentsDictionary = _
                    client.GetMonitoredItemArgumentsDictionary()

            For Each monitoredItemArguments As EasyUAMonitoredItemArguments In monitoredItemArgumentsDictionary.Values
                Console.WriteLine()
                Console.WriteLine("NodeDescriptor: {0}", monitoredItemArguments.NodeDescriptor)
                Console.WriteLine("SamplingInterval: {0}", monitoredItemArguments.MonitoringParameters.SamplingInterval)
                Console.WriteLine("PublishingInterval: {0}", monitoredItemArguments.SubscriptionParameters.PublishingInterval)
            Next monitoredItemArguments

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Your code would do the processing here
        End Sub
    End Class
End Namespace
// This example shows how to subscribe to changes of multiple monitored items
// and display each change, identifying the different subscriptions by an
// integer.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        public static void StateAsInteger()
        {
            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 and hook events.
            var client = new EasyUAClient();
            client.DataChangeNotification += ClientOnDataChangeNotification_StateAsInteger;

            Console.WriteLine("Subscribing...");
            int[] handleArray = client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000)
                        {State = 1},    // An integer we have chosen to identify the subscription
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000)
                        {State = 2},    // An integer we have chosen to identify the subscription
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                        {State = 3}     // An integer we have chosen to identify the subscription
                });

            for (int i = 0; i < handleArray.Length; i++)
                Console.WriteLine($"handleArray[{i}]: {handleArray[i]}");

            Console.WriteLine("Processing monitored item changed events for 10 seconds...");
            Thread.Sleep(10 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void ClientOnDataChangeNotification_StateAsInteger(object sender, EasyUADataChangeNotificationEventArgs eventArgs)
        {
            // Obtain the integer state we have passed in.
            var stateAsInteger = (int) eventArgs.Arguments.State;

            // Display the data.
            if (eventArgs.Succeeded)
                Console.WriteLine($"{stateAsInteger}: {eventArgs.AttributeData}");
            else
                Console.WriteLine($"{stateAsInteger} *** Failure: {eventArgs.ErrorMessageBrief}");
        }
    }
}
# This example shows how to subscribe to changes of multiple monitored items
# and display each change, identifying the different subscriptions by an
# integer.

#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

# Data change notification handler
Register-ObjectEvent -InputObject $client -EventName DataChangeNotification -Action { 
    # Obtain the integer state we have passed in.
    [int]$stateAsInteger = $EventArgs.Arguments.State

    # Display the data.
    if ($EventArgs.Succeeded) {
        Write-Host "$($stateAsinteger): $($EventArgs.AttributeData)"
    }
    else {
        Write-Host "$($stateAsinteger) *** Failure: $($EventArgs.ErrorMessageBrief)"
    }
}

Write-Host "Subscribing..."
$handleArray = $client.SubscribeMultipleMonitoredItems(@(
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10845")), 
        1000) -Property @{State = 1}), # An integer we have chosen to identify the subscription
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10853")), 
        1000) -Property @{State = 2}), # An integer we have chosen to identify the subscription
    (New-Object UAMonitoredItemArguments(
        (New-Object UAAttributeArguments($endpointDescriptor, [UANodeDescriptor]"nsu=http://test.org/UA/Data/ ;i=10855")),
        1000) -Property @{State = 3}) # An integer we have chosen to identify the subscription
    ))

for ($i = 0; $i -lt $handleArray.Length; $i++) {
    Write-Host "handleArray[$($i)]: $($handleArray[$i])"
}

Write-Host
Write-Host "Processing monitored item changed events for 10 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 10) {    
    Start-Sleep -Seconds 1
}

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."
# This example shows how to subscribe to changes of multiple monitored items
# and display each change, identifying the different subscriptions by an
# integer.

# 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 *


def dataChangeNotification(sender, eventArgs):
    # Obtain the integer state we have passed in.
    stateAsInteger = int(eventArgs.Arguments.State)
    # Display value.
    if eventArgs.Succeeded:
        print(stateAsInteger, ': ', eventArgs.AttributeData.Value, sep='')
    else:
        print(stateAsInteger, ' *** Failure: ', eventArgs.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
monitoredItemArguments1 = EasyUAMonitoredItemArguments(
    None,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
    UAMonitoringParameters(1000))
monitoredItemArguments1.State = 1   # an integer we have chosen to identify the subscription
monitoredItemArguments2 = EasyUAMonitoredItemArguments(
    None,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
    UAMonitoringParameters(1000))
monitoredItemArguments2.State = 2   # an integer we have chosen to identify the subscription
monitoredItemArguments3 = EasyUAMonitoredItemArguments(
    None,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
    UAMonitoringParameters(1000))
monitoredItemArguments3.State = 3   # an integer we have chosen to identify the subscription

client.SubscribeMultipleMonitoredItems([
    monitoredItemArguments1,
    monitoredItemArguments2,
    monitoredItemArguments3,
    ])

print('Processing data change events for 10 seconds...')
time.sleep(10)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of multiple monitored items
' and display each change, identifying the different subscriptions by an
' integer.

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

Namespace _EasyUAClient
    Partial Friend Class SubscribeMultipleMonitoredItems
        Public Shared Sub StateAsInteger()

            ' 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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf ClientOnDataChangeNotification_StateAsInteger

            Console.WriteLine("Subscribing...")
            Dim handleArray() As Integer = client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _
                { _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000) _
                         With {.State = 1}, _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000) _
                         With {.State = 2}, _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _
                        With {.State = 3} _
                } _
             ) ' An integer we have chosen to identify the subscription

            For i As Integer = 0 To handleArray.Length - 1
                Console.WriteLine("handleArray[{0}]: {1}", i, handleArray(i))
            Next i

            Console.WriteLine("Processing monitored item changed events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Finished.")
        End Sub

        Private Shared Sub ClientOnDataChangeNotification_StateAsInteger(ByVal sender As Object, ByVal eventArgs As EasyUADataChangeNotificationEventArgs)
            ' Obtain the integer state we have passed in.
            Dim stateAsInteger As Integer = CInt(eventArgs.Arguments.State)

            ' Display the data
            If eventArgs.Succeeded Then
                Console.WriteLine("{0}: {1}", stateAsInteger, eventArgs.AttributeData)
            Else
                Console.WriteLine("{0} *** Failure: {1}", stateAsInteger, eventArgs.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace
Rem This example shows how to subscribe to changes of multiple monitored items
Rem and display each change, identifying the different subscriptions by an
Rem integer.

' The client object, with events
'Public WithEvents Client6 As EasyUAClient

Public Sub SubscribeMultipleMonitoredItems_StateAsInteger_Command_Click()
    OutputText = ""

    Set Client6 = New EasyUAClient

    OutputText = OutputText & "Subscribing..." & vbCrLf
    Dim MonitoringParameters As New UAMonitoringParameters
    MonitoringParameters.SamplingInterval = 1000
    
    Dim MonitoredItemArguments1 As New EasyUAMonitoredItemArguments
    MonitoredItemArguments1.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    MonitoredItemArguments1.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10845"
    Set MonitoredItemArguments1.MonitoringParameters = MonitoringParameters
    MonitoredItemArguments1.SetState 1 ' An integer we have chosen to identify the subscription
    
    Dim MonitoredItemArguments2 As New EasyUAMonitoredItemArguments
    MonitoredItemArguments2.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    MonitoredItemArguments2.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10853"
    Set MonitoredItemArguments2.MonitoringParameters = MonitoringParameters
    MonitoredItemArguments2.SetState 2 ' An integer we have chosen to identify the subscription
    
    Dim MonitoredItemArguments3 As New EasyUAMonitoredItemArguments
    MonitoredItemArguments3.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    MonitoredItemArguments3.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10855"
    Set MonitoredItemArguments3.MonitoringParameters = MonitoringParameters
    MonitoredItemArguments3.SetState 3 ' An integer we have chosen to identify the subscription
    
    Dim arguments(2) As Variant
    Set arguments(0) = MonitoredItemArguments1
    Set arguments(1) = MonitoredItemArguments2
    Set arguments(2) = MonitoredItemArguments3
    Dim handleArray As Variant
    handleArray = Client6.SubscribeMultipleMonitoredItems(arguments)

    Dim i As Long: For i = LBound(handleArray) To UBound(handleArray)
        OutputText = OutputText & "handleArray(" & i & "): " & handleArray(i) & vbCrLf
    Next

    OutputText = OutputText & "Processing monitored item changed events for 10 seconds..." & vbCrLf
    Pause 10000

    OutputText = OutputText & "Unsubscribing..." & vbCrLf
    Call Client6.UnsubscribeAllMonitoredItems

    OutputText = OutputText & "Waiting for 5 seconds..." & vbCrLf
    Pause 5000

    Set Client2 = Nothing
    OutputText = OutputText & "Finished." & vbCrLf
End Sub

Public Sub Client6_DataChangeNotification(ByVal sender As Variant, ByVal eventArgs As EasyUADataChangeNotificationEventArgs)
    ' Obtain the integer state we have passed in.
    Dim stateAsInteger As Integer: stateAsInteger = eventArgs.arguments.State
    If eventArgs.Succeeded Then
        OutputText = OutputText & stateAsInteger & ": " & eventArgs.AttributeData & vbCrLf
    Else
        OutputText = OutputText & stateAsInteger & " *** Failure: " & eventArgs.ErrorMessageBrief & vbCrLf
    End If
End Sub
// This example shows how to subscribe to changes of multiple monitored items
// and display each change, identifying the different subscriptions by an
// object.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        class CustomObject
        {
            public CustomObject(string name)
            {
                Name = name;
            }

            public string Name { get; }
        }
        

        public static void StateAsObject()
        {
            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 and hook events
            var client = new EasyUAClient();
            client.DataChangeNotification += ClientOnDataChangeNotification_StateAsObject;

            Console.WriteLine("Subscribing...");
            int[] handleArray = client.SubscribeMultipleMonitoredItems(new[]
                {
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000)
                        {State = new CustomObject("First")},    // A custom object that corresponds to the subscription
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000)
                        {State = new CustomObject("Second")},    // A custom object that corresponds to the subscription
                    new EasyUAMonitoredItemArguments(null, endpointDescriptor, 
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000)
                        {State = new CustomObject("Third")},    // A custom object that corresponds to the subscription
                });

            for (int i = 0; i < handleArray.Length; i++)
                Console.WriteLine($"handleArray[{i}]: {handleArray[i]}");

            Console.WriteLine("Processing monitored item changed events for 10 seconds...");
            Thread.Sleep(10 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }

        static void ClientOnDataChangeNotification_StateAsObject(object sender, EasyUADataChangeNotificationEventArgs eventArgs)
        {
            // Obtain the custom object we have passed in.
            var stateAsObject = (CustomObject) eventArgs.Arguments.State;

            // Display the data
            if (eventArgs.Succeeded)
                Console.WriteLine($"{stateAsObject.Name}: {eventArgs.AttributeData}");
            else
                Console.WriteLine($"{stateAsObject.Name} *** Failure: {eventArgs.ErrorMessageBrief}");
        }
    }
}
# This example shows how to subscribe to changes of multiple monitored items
# and display each change, identifying the different subscriptions by an
# object.

# 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 *


class CustomObject(object):
    def __init__(self, name):
        self.name = name


def dataChangeNotification(sender, eventArgs):
    # Obtain the custom object we have passed in.
    stateAsObject = eventArgs.Arguments.State
    # Display value.
    if eventArgs.Succeeded:
        print(stateAsObject.name, ': ', eventArgs.AttributeData.Value, sep='')
    else:
        print(stateAsObject.name, ' *** Failure: ', eventArgs.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

print('Subscribing...')
monitoredItemArguments1 = EasyUAMonitoredItemArguments(
    None,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845'),
    UAMonitoringParameters(1000))
monitoredItemArguments1.State = CustomObject('First')    # a custom object that corresponds to the subscription
monitoredItemArguments2 = EasyUAMonitoredItemArguments(
    None,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853'),
    UAMonitoringParameters(1000))
monitoredItemArguments2.State = CustomObject('Second')    # a custom object that corresponds to the subscription
monitoredItemArguments3 = EasyUAMonitoredItemArguments(
    None,
    endpointDescriptor,
    UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855'),
    UAMonitoringParameters(1000))
monitoredItemArguments3.State = CustomObject('Third')    # a custom object that corresponds to the subscription

client.SubscribeMultipleMonitoredItems([
    monitoredItemArguments1,
    monitoredItemArguments2,
    monitoredItemArguments3,
    ])

print('Processing data change events for 10 seconds...')
time.sleep(10)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of multiple monitored items
' and display each change, identifying the different subscriptions by an
' object.

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

Namespace _EasyUAClient
    Partial Friend Class SubscribeMultipleMonitoredItems
        Class CustomObject
            Public Sub New(ByVal name As String)
                _Name = name
            End Sub
            Public ReadOnly Property Name As String
                Get
                    Return _Name
                End Get
            End Property
            Private ReadOnly _Name As String
        End Class

        Public Shared Sub StateAsObject()

            ' 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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf ClientOnDataChangeNotification_StateAsObject

            Console.WriteLine("Subscribing...")
            Dim handleArray() As Integer = client.SubscribeMultipleMonitoredItems(New EasyUAMonitoredItemArguments() _
                { _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/ ;i=10845", 1000) _
                         With {.State = New CustomObject("First")}, _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/ ;i=10853", 1000) _
                         With {.State = New CustomObject("Second")}, _
                    New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, _
                        "nsu=http://test.org/UA/Data/ ;i=10855", 1000) _
                        With {.State = New CustomObject("Third")} _
                } _
            ) ' A custom object that corresponds to the subscription

            For i As Integer = 0 To handleArray.Length - 1
                Console.WriteLine("handleArray[{0}]: {1}", i, handleArray(i))
            Next i

            Console.WriteLine("Processing monitored item changed events for 10 seconds...")
            Threading.Thread.Sleep(10 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Finished.")
        End Sub

        Private Shared Sub ClientOnDataChangeNotification_StateAsObject(ByVal sender As Object, ByVal eventArgs As EasyUADataChangeNotificationEventArgs)
            ' Obtain the custom object we have passed in.
            Dim stateAsObject As CustomObject = CType(eventArgs.Arguments.State, CustomObject)

            ' Display the data
            If eventArgs.Succeeded Then
                Console.WriteLine("{0}: {1}", stateAsObject.Name, eventArgs.AttributeData)
            Else
                Console.WriteLine("{0} *** Failure: {1}", stateAsObject.Name, eventArgs.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace
// This example shows how to subscribe to changes of all data variables under a specified object in OPC UA address space.

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

namespace UADocExamples._EasyUAClient
{
    partial class SubscribeMultipleMonitoredItems
    {
        public static void AllInObject()
        {
            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 and hook events
            var client = new EasyUAClient();
            client.DataChangeNotification += client_DataChangeNotification_AllInObject;

            // Obtain variables under "Scalar" node
            Console.WriteLine("Browsing...");
            UANodeElementCollection nodeElementCollection;
            try
            {
                nodeElementCollection = client.BrowseDataVariables(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;ns=2;i=10787");
            }
            catch (UAException uaException)
            {
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
                return;
            }

            // Create array with monitored item arguments
            EasyUAMonitoredItemArguments[] monitoredItemArgumentsArray = nodeElementCollection
                .Select(element => new EasyUAMonitoredItemArguments(null, endpointDescriptor, element))
                .ToArray();

            Console.WriteLine("Subscribing...");
            client.SubscribeMultipleMonitoredItems(monitoredItemArgumentsArray);

            Console.WriteLine("Processing monitored item changed events for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);
        }

        static void client_DataChangeNotification_AllInObject(object sender, EasyUADataChangeNotificationEventArgs e)
        {
            // Display value
            if (e.Succeeded)
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value);
            else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief);
        }
    }
}
# This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item
# with each change.

# 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 *


def dataChangeNotification(sender, e):
    # Display value.
    if e.Succeeded:
        print(e.Arguments.NodeDescriptor, ': ', e.AttributeData.Value, sep='')
    else:
        print(e.Arguments.NodeDescriptor, ' *** Failure: ', e.ErrorMessageBrief, sep='')


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 and hook events.
client = EasyUAClient()
client.DataChangeNotification += dataChangeNotification

# Obtain variables under "Scalar" node.
print('Browsing...')
try:
    nodeElementCollection = IEasyUAClientExtension.BrowseDataVariables(client,
        endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;ns=2;i=10787'))
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Create array with monitored item arguments.
monitoredItemArgumentsArray = list(map(
    lambda element: EasyUAMonitoredItemArguments(None, endpointDescriptor, element.ToUANodeDescriptor()),
    nodeElementCollection))

print('Subscribing...')
client.SubscribeMultipleMonitoredItems(monitoredItemArgumentsArray)

print('Processing data change events for 20 seconds...')
time.sleep(20)

print('Unsubscribing...')
client.UnsubscribeAllMonitoredItems()

print('Waiting for 5 seconds...')
time.sleep(5)

print('Finished.')
' This example shows how to subscribe to changes of all data variables under a specified object in OPC UA address space.

Imports System.Linq
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace _EasyUAClient
    Partial Friend Class SubscribeMultipleMonitoredItems
        Public Shared Sub AllInObject()

            ' 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 and hook events
            Dim client = New EasyUAClient()
            AddHandler client.DataChangeNotification, AddressOf client_DataChangeNotification_AllInObject

            ' Obtain variables under "Scalar" node
            Console.WriteLine("Subscribing...")
            Dim nodeElementCollection As UANodeElementCollection
            Try
                nodeElementCollection = client.BrowseDataVariables(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;ns=2;i=10787")
            Catch uaException As UAException
                Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
                Exit Sub
            End Try

            ' Create array with monitored item arguments

            Dim monitoredItemArgumentsArray() As EasyUAMonitoredItemArguments = nodeElementCollection.Select(Function(element) New EasyUAMonitoredItemArguments(Nothing, endpointDescriptor, element)).ToArray()

            Console.WriteLine("Subscribing...")
            client.SubscribeMultipleMonitoredItems(monitoredItemArgumentsArray)

            Console.WriteLine("Processing monitored item changed events for 20 seconds...")
            Threading.Thread.Sleep(20 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)
        End Sub

        Private Shared Sub client_DataChangeNotification_AllInObject(ByVal sender As Object, ByVal e As EasyUADataChangeNotificationEventArgs)
            ' Display value
            If e.Succeeded Then
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value)
            Else
                Console.WriteLine("{0} *** Failure: {1}", e.Arguments.NodeDescriptor, e.ErrorMessageBrief)
            End If
        End Sub
    End Class
End Namespace
Inheritance Hierarchy

System.Object
   OpcLabs.BaseLib.Object2
      OpcLabs.BaseLib.Info
         OpcLabs.BaseLib.OperationModel.OperationArguments
            OpcLabs.EasyOpc.UA.OperationModel.UANodeArguments
               OpcLabs.EasyOpc.UA.OperationModel.UAAttributeArguments
                  OpcLabs.EasyOpc.UA.OperationModel.UAMonitoredItemArguments
                     OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments
                        OpcLabs.EasyOpc.UA.Generic.EasyUADataChangeArguments<TValue>

Requirements

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

See Also