From 422e5b7db211494d91b67753407053a99ca41d7a Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 14 Jun 2026 03:27:03 -0400 Subject: [PATCH] refactor(alarms): harden ExtractTagAlarm severity parse (TryGetInt32) + trim projector prior-state (review nits) --- .../ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs | 2 +- .../Drivers/DeploymentArtifact.cs | 2 +- .../Drivers/NativeAlarmProjector.cs | 9 +++------ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs b/src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs index b64db8e0..ddeae6b9 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Phase7Composer.cs @@ -469,7 +469,7 @@ public static class Phase7Composer var type = a.TryGetProperty("alarmType", out var tEl) && tEl.ValueKind == JsonValueKind.String ? (tEl.GetString() ?? "AlarmCondition") : "AlarmCondition"; var sev = a.TryGetProperty("severity", out var sEl) && sEl.ValueKind == JsonValueKind.Number - ? sEl.GetInt32() : 500; + && sEl.TryGetInt32(out var sv) ? sv : 500; return new EquipmentTagAlarmInfo(type, sev); } catch (JsonException) { return null; } diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DeploymentArtifact.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DeploymentArtifact.cs index 1407bbc0..5f59fa21 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DeploymentArtifact.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DeploymentArtifact.cs @@ -666,7 +666,7 @@ public static class DeploymentArtifact var type = a.TryGetProperty("alarmType", out var tEl) && tEl.ValueKind == JsonValueKind.String ? (tEl.GetString() ?? "AlarmCondition") : "AlarmCondition"; var sev = a.TryGetProperty("severity", out var sEl) && sEl.ValueKind == JsonValueKind.Number - ? sEl.GetInt32() : 500; + && sEl.TryGetInt32(out var sv) ? sv : 500; return new EquipmentTagAlarmInfo(type, sev); } catch (JsonException) { return null; } diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/NativeAlarmProjector.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/NativeAlarmProjector.cs index 9cea1f3c..a7e2b75e 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/NativeAlarmProjector.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/NativeAlarmProjector.cs @@ -12,8 +12,7 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Drivers; /// public sealed class NativeAlarmProjector { - private readonly Dictionary _prior = - new(StringComparer.Ordinal); + private readonly Dictionary _prior = new(StringComparer.Ordinal); /// Project an alarm transition onto the full condition snapshot for . /// The materialised condition node's id (the projection's state key). @@ -21,9 +20,7 @@ public sealed class NativeAlarmProjector /// The full Part 9 condition snapshot to write to the node. public AlarmConditionSnapshot Project(string nodeId, AlarmEventArgs e) { - var prev = _prior.TryGetValue(nodeId, out var p) - ? p - : (Active: false, Acked: true, Severity: (ushort)0, Message: string.Empty); + var prev = _prior.TryGetValue(nodeId, out var p) ? p : (Active: false, Acked: true); var sev = MapSeverity(e.Severity); var (active, acked) = e.Kind switch { @@ -32,7 +29,7 @@ public sealed class NativeAlarmProjector AlarmTransitionKind.Clear => (false, prev.Acked), _ => (prev.Active, prev.Acked), }; - _prior[nodeId] = (active, acked, sev, e.Message); + _prior[nodeId] = (active, acked); return new AlarmConditionSnapshot( Active: active, Acknowledged: acked, Confirmed: true, Enabled: true, Shelving: AlarmShelvingKind.Unshelved, Severity: sev, Message: e.Message);