feat(dcl): OPC UA Alarms & Conditions adapter (event subscription + ConditionRefresh)

Adds IAlarmSubscribableConnection to OpcUaDataConnection, IOpcUaClient alarm
subscription methods, and RealOpcUaClient A&C event monitored-item +
EventFilter + ConditionRefresh snapshot, mapping fields via OpcUaAlarmMapper.
Behavior verified against a live A&C server in Task 28; mapper unit-tested.
This commit is contained in:
Joseph Doherty
2026-05-29 16:42:27 -04:00
parent 1fbb814daa
commit 0d30b7dec0
3 changed files with 240 additions and 1 deletions
@@ -17,7 +17,7 @@ namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters;
/// - Read/Write → Read/Write service calls
/// - Quality → OPC UA StatusCode mapping
/// </summary>
public class OpcUaDataConnection : IDataConnection, IBrowsableDataConnection
public class OpcUaDataConnection : IDataConnection, IBrowsableDataConnection, IAlarmSubscribableConnection
{
private readonly IOpcUaClientFactory _clientFactory;
private readonly ILogger<OpcUaDataConnection> _logger;
@@ -174,6 +174,27 @@ public class OpcUaDataConnection : IDataConnection, IBrowsableDataConnection
cancellationToken);
}
/// <inheritdoc />
public async Task<string> SubscribeAlarmsAsync(
string sourceReference, string? conditionFilter,
AlarmTransitionCallback callback, CancellationToken cancellationToken = default)
{
EnsureConnected();
// The client maps OPC UA A&C event fields → NativeAlarmTransition via
// OpcUaAlarmMapper and replays a snapshot on (re)subscribe.
return await _client!.CreateAlarmSubscriptionAsync(
sourceReference, conditionFilter,
transition => callback(transition),
cancellationToken);
}
/// <inheritdoc />
public async Task UnsubscribeAlarmsAsync(string subscriptionId, CancellationToken cancellationToken = default)
{
if (_client != null)
await _client.RemoveAlarmSubscriptionAsync(subscriptionId, cancellationToken);
}
/// <inheritdoc />
public async Task UnsubscribeAsync(string subscriptionId, CancellationToken cancellationToken = default)
{