C# / .NET · recipe

Subscribe to alarms and events in C#

Monitor the Server object's EventNotifier with an EventFilter whose select clause names the fields you want. The reference stack has helpers that build the filter and unpack the field values in order.

StackOPCFoundation/UA-.NETStandard
Version1.5.378.156 stable, 2.0.0-preview.2

The code

var filter = new FilterDefinition
{
    AreaId          = ObjectIds.Server,
    Severity        = EventSeverity.Min,
    IgnoreSuppressedOrShelved = true,
    EventTypes      = new NodeIdCollection { ObjectTypeIds.BaseEventType },
};
filter.SelectClauses = filter.ConstructSelectClauses(
    session, ObjectTypeIds.BaseEventType);

var subscription = new Subscription(session.DefaultSubscription)
{
    PublishingInterval = 500, KeepAliveCount = 10, LifetimeCount = 100,
};
session.AddSubscription(subscription);
subscription.Create();

var item = filter.CreateMonitoredItem(session);
item.Notification += (mi, e) =>
{
    if (e.NotificationValue is not EventFieldList fields) return;
    var ev = filter.GetFilterTargetValues(fields.EventFields);
    Console.WriteLine($"[{ev.Severity}] {ev.SourceName}: {ev.Message?.Text}");
};

subscription.AddItem(item);
subscription.ApplyChanges();
await Task.Delay(10000);

What it prints

[500] MachineTool_1: Tool life below threshold
[800] MachineTool_1: Tool breakage detected
[100] Server: Session activated

Notes

  • The select clause order determines the field order in every notification. Use the helper that maps them back by name rather than indexing positionally.
  • Narrow EventTypes to what you care about. Subscribing to BaseEventType on a busy server delivers a lot of noise you then pay to discard.
  • Call ConditionRefresh after a reconnect, or your client believes the plant is healthy while alarms are still active.
  • Add ConditionClassId to the select clause for OEE work: it is what makes downtime reasons portable across machine vendors.

What breaks first

The subscription is created but no events arrive BadEventFilterInvalid
A select clause field does not exist on the event types the server emits. Start from the base fields, confirm events flow, then add fields back individually.
Other recipes in this stack

Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.

Free download
OPC UA Troubleshooting & Integration Checklist
The field-tested checklist engineers use to diagnose certificates, ports and namespace problems fast, plus a Python (asyncua) client template.
Get the free checklist →
Free, no course, no login