Subscription is initiated by calling one of the SubscribeMonitoredItem, SubscribeDataChange, 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.
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.
// 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" (not in .NET Standard)
// 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("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);
}
static void client_DataChangeNotification(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.
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace UADocExamples._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" (not in .NET Standard)
' 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 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";
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";
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";
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
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';
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';
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';
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.');
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: 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";
$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";
$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";
$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
Private 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 = "http://opcua.demo-this.com:51211/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 = "http://opcua.demo-this.com:51211/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 = "http://opcua.demo-this.com:51211/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 & "Done." & vbCrLf
End Sub
Private 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 = "http://opcua.demo-this.com:51211/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 = "http://opcua.demo-this.com:51211/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 = "http://opcua.demo-this.com:51211/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
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.
See Also
Recommended
Knowledge Base
Installed Examples - Console
Installed Examples - WPF