namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions; /// /// Driver capability for alarm events. Optional — only drivers whose backends expose /// alarm conditions implement this. Currently: Galaxy (MxAccess alarms), FOCAS /// (CNC alarms), OPC UA Client (A&C events from upstream server), MTConnect /// (CONDITION data items, Gitea #626). /// public interface IAlarmSource { /// /// Subscribe to alarm events for a node-set (typically: a folder or equipment subtree). /// The driver fires for every alarm transition. /// /// The driver node IDs to subscribe to. /// Cancellation token for the operation. /// A handle identifying the created subscription. Task SubscribeAlarmsAsync( IReadOnlyList sourceNodeIds, CancellationToken cancellationToken); /// Cancel an alarm subscription returned by . /// The subscription handle returned from . /// Cancellation token for the operation. /// A task that represents the asynchronous operation. Task UnsubscribeAlarmsAsync(IAlarmSubscriptionHandle handle, CancellationToken cancellationToken); /// Acknowledge one or more active alarms by source node ID + condition ID. /// The batch of alarm acknowledgement requests. /// Cancellation token for the operation. /// A task that represents the asynchronous operation. Task AcknowledgeAsync( IReadOnlyList acknowledgements, CancellationToken cancellationToken); /// Server-pushed alarm transition (raise / clear / change). event EventHandler? OnAlarmEvent; } /// Opaque alarm-subscription identity returned by . public interface IAlarmSubscriptionHandle { /// Driver-internal subscription identifier (for diagnostics + post-mortem). string DiagnosticId { get; } } /// One alarm acknowledgement in a batch. /// Driver-side identifier for the alarm source. /// Stable id correlating raise / ack / clear of the same condition. /// Operator-supplied comment forwarded to the upstream alarm system. /// Authenticated principal performing the ack; null on the raw/non-OPC-UA path. public sealed record AlarmAcknowledgeRequest( string SourceNodeId, string ConditionId, string? Comment, string? OperatorUser = null); /// Event payload for . /// Subscription this event belongs to. /// Driver-side identifier for the alarm source. /// Stable id correlating raise / ack / clear of the same condition. /// Driver-defined alarm type name (e.g. AnalogLimitAlarm.HiHi). /// Human-readable alarm description. /// Four-bucket severity ladder. /// When this transition occurred. /// /// Operator-supplied comment recorded by the upstream alarm system on Acknowledge /// transitions. Null on raise / clear, or when the upstream path can't surface /// the comment (the Galaxy sub-attribute fallback path collapses comments into a /// single string write — null on that path; the driver-native gateway path /// populates this). /// /// /// When the alarm originally entered the active state. Preserved across /// Acknowledge transitions so OPC UA Part 9 conditions keep the original raise /// time in Time. Null when the upstream path doesn't surface it. /// /// /// Upstream alarm taxonomy bucket (e.g. Process / Safety / /// Diagnostics). Maps to OPC UA ConditionClassName downstream when /// a class mapping is configured. Null when the upstream path doesn't carry it. /// /// /// The alarm transition kind (raise / acknowledge / clear / retrigger). Lets a /// consumer derive OPC UA Part 9 active/ack state without inferring it from /// other fields. when the upstream /// path doesn't surface a distinct kind. /// /// /// Optional exact OPC UA severity (1..1000) for a source whose own scale is finer than the four /// buckets (Gitea #626: MTConnect Warning = 500, Fault = 800). When set it /// supersedes the bucket on the projected Part 9 condition (clamped to 1..1000); null — every /// pre-#626 source — keeps the bucket mapping. must still carry the nearest /// bucket for consumers that only read the bucket. /// /// /// Optional status code of the condition's SOURCE data (Part 9 ConditionType.Quality), for a /// source that can report "no value for this condition" per alarm rather than per connection (Gitea /// #626: MTConnect Unavailable). null keeps the pre-#626 behaviour (projected Good; /// driver-wide comms loss is annotated separately by the host). An event whose is /// and which carries a quality is a /// quality-only annotation (): the host updates (via its Quality-only node path) the condition's /// Quality without touching its Active/Acked state and publishes no alerts row for it. /// public sealed record AlarmEventArgs( IAlarmSubscriptionHandle SubscriptionHandle, string SourceNodeId, string ConditionId, string AlarmType, string Message, AlarmSeverity Severity, DateTime SourceTimestampUtc, string? OperatorComment = null, DateTime? OriginalRaiseTimestampUtc = null, string? AlarmCategory = null, AlarmTransitionKind Kind = AlarmTransitionKind.Unspecified, int? OpcUaSeverity = null, uint? QualityStatusCode = null) { /// /// True when this event only re-annotates the condition's source-data quality — a /// with an kind. No /// alarm-state change happened, so the host must not publish it as an alarm transition. /// public bool IsQualityOnly => Kind == AlarmTransitionKind.Unspecified && QualityStatusCode is not null; } /// Mirrors the NodePermissions alarm-severity enum in docs/v2/acl-design.md. public enum AlarmSeverity { Low, Medium, High, Critical } /// /// Kind of alarm state change carried by , letting a /// consumer derive OPC UA Part 9 active/ack state. Mirrors the driver-side /// transition-kind enums (e.g. Galaxy's GalaxyAlarmTransitionKind). /// public enum AlarmTransitionKind { Unspecified = 0, Raise, Acknowledge, Clear, Retrigger }