fix(alarms): Severity runs one direction, higher = more urgent; raw priority kept (#129)
AlarmConditionState.Severity mixed two conventions: OPC UA rows carried Part 9 Severity (higher = more severe) while MxGateway native alarms and computed alarms carried a raw AVEVA-style priority (1 = most urgent). Every consumer ranks higher as worse, so Worst Severity, the severity filter/sort and the site event-log Error threshold picked the LEAST urgent MxGateway/computed alarms. - AlarmPriorityBands: the OtOpcUa GalaxyAlarmPriority table (lmxopcua#887, b61f3e05), value for value: 1-250 -> 1000, 251-500 -> 750, 501-750 -> 500, 751-999 -> 250; <= 0 clamps to Critical, > 999 to Low. - MxGatewayAlarmMapper bands the gateway severity (= AVEVA priority); AlarmConditionStateFactory.ForComputed bands PriorityLevel. OPC UA unchanged. - AlarmConditionState gains trailing Priority (int?): the raw source number, exactly the pre-#129 Severity. AlarmStateChanged.Priority and the wire AlarmStateUpdate.priority keep that meaning (no proto change); central derives Severity by kind (SeverityFromPriority), so an older site decodes correctly. - ScriptAlarm gains trailing Priority. The native MES 900-999 band and the MES API Severity/MinSeverity/MaxSeverity key off Priority; rig seed scripts moved from a.Severity to a.Priority, so MES output is unchanged. - AlarmActor raise logs Error when the banded severity >= 700 (same threshold as NativeAlarmActor): priority 1-500 Error, 501+ Warning (was raw >= 700). - NativeAlarmActor upgrades pre-#129 native_alarm_state rows on rehydrate. - Debug snapshot decode restores Condition.Priority from the row's priority. - Docs: Commons, DCL, SiteRuntime, Communication, CentralUI, InboundAPI, HighLevelReqs, MES alarm-status plan, CLAUDE.md. Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
This commit is contained in:
@@ -42,7 +42,8 @@ public class AlarmsAccessorTests : TestKit, IDisposable
|
||||
Kind = AlarmKind.NativeMxAccess,
|
||||
Condition = new AlarmConditionState(
|
||||
Active: true, Acknowledged: true, Confirmed: null,
|
||||
Shelve: AlarmShelveState.TimedShelved, Suppressed: true, Severity: 950),
|
||||
// AVEVA priority 950 (inside the MES 900-999 band) banded to Low = 250 (#129).
|
||||
Shelve: AlarmShelveState.TimedShelved, Suppressed: true, Severity: 250, Priority: 950),
|
||||
SourceReference = "Z28061.HeartbeatTimeoutAlarm",
|
||||
NativeSourceCanonicalName = "ReactorAlarms",
|
||||
AlarmTypeName = "DiscreteAlarm",
|
||||
@@ -108,7 +109,8 @@ public class AlarmsAccessorTests : TestKit, IDisposable
|
||||
Assert.Null(alarm.Confirmed);
|
||||
Assert.True(alarm.Shelved); // TimedShelved collapses to a single boolean
|
||||
Assert.True(alarm.Suppressed);
|
||||
Assert.Equal(950, alarm.Severity);
|
||||
Assert.Equal(250, alarm.Severity);
|
||||
Assert.Equal(950, alarm.Priority); // the MES band keys off the raw priority (#129)
|
||||
Assert.Equal("NativeMxAccess", alarm.Kind);
|
||||
Assert.Equal("Heartbeat lost", alarm.Message);
|
||||
Assert.Equal("DiscreteAlarm", alarm.AlarmTypeName);
|
||||
@@ -166,7 +168,8 @@ public class AlarmsAccessorTests : TestKit, IDisposable
|
||||
Assert.True(alarm.Active);
|
||||
Assert.True(alarm.Acknowledged); // computed alarms are auto-acked…
|
||||
Assert.Null(alarm.AckTime); // …but carry no ack instant
|
||||
Assert.Equal(700, alarm.Severity);
|
||||
Assert.Equal(500, alarm.Severity); // PriorityLevel 700 banded: Medium → 500 (#129)
|
||||
Assert.Equal(700, alarm.Priority);
|
||||
Assert.Equal(string.Empty, alarm.NativeSourceCanonicalName);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user