docs(alarms): native driver-alarm TagConfig schema (Phase B)
This commit is contained in:
@@ -111,6 +111,71 @@ 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.
|
||||
|
||||
## Native driver alarms (equipment-tag path)
|
||||
|
||||
> Design reference: [docs/plans/2026-06-14-galaxy-phase-b-native-alarms-design.md](plans/2026-06-14-galaxy-phase-b-native-alarms-design.md)
|
||||
|
||||
A native driver alarm is an authored equipment `Tag` bound to an `IAlarmSource`
|
||||
driver (today: Galaxy `GalaxyMxGateway`) whose `TagConfig` carries an `"alarm"`
|
||||
object alongside the usual `"FullName"`:
|
||||
|
||||
```json
|
||||
{ "FullName": "TestMachine_002.HiAlarm", "alarm": { "alarmType": "OffNormalAlarm", "severity": 700 } }
|
||||
```
|
||||
|
||||
`"alarm"` **absent** → the tag materialises as an ordinary value variable
|
||||
(unchanged behaviour). `"alarm"` **present** → the tag materialises as a Part 9
|
||||
`AlarmConditionState` under its equipment folder **instead of** a value variable.
|
||||
No EF/schema change is required; the intent rides in the schemaless `TagConfig`
|
||||
blob and is parsed byte-parity in both the compose (`Phase7Composer`) and deploy
|
||||
(`DeploymentArtifact`) paths.
|
||||
|
||||
### TagConfig alarm fields
|
||||
|
||||
| Field | Values | Default |
|
||||
|---|---|---|
|
||||
| `alarmType` | `"AlarmCondition"`, `"OffNormalAlarm"`, `"DiscreteAlarm"`, `"LimitAlarm"` | `"AlarmCondition"` |
|
||||
| `severity` | OPC UA 1–1000 scale | `500` |
|
||||
|
||||
An unknown `alarmType` string falls back to the base `AlarmCondition` OPC UA
|
||||
ObjectType. `severity` seeds the condition's initial severity at materialisation;
|
||||
the driver's live alarm events may carry a different severity that overrides it at
|
||||
runtime.
|
||||
|
||||
### Runtime flow
|
||||
|
||||
The driver's live `IAlarmSource.OnAlarmEvent` is the sole input. Transition kinds
|
||||
(`Raise`, `Clear`, `Acknowledge`, `Retrigger`) drive the condition's Active /
|
||||
Acknowledged / Severity / Message fields via `NativeAlarmProjector`, a pure
|
||||
per-condition state projector. The projected `AlarmConditionSnapshot` is forwarded
|
||||
through `DriverHostActor` → `OpcUaPublishActor.AlarmStateUpdate` →
|
||||
`OtOpcUaNodeManager.WriteAlarmCondition` — the same delta-gated Part 9
|
||||
condition-event path that scripted alarms use, reused verbatim.
|
||||
|
||||
The same `AlarmTransitionEvent` that scripted alarms publish is emitted to the
|
||||
cluster `alerts` topic, so the AdminUI `/alerts` page and the Historian sink see
|
||||
native alarm transitions identically. Publication to the `alerts` topic is
|
||||
**Primary-gated** (only the redundancy Primary publishes cluster-wide transitions);
|
||||
the OPC UA condition-node write is ungated on all nodes so a Secondary stays warm
|
||||
for failover.
|
||||
|
||||
The alarm is authored on the `Tags` tab of the equipment page (`/uns/equipment/{id}`)
|
||||
by editing the tag's raw `TagConfig` JSON to include the `"alarm"` object. No
|
||||
other configuration is required.
|
||||
|
||||
### Deferred follow-ups
|
||||
|
||||
Two items are explicitly out of scope for Phase B:
|
||||
|
||||
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
|
||||
by editing the tag's raw `TagConfig` JSON today; a future picker enhancement
|
||||
could pre-fill `alarmType` / `severity` from driver discovery
|
||||
(`DriverAttributeInfo.IsAlarm`).
|
||||
|
||||
## Inbound operator ack/shelve
|
||||
|
||||
Operators interact with active scripted alarms through two surfaces — both converge on the same `alarm-commands` DPS topic consumed by `ScriptedAlarmHostActor`.
|
||||
|
||||
Reference in New Issue
Block a user