QuickOPC User's Guide and Reference
SelectClauses Property (UAEventFilter)
Example 



OpcLabs.EasyOpcUA Assembly > OpcLabs.EasyOpc.UA Namespace > UAEventFilter Class : SelectClauses Property
Collection of the attribute fields to return with each Event in a Notification.
Syntax
'Declaration
 
<DataMemberAttribute()>
<ElementsNotNullAttribute()>
<NotNullAttribute()>
Public Property SelectClauses As UAAttributeFieldCollection
'Usage
 
Dim instance As UAEventFilter
Dim value As UAAttributeFieldCollection
 
instance.SelectClauses = value
 
value = instance.SelectClauses
[DataMember()]
[ElementsNotNull()]
[NotNull()]
public UAAttributeFieldCollection SelectClauses {get; set;}
[DataMember()]
[ElementsNotNull()]
[NotNull()]
public:
property UAAttributeFieldCollection^ SelectClauses {
   UAAttributeFieldCollection^ get();
   void set (    UAAttributeFieldCollection^ value);
}
Remarks

In order to obtain or modify this parameter, access the UAMonitoringParameters.EventFilter property of OpcLabs.EasyOpc.UA.OperationModel.UAMonitoredItemArguments.MonitoringParameters.

Example

.NET

COM

.NET

// This example shows how to select fields for event notifications.

using System;
using System.Collections.Generic;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.AlarmsAndConditions;
using OpcLabs.EasyOpc.UA.Filtering;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.AlarmsAndConditions
{
    class SelectClauses
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

            // Instantiate the client object and hook events.
            var client = new EasyUAClient();
            client.EventNotification += client_EventNotification;

            Console.WriteLine("Subscribing...");
            client.SubscribeEvent(
                endpointDescriptor,
                UAObjectIds.Server,
                1000,
                new UAAttributeFieldCollection
                {
                    // Select specific fields using standard operand symbols.
                    UABaseEventObject.Operands.NodeId,
                    UABaseEventObject.Operands.SourceNode,
                    UABaseEventObject.Operands.SourceName,
                    UABaseEventObject.Operands.Time,

                    // Select specific fields using an event type ID and a simple relative path.
                    UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Message"),
                    UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Severity")
                });

            Console.WriteLine("Processing event notifications for 30 seconds...");
            System.Threading.Thread.Sleep(30 * 1000);

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

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

            Console.WriteLine("Finished.");
        }

        static void client_EventNotification(object sender, EasyUAEventNotificationEventArgs e)
        {
            Console.WriteLine();

            // Display the event.
            if (e.EventData is null)
            {
                Console.WriteLine(e);
                return;
            }
            Console.WriteLine("All fields:");
            foreach (KeyValuePair<UAAttributeField, ValueResult> pair in e.EventData.FieldResults)
            {
                UAAttributeField attributeField = pair.Key;
                ValueResult valueResult = pair.Value;
                Console.WriteLine($"  {attributeField} -> {valueResult}");
            }

            // Extracting a specific field using a standard operand symbol.
            Console.WriteLine($"Source name: {e.EventData.FieldResults[UABaseEventObject.Operands.SourceName]}");

            // Extracting a specific field using an event type ID and a simple relative path.
            Console.WriteLine(
                $"Message: {e.EventData.FieldResults[UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Message")]}");
        }
    }
}
# This example shows how to select fields for event notifications.

#requires -Version 5.1
using namespace OpcLabs.BaseLib.OperationModel
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

# 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 object.
$client = New-Object EasyUAClient

# Event notification handler
Register-ObjectEvent -InputObject $client -EventName EventNotification -Action { 
    Write-Host 

    # Display the event.
    if ($EventArgs.EventData -eq $null) {
        Write-Host $EventArgs
        return
    }
    Write-Host "All fields:"
    foreach ($pair in $EventArgs.EventData.FieldResults.GetEnumerator()) {
        [UAAttributeField]$attributeField = $pair.Key
        [ValueResult]$valueResult = $pair.Value
        Write-Host "  $($attributeField) -> $($valueResult)"
    }

    # Extracting a specific field using a standard operand symbol.
    Write-Host "Source name: $($EventArgs.EventData.FieldResults[[UABaseEventObject+Operands]::SourceName])"

    # Extracting a specific field using an event type ID and a simple relative path.
    Write-Host `
        "Message: $($EventArgs.EventData.FieldResults[[UAFilterElements]::SimpleAttribute([UAObjectTypeIds]::BaseEventType, "/Message")])"
}

Write-Host "Subscribing..."

$attributeFieldCollection = New-Object UAAttributeFieldCollection

# Select specific fields using standard operand symbols.
$attributeFieldCollection.Add([UABaseEventObject+Operands]::NodeId)
$attributeFieldCollection.Add([UABaseEventObject+Operands]::SourceNode)
$attributeFieldCollection.Add([UABaseEventObject+Operands]::SourceName) 
$attributeFieldCollection.Add([UABaseEventObject+Operands]::Time)

# Select specific fields using an event type ID and a simple relative path.
$attributeFieldCollection.Add([UAFilterElements]::SimpleAttribute([UAObjectTypeIds]::BaseEventType, "/Message"))
$attributeFieldCollection.Add([UAFilterElements]::SimpleAttribute([UAObjectTypeIds]::BaseEventType, "/Severity"))

[IEasyUAClientExtension]::SubscribeEvent($client, 
    $endpointDescriptor, [UAObjectIds]::Server, 1000, [UAEventFilter]$attributeFieldCollection)

Write-Host "Processing event notifications for 30 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 30) {    
    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 select fields for event notifications.

# 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.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):
    print()

    # Display the event.
    if eventArgs.EventData is None:
        print(eventArgs)
        return
    print('All fields:')
    for pair in eventArgs.EventData.FieldResults:
        attributeField = pair.Key
        valueResult = pair.Value
        print('  ', attributeField, ' -> ', valueResult, sep='')

    # Extracting a specific field using a standard operand symbol.
    print('Source name: ',
          eventArgs.EventData.FieldResults.get_Item(UAAttributeField(UABaseEventObject.Operands.SourceName)),
          sep='')

    # Extracting a specific field using an event type ID and a simple relative path.
    print('Message: ',
          eventArgs.EventData.FieldResults.get_Item(UAAttributeField(
              UAFilterElements.SimpleAttribute(UANodeDescriptor(UAObjectTypeIds.BaseEventType), '/Message'))),
          sep='')


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

# Instantiate the client object and hook events.
client = EasyUAClient()
client.EventNotification += eventNotification

print('Subscribing...')
attributeFieldCollection = UAAttributeFieldCollection([
    # Select specific fields using standard operand symbols.
    UAAttributeField(UABaseEventObject.Operands.NodeId),
    UAAttributeField(UABaseEventObject.Operands.SourceNode),
    UAAttributeField(UABaseEventObject.Operands.SourceName),
    UAAttributeField(UABaseEventObject.Operands.Time),

    # Select specific fields using an event type ID and a simple relative path.
    UAAttributeField(UAFilterElements.SimpleAttribute(UANodeDescriptor(UAObjectTypeIds.BaseEventType), "/Message")),
    UAAttributeField(UAFilterElements.SimpleAttribute(UANodeDescriptor(UAObjectTypeIds.BaseEventType), "/Severity"))
    ])
IEasyUAClientExtension.SubscribeEvent(
    client,
    endpointDescriptor,
    UANodeDescriptor(UAObjectIds.Server),
    1000,
    UAEventFilter(attributeFieldCollection))

print('Processing event notifications for 30 seconds...')
time.sleep(30)

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

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

print('Finished.')
' This example shows how to select fields for event notifications.

Imports OpcLabs.EasyOpc.UA
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 SelectClauses
        Public Shared Sub Main1()
            ' Instantiate the client object and hook events
            Dim client = New EasyUAClient()
            AddHandler client.EventNotification, AddressOf client_EventNotification

            Console.WriteLine("Subscribing...")
            ' Select specific fields using standard operand symbols
            ' Select specific fields using an event type ID and a simple relative path
            client.SubscribeEvent( _
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer", _
                UAObjectIds.Server, _
                1000, _
                New UAAttributeFieldCollection() From
                {
                    UABaseEventObject.Operands.NodeId,
                    UABaseEventObject.Operands.SourceNode,
                    UABaseEventObject.Operands.SourceName,
                    UABaseEventObject.Operands.Time,
 _
                    UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Message"),
                    UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Severity")
                })

            Console.WriteLine("Processing event notifications for 30 seconds...")
            Threading.Thread.Sleep(30 * 1000)

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

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

        Private Shared Sub client_EventNotification(ByVal sender As Object, ByVal e As EasyUAEventNotificationEventArgs)
            Console.WriteLine()

            ' Display the event
            If e.EventData Is Nothing Then
                Console.WriteLine(e)
                Exit Sub
            End If
            For Each pair In e.EventData.FieldResults
                Dim attributeField = pair.Key
                Dim valueResult = pair.Value
                Console.WriteLine("  {0} -> {1}", attributeField, valueResult)
            Next pair
            ' Extracting a specific field using a standard operand symbol
            Console.WriteLine("Source name: {0}", _
                e.EventData.FieldResults(UABaseEventObject.Operands.SourceName))
            ' Extracting a specific field using an event type ID and a simple relative path
            Console.WriteLine("Message: {0}", _
                e.EventData.FieldResults(UAFilterElements.SimpleAttribute(UAObjectTypeIds.BaseEventType, "/Message")))
        End Sub
    End Class
End Namespace
// This example shows how to select fields for event notifications.

type
  TClientEventHandlers4 = class
    procedure OnEventNotification(
      Sender: TObject;
      sender0: OleVariant;
      eventArgs: _EasyUAEventNotificationEventArgs);
  end;

procedure TClientEventHandlers4.OnEventNotification(
  Sender: TObject;
  sender0: OleVariant;
  eventArgs: _EasyUAEventNotificationEventArgs);

  function ToUAAttributeField(Operand: UASimpleAttributeOperand): UAAttributeField;
  var
    AttributeField: UAAttributeField;
  begin
    AttributeField := CoUAAttributeField.Create;
    AttributeField.Operand := Operand;
    ToUAAttributeField := AttributeField;
  end;

  function UAFilterElements_SimpleAttribute(TypeId: UANodeId; SimpleRelativeBrowsePathString: string): UASimpleAttributeOperand;
  var
    Operand: UASimpleAttributeOperand;
    BrowsePathParser: UABrowsePathParser;
  begin
    BrowsePathParser := CoUABrowsePathParser.Create;
    Operand := CoUASimpleAttributeOperand.Create;
    Operand.TypeId.NodeId := TypeId;
    Operand.QualifiedNames := BrowsePathParser.ParseRelative(SimpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
    UAFilterElements_SimpleAttribute := Operand;
  end;

  function ObjectTypeIds_BaseEventType: UANodeId;
  var
    NodeId: UANodeId;
  begin
    NodeId := CoUANodeId.Create;
    NodeId.StandardName := 'BaseEventType';
    ObjectTypeIds_BaseEventType := NodeId;
  end;

var
  Count: Cardinal;
  Element: OleVariant;
  EntryEnumerator: IEnumVariant;
  Entry: DictionaryEntry2;
  AttributeField: UAAttributeField;
  AValueResult: ValueResult;
begin
  WriteLn;

  // Display the event
  if eventArgs.EventData = nil then
  begin
    WriteLn(eventArgs.ToString);
    Exit;
  end;
  WriteLn('All fields:');
  EntryEnumerator := eventArgs.EventData.FieldResults.GetEnumerator;
  while EntryEnumerator.Next(1, Element, Count) = S_OK do
  begin
    Entry := IUnknown(Element) as DictionaryEntry2;
    AttributeField := IUnknown(Entry.key) as UAAttributeField;
    AValueResult := IUnknown(Entry.Value) as ValueResult;
    WriteLn('  ', AttributeField.ToString, ' -> ', AValueResult.ToString);
  end;
  // Extracting a specific field using an event type ID and a simple relative path
  WriteLn('Source name: ',
    eventArgs.EventData.FieldResults[ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName'))].ToString);
  WriteLn('Message: ',
    eventArgs.EventData.FieldResults[ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message'))].ToString);
end;

class procedure SelectClauses.Main;

  function ToUAAttributeField(Operand: UASimpleAttributeOperand): UAAttributeField;
  var
    AttributeField: UAAttributeField;
  begin
    AttributeField := CoUAAttributeField.Create;
    AttributeField.Operand := Operand;
    ToUAAttributeField := AttributeField;
  end;

  function ObjectTypeIds_BaseEventType: UANodeId;
  var
    NodeId: UANodeId;
  begin
    NodeId := CoUANodeId.Create;
    NodeId.StandardName := 'BaseEventType';
    ObjectTypeIds_BaseEventType := NodeId;
  end;

  function UABaseEventObject_Operands_NodeId: UASimpleAttributeOperand;
  var
    Operand: UASimpleAttributeOperand;
  begin
    Operand := CoUASimpleAttributeOperand.Create;
    Operand.TypeId.NodeId.StandardName := 'BaseEventType';
    Operand.AttributeId := UAAttributeId_NodeId;
    UABaseEventObject_Operands_NodeId := Operand;
  end;

  function UAFilterElements_SimpleAttribute(TypeId: UANodeId; SimpleRelativeBrowsePathString: string): UASimpleAttributeOperand;
  var
    Operand: UASimpleAttributeOperand;
    BrowsePathParser: UABrowsePathParser;
  begin
    BrowsePathParser := CoUABrowsePathParser.Create;
    Operand := CoUASimpleAttributeOperand.Create;
    Operand.TypeId.NodeId := TypeId;
    Operand.QualifiedNames := BrowsePathParser.ParseRelative(SimpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
    UAFilterElements_SimpleAttribute := Operand;
  end;

var
  Arguments: OleVariant;
  EvsClient: TEvsEasyUAClient;
  Client: EasyUAClient;
  ClientEventHandlers: TClientEventHandlers4;
  Handle: Cardinal;
  HandleArray: OleVariant;
  MonitoredItemArguments: EasyUAMonitoredItemArguments;
  MonitoringParameters: UAMonitoringParameters;
  EventFilter: UAEventFilter;
  SelectClauses: UAAttributeFieldCollection;
begin
  // Instantiate the client object and hook events
  EvsClient := TEvsEasyUAClient.Create(nil);
  Client := EvsClient.ComServer;
  ClientEventHandlers := TClientEventHandlers4.Create;
  EvsClient.OnEventNotification := @ClientEventHandlers.OnEventNotification;

  WriteLn('Subscribing...');

  SelectClauses := CoUAAttributeFieldCollection.Create;
  // Select specific fields using an event type ID and a simple relative path
  SelectClauses.Add(ToUAAttributeField(UABaseEventObject_Operands_NodeId));
  SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode')));
  SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName')));
  SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Time')));
  SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message')));
  SelectClauses.Add(ToUAAttributeField(UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity')));

  EventFilter := CoUAEventFilter.Create;
  EventFilter.SelectClauses := SelectClauses;

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

  MonitoredItemArguments := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments.EndpointDescriptor.UrlString := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';
  MonitoredItemArguments.NodeDescriptor.NodeId.StandardName := 'Server';
  MonitoredItemArguments.MonitoringParameters := MonitoringParameters;
  //MonitoredItemArguments.SubscriptionParameters.PublishingInterval := 0;
  MonitoredItemArguments.AttributeId := UAAttributeId_EventNotifier;

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

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

  WriteLn('Processing event notifications for 30 seconds...');
  PumpSleep(30*1000);

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

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

  WriteLn('Finished...');
end;
// This example shows how to select fields for event notifications.

type
  THelperMethods17 = class
    class function ObjectTypeIds_BaseEventType: _UANodeId; static;
    class function UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand;
    class function UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Time: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Message: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand; static;
  end;

type
  TClientEventHandlers17 = class
    procedure Client_EventNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUAEventNotificationEventArgs);
  end;

procedure TClientEventHandlers17.Client_EventNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUAEventNotificationEventArgs);
var
  AttributeField: OleVariant;
  Count: Cardinal;
  Element: OleVariant;
  EntryEnumerator: IEnumVARIANT;
  ValueResult: OleVariant;
begin
  WriteLn;

  // Display the event
  if eventArgs.EventData = nil then
  begin
    WriteLn(eventArgs.ToString);
    Exit;
  end;

  WriteLn('All fields:');

  EntryEnumerator := eventArgs.EventData.FieldResults.GetEnumerator;
  while (EntryEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    AttributeField := IUnknown(Element.Key) as _UAAttributeField;
    ValueResult := IUnknown(Element.Value) as _ValueResult;
    WriteLn(' ', AttributeField.ToString, ' -> ', ValueResult.ToString);
  end;

  // Extracting specific fields using an event type ID and a simple relative path
  WriteLn('Source name: ', eventArgs.EventData.FieldResults.Item[THelperMethods17.UABaseEventObject_Operands_SourceName.ToUAAttributeField].ToString);
  WriteLn('Message: ', eventArgs.EventData.FieldResults.Item[THelperMethods17.UABaseEventObject_Operands_Message.ToUAAttributeField].ToString);
end;

class procedure SelectClauses.Main;
const
  UAObjectIds_Server = 'nsu=http://opcfoundation.org/UA/;i=2253';
var
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers17;
  EndpointDescriptor: string;
  EventFilter: _UAEventFilter;
  MonitoredItemArguments: _EasyUAMonitoredItemArguments;
  MonitoringParameters: _UAMonitoringParameters;
  SelectClauses: UAAttributeFieldCollection;
begin
  EndpointDescriptor := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';

  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers17.Create;
  Client.OnEventNotification := ClientEventHandlers.Client_EventNotification;

  WriteLn('Subscribing...');

  SelectClauses := CoUAAttributeFieldCollection.Create;
  // Select specific fields using an event type ID and a simple relative path
  SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_NodeId.ToUAAttributeField);
  SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_SourceNode.ToUAAttributeField);
  SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_SourceName.ToUAAttributeField);
  SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_Time.ToUAAttributeField);
  SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_Message.ToUAAttributeField);
  SelectClauses.Add(THelperMethods17.UABaseEventObject_Operands_Severity.ToUAAttributeField);

  EventFilter := CoUAEventFilter.Create;
  EventFilter.SelectClauses := SelectClauses;

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

  MonitoredItemArguments := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments.EndpointDescriptor.UrlString := EndpointDescriptor;
  MonitoredItemArguments.NodeDescriptor.NodeId.StandardName := 'Server';
  MonitoredItemArguments.MonitoringParameters := MonitoringParameters;
  //MonitoredItemArguments.SubscriptionParameters.PublishingInterval := 0;
  MonitoredItemArguments.AttributeId := UAAttributeId_EventNotifier;

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

  Client.SubscribeMultipleMonitoredItems(Arguments);

  WriteLn('Processing event notifications for 30 seconds...');
  PumpSleep(30*1000);

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

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

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


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

class function THelperMethods17.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 THelperMethods17.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 THelperMethods17.UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode');
end;

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

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

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

class function THelperMethods17.UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity');
end;
// This example shows how to select fields for event notifications.

const UAAttributeId_NodeId = 1;
const UAAttributeId_EventNotifier = 12;

class ClientEvents {
    function EventNotification($Sender, $E)
    {
        printf("\n");

        // Display the event
        if (is_null($E->EventData)) {
            printf("%s\n", $E);
            return;
        }

        printf("All fields:\n");

        foreach ($E->EventData->FieldResults as $Pair)
        {
            $AttributeField = $Pair->Key;
            $ValueResult = $Pair->Value;
            printf("  %s -> %s\n", $AttributeField, $ValueResult);
        }

        // Extracting specific fields using an event type ID and a simple relative path
        printf("Source name: %s\n", $E->EventData->FieldResults->Item(UABaseEventObject_Operands_SourceName()->ToUAAttributeField()));
        printf("Message: %s\n", $E->EventData->FieldResults->Item(UABaseEventObject_Operands_Message()->ToUAAttributeField()));
    }
}

const UAObjectIds_Server = "nsu=http://opcfoundation.org/UA/;i=2253";

$EndpointDescriptor = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

// 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");

$SelectClauses = new COM("OpcLabs.EasyOpc.UA.UAAttributeFieldCollection");
// Select specific fields using an event type ID and a simple relative path
$SelectClauses->Add(UABaseEventObject_Operands_NodeId()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_SourceNode()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_SourceName()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_Time()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_Message()->ToUAAttributeField());
$SelectClauses->Add(UABaseEventObject_Operands_Severity()->ToUAAttributeField());

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

$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->EndpointDescriptor->UrlString = $EndpointDescriptor;
$MonitoredItemArguments->NodeDescriptor->NodeId->StandardName = "Server";
$MonitoredItemArguments->MonitoringParameters = $MonitoringParameters;
// $MonitoredItemArguments->SubscriptionParameters->PublishingInterval = 0;
$MonitoredItemArguments->AttributeId = UAAttributeId_EventNotifier;

$Arguments[0] = $MonitoredItemArguments;

$Client->SubscribeMultipleMonitoredItems($Arguments);

printf("Processing event notifications for 30 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 30);

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_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_Message() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Message");
}

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


// Example output (truncated):
//Subscribing...
//Processing event notifications for 30 seconds...
//
//[] Success
//
//[] Success; Refresh; RefreshInitiated
//
//All fields:
//  NodeId="BaseEventType", NodeId -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?OnlineState {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
//  NodeId="BaseEventType"/EventId -> Success; [16] {95, 68, 22, 205, 114, ...} {System.Byte[]}
//  NodeId="BaseEventType"/EventType -> Success; DialogConditionType {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
//  NodeId="BaseEventType"/SourceNode -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
//  NodeId="BaseEventType"/SourceName -> Success; EastTank {System.String}
//  NodeId="BaseEventType"/Time -> Success; 9/10/2019 8:08:23 PM {System.DateTime}
//  NodeId="BaseEventType"/ReceiveTime -> Success; 9/10/2019 8:08:23 PM {System.DateTime}
//  NodeId="BaseEventType"/LocalTime -> Success; 00:00, DST {OpcLabs.EasyOpc.UA.UATimeZoneData}
//  NodeId="BaseEventType"/Message -> Success; The dialog was activated {System.String}
//  NodeId="BaseEventType"/Severity -> Success; 100 {System.Int32}
//Source name: Success; EastTank {System.String}
//Message: Success; The dialog was activated {System.String}
//
//All fields:
//  NodeId="BaseEventType", NodeId -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Red {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
//  NodeId="BaseEventType"/EventId -> Success; [16] {124, 156, 219, 54, 120, ...} {System.Byte[]}
//  NodeId="BaseEventType"/EventType -> Success; ExclusiveDeviationAlarmType {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
//  NodeId="BaseEventType"/SourceNode -> Success; nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank {OpcLabs.EasyOpc.UA.AddressSpace.UANodeId}
//  NodeId="BaseEventType"/SourceName -> Success; EastTank {System.String}
//  NodeId="BaseEventType"/Time -> Success; 10/14/2019 4:00:13 PM {System.DateTime}
//  NodeId="BaseEventType"/ReceiveTime -> Success; 10/14/2019 4:00:13 PM {System.DateTime}
//  NodeId="BaseEventType"/LocalTime -> Success; 00:00, DST {OpcLabs.EasyOpc.UA.UATimeZoneData}
//  NodeId="BaseEventType"/Message -> Success; The alarm was acknoweledged. {System.String}
//  NodeId="BaseEventType"/Severity -> Success; 500 {System.Int32}
//Source name: Success; EastTank {System.String}
//Message: Success; The alarm was acknoweledged. {System.String}
//
//...

// This example shows how to obtain acknowledged state of events, and acknowledge an event that is not acknowledged yet.

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;
                        var ackedStateId = (bool)ackedStateIdResult.Value;
                        Console.WriteLine($"AckedState/Id: {ackedStateId}");

                        // Only attempt to acknowledge when not acknowledged yet.
                        if (ackedStateId)
                            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.

# 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