OPC Studio User's Guide and Reference
Acknowledge Method (EasyUAAlarmsAndConditionsClientCore)
Example 



OpcLabs.EasyOpcUA Assembly > OpcLabs.EasyOpc.UA.AlarmsAndConditions Namespace > EasyUAAlarmsAndConditionsClientCore Class : Acknowledge Method
Endpoint descriptor. Identifies the OPC-UA server.

Because the OpcLabs.EasyOpc.UA.UAEndpointDescriptor has implicit conversions from System.String and System.Uri, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a string (representing the endpoint URL, or a so-called OPC UA endpoint descriptor string), or a System.Uri object, in place of this parameter, and the corresponding endpoint descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the FromString or FromUri static method instead.

Also, because the OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement and OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement have an implicit conversion to OpcLabs.EasyOpc.UA.UAEndpointDescriptor, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement or OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement (results from OPC UA discovery) in place of this parameter, and the corresponding endpoint descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can convert a (non-null) OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement or OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement to OpcLabs.EasyOpc.UA.UAEndpointDescriptor using the OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement.ToUAEndpointDescriptor or OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement.ToUAEndpointDescriptor method instead.

If you are using OPC Wizard (for server development), an implicit conversion from OpcLabs.EasyOpc.UA.EasyUAServerCore can be used in the same way to simply pass the server object in place of this parameter, which will use its OpcLabs.EasyOpc.UA.EasyUAServerCore.EffectiveServerDescriptor property for the connection.

The value of this parameter cannot be null (Nothing in Visual Basic).

Node descriptor. Identifies the node in OPC server's address space.

Because the OpcLabs.EasyOpc.UA.UANodeDescriptor has implicit conversions from OpcLabs.EasyOpc.UA.AddressSpace.UANodeId, OpcLabs.EasyOpc.UA.AddressSpace.UANodeElement, OpcLabs.EasyOpc.UA.Navigation.UABrowsePath and System.String, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a OpcLabs.EasyOpc.UA.AddressSpace.UANodeId object (representing the Id of the OPC UA node), a node element object (from OPC UA browsing), OpcLabs.EasyOpc.UA.Navigation.UABrowsePath object (representing OPC UA absolute browse path), or a string (with expanded node Id text) in place of this parameter, and the corresponding node descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the FromString, FromUABrowsePath, FromUANodeElement or FromUANodeId static method instead.

If you are using OPC Wizard (for server development), an implicit conversion from OpcLabs.EasyOpc.UA.NodeSpace.UAServerNode can be used in the same way to simply pass the server node in place of this parameter, which will use its OpcLabs.EasyOpc.UA.NodeSpace.UAServerNode.EffectiveNodeDescriptor property for the operation.

The value of this parameter cannot be null (Nothing in Visual Basic).

EventId identifying a particular Event Notification. Only Event Notifications where AckedState/Id was FALSE can be acknowledged.

The value of this parameter cannot be null (Nothing in Visual Basic).

A localized text to be applied to the Condition.

The value of this parameter cannot be null (Nothing in Visual Basic).

The Acknowledge Method is used to acknowledge an Event Notification for a Condition instance state where AckedState is FALSE.
Syntax
'Declaration
 
Public Sub Acknowledge( _
   ByVal endpointDescriptor As UAEndpointDescriptor, _
   ByVal objectOrConditionNodeDescriptor As UANodeDescriptor, _
   ByVal eventId() As Byte, _
   ByVal comment As String _
) 
'Usage
 
Dim instance As EasyUAAlarmsAndConditionsClientCore
Dim endpointDescriptor As UAEndpointDescriptor
Dim objectOrConditionNodeDescriptor As UANodeDescriptor
Dim eventId() As Byte
Dim comment As String
 
instance.Acknowledge(endpointDescriptor, objectOrConditionNodeDescriptor, eventId, comment)

Parameters

endpointDescriptor
Endpoint descriptor. Identifies the OPC-UA server.

Because the OpcLabs.EasyOpc.UA.UAEndpointDescriptor has implicit conversions from System.String and System.Uri, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a string (representing the endpoint URL, or a so-called OPC UA endpoint descriptor string), or a System.Uri object, in place of this parameter, and the corresponding endpoint descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the FromString or FromUri static method instead.

Also, because the OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement and OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement have an implicit conversion to OpcLabs.EasyOpc.UA.UAEndpointDescriptor, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement or OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement (results from OPC UA discovery) in place of this parameter, and the corresponding endpoint descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can convert a (non-null) OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement or OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement to OpcLabs.EasyOpc.UA.UAEndpointDescriptor using the OpcLabs.EasyOpc.UA.Discovery.UAApplicationElement.ToUAEndpointDescriptor or OpcLabs.EasyOpc.UA.Discovery.UADiscoveryElement.ToUAEndpointDescriptor method instead.

If you are using OPC Wizard (for server development), an implicit conversion from OpcLabs.EasyOpc.UA.EasyUAServerCore can be used in the same way to simply pass the server object in place of this parameter, which will use its OpcLabs.EasyOpc.UA.EasyUAServerCore.EffectiveServerDescriptor property for the connection.

The value of this parameter cannot be null (Nothing in Visual Basic).

objectOrConditionNodeDescriptor
Node descriptor. Identifies the node in OPC server's address space.

Because the OpcLabs.EasyOpc.UA.UANodeDescriptor has implicit conversions from OpcLabs.EasyOpc.UA.AddressSpace.UANodeId, OpcLabs.EasyOpc.UA.AddressSpace.UANodeElement, OpcLabs.EasyOpc.UA.Navigation.UABrowsePath and System.String, in languages that support implicit conversion operators (such as C# or VB.NET), you can simply use a OpcLabs.EasyOpc.UA.AddressSpace.UANodeId object (representing the Id of the OPC UA node), a node element object (from OPC UA browsing), OpcLabs.EasyOpc.UA.Navigation.UABrowsePath object (representing OPC UA absolute browse path), or a string (with expanded node Id text) in place of this parameter, and the corresponding node descriptor will be constructed automatically. When the implicit conversion operators are not supported (such as with Python.NET), you can use the FromString, FromUABrowsePath, FromUANodeElement or FromUANodeId static method instead.

If you are using OPC Wizard (for server development), an implicit conversion from OpcLabs.EasyOpc.UA.NodeSpace.UAServerNode can be used in the same way to simply pass the server node in place of this parameter, which will use its OpcLabs.EasyOpc.UA.NodeSpace.UAServerNode.EffectiveNodeDescriptor property for the operation.

The value of this parameter cannot be null (Nothing in Visual Basic).

eventId
EventId identifying a particular Event Notification. Only Event Notifications where AckedState/Id was FALSE can be acknowledged.

The value of this parameter cannot be null (Nothing in Visual Basic).

comment
A localized text to be applied to the Condition.

The value of this parameter cannot be null (Nothing in Visual Basic).

Exceptions
ExceptionDescription

A null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.

This is a usage error, i.e. it will never occur (the exception will not be thrown) in a correctly written program. Your code should not catch this exception.

The OPC UA operation has failed. This operation exception in uniformly used to allow common handling of various kinds of errors. The System.Exception.InnerException always contains information about the actual error cause.

This is an operation error that depends on factors external to your program, and thus cannot be always avoided. Your code must handle it appropriately.

Remarks
Normally, the NodeId of the object instance as the ObjectId is passed to the Call Service. However, some Servers do not expose Condition instances in the AddressSpace. Therefore, all Servers shall also allow Clients to call the Acknowledge Method by specifying ConditionId as the ObjectId. The Method cannot be called with an ObjectId of the AcknowledgeableConditionType Node.
Example
// This example shows how to acknowledge an OPC UA event.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Threading;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.AlarmsAndConditions;
using OpcLabs.EasyOpc.UA.Filtering;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.AlarmsAndConditions
{
    partial class Acknowledge
    {
        public static void Main1()
        {
            // Define which server we will work with.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

            // Instantiate the client objects.
            var client = new EasyUAClient();
            IEasyUAAlarmsAndConditionsClient alarmsAndConditionsClient = client.AsAlarmsAndConditionsClient();

            UANodeId nodeId = null;
            byte[] eventId = null;
            var anEvent = new ManualResetEvent(initialState: false);

            Console.WriteLine("Subscribing...");
            client.SubscribeEvent(
                endpointDescriptor,
                UAObjectIds.Server,
                1000,
                new UAEventFilterBuilder(
                    UAFilterElements.Equals(
                        UABaseEventObject.Operands.NodeId,
                        new UANodeId(nodeIdExpandedText: "nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow")),
                    UABaseEventObject.AllFields),
                (sender, eventArgs) =>
                {
                    if (!eventArgs.Succeeded)
                    {
                        Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}");
                        return;
                    }
                    if (!(eventArgs.EventData is null))
                    {
                        UABaseEventObject baseEventObject = eventArgs.EventData.BaseEvent;
                        Console.WriteLine(baseEventObject);

                        // Make sure we do not catch the event more than once.
                        if (anEvent.WaitOne(0))
                            return;

                        nodeId = baseEventObject.NodeId;
                        eventId = baseEventObject.EventId;

                        anEvent.Set();
                    }
                },
                state:null);

            Console.WriteLine("Waiting for an event for 30 seconds...");
            if (!anEvent.WaitOne(30*1000))
            {
                Console.WriteLine("Event not received.");
                return;
            }

            Console.WriteLine("Acknowledging an event...");
            try
            {
                alarmsAndConditionsClient.Acknowledge(
                    endpointDescriptor,
                    nodeId,
                    eventId,
                    "Acknowledged by an automated example code.");
            }
            catch (UAException uaException)
            {
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}");
            }

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

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

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

            Console.WriteLine("Finished.");
        }



        // Example output:
        //Subscribing...
        //Waiting for an event for 30 seconds...
        //[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
        //Acknowledging an event...
        //Waiting for 5 seconds...
        //[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
        //Unsubscribing...
        //Waiting for 5 seconds...
        //Finished.
    }
}
# This example shows how to acknowledge an OPC UA event.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in PowerShell on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PowerShell .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.

#requires -Version 5.1
using namespace System.Threading
using namespace OpcLabs.EasyOpc.UA
using namespace OpcLabs.EasyOpc.UA.AddressSpace
using namespace OpcLabs.EasyOpc.UA.AddressSpace.Standard
using namespace OpcLabs.EasyOpc.UA.AlarmsAndConditions
using namespace OpcLabs.EasyOpc.UA.Filtering
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"

# Define which server we will work with.
[UAEndpointDescriptor]$endpointDescriptor = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"

# Instantiate the client objects.
$client = New-Object EasyUAClient
$alarmsAndConditionsClient = $client.AsAlarmsAndConditionsClient()

# Event notification handler
Register-ObjectEvent -InputObject $client -EventName EventNotification -Action { 
    if (-not $EventArgs.Succeeded) {
        Write-Host "*** Failure: $($EventArgs.ErrorMessageBrief)"
        return
    }
    if ($EventArgs.EventData -ne $null) {
        $baseEventObject = $EventArgs.EventData.BaseEvent
        Write-Host $baseEventObject

        # Make sure we do not catch the event more than once.
        if ($acknowledged) {
            return
        }

        $global:nodeId = $baseEventObject.NodeId
        $global:eventId = $baseEventObject.EventId

        $global:acknowledged = $true
    }
}

Write-Host "Subscribing..."
$global:acknowledged = $false
[IEasyUAClientExtension]::SubscribeEvent($client, 
    $endpointDescriptor, 
    [UAObjectIds]::Server, 
    1000,
    [UAEventFilter](New-Object UAEventFilterBuilder(
        [UAFilterElements]::Equals(
            [UABaseEventObject+Operands]::NodeId, 
            (New-Object UANodeId("nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow"))),
        [UABaseEventObject]::AllFields))
    )

Write-Host "Waiting for an event for 30 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 30) {    
    if ($global:acknowledged) {
        break
    }
    Start-Sleep -Seconds 1
}
if (-not $global:acknowledged) {
    Write-Host "Event not received."
    return
}

Write-Host "Acknowledging an event..."
try {
    $alarmsAndConditionsClient.Acknowledge(
        $endpointDescriptor,
        $global:nodeId,
        $global:eventId,
        "Acknowledged by an automated example code.")
}
catch [UAException] {
    Write-Host "*** Failure: $($PSItem.Exception.GetBaseException().Message)"
    return
}

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...
#Waiting for an event for 30 seconds...
#[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
#Acknowledging an event...
#Waiting for 5 seconds...
#[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
#Unsubscribing...
#Waiting for 5 seconds...
#Finished.
' This example shows how to obtain acknowledge an event.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports System
Imports System.Threading
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.AddressSpace.Standard
Imports OpcLabs.EasyOpc.UA.AlarmsAndConditions
Imports OpcLabs.EasyOpc.UA.Filtering
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace AlarmsAndConditions
    Friend Class Acknowledge
        Public Shared Sub Main1()

            ' Instantiate the client object
            Dim client = New EasyUAClient()
            Dim alarmsAndConditionsClient As IEasyUAAlarmsAndConditionsClient = client.AsAlarmsAndConditionsClient()

            Dim nodeId As UANodeId = Nothing
            Dim eventId As Byte() = Nothing
            Dim anEvent = New ManualResetEvent(initialState:=False)

            Console.WriteLine("Subscribing...")
            client.SubscribeEvent(
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
                UAObjectIds.Server,
                1000,
                New UAEventFilterBuilder(
                    UAFilterElements.Equals(
                        UABaseEventObject.Operands.NodeId,
                        New UANodeId(nodeIdExpandedText:="nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow")),
                        UABaseEventObject.AllFields),
                Sub(sender, eventArgs)
                    If Not eventArgs.Succeeded Then
                        Console.WriteLine("*** Failure: {0}", eventArgs.ErrorMessageBrief)
                        Return
                    End If
                    If eventArgs.EventData IsNot Nothing Then
                        Dim baseEventObject = eventArgs.EventData.BaseEvent
                        Console.WriteLine(baseEventObject)

                        ' Make sure we do not catch the event more than once
                        If anEvent.WaitOne(0) Then
                            Return
                        End If

                        nodeId = baseEventObject.NodeId
                        eventId = baseEventObject.EventId

                        anEvent.Set()
                    End If
                End Sub,
                state:=Nothing)

            Console.WriteLine("Waiting for an event for 30 seconds...")
            If Not anEvent.WaitOne(30 * 1000) Then
                Console.WriteLine("Event not received")
                Return
            End If

            Console.WriteLine("Acknowledging an event...")
            Try
                alarmsAndConditionsClient.Acknowledge(
                    "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
                    nodeId,
                    eventId,
                    "Acknowledged by an automated example code")
            Catch uaException As UAException
                Console.WriteLine("Failure: {0}", uaException.GetBaseException().Message)
            End Try

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

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

            Console.WriteLine("Waiting for 5 seconds...")
            Thread.Sleep(5 * 1000)
        End Sub
    End Class
End Namespace
// This example shows how to acknowledge an OPC UA event.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

type
  THelperMethods11 = class
    class function ObjectTypeIds_BaseEventType: _UANodeId; static;
    class function UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_EventId: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_EventType: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Time: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_ReceiveTime: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_LocalTime: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Message: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_AllFields: _UAAttributeFieldCollection; static;
  end;

type
  TClientEventHandlers11 = class
    procedure Client_EventNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUAEventNotificationEventArgs);
    private
      FAnEvent: Boolean;
      FEventId: OleVariant;
      FNodeId: _UANodeId;
    published
      property AnEvent: Boolean read FAnEvent write FAnEvent;
      property EventId: OleVariant read FEventId;
      property NodeId: _UANodeId read FNodeId;
  end;

procedure TClientEventHandlers11.Client_EventNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUAEventNotificationEventArgs);
var
  BaseEventObject: _UABaseEventObject;
begin
  if not eventArgs.Succeeded then
  begin
    WriteLn(Format('*** Failure: %s', [eventArgs.ErrorMessageBrief]));
    Exit;
  end;

  if eventArgs.EventData <> nil then
  begin
    BaseEventObject := eventArgs.EventData.BaseEvent;
      WriteLn(BaseEventObject.ToString);

    // Make sure we do not catch the event more than once
    if FAnEvent then
      Exit;

    FNodeId := BaseEventObject.NodeId;
    TVarData(FEventId).VType := varArray or varVariant;
    TVarData(FEventId).VArray := PVarArray(BaseEventObject.EventId);
    FAnEvent := True;
  end;
end;

class procedure Acknowledge.Main;
var
  AlarmsAndConditionsClient: _EasyUAAlarmsAndConditionsClient;
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers11;
  EndpointDescriptor: string;
  EndTime: Cardinal;
  EventFilter: _UAEventFilter;
  MonitoredItemArguments: _EasyUAMonitoredItemArguments;
  MonitoringParameters: _UAMonitoringParameters;
  Operand1: _UASimpleAttributeOperand;
  Operand2: _UALiteralOperand;
  NodeDescriptor: _UANodeDescriptor;
  NodeId: _UANodeId;
  ServerNodeId: _UANodeID;
  WhereClause: _UAContentFilterElement;
begin
  // Define which server we will work with.
  EndpointDescriptor := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';

  // Event filter: Events with specific node ID.
  Operand1 := THelperMethods11.UABaseEventObject_Operands_NodeId;
  NodeId := CoUANodeId.Create;
  NodeId.ExpandedText := 'nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow';
  Operand2 := CoUALiteralOperand.Create;
  Operand2.Value := NodeId;
  WhereClause := CoUAContentFilterElement.Create;
  WhereClause.FilterOperator := UAFilterOperator_Equals;
  WhereClause.FilterOperands.Add(Operand1);
  WhereClause.FilterOperands.Add(Operand2);

  EventFilter := CoUAEventFilter.Create;
  EventFilter.SelectClauses := THelperMethods11.UABaseEventObject_AllFields;
  EventFilter.WhereClause := WhereClause;

  ServerNodeId := CoUANodeId.Create;
  ServerNodeId.StandardName := 'Server';

  MonitoringParameters := CoUAMonitoringParameters.Create;
  MonitoringParameters.EventFilter := EventFilter;
  MonitoringParameters.QueueSize := 1000;
  MonitoringParameters.SamplingInterval := 1000;

  MonitoredItemArguments := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments.AttributeId := UAAttributeId_EventNotifier;
  MonitoredItemArguments.EndpointDescriptor.UrlString := EndpointDescriptor;
  MonitoredItemArguments.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments.NodeDescriptor.NodeId := ServerNodeId;

  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers11.Create;
  Client.OnEventNotification := ClientEventHandlers.Client_EventNotification;
  AlarmsAndConditionsClient := Client.AsAlarmsAndConditionsClient;
  ClientEventHandlers.AnEvent := False;

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

  WriteLn('Subscribing...');
  Client.SubscribeMultipleMonitoredItems(Arguments);

  WriteLn('Waiting for an event for 30 seconds...');
  EndTime := Ticks + 30*1000;
  repeat
      if ClientEventHandlers.AnEvent or (EndTime < Ticks) then
        Break;
      PumpSleep(1000);
  until False;

  if ClientEventHandlers.AnEvent then
  begin
    WriteLn('Acknowledging an event...');
    try
      NodeDescriptor := CoUANodeDescriptor.Create;
      NodeDescriptor.NodeId := ClientEventHandlers.NodeId;
      AlarmsAndConditionsClient.Acknowledge(
       MonitoredItemArguments.EndpointDescriptor,
       NodeDescriptor,
       ClientEventHandlers.EventId,
       'Acknowledged by an automated example code.');
    except
      on E: EOleException do
      begin
        WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
        Exit;
      end;
    end;
  end
  else
  begin
    WriteLn('Event not received.');
  end;

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

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

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

  WriteLn('Finished.');
  VarClear(Arguments);
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;

// Example output:
// Subscribing...
// Waiting for an event for 30 seconds...
// [EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
// Acknowledging an event...
// Waiting for 5 seconds...
// [EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
// Unsubscribing...
// Waiting for 5 seconds...


class function THelperMethods11.ObjectTypeIds_BaseEventType: _UANodeId;
  var NodeId: _UANodeId;
  begin
    NodeId := CoUANodeId.Create;
    NodeId.StandardName := 'BaseEventType';
    Result := NodeId;
  end;

class function THelperMethods11.UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand;
var
  BrowsePathParser: _UABrowsePathParser;
  Operand: _UASimpleAttributeOperand;
begin
  BrowsePathParser := CoUABrowsePathParser.Create;
  Operand := CoUASimpleAttributeOperand.Create;
  Operand.TypeId.NodeId := TypeId;
  Operand.QualifiedNames := BrowsePathParser.ParseRelative(simpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
  Result := Operand;
end;

class function THelperMethods11.UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand;
var
  Operand: _UASimpleAttributeOperand;
begin
  Operand := CoUASimpleAttributeOperand.Create;
  Operand.TypeId.NodeId.StandardName := 'BaseEventType';
  Operand.AttributeId := UAAttributeId_NodeId;
  Result := Operand;
end;

class function THelperMethods11.UABaseEventObject_Operands_EventId: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/EventId');
end;

class function THelperMethods11.UABaseEventObject_Operands_EventType: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/EventType');
end;

class function THelperMethods11.UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode');
end;

class function THelperMethods11.UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName');
end;

class function THelperMethods11.UABaseEventObject_Operands_Time: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Time');
end;

class function THelperMethods11.UABaseEventObject_Operands_ReceiveTime: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/ReceiveTime');
end;

class function THelperMethods11.UABaseEventObject_Operands_LocalTime: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/LocalTime');
end;

class function THelperMethods11.UABaseEventObject_Operands_Message: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message');
end;

class function THelperMethods11.UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity');
end;

class function THelperMethods11.UABaseEventObject_AllFields: _UAAttributeFieldCollection;
var
  Fields: _UAAttributeFieldCollection;
begin
  Fields := CoUAAttributeFieldCollection.Create;
  Fields.Add(UABaseEventObject_Operands_NodeId.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_EventId.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_EventType.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_SourceNode.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_SourceName.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Time.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_ReceiveTime.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_LocalTime.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Message.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Severity.ToUAAttributeField);

  Result := Fields;
end;
// This example shows how to acknowledge an OPC UA event.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

const UAAttributeId_NodeId = 1;
const UAAttributeId_EventNotifier = 12;

const UAFilterOperator_Equals = 1;

class ClientEvents {
    private $AnEvent = false;
    private $EventId;
    private $NodeId;

    function EventNotification($Sender, $E)
    {
        if (!$E->Succeeded) {
            printf(" *** Failure: %s\n", $E->ErrorMessageBrief);
            return;
        }

        if (!is_null($E->EventData)) {
            $BaseEventObject = $E->EventData->BaseEvent;
            printf("%s\n", $BaseEventObject);

            // Make sure we do not catch the event more than once
           if ($this->AnEvent)
               return;

           $this->NodeId = $BaseEventObject->NodeId;
           $this->EventId = $BaseEventObject->EventId;
           $this->AnEvent = true;
        }
    }

    public function getAnEvent() {
        return $this->AnEvent;
    }

    public function getEventId() {
        return $this->EventId;
    }

    public function getNodeId() {
        return $this->NodeId;
    }
}


// Define which server we will work with.
$EndpointDescriptor = new COM("OpcLabs.EasyOpc.UA.UAEndpointDescriptor");
$EndpointDescriptor->UrlString = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

// Event filter: Events with specific node ID.
$Operand1 = UABaseEventObject_Operands_NodeId();
$NodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId->ExpandedText = "nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow";
$Operand2 = new COM("OpcLabs.EasyOpc.UA.Filtering.UALiteralOperand");
$Operand2->Value = $NodeId;
$WhereClause = new COM("OpcLabs.EasyOpc.UA.Filtering.UAContentFilterElement");
$WhereClause->FilterOperator = UAFilterOperator_Equals;
$WhereClause->FilterOperands->Add($Operand1);
$WhereClause->FilterOperands->Add($Operand2);

$EventFilter = new COM("OpcLabs.EasyOpc.UA.UAEventFilter");
$EventFilter->SelectClauses = UABaseEventObject_AllFields();
$EventFilter->WhereClause = $WhereClause;

$ServerNodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$ServerNodeId->StandardName = "Server";

$MonitoringParameters = new COM("OpcLabs.EasyOpc.UA.UAMonitoringParameters");
$MonitoringParameters->EventFilter = $EventFilter;
$MonitoringParameters->QueueSize = 1000;
$MonitoringParameters->SamplingInterval = 1000;

$MonitoredItemArguments = new COM("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments");
$MonitoredItemArguments->AttributeId = UAAttributeId_EventNotifier;
$MonitoredItemArguments->EndpointDescriptor = $EndpointDescriptor;
$MonitoredItemArguments->MonitoringParameters = $MonitoringParameters;
$MonitoredItemArguments->NodeDescriptor->NodeId = $ServerNodeId;

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

$arguments[0] = $MonitoredItemArguments;

printf("Subscribing...\n");
$Client->SubscribeMultipleMonitoredItems($arguments);

printf("Waiting for an event for 30 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while ((time() < $startTime + 30) and !($ClientEvents->getAnEvent()));

if ($ClientEvents->getAnEvent()) {
    printf("Acknowledging an event...\n");
    try
    {
        $NodeDescriptor = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
        $NodeDescriptor->NodeId = $ClientEvents->getNodeId();
        $AlarmsAndConditionsClient->Acknowledge(
           $EndpointDescriptor,
           $NodeDescriptor,
           $ClientEvents->getEventId(),
           "Acknowledged by an automated example code.");
    }
    catch (com_exception $e)
    {
          printf("Failure: %s\n", $e->getMessage());
    }
}
else {
    printf("Event not received.\n");
}

printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);

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

printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);


function ObjectTypeIds_BaseEventType() {
    $NodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
    $NodeId->StandardName = "BaseEventType";
    return $NodeId;
}

function UAFilterElements_SimpleAttribute($TypeId, $simpleRelativeBrowsePathString) {
  $BrowsePathParser = new COM("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser");
  $Operand = new COM("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand");
  $Operand->TypeId->NodeId = $TypeId;
  $Operand->QualifiedNames = $BrowsePathParser->ParseRelative($simpleRelativeBrowsePathString)->ToUAQualifiedNameCollection;
  return $Operand;
}

function UABaseEventObject_Operands_NodeId() {
    $Operand = new COM("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand");
    $Operand->TypeId->NodeId->StandardName = "BaseEventType";
    $Operand->AttributeId = UAAttributeId_NodeId;
    return $Operand;
}

function UABaseEventObject_Operands_EventId() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/EventId");
}

function UABaseEventObject_Operands_EventType() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/EventType");
}

function UABaseEventObject_Operands_SourceNode() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/SourceNode");
}

function UABaseEventObject_Operands_SourceName() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/SourceName");
}

function UABaseEventObject_Operands_Time() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Time");
}

function UABaseEventObject_Operands_ReceiveTime() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/ReceiveTime");
}

function UABaseEventObject_Operands_LocalTime() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/LocalTime");
}

function UABaseEventObject_Operands_Message() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Message");
}

function UABaseEventObject_Operands_Severity() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Severity");
}


function UABaseEventObject_AllFields() {
    $Fields = new COM("OpcLabs.EasyOpc.UA.UAAttributeFieldCollection");
    $Fields->Add(UABaseEventObject_Operands_NodeId()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_EventId()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_EventType()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_SourceNode()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_SourceName()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_Time()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_ReceiveTime()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_LocalTime()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_Message()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_Severity()->ToUAAttributeField);

    return $Fields;
}
Rem This example shows how to acknowledge an OPC UA event.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.

Option Explicit

Const UAAttributeId_NodeId = 1
Const UAAttributeId_EventNotifier = 12

Const UAFilterOperator_Equals = 1

' Define which server we will work with.
Dim EndpointDescriptor: Set EndpointDescriptor = CreateObject("OpcLabs.EasyOpc.UA.UAEndpointDescriptor")
EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"

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

'
Dim NodeId
Dim EventId
Dim anEvent: anEvent = False ' Some tools have event objects, but VBScript doesn't, we will use a boolean flag instead.

' Prepare arguments
Dim arguments(0)
Set arguments(0) = CreateMonitoredItemArguments

WScript.Echo "Subscribing..."
Client.SubscribeMultipleMonitoredItems arguments

WScript.Echo "Waiting for an event for 30 seconds..."
Dim endTime: endTime = Now() + 30*(1/24/60/60)
While (Not anEvent) And (Now() < endTime)
    WScript.Sleep 1000
WEnd
If Not anEvent Then
    WScript.Echo "Event not received."
    WScript.Quit
End If

WScript.Echo "Acknowledging an event..."
Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.UA.UANodeDescriptor")
Set NodeDescriptor.NodeId = NodeId
On Error Resume Next
AlarmsAndConditionsClient.Acknowledge EndpointDescriptor, NodeDescriptor, EventId, "Acknowledged by an automated example code."
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0

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

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

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



Function ObjectTypeIds_BaseEventType
    Dim NodeId: Set NodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
    NodeId.StandardName = "BaseEventType"
    Set ObjectTypeIds_BaseEventType = NodeId
End Function

Function UAFilterElements_SimpleAttribute(TypeId, simpleRelativeBrowsePathString)
    Dim BrowsePathParser: Set BrowsePathParser = CreateObject("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser")
    Dim Operand: Set Operand = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand")
    Set Operand.TypeId.NodeId = TypeId
    Set Operand.QualifiedNames = BrowsePathParser.ParseRelative(simpleRelativeBrowsePathString).ToUAQualifiedNameCollection
    Set UAFilterElements_SimpleAttribute = Operand
End Function

Function UABaseEventObject_Operands_NodeId
    Dim Operand: Set Operand = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand")
    Operand.TypeId.NodeId.StandardName = "BaseEventType"
    Operand.AttributeId = UAAttributeId_NodeId
    Set UABaseEventObject_Operands_NodeId = Operand
End Function

Function UABaseEventObject_Operands_EventId
    Set UABaseEventObject_Operands_EventId = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/EventId")
End Function

Function UABaseEventObject_Operands_EventType
    Set UABaseEventObject_Operands_EventType = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/EventType")
End Function

Function UABaseEventObject_Operands_SourceNode
    Set UABaseEventObject_Operands_SourceNode = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/SourceNode")
End Function

Function UABaseEventObject_Operands_SourceName
    Set UABaseEventObject_Operands_SourceName = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/SourceName")
End Function

Function UABaseEventObject_Operands_Time
    Set UABaseEventObject_Operands_Time = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/Time")
End Function

Function UABaseEventObject_Operands_ReceiveTime
    Set UABaseEventObject_Operands_ReceiveTime = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/ReceiveTime")
End Function

Function UABaseEventObject_Operands_LocalTime
    Set UABaseEventObject_Operands_LocalTime = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/LocalTime")
End Function

Function UABaseEventObject_Operands_Message
    Set UABaseEventObject_Operands_Message = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/Message")
End Function

Function UABaseEventObject_Operands_Severity
    Set UABaseEventObject_Operands_Severity = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/Severity")
End Function

Function UABaseEventObject_AllFields
    Dim Fields: Set Fields = CreateObject("OpcLabs.EasyOpc.UA.UAAttributeFieldCollection")

    Fields.Add UABaseEventObject_Operands_NodeId.ToUAAttributeField

    Fields.Add UABaseEventObject_Operands_EventId.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_EventType.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_SourceNode.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_SourceName.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_Time.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_ReceiveTime.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_LocalTime.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_Message.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_Severity.ToUAAttributeField

    Set UABaseEventObject_AllFields = Fields
End Function

Function CreateMonitoredItemArguments
    ' Event filter: Events with specific node ID.
    Dim Operand1: Set Operand1 = UABaseEventObject_Operands_NodeId
    Dim NodeId: Set NodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
    NodeId.ExpandedText = "nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow"
    Dim Operand2: Set Operand2 = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UALiteralOperand")
    Set Operand2.Value = NodeId
    Dim WhereClause: Set WhereClause = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UAContentFilterElement")
    WhereClause.FilterOperator = UAFilterOperator_Equals
    WhereClause.FilterOperands.Add Operand1
    WhereClause.FilterOperands.Add Operand2

    Dim EventFilter: Set EventFilter = CreateObject("OpcLabs.EasyOpc.UA.UAEventFilter")
    Set EventFilter.SelectClauses = UABaseEventObject_AllFields
    Set EventFilter.WhereClause = WhereClause

    Dim ServerNodeId: Set ServerNodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
    ServerNodeId.StandardName = "Server"

    Dim MonitoringParameters: Set MonitoringParameters = CreateObject("OpcLabs.EasyOpc.UA.UAMonitoringParameters")
    Set MonitoringParameters.EventFilter = EventFilter
    MonitoringParameters.QueueSize = 1000
    MonitoringParameters.SamplingInterval = 1000

    Dim MonitoredItemArguments: Set MonitoredItemArguments = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments")
    MonitoredItemArguments.AttributeId = UAAttributeId_EventNotifier
    MonitoredItemArguments.EndpointDescriptor = EndpointDescriptor
    Set MonitoredItemArguments.MonitoringParameters = MonitoringParameters
    Set MonitoredItemArguments.NodeDescriptor.NodeId = ServerNodeId

    Set CreateMonitoredItemArguments = MonitoredItemArguments
End Function

Sub Client_EventNotification(Sender, EventArgs)
    If Not EventArgs.Succeeded Then
        WScript.Echo "*** Failure: " & EventArgs.ErrorMessageBrief
        Exit Sub
    End If

    If Not (EventArgs.EventData Is Nothing) Then
        Dim BaseEventObject: Set BaseEventObject = EventArgs.EventData.BaseEvent
        WScript.Echo BaseEventObject

        ' Make sure we do not catch the event more than once
        If anEvent Then
            Exit Sub
        End If

        Set NodeId = BaseEventObject.NodeId
        EventId = BaseEventObject.EventId

        anEvent = True
    End If
End Sub



' Example output:
'Subscribing...
'Waiting for an event for 30 seconds...
'[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
'Acknowledging an event...
'Waiting for 5 seconds...
'[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
'Unsubscribing...
'Waiting for 5 seconds...
#  This example shows how to acknowledge an OPC UA event.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from System.Collections.Generic import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.AddressSpace import *
from OpcLabs.EasyOpc.UA.Navigation import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Define which server we will work with.
endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer')

# Define which alarm we will work with.
alarmNodeDescriptor = UANodeDescriptor(UANodeId(
    'http://opcfoundation.org/Quickstarts/AlarmCondition',  # namespaceUriString
    '1:Colours/EastTank?Yellow'))   # identifier

# Knowing the alarm node, and the fact that is an instance of NonExclusiveLevelAlarmType (or its subtype),
# determine what is its LowState/Id node.
lowStateIdBrowsePathElements = List[UABrowsePathElement]()
lowStateIdBrowsePathElements.Add(UABrowsePathElement.CreateSimple(UAQualifiedName('ns=0;s=LowState')))
lowStateIdBrowsePathElements.Add(UABrowsePathElement.CreateSimple(UAQualifiedName('ns=0;s=Id')))
lowStateIdNodeDescriptor = UANodeDescriptor(UABrowsePath(alarmNodeDescriptor, lowStateIdBrowsePathElements))

# Instantiate the client objects
client = EasyUAClient()

print('Reading the alarm state...')
try:
    lowStateId = IEasyUAClientExtension.ReadValue(client, endpointDescriptor, lowStateIdNodeDescriptor)
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

print('Id of LowState: ', lowStateId, sep='')

print()
print('Finished.')
// This example shows how to obtain acknowledged state of events, and acknowledge an event that is not acknowledged yet.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Diagnostics;
using System.Threading;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.AlarmsAndConditions;
using OpcLabs.EasyOpc.UA.Filtering;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.AlarmsAndConditions
{
    partial class Acknowledge
    {
        public static void AckedState()
        {
            // Define which server we will work with.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

            // Instantiate the client objects.
            var client = new EasyUAClient();
            IEasyUAAlarmsAndConditionsClient alarmsAndConditionsClient = client.AsAlarmsAndConditionsClient();

            UANodeId nodeId = null;
            byte[] eventId = null;
            var anEvent = new ManualResetEvent(initialState: false);

            // Prepare the Select clauses.
            UAAttributeFieldCollection selectClauses = UABaseEventObject.AllFields;
            UASimpleAttributeOperand ackedStateIdOperand = UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/AckedState/Id");
            selectClauses.Add(ackedStateIdOperand);

            Console.WriteLine("Subscribing...");
            client.SubscribeEvent(
                endpointDescriptor,
                UAObjectIds.Server,
                1000,
                new UAEventFilterBuilder(
                    // We will auto-acknowledge an event with severity less than 200.
                    UAFilterElements.LessThan(UABaseEventObject.Operands.Severity, 200),
                    selectClauses),
                (sender, eventArgs) =>
                {
                    if (!eventArgs.Succeeded)
                    {
                        Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}");
                        return;
                    }

                    UAEventData eventData = eventArgs.EventData;
                    if (!(eventData is null))
                    {
                        UABaseEventObject baseEventObject = eventData.BaseEvent;
                        Console.WriteLine(baseEventObject);

                        // Obtain the acknowledge state of the event.
                        ValueResult ackedStateIdResult = eventData.FieldResults[ackedStateIdOperand];
                        Debug.Assert(!(ackedStateIdResult is null));
                        if (!ackedStateIdResult.Succeeded)
                            return;
                        bool? ackedStateId = (ackedStateIdResult.Value is bool) ? (bool?)ackedStateIdResult.Value : null;
                        Console.WriteLine($"AckedState/Id: {ackedStateId}");

                        // Only attempt to acknowledge when not acknowledged yet.
                        if (ackedStateId != false)
                            return;

                        // Make sure we do not catch the event more than once.
                        if (anEvent.WaitOne(0))
                            return;

                        nodeId = baseEventObject.NodeId;
                        eventId = baseEventObject.EventId;

                        anEvent.Set();
                    }
                },
                state:null);

            Console.WriteLine("Waiting for an acknowledgeable event for 10 minutes...");
            if (!anEvent.WaitOne(10*60*1000))
            {
                Console.WriteLine("Event not received.");
                return;
            }

            Console.WriteLine();
            Console.WriteLine("Acknowledging an event...");
            try
            {
                alarmsAndConditionsClient.Acknowledge(
                    endpointDescriptor,
                    nodeId,
                    eventId,
                    "Acknowledged by an automated example code.");
            }
            catch (UAException uaException)
            {
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}");
            }

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

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

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

            Console.WriteLine("Finished.");
        }
    }
}
' This example shows how to obtain acknowledged state of events, and acknowledge an event that is not acknowledged yet.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports System
Imports System.Threading
Imports OpcLabs.BaseLib
Imports OpcLabs.BaseLib.OperationModel
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.AddressSpace.Standard
Imports OpcLabs.EasyOpc.UA.AlarmsAndConditions
Imports OpcLabs.EasyOpc.UA.Filtering
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace AlarmsAndConditions
    Partial Friend Class Acknowledge
        Public Shared Sub AckedState()
            ' Define which server we will work with.
            Dim endpointDescriptor As UAEndpointDescriptor =
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"

            ' Instantiate the client object
            Dim client = New EasyUAClient()
            Dim alarmsAndConditionsClient As IEasyUAAlarmsAndConditionsClient = client.AsAlarmsAndConditionsClient()

            Dim nodeId As UANodeId = Nothing
            Dim eventId As Byte() = Nothing
            Dim anEvent = New ManualResetEvent(initialState:=False)

            ' Prepare the Select clauses.
            Dim selectClauses As UAAttributeFieldCollection = UABaseEventObject.AllFields
            Dim ackedStateIdOperand As UASimpleAttributeOperand = UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/AckedState/Id")
            selectClauses.Add(ackedStateIdOperand)

            Console.WriteLine("Subscribing...")
            client.SubscribeEvent(
                endpointDescriptor,
                UAObjectIds.Server,
                1000,
                New UAEventFilterBuilder(UAFilterElements.LessThan(UABaseEventObject.Operands.Severity, 200),
                    selectClauses), ' We will auto-acknowledge an event with severity less than 200.
                Sub(sender, eventArgs)
                    If Not eventArgs.Succeeded Then
                        Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}")
                        Return
                    End If

                    Dim eventData As UAEventData = eventArgs.EventData
                    If eventData IsNot Nothing Then
                        Dim baseEventObject = eventArgs.EventData.BaseEvent
                        Console.WriteLine(baseEventObject)

                        ' Obtain the acknowledge state of the event.
                        Dim ackedStateIdResult As ValueResult = eventData.FieldResults(ackedStateIdOperand)
                        Debug.Assert(ackedStateIdResult IsNot Nothing)
                        If Not ackedStateIdResult.Succeeded Then
                            Return
                        End If
                        Dim ackedStateId As Boolean? = If((TypeOf ackedStateIdResult.Value Is Boolean), CType(ackedStateIdResult.Value, Boolean?), Nothing)
                        Console.WriteLine($"AckedState/Id: {ackedStateId}")

                        ' Only attempt to acknowledge when Not acknowledged yet.
                        If Not ackedStateId = False Then
                            Return
                        End If


                        ' Make sure we do not catch the event more than once
                        If anEvent.WaitOne(0) Then
                            Return
                        End If

                        nodeId = baseEventObject.NodeId
                        eventId = baseEventObject.EventId

                        anEvent.Set()
                    End If
                End Sub,
                state:=Nothing)

            Console.WriteLine("Waiting for an acknowledgeable event for 10 minutes...")
            If Not anEvent.WaitOne(10 * 60 * 1000) Then
                Console.WriteLine("Event not received")
                Return
            End If

            Console.WriteLine()
            Console.WriteLine("Acknowledging an event...")
            Try
                alarmsAndConditionsClient.Acknowledge(
                    endpointDescriptor,
                    nodeId,
                    eventId,
                    "Acknowledged by an automated example code.")
            Catch uaException As UAException
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}")
            End Try

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

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

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

            Console.WriteLine("Finished.")
        End Sub
    End Class
End Namespace
# This example shows how to obtain acknowledged state of events, and acknowledge an event that is not acknowledged yet.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from System.Threading import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.AddressSpace.Standard import *
from OpcLabs.EasyOpc.UA.AlarmsAndConditions import *
from OpcLabs.EasyOpc.UA.Filtering import *
from OpcLabs.EasyOpc.UA.OperationModel import *


def eventNotification(sender, eventArgs):
    global ackedStateIdOperand
    global anEvent
    global eventId
    global nodeId

    if not eventArgs.Succeeded:
        print('*** Failure: ', eventArgs.ErrorMessageBrief, sep='')
        return

    eventData = eventArgs.EventData
    if not eventData is None:
        baseEventObject = eventData.BaseEvent
        print(baseEventObject)

        # Obtain the acknowledge state of the event.
        ackedStateIdResult = eventData.FieldResults.get_Item(UAAttributeField(ackedStateIdOperand))
        assert ackedStateIdResult is not None
        if not ackedStateIdResult.Succeeded:
            return
        ackedStateId = ackedStateIdResult.Value
        print('AckedState/Id: ', ackedStateId, sep='')

        # Only attempt to acknowledge when not acknowledged yet.
        if ackedStateId != False:
            return

        # Make sure we do not catch the event more than once.
        if anEvent.WaitOne(0):
            return

        nodeId = baseEventObject.NodeId
        eventId = baseEventObject.EventId

        anEvent.Set()


# Define which server we will work with.
endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer')

# Instantiate the client objects.
client = EasyUAClient()
alarmsAndConditionsClient = IEasyUAClientExtension.AsAlarmsAndConditionsClient(client)

nodeId = None
eventId = None
anEvent = ManualResetEvent(False)   # initialState

# Prepare the Select clauses.
selectClauses = UABaseEventObject.AllFields
ackedStateIdOperand = UAFilterElements.SimpleAttribute(
    UANodeDescriptor(UAObjectTypeIds.BaseEventType),
    '/AckedState/Id')
selectClauses.Add(UAAttributeField(ackedStateIdOperand))

print('Subscribing...')
eventFilterBuilder = UAEventFilterBuilder(
    # We will auto-acknowledge an event with severity less than 200.
    UAFilterElements.LessThan(UABaseEventObject.Operands.Severity, 200),
    selectClauses)
IEasyUAClientExtension.SubscribeEvent(
    client,
    endpointDescriptor,
    UANodeDescriptor(UAObjectIds.Server),
    1000,
    UAEventFilterBuilder.ToUAEventFilter(eventFilterBuilder),
    EasyUAEventNotificationEventHandler(eventNotification),
    None)   # state

print('Waiting for an acknowledgeable event for 10 minutes...')
if not anEvent.WaitOne(10*60*1000):
    print('Event not received.')
    exit()

print()
print('Acknowledging an event...')
try:
    alarmsAndConditionsClient.Acknowledge(
        endpointDescriptor,
        UANodeDescriptor(nodeId),
        eventId,
        'Acknowledged by an automated example code.')
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
print('Event successfully acknowledged.')

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

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

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

print('Finished.')
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