From 7e86fa7099a5977ee9fe47844000af0bf7a30bc7 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 14 Jun 2026 03:58:46 -0400 Subject: [PATCH] fix(alarms): normalise native TransitionKind to canonical EmissionKind vocabulary (review) --- .../Drivers/DriverHostActor.cs | 15 ++++++++++++++- .../Drivers/DriverHostActorNativeAlarmTests.cs | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs index bb63e8a5..da5abc6a 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs @@ -542,7 +542,7 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers AlarmId: nodeId, EquipmentPath: meta.EquipmentId, AlarmName: meta.Name, - TransitionKind: msg.Args.Kind.ToString(), + TransitionKind: ToEventKind(msg.Args.Kind), // The projector mapped the four-bucket AlarmSeverity onto the OPC UA 1..1000 scale already; // reuse its ushort so the condition node + the alerts row agree on severity. Severity: snapshot.Severity, @@ -559,6 +559,19 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers } } + /// Maps a native onto the canonical alarm event-kind + /// vocabulary scripted alarms emit (the EmissionKind names) so a native row renders with the + /// correct chip on the /alerts page and historizes into the same EventKind column as + /// scripted alarms. An unmapped/unknown transition surfaces as Activated (visible) rather than + /// a grey unknown label. + private static string ToEventKind(AlarmTransitionKind kind) => kind switch + { + AlarmTransitionKind.Raise or AlarmTransitionKind.Retrigger => "Activated", + AlarmTransitionKind.Clear => "Cleared", + AlarmTransitionKind.Acknowledge => "Acknowledged", + _ => "Activated", + }; + /// /// Routes an inbound operator write (Task 11 Asks this from the OPC UA node-manager side) to the /// owning driver child. Order matters: diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorNativeAlarmTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorNativeAlarmTests.cs index 1bc2a7f2..425426b2 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorNativeAlarmTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorNativeAlarmTests.cs @@ -139,7 +139,7 @@ public sealed class DriverHostActorNativeAlarmTests : RuntimeActorTestBase evt.AlarmId.ShouldBe("eq-1/temp_hi"); // the folder-scoped condition NodeId evt.EquipmentPath.ShouldBe("eq-1"); // from the alarm-bearing tag's EquipmentId evt.AlarmName.ShouldBe("temp_hi"); // from the tag's Name - evt.TransitionKind.ShouldBe("Raise"); // AlarmEventArgs.Kind.ToString() + evt.TransitionKind.ShouldBe("Activated"); // native Kind → canonical EmissionKind vocabulary (Raise → Activated) evt.AlarmTypeName.ShouldBe("OffNormalAlarm"); // the tag's alarm AlarmType evt.Severity.ShouldBe(700); // AlarmSeverity.High → projector 700 evt.Message.ShouldBe("temperature high");