From d5afd932e8c62673ea3006dde7321277196ab302 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 12 Nov 2026 11:47:17 -0500 Subject: [PATCH] docs(otopcua-history): #886 Galaxy-backed folders serve AVEVA A&E history (3a312ffd), consumer impact Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi --- .claude/skills/sister-project-history/otopcua.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.claude/skills/sister-project-history/otopcua.md b/.claude/skills/sister-project-history/otopcua.md index f144b37..f1709c9 100644 --- a/.claude/skills/sister-project-history/otopcua.md +++ b/.claude/skills/sister-project-history/otopcua.md @@ -482,9 +482,17 @@ its Galaxy acks fail against mxaccessgw `2b13564e` did not apply to this box's d - **ScadaBridge consumer impact: none.** ScadaBridge's OPC UA adapter does no HistoryRead and never reads these nodes. Generic OPC UA clients, such as third-party historians or trend tools, now see true history flags and may start issuing HistoryRead. The flags are metadata only: no NodeIds, AccessLevels or HistoryRead/HistoryUpdate results change, except an update whose op the backend doesn't declare (none today). - The #801 live gate (`AvevaGatewayHistoryLiveGateTests`) now asserts the Gateway flags; it hasn't been re-run on vd03. +- **2026-11-12 master `3a312ffd` (#886, not deployed): Galaxy-backed folders now serve AVEVA's own alarm/event history.** A notifier folder used to read one historian source, its RawPath or EquipmentId. AVEVA files a Galaxy object's A&E history under the object's `tag_name`, so no production folder ever got it. Now a folder reads its own source plus the Galaxy object of every native condition that fires on it live, which means its parent Raw device folder and every wired UNS equipment folder. The object is the condition's raw-tag `attributeRef` up to the first `.`. It is plumbed as `RawTagPlan.NativeAlarmReference`, then a new sink call `BindNativeAlarmHistory`. + - **How it reads:** there is one gateway `ReadEvents` per source, because the filter takes a single predicate; the historiangw wire is unchanged. `EventSourceFanOut` merges the reads in `(time, source, arrival)` order and bounds each page at a truncated source's stop. Paging, reverse reads and continuation points are unchanged. The #882 `.`-boundary rule applies per object. The per-folder ACL (#826) governs everything: a denied folder reads nothing. + - **Field mapping** (property keys now case-insensitive; AVEVA lower-cases OtOpcUa's own keys too): + - **Severity:** `priority` maps through the same table live Galaxy alarms use (`GalaxyAlarmPriority`): 500/700 → 750, 999 → 1000. Before, every row was Severity 1. ⚠️ That table ranks a higher number as more severe, but AVEVA ranks priority 1 as most urgent. Filed as **lmxopcua#887**; fixing it changes live and history severity together. + - **SourceNode / ConditionName:** a row whose `source_conditionvariable` names a native condition firing on that folder carries that condition's SourceNode and live ConditionName. + - **ScadaBridge consumer impact: none.** ScadaBridge does no HistoryRead. Generic OPC UA history clients reading a Galaxy-backed equipment or raw folder now get AVEVA's A&E rows: more rows, a real Severity, and a ConditionName/SourceNode on the folder's own conditions. On a folder named after its object (the #801 harness case) only the Severity changes. + - **Live check (read-only, no WinRM):** vd03 HistorianGateway `ea9f21c`, equipment folder `EQ-886-ZipsenLeft`, backed by objects `DevWinPlatform` + `Left_001`. It returned 0 events before and **92** now, equal to the unfiltered read's rows for both objects. Paged and reverse reads agree, and 73 rows resolve to their live condition. Record: OtOpcUa `docs/plans/evidence/2026-11-10-opcua2/aveva-history-801.md` § "#886 re-run". + - **2026-11-12 master `da948e5f` (#882, not deployed): a folder's event history now includes its object's attribute alarms.** With the Gateway historian backend, HistoryReadEvents on a notifier folder now returns the object's own events and also the alarms on its attributes, which AVEVA reports as `.` (for example `DevWinPlatform.CPULoadAvg`). Before, the backend's client-side source filter dropped them: on vd03 `DevWinPlatform` returned 2 events, and now returns 72. Matching uses the `.` boundary: `X` never serves `X2.*`. There is no HistorianGateway wire change; the gateway's one `Source_Object` read already returned them (historiangw#133 cross-link closed). Each event keeps its own SourceName, and its SourceNode is null for AVEVA rows. The per-folder ACL verdict (#826) governs these events: a denied folder answers `BadUserAccessDenied` before any backend call. SqlServer and QuestDB keep exact matching. - **ScadaBridge consumer impact: none.** ScadaBridge does no HistoryRead. A generic OPC UA history client reading folder event history gets more rows per folder: attribute alarms appear alongside object events. - - **Production caveat, #886 (open):** a folder's historian source is its RawPath or EquipmentId, never a Galaxy `tag_name`. AVEVA's own A&E history therefore reaches a folder only where those names coincide (the #801 harness names the folder after the object). AVEVA `priority` and `alarm_id` are not mapped either, so Severity is 1 and ConditionName is null on AVEVA rows. + - **Production caveat, #886 (fixed in `3a312ffd`, below):** a folder's historian source is its RawPath or EquipmentId, never a Galaxy `tag_name`. AVEVA's own A&E history therefore reaches a folder only where those names coincide (the #801 harness names the folder after the object). AVEVA `priority` and `alarm_id` are not mapped either, so Severity is 1 and ConditionName is null on AVEVA rows. - **Live check:** re-ran the #801 gate read-only against vd03 HistorianGateway `ea9f21c`. 221 of 225 cases are identical to the #801 baseline; the 4 that differ are exactly the `DevWinPlatform` event cases. Record: OtOpcUa `docs/plans/evidence/2026-11-10-opcua2/aveva-history-801.md` § "#882 re-run". - **2026-11-12 master `be28aa44` (#880, not deployed): SDK 2 OtOpcUa clients log in to SDK 1.5 servers with production API keys again.** SDK 2.0.1's UserName handler sends any password over 64 bytes as an `RsaEncryptedSecret` (`EncryptionAlgorithm` null). The 64-byte threshold is a private constant with no setting, and it is unchanged in 2.0.2 and on upstream master. SDK 1.5.378 (.106 and .182) decrypts only the legacy RSA-OAEP format and answers a null algorithm with `BadIdentityTokenInvalid` before any key check. Every API key is 65 characters, so the SDK 2 CLI/UI, the OpcUaClient driver and the AdminUI browse could not log in to QA vq03/vq04 (`b8b4c18f`) or a rolled-back node.