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 7723c662..aa679d8f 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs
@@ -171,7 +171,7 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
/// TagConfig.alarm.historizeToAveva; it is threaded onto the transition so the
/// HistorianAdapterActor's is not false gate suppresses the durable AVEVA row only on an
/// explicit false (mirroring the scripted-alarm opt-out).
- private readonly Dictionary _alarmMetaByNodeId =
+ private readonly Dictionary ReferencingEquipmentPaths)> _alarmMetaByNodeId =
new(StringComparer.Ordinal);
/// Derives a full Part 9 condition snapshot from each native alarm transition delta,
@@ -1048,7 +1048,8 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
if (!serviceAlertsAsPrimary) continue;
var meta = _alarmMetaByNodeId.TryGetValue(nodeId, out var m)
- ? m : (EquipmentId: nodeId, Name: nodeId, AlarmType: "AlarmCondition", HistorizeToAveva: (bool?)null);
+ ? m : (EquipmentId: nodeId, Name: nodeId, AlarmType: "AlarmCondition", HistorizeToAveva: (bool?)null,
+ ReferencingEquipmentPaths: (IReadOnlyList)Array.Empty());
_mediator.Tell(new Publish(ScriptedAlarmHostActor.AlertsTopic, new AlarmTransitionEvent(
AlarmId: nodeId,
EquipmentPath: meta.EquipmentId,
@@ -1068,7 +1069,10 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
// historize). The HistorianAdapterActor gate (historizeToAveva is not false) historizes null +
// true and suppresses the durable AVEVA row only on an explicit false — the same posture as the
// scripted-alarm opt-out. null here rides through unchanged (the gate treats it as default-on).
- HistorizeToAveva: meta.HistorizeToAveva)));
+ HistorizeToAveva: meta.HistorizeToAveva,
+ // WP4: the Area/Line/Equipment UNS paths that reference this raw condition — the /alerts row
+ // renders them as the equipment list (empty for a raw condition no equipment references yet).
+ ReferencingEquipmentPaths: meta.ReferencingEquipmentPaths)));
}
}
@@ -1573,8 +1577,10 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
// Inverse 1:1 map for the inbound native-condition ack path (keyed by BARE condition NodeId).
_driverRefByAlarmNodeId[t.NodeId] = key;
// Per-condition metadata for the alerts fan-out. WP4 refines /alerts identity to the referencing
- // equipment paths; WP3 keys the display off the RawPath.
- _alarmMetaByNodeId[t.NodeId] = (t.NodeId, t.Name, t.Alarm.AlarmType, t.Alarm.HistorizeToAveva);
+ // equipment paths; WP3 keys the display off the RawPath. The referencing-equipment paths (the
+ // Area/Line/Equipment UNS folder paths carried on the RawTagPlan) ride onto every transition so
+ // the /alerts row lists which equipment reference this raw condition.
+ _alarmMetaByNodeId[t.NodeId] = (t.NodeId, t.Name, t.Alarm.AlarmType, t.Alarm.HistorizeToAveva, t.ReferencingEquipmentPaths);
continue;
}