docs(alarms): OPC UA Enable/Disable wired + native-ack→AVEVA with principal + HistoryUpdate permission bit
This commit is contained in:
+25
-9
@@ -109,7 +109,7 @@ Every mutation the state machine produces is immediately persisted inside the en
|
||||
Two mapping notes specific to this adapter:
|
||||
|
||||
- `SubscribeAlarmsAsync` accepts a list of source-node-id filters, interpreted as Equipment-path prefixes. Empty list matches every alarm. Each emission is matched against every live subscription — the adapter keeps no per-subscription cursor.
|
||||
- `IAlarmSource.AcknowledgeAsync` does not carry a user identity. The adapter defaults the audit user to `"opcua-client"` so callers using the base interface still produce an audit entry. The server's Part 9 method handlers call the engine's richer `AcknowledgeAsync` / `ConfirmAsync` / `OneShotShelveAsync` / `TimedShelveAsync` / `UnshelveAsync` / `AddCommentAsync` directly with the authenticated principal instead.
|
||||
- `IAlarmSource.AcknowledgeAsync` accepts an `AlarmAcknowledgeRequest` list; the `OperatorUser` field carries the authenticated principal when available. The adapter passes `OperatorUser` through to the engine's `AcknowledgeAsync`; when `OperatorUser` is null (non-OPC-UA callers using the raw interface) it falls back to `"opcua-client"` so callers still produce an audit entry. The server's Part 9 method handlers call the engine's richer `AcknowledgeAsync` / `ConfirmAsync` / `OneShotShelveAsync` / `TimedShelveAsync` / `UnshelveAsync` / `AddCommentAsync` directly with the authenticated principal instead of going through this adapter.
|
||||
|
||||
## Native driver alarms (equipment-tag path)
|
||||
|
||||
@@ -193,15 +193,27 @@ The alarm is authored on the `Tags` tab of the equipment page (`/uns/equipment/{
|
||||
by editing the tag's raw `TagConfig` JSON to include the `"alarm"` object. No
|
||||
other configuration is required.
|
||||
|
||||
### Deferred follow-ups
|
||||
### Native-alarm OPC UA operator operations
|
||||
|
||||
Two items are explicitly out of scope for Phase B:
|
||||
An OPC UA client can **Acknowledge** a native (e.g. Galaxy) condition and the ack
|
||||
now propagates to the device. The `OnAcknowledge` handler on a native condition
|
||||
routes through a separate `NativeAlarmAckRouter` seam (instead of the scripted
|
||||
`AlarmCommandRouter`) → `DriverHostActor` (a condition NodeId → `(DriverInstanceId,
|
||||
FullName)` inverse map, Primary-gated) → the owning driver's
|
||||
`IAlarmSource.AcknowledgeAsync` → Galaxy gateway → AVEVA. The call carries the
|
||||
authenticated operator's display name via the `AlarmAcknowledgeRequest.OperatorUser`
|
||||
field. This is fire-and-forget — a failed upstream ack is not surfaced back to the
|
||||
OPC UA client (mirrors the Galaxy write-outcome limitation). See [AlarmTracking.md
|
||||
§Native alarm acknowledge → AVEVA](AlarmTracking.md#native-alarm-acknowledge--aveva)
|
||||
for the full routing diagram.
|
||||
|
||||
1. **Inbound device-ack**: an OPC UA client `Acknowledge` currently updates the
|
||||
local `AlarmConditionState` but does **not** yet propagate back to the device
|
||||
via `IAlarmSource.AcknowledgeAsync` (→ AVEVA). Device-ack round-trip is a
|
||||
deferred follow-up.
|
||||
2. **AdminUI Galaxy address-picker pre-fill**: the `alarm` object must be authored
|
||||
**Enable/Disable** on a native condition returns `BadNotSupported` — the driver
|
||||
backing a native alarm has no enable/disable surface distinct from OPC UA; the
|
||||
Part 9 enable/disable concept maps to the scripted-alarm engine only.
|
||||
|
||||
One item remains explicitly out of scope:
|
||||
|
||||
1. **AdminUI Galaxy address-picker pre-fill**: the `alarm` object must be authored
|
||||
by editing the tag's raw `TagConfig` JSON today; a future picker enhancement
|
||||
could pre-fill `alarmType` / `severity` from driver discovery
|
||||
(`DriverAttributeInfo.IsAlarm`).
|
||||
@@ -212,10 +224,14 @@ Operators interact with active scripted alarms through two surfaces — both con
|
||||
|
||||
### AlarmAck gate (OPC UA method path)
|
||||
|
||||
`OtOpcUaNodeManager` wires the OPC UA Part 9 condition methods (Acknowledge / Confirm / AddComment / OneShotShelve / TimedShelve / Unshelve) on each `AlarmConditionState` node. Every method call is gated on the `AlarmAck` LDAP role — fail-closed: a session with no resolved roles or no `AlarmAck` group membership receives `BadUserAccessDenied` immediately without reaching the engine. The role is carried on the session by `RoleCarryingUserIdentity` (a `UserIdentity` subclass that preserves the LDAP-resolved role set past `OpcUaApplicationHost`).
|
||||
`OtOpcUaNodeManager` wires the OPC UA Part 9 condition methods (Acknowledge / Confirm / AddComment / OneShotShelve / TimedShelve / Unshelve / Enable / Disable) on each `AlarmConditionState` node. Every method call is gated on the `AlarmAck` LDAP role — fail-closed: a session with no resolved roles or no `AlarmAck` group membership receives `BadUserAccessDenied` immediately without reaching the engine. The role is carried on the session by `RoleCarryingUserIdentity` (a `UserIdentity` subclass that preserves the LDAP-resolved role set past `OpcUaApplicationHost`).
|
||||
|
||||
On allow, the handler publishes a `Commons.OpcUa.AlarmCommand` (containing command kind, condition id, comment, and operator principal) onto the `alarm-commands` DPS topic. The node manager itself stays Akka-free: the dispatch action is a settable `Action<AlarmCommand>` injected at boot by the hosted service.
|
||||
|
||||
**Scripted vs native conditions — Enable/Disable and Acknowledge:**
|
||||
- **Scripted conditions** — all eight Part 9 operations (including Enable/Disable) route through `AlarmCommandRouter` onto the `alarm-commands` topic, which `ScriptedAlarmHostActor` dispatches to the engine (`EnableAsync` / `DisableAsync` / `AcknowledgeAsync` / …). On enable, `ActiveState` is re-derived from the next predicate evaluation.
|
||||
- **Native (driver-fed) conditions** — `OnAcknowledge` branches to `NativeAlarmAckRouter` and routes the ack to the owning driver rather than the scripted engine (see §[Native-alarm OPC UA operator operations](#native-alarm-opc-ua-operator-operations) above). `OnEnableDisable` returns `BadNotSupported` immediately — native conditions have no engine-side enable/disable surface.
|
||||
|
||||
`OnTimedUnshelve` (the SDK's internal auto-unshelve timer) bypasses the client gate — it is system-initiated and not subject to operator role checks.
|
||||
|
||||
### Delta-gate de-duplication
|
||||
|
||||
Reference in New Issue
Block a user