From 6e1903b23121d9faaac32b45d8aff391189dff2b Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 13 Jul 2026 09:57:36 -0400 Subject: [PATCH] docs(r2-12): document 5 alarm operator CLI commands; fix StyleGuide product name; add minimal .editorconfig (07/U-3, 07/C-5) - docs/Client.CLI.md: added ### ack / confirm / shelve / enable / disable sections (synopsis + options + example + expected output), each noting the AlarmAck LDAP-role gate and that --event-id comes from a prior `alarms` notification. Doc now covers all 13 CLI commands (was 8). Overview operations list updated. - StyleGuide.md: 'ScadaBridge' -> 'OtOpcUa' (header line 3) + the ScadaBridge:Timeout config-key example -> OpcUa:Timeout. - .editorconfig (new, root): minimal code-style anchor; all C# analyzer rules at suggestion severity so nothing fails a TreatWarningsAsErrors build (verified: 808 warnings unchanged from baseline, 0 errors). --- .editorconfig | 25 ++++ StyleGuide.md | 4 +- .../R2-12-repo-hygiene-plan.md.tasks.json | 6 +- docs/Client.CLI.md | 110 +++++++++++++++++- 4 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..1cf23163 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,25 @@ +# Minimal repo code-style anchor (R2-12 / 07/C-5). Documents the already-consistent +# conventions; all C# analyzer rules are `suggestion` severity so nothing here can fail a +# TreatWarningsAsErrors build. +root = true + +[*] +charset = utf-8 +insert_final_newline = true +indent_style = space + +[*.{cs,csproj,props,targets}] +indent_size = 4 + +[*.cs] +csharp_style_namespace_declarations = file_scoped:suggestion +dotnet_naming_rule.private_fields_underscore.severity = suggestion +dotnet_naming_rule.private_fields_underscore.symbols = private_fields +dotnet_naming_rule.private_fields_underscore.style = underscore_camel +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private +dotnet_naming_style.underscore_camel.capitalization = camel_case +dotnet_naming_style.underscore_camel.required_prefix = _ + +[*.{yml,yaml,json}] +indent_size = 2 diff --git a/StyleGuide.md b/StyleGuide.md index ad60857e..54f1fd36 100644 --- a/StyleGuide.md +++ b/StyleGuide.md @@ -1,6 +1,6 @@ # Documentation Style Guide -This guide defines writing conventions and formatting rules for all ScadaBridge documentation. +This guide defines writing conventions and formatting rules for all OtOpcUa documentation. ## Tone and Voice @@ -144,7 +144,7 @@ Use backticks for: - Class names: `ScadaGatewayActor` - Method names: `HandleMessage()` - File names: `appsettings.json` -- Configuration keys: `ScadaBridge:Timeout` +- Configuration keys: `OpcUa:Timeout` - Command-line commands: `dotnet build` ### Links diff --git a/archreview/plans/R2-12-repo-hygiene-plan.md.tasks.json b/archreview/plans/R2-12-repo-hygiene-plan.md.tasks.json index 49363eb6..84bfd7bd 100644 --- a/archreview/plans/R2-12-repo-hygiene-plan.md.tasks.json +++ b/archreview/plans/R2-12-repo-hygiene-plan.md.tasks.json @@ -9,9 +9,9 @@ { "id": 5, "subject": "T5b: U-4 — untrack pending/current + gitignore, archive stillpending + HISTORIAN-GATEWAY to docs/plans/, delete looseends.md, repoint docs/Historian.md (Commit 2; SIGN-OFF for the delete)", "status": "completed", "blockedBy": [4] }, { "id": 6, "subject": "T6: S-3 — git rm .github/workflows/v2-e2e.yml (zero Category=E2E proven; SIGN-OFF); record E2ETests+zero-match-guard follow-up", "status": "completed", "blockedBy": [] }, { "id": 7, "subject": "T7: P-5 — delete redundant integration matrix job from v2-ci.yml + fix header comments; YAML-validate (Commit 3 with T6)", "status": "completed", "blockedBy": [6] }, - { "id": 8, "subject": "T8: U-3 — add ack/confirm/shelve/enable/disable sections to docs/Client.CLI.md; correct command count to 13", "status": "pending", "blockedBy": [] }, - { "id": 9, "subject": "T9a: C-5 proof — ScadaBridge sweep of StyleGuide.md + confirm no .editorconfig", "status": "pending", "blockedBy": [] }, - { "id": 10, "subject": "T9b: C-5 — StyleGuide ScadaBridge->OtOpcUa + minimal suggestion-severity .editorconfig; no new TWE warnings (Commit 4 with T8)", "status": "pending", "blockedBy": [9] }, + { "id": 8, "subject": "T8: U-3 — add ack/confirm/shelve/enable/disable sections to docs/Client.CLI.md; correct command count to 13", "status": "completed", "blockedBy": [] }, + { "id": 9, "subject": "T9a: C-5 proof — ScadaBridge sweep of StyleGuide.md + confirm no .editorconfig", "status": "completed", "blockedBy": [] }, + { "id": 10, "subject": "T9b: C-5 — StyleGuide ScadaBridge->OtOpcUa + minimal suggestion-severity .editorconfig; no new TWE warnings (Commit 4 with T8)", "status": "completed", "blockedBy": [9] }, { "id": 11, "subject": "T10: C-4 — probe feed for xunit-v3 Akka TestKit; Branch A migrate 3 holdouts + drop 2.9.2 pin, else Branch B bump 2.9.x + blocker comment at the pin (Commit 5)", "status": "pending", "blockedBy": [] }, { "id": 12, "subject": "T11: final verification — whole-solution build+test, all hygiene assertions empty, update STATUS.md (U-9 already done, do not re-plan)", "status": "pending", "blockedBy": [1, 3, 5, 7, 8, 10, 11] } ], diff --git a/docs/Client.CLI.md b/docs/Client.CLI.md index 3d7f5a3d..1761c6b0 100644 --- a/docs/Client.CLI.md +++ b/docs/Client.CLI.md @@ -4,7 +4,7 @@ `ZB.MOM.WW.OtOpcUa.Client.CLI` is a cross-platform command-line client for the OtOpcUa OPC UA server. It targets .NET 10 and uses the shared `IOpcUaClientService` from `Client.Shared` for all OPC UA operations. Commands are routed and parsed by [CliFx](https://github.com/Tyrrrz/CliFx). -The CLI is the primary tool for operators and developers to test and interact with the server from a terminal. It supports all core operations: connectivity testing, browsing, reading, writing, subscriptions, alarm monitoring, history reads, and redundancy queries. Any driver surface exposed by the server (Galaxy, Modbus, S7, AB CIP, AB Legacy, TwinCAT, FOCAS, OPC UA Client) is reachable through these commands — the CLI is driver-agnostic because everything below the OPC UA endpoint is. +The CLI is the primary tool for operators and developers to test and interact with the server from a terminal. It supports all core operations: connectivity testing, browsing, reading, writing, subscriptions, alarm monitoring, alarm operator actions (acknowledge / confirm / shelve / enable / disable), history reads, and redundancy queries. Any driver surface exposed by the server (Galaxy, Modbus, S7, AB CIP, AB Legacy, TwinCAT, FOCAS, OPC UA Client) is reachable through these commands — the CLI is driver-agnostic because everything below the OPC UA endpoint is. ## Build and Run @@ -240,6 +240,114 @@ otopcua-cli alarms -u opc.tcp://localhost:4840/OtOpcUa \ | `-i` / `--interval` | Publishing interval in milliseconds (default: 1000) | | `--refresh` | Request a `ConditionRefresh` after subscribing to get current retained alarm states | +### ack + +Acknowledges an active alarm condition via the OPC UA Part 9 `Acknowledge` method. The server gates this on the **`AlarmAck`** LDAP role (fail-closed — a session without `AlarmAck` group membership gets `BadUserAccessDenied`; see [ScriptedAlarms.md](ScriptedAlarms.md) §"AlarmAck gate"). The `--event-id` is the hex-encoded `EventId` taken from a prior `alarms` subscription notification for the same condition. + +```bash +otopcua-cli ack -u opc.tcp://localhost:4840/OtOpcUa \ + -n "ns=1;s=TestMachine_001" -e 0A1B2C -c "Investigating" +``` + +| Flag | Description | +|------|-------------| +| `-n` / `--node` | Condition node ID of the alarm to acknowledge (**required**) | +| `-e` / `--event-id` | `EventId` from the alarm notification, hex-encoded (e.g. `0A1B2C`) (**required**) | +| `-c` / `--comment` | Operator comment for the acknowledgment (optional) | + +Example output: + +```text +Acknowledge successful: ns=1;s=TestMachine_001 +``` + +### confirm + +Confirms an already-acknowledged alarm condition via the OPC UA Part 9 `Confirm` method — the second stage of two-stage acknowledgment. Same `AlarmAck` role gate and same `--event-id` source (a prior `alarms` notification) as `ack`. + +```bash +otopcua-cli confirm -u opc.tcp://localhost:4840/OtOpcUa \ + -n "ns=1;s=TestMachine_001" -e 0A1B2C -c "Root cause cleared" +``` + +| Flag | Description | +|------|-------------| +| `-n` / `--node` | Condition node ID of the alarm to confirm (**required**) | +| `-e` / `--event-id` | `EventId` from the alarm notification, hex-encoded (**required**) | +| `-c` / `--comment` | Operator comment for the confirmation (optional) | + +Example output: + +```text +Confirm successful: ns=1;s=TestMachine_001 +``` + +### shelve + +Shelves or unshelves an active alarm condition via the OPC UA Part 9 `ShelvedStateMachine` (`OneShotShelve` / `TimedShelve` / `Unshelve`). Gated on the `AlarmAck` role. `--duration` is given in **seconds** (converted to milliseconds for the OPC UA call) and is required only for `--kind Timed`. + +```bash +# One-shot shelve until the next clear +otopcua-cli shelve -u opc.tcp://localhost:4840/OtOpcUa \ + -n "ns=1;s=TestMachine_001" -k OneShot + +# Timed shelve for 300 seconds +otopcua-cli shelve -u opc.tcp://localhost:4840/OtOpcUa \ + -n "ns=1;s=TestMachine_001" -k Timed -d 300 + +# Unshelve +otopcua-cli shelve -u opc.tcp://localhost:4840/OtOpcUa \ + -n "ns=1;s=TestMachine_001" -k Unshelve +``` + +| Flag | Description | +|------|-------------| +| `-n` / `--node` | Condition node ID of the alarm to shelve/unshelve (**required**) | +| `-k` / `--kind` | Shelve operation: `OneShot` \| `Timed` \| `Unshelve` (**required**) | +| `-d` / `--duration` | Shelving duration in **seconds** (must be > 0; **required for `--kind Timed`**) | + +Example output: + +```text +Timed successful: ns=1;s=TestMachine_001 +``` + +### enable + +Enables an alarm condition via the OPC UA Part 9 `ConditionType.Enable` method (resumes evaluation/reporting for a previously disabled condition). Gated on the `AlarmAck` role. + +```bash +otopcua-cli enable -u opc.tcp://localhost:4840/OtOpcUa -n "ns=1;s=TestMachine_001" +``` + +| Flag | Description | +|------|-------------| +| `-n` / `--node` | Condition node ID of the alarm to enable (**required**) | + +Example output: + +```text +Enable successful: ns=1;s=TestMachine_001 +``` + +### disable + +Disables an alarm condition via the OPC UA Part 9 `ConditionType.Disable` method (stops evaluation/reporting). Gated on the `AlarmAck` role. + +```bash +otopcua-cli disable -u opc.tcp://localhost:4840/OtOpcUa -n "ns=1;s=TestMachine_001" +``` + +| Flag | Description | +|------|-------------| +| `-n` / `--node` | Condition node ID of the alarm to disable (**required**) | + +Example output: + +```text +Disable successful: ns=1;s=TestMachine_001 +``` + ### redundancy Reads the OPC UA redundancy state from a server: redundancy mode, service level, server URIs, and application URI.