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");