docs: native alarm ingestion across component docs + CLAUDE.md
This commit is contained in:
@@ -173,6 +173,58 @@ DCL is a clean data pipe on the hot path. Browse is an **opt-in capability** for
|
||||
- Browse runs against the live session; no caching at DCL.
|
||||
- **Frame-size guard**: the reply crosses the site→central Akka frame (default 128 KB) on a temp Ask actor; an oversized reply is silently discarded by remoting, hanging the picker. The child handler caps each `BrowseNodeResult` to a byte budget (~100 KB) before replying, OR-ing the adapter's own truncation signal into `Truncated`. This is protocol-agnostic (every adapter's reply funnels through it). Per-protocol upstream caps narrow the window first: OPC UA requests at most 500 references per node (continuation point → `Truncated`); MxGateway relies on the gateway's `BrowseChildren` page cap. A `Truncated` level prompts manual node-id entry in the picker rather than auto-paging.
|
||||
|
||||
## Native Alarm Mirroring
|
||||
|
||||
Some data sources publish their own alarms — OPC UA **Alarms & Conditions** servers and the **MxAccess Gateway**. The DCL can mirror these native alarms into the Site Runtime as a **read-only** feed: ScadaBridge reflects source alarm state but never acknowledges, confirms, shelves, or otherwise writes back to the source. This complements (does not replace) ScadaBridge's own computed alarms; it feeds the Site Runtime's `NativeAlarmActor` peer subsystem.
|
||||
|
||||
Like browse, this is an **opt-in capability** for protocols that support it. It does not touch the hot value path — alarm transitions flow over a separate per-connection feed.
|
||||
|
||||
### Capability Seam
|
||||
|
||||
Mirroring is exposed via the optional `IAlarmSubscribableConnection` capability interface (in Commons), which an `IDataConnection` implementation **may also** implement (mirroring the `IBrowsableDataConnection` pattern; consumed by the `DataConnectionActor` only):
|
||||
|
||||
```
|
||||
IAlarmSubscribableConnection
|
||||
├── SubscribeAlarmsAsync(sourceReference, conditionFilter?, callback, ct) → subscriptionId
|
||||
└── UnsubscribeAlarmsAsync(subscriptionId, ct) → void
|
||||
```
|
||||
|
||||
The `AlarmTransitionCallback` delivers a protocol-neutral `NativeAlarmTransition` per transition. On every (re)subscribe the adapter replays a **snapshot** of currently-active conditions (`Snapshot…` records terminated by a `SnapshotComplete` sentinel) so consumers can reconcile state after a reconnect.
|
||||
|
||||
### Protocol Adapters
|
||||
|
||||
- **OPC UA** (`OpcUaDataConnection` + `RealOpcUaClient`): a single **event MonitoredItem** (`AttributeId = EventNotifier`) on the Server object, with an `EventFilter` selecting `EventType` / `SourceNode` / `Severity` plus the `ConditionType` / `AcknowledgeableConditionType` / `AlarmConditionType` state fields. `ConditionRefresh` is invoked on subscribe to replay active conditions as the snapshot. The OPC UA field → `NativeAlarmTransition` mapping is isolated in the pure helper `OpcUaAlarmMapper`, unit-testable without a live server.
|
||||
- **MxGateway** (`MxGatewayDataConnection` + `RealMxGatewayClient`): mirrors over the gateway package's `StreamAlarmsAsync` — a resumable background stream whose reconnect re-sends a snapshot. The field mapping lives in `MxGatewayAlarmMapper`.
|
||||
|
||||
Other/custom protocols do not implement the capability; a subscribe request against such a connection is replied to with a failure (`SubscribeAlarmsResponse.Success = false`).
|
||||
|
||||
### Connection Actor Behavior
|
||||
|
||||
The `DataConnectionActor` opens **one alarm feed per connection** (not per subscriber) and routes incoming transitions to instance subscribers by **source-object reference** — a prefix match of the transition's `SourceObjectReference` (falling back to `SourceReference`) against each subscriber's registered `SourceReference`. Subscribers (the Site Runtime's `NativeAlarmActor` instances) are **ref-counted per source**, so the underlying feed is opened once and torn down only when the last subscriber for that source unsubscribes.
|
||||
|
||||
- **State gating**: `SubscribeAlarmsRequest` is handled only in the **Connected** state; requests arriving while **Connecting**/**Reconnecting** are stashed (standard Become/Stash) and processed on entering Connected.
|
||||
- **Capability check**: if `_adapter is not IAlarmSubscribableConnection`, the actor replies `SubscribeAlarmsResponse(Success = false, ...)`.
|
||||
- **Reconnect handling**: on entering **Reconnecting**, the actor pushes a `NativeAlarmSourceUnavailable` to every alarm subscriber (consumers mark mirrored alarms uncertain rather than clearing them). On successful reconnection it re-subscribes the feed; the adapter re-emits a snapshot, reconciling state.
|
||||
|
||||
### Protocol-Neutral Types & Messages
|
||||
|
||||
All defined in Commons so the feed is identical across protocols:
|
||||
|
||||
| Type | Shape |
|
||||
|------|-------|
|
||||
| `NativeAlarmTransition` | `SourceReference`, `SourceObjectReference`, `AlarmTypeName`, `Kind`, `Condition`, `Category`, `Description`, `Message`, `OperatorUser`, `OperatorComment`, `OriginalRaiseTime?`, `TransitionTime`, `CurrentValue`, `LimitValue` |
|
||||
| `AlarmConditionState` | `Active`, `Acknowledged`, `Confirmed?` (null when not confirmable), `Shelve`, `Suppressed`, `Severity` (0–1000) |
|
||||
| `AlarmTransitionKind` (enum) | `Snapshot`, `SnapshotComplete`, `Raise`, `Acknowledge`, `Clear`, `Retrigger`, `StateChange` |
|
||||
|
||||
`OperatorUser` / `OperatorComment` and `CurrentValue` / `LimitValue` are display-only mirrors from the source.
|
||||
|
||||
**Messages:**
|
||||
|
||||
- `SubscribeAlarmsRequest` / `SubscribeAlarmsResponse` — instance (via the DCL manager) subscribes a source binding to native alarms; the response carries success + an optional error message.
|
||||
- `UnsubscribeAlarmsRequest` — cancels a native alarm subscription for an instance + source.
|
||||
- `NativeAlarmTransitionUpdate(ConnectionName, Transition)` — DCL → instance: one routed transition (including snapshot replay).
|
||||
- `NativeAlarmSourceUnavailable(ConnectionName, SourceReference, Timestamp)` — DCL → instance: the feed for a source became unavailable (connection lost).
|
||||
|
||||
## Value Update Message Format
|
||||
|
||||
Each value update delivered to an Instance Actor includes:
|
||||
@@ -245,11 +297,13 @@ The DCL reports the following metrics to the Health Monitoring component via the
|
||||
## Dependencies
|
||||
|
||||
- **Site Runtime (Instance Actors)**: Receives subscription registrations and delivers value updates. Receives write requests.
|
||||
- **Site Runtime (NativeAlarmActor)**: For alarm-subscribable connections, receives `SubscribeAlarmsRequest`/`UnsubscribeAlarmsRequest` and delivers `NativeAlarmTransitionUpdate` / `NativeAlarmSourceUnavailable` (read-only native alarm mirroring).
|
||||
- **Health Monitoring**: Reports connection status.
|
||||
- **Site Event Logging**: Logs connection status changes.
|
||||
|
||||
## Interactions
|
||||
|
||||
- **Site Runtime (Instance Actors)**: Bidirectional — delivers value updates, receives subscription registrations and write-back commands.
|
||||
- **Site Runtime (NativeAlarmActor)**: Bidirectional — receives alarm subscribe/unsubscribe requests, delivers native alarm transitions and source-unavailable notifications (read-only; no ack-back to the source).
|
||||
- **Health Monitoring**: Reports connection health periodically.
|
||||
- **Site Event Logging**: Logs connection/disconnection events.
|
||||
|
||||
Reference in New Issue
Block a user