feat(alarms): carry transition Kind on AlarmEventArgs; Galaxy populates it (Phase B WS-1)

This commit is contained in:
Joseph Doherty
2026-06-14 03:04:44 -04:00
parent a996f03b5b
commit f44d8d1e6b
5 changed files with 87 additions and 2 deletions
@@ -71,6 +71,12 @@ public sealed record AlarmAcknowledgeRequest(
/// <c>Diagnostics</c>). Maps to OPC UA <c>ConditionClassName</c> downstream when
/// a class mapping is configured. Null when the upstream path doesn't carry it.
/// </param>
/// <param name="Kind">
/// 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. <see cref="AlarmTransitionKind.Unspecified"/> when the upstream
/// path doesn't surface a distinct kind.
/// </param>
public sealed record AlarmEventArgs(
IAlarmSubscriptionHandle SubscriptionHandle,
string SourceNodeId,
@@ -81,7 +87,15 @@ public sealed record AlarmEventArgs(
DateTime SourceTimestampUtc,
string? OperatorComment = null,
DateTime? OriginalRaiseTimestampUtc = null,
string? AlarmCategory = null);
string? AlarmCategory = null,
AlarmTransitionKind Kind = AlarmTransitionKind.Unspecified);
/// <summary>Mirrors the <c>NodePermissions</c> alarm-severity enum in <c>docs/v2/acl-design.md</c>.</summary>
public enum AlarmSeverity { Low, Medium, High, Critical }
/// <summary>
/// Kind of alarm state change carried by <see cref="AlarmEventArgs.Kind"/>, letting a
/// consumer derive OPC UA Part 9 active/ack state. Mirrors the driver-side
/// transition-kind enums (e.g. Galaxy's <c>GalaxyAlarmTransitionKind</c>).
/// </summary>
public enum AlarmTransitionKind { Unspecified = 0, Raise, Acknowledge, Clear, Retrigger }
@@ -1153,7 +1153,17 @@ public sealed class GalaxyDriver
SourceTimestampUtc: transition.TransitionTimestampUtc,
OperatorComment: string.IsNullOrEmpty(transition.OperatorComment) ? null : transition.OperatorComment,
OriginalRaiseTimestampUtc: transition.OriginalRaiseTimestampUtc,
AlarmCategory: string.IsNullOrEmpty(transition.Category) ? null : transition.Category);
AlarmCategory: string.IsNullOrEmpty(transition.Category) ? null : transition.Category,
// Fully-qualify the Core.Abstractions enum: this file also imports
// MxGateway.Contracts.Proto, which defines a same-named AlarmTransitionKind.
Kind: transition.TransitionKind switch
{
GalaxyAlarmTransitionKind.Raise => Core.Abstractions.AlarmTransitionKind.Raise,
GalaxyAlarmTransitionKind.Acknowledge => Core.Abstractions.AlarmTransitionKind.Acknowledge,
GalaxyAlarmTransitionKind.Clear => Core.Abstractions.AlarmTransitionKind.Clear,
GalaxyAlarmTransitionKind.Retrigger => Core.Abstractions.AlarmTransitionKind.Retrigger,
_ => Core.Abstractions.AlarmTransitionKind.Unspecified,
});
try
{
OnAlarmEvent?.Invoke(this, args);