feat(adminui): native-alarm HistorizeToAveva opt-out
This commit is contained in:
@@ -139,9 +139,13 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
|
||||
private readonly Dictionary<string, (string DriverInstanceId, string FullName)> _driverRefByAlarmNodeId =
|
||||
new(StringComparer.Ordinal);
|
||||
|
||||
/// <summary>Condition NodeId → (EquipmentId, tag Name, OPC UA alarm type) for building the
|
||||
/// AlarmTransitionEvent fan-out. Built in the same PushDesiredSubscriptions alarm branch.</summary>
|
||||
private readonly Dictionary<string, (string EquipmentId, string Name, string AlarmType)> _alarmMetaByNodeId =
|
||||
/// <summary>Condition NodeId → (EquipmentId, tag Name, OPC UA alarm type, HistorizeToAveva) for building
|
||||
/// the AlarmTransitionEvent fan-out. Built in the same PushDesiredSubscriptions alarm branch.
|
||||
/// HistorizeToAveva (bool?, null ⇒ historize) is the native per-condition opt-out parsed from
|
||||
/// <c>TagConfig.alarm.historizeToAveva</c>; it is threaded onto the transition so the
|
||||
/// HistorianAdapterActor's <c>is not false</c> gate suppresses the durable AVEVA row only on an
|
||||
/// explicit false (mirroring the scripted-alarm opt-out).</summary>
|
||||
private readonly Dictionary<string, (string EquipmentId, string Name, string AlarmType, bool? HistorizeToAveva)> _alarmMetaByNodeId =
|
||||
new(StringComparer.Ordinal);
|
||||
|
||||
/// <summary>Derives a full Part 9 condition snapshot from each native alarm transition delta,
|
||||
@@ -589,7 +593,7 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
|
||||
if (_localRole is RedundancyRole.Secondary or RedundancyRole.Detached) continue;
|
||||
|
||||
var meta = _alarmMetaByNodeId.TryGetValue(nodeId, out var m)
|
||||
? m : (EquipmentId: nodeId, Name: nodeId, AlarmType: "AlarmCondition");
|
||||
? m : (EquipmentId: nodeId, Name: nodeId, AlarmType: "AlarmCondition", HistorizeToAveva: (bool?)null);
|
||||
_mediator.Tell(new Publish(ScriptedAlarmHostActor.AlertsTopic, new AlarmTransitionEvent(
|
||||
AlarmId: nodeId,
|
||||
EquipmentPath: meta.EquipmentId,
|
||||
@@ -605,9 +609,11 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
|
||||
TimestampUtc: msg.Args.SourceTimestampUtc,
|
||||
AlarmTypeName: meta.AlarmType,
|
||||
Comment: msg.Args.OperatorComment,
|
||||
// Native alarms always historize (no per-condition opt-out surface yet — that is a
|
||||
// scripted-alarm plan flag); pass a concrete true so the historian's null-default isn't relied on.
|
||||
HistorizeToAveva: true)));
|
||||
// Per-condition opt-out parsed from TagConfig.alarm.historizeToAveva (bool?, null ⇒ absent ⇒
|
||||
// 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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1020,7 +1026,7 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers
|
||||
// Capture the per-condition metadata the alerts fan-out (ForwardNativeAlarm) needs to build
|
||||
// the AlarmTransitionEvent: the equipment path, the operator-visible alarm name, and the
|
||||
// OPC UA Part 9 subtype. Keyed by the condition NodeId (the projection's own key).
|
||||
_alarmMetaByNodeId[nodeId] = (t.EquipmentId, t.Name, t.Alarm.AlarmType);
|
||||
_alarmMetaByNodeId[nodeId] = (t.EquipmentId, t.Name, t.Alarm.AlarmType, t.Alarm.HistorizeToAveva);
|
||||
continue;
|
||||
}
|
||||
if (!_nodeIdByDriverRef.TryGetValue(key, out var set))
|
||||
|
||||
Reference in New Issue
Block a user