From 39457899701ac3887af82262ca5d353ee51e8706 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 16 Jun 2026 06:40:40 -0400 Subject: [PATCH] =?UTF-8?q?docs(dcl):=20M2.13=20review=20nits=20=E2=80=94?= =?UTF-8?q?=20OriginalRaiseTime=20ConditionRefresh/UTC=20caveats=20+=20Des?= =?UTF-8?q?cription-vs-Message=20note=20(#27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Adapters/RealOpcUaClient.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealOpcUaClient.cs b/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealOpcUaClient.cs index 82988318..b40d2d44 100644 --- a/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealOpcUaClient.cs +++ b/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealOpcUaClient.cs @@ -398,7 +398,11 @@ public class RealOpcUaClient : IOpcUaClient // 13: AlarmConditionType/ActiveState/TransitionTime — the UTC instant the active-state // last flipped to TRUE. Mapped to OriginalRaiseTime; absent on non-AlarmCondition - // events (ConditionType base events rarely carry it). + // events (ConditionType base events rarely carry it). CAVEAT: during a + // ConditionRefresh replay the server MAY re-stamp this to the current/restart time + // rather than the historical raise instant (OPC UA Part 9 §5.5.2 makes it advisory), + // so a snapshot-derived OriginalRaiseTime can look like the refresh time — it is + // display-only and not treated as authoritative. filter.SelectClauses.Add(SelectField(ObjectTypeIds.AlarmConditionType, "ActiveState", "TransitionTime")); // 13 // 14–17: LimitAlarmType limit thresholds — configuration-time set-points exposed as @@ -413,8 +417,9 @@ public class RealOpcUaClient : IOpcUaClient // UNAVAILABLE via standard OPC UA A&C event fields (documented here so future // maintainers know these were considered, not overlooked): // Category — not a standard event field; server-specific extensions only. - // Description — not a per-event text field; the OPC UA Description attribute is a - // static node property, not carried in event notifications. + // Description — NativeAlarmTransition.Description is a static template description; + // OPC UA events carry dynamic Message text (index 4, mapped) but no + // static template description in the notification, so this stays empty. // OperatorUser — not available on the standard ConditionRefresh replay stream; // present on Acknowledge/Confirm method call results, but those do // not flow through the monitored-item subscription. @@ -539,6 +544,8 @@ public class RealOpcUaClient : IOpcUaClient // transitioned to TRUE). Absent on non-AlarmCondition events → guard + null fallback. DateTimeOffset? originalRaiseTime = null; if (fields.Count > 13 && fields[13].Value is DateTime activeTransitionTime) + // OPC UA mandates UTC for DateTime fields; a TimeSpan.Zero offset treats an + // Unspecified Kind as UTC (consistent with the Time→TransitionTime mapping above). originalRaiseTime = new DateTimeOffset(activeTransitionTime, TimeSpan.Zero); // Indices 14–17: LimitAlarmType set-point thresholds (HighHighLimit/HighLimit/