diff --git a/docs/AlarmTracking.md b/docs/AlarmTracking.md index 03f03d62..54bfa527 100644 --- a/docs/AlarmTracking.md +++ b/docs/AlarmTracking.md @@ -13,7 +13,7 @@ historical reference. |----------------------------------|--------------------------|------| | **Galaxy MxAccess (driver-native)** | `GalaxyDriver : IAlarmSource` | gateway → worker → MxAccess alarm sink → `MX_EVENT_FAMILY_ON_ALARM_TRANSITION` → `EventPump` → driver `OnAlarmEvent` → `AlarmConditionService` | | **Galaxy sub-attribute fallback** | `IWritable` writes to `$Alarm*` sub-attributes | gateway data subscription → driver `OnDataChange` → `DriverNodeManager` ConditionSink → `AlarmConditionService` | -| **Scripted alarms** | `Phase7EngineComposer` | server-side script evaluator → `Phase7EngineComposer.RouteToHistorianAsync` + `AlarmConditionService` | +| **Scripted alarms** | `Phase7Composer` | server-side script evaluator → `ScriptedAlarmActor` transitions → `HistorianAdapterActor` → `IAlarmHistorianSink` | All three converge on the alarm-state actor — in v2 the OPC UA Part 9 state machine lives inside `ScriptedAlarmActor` @@ -104,23 +104,25 @@ calls. Scripted alarms (and any future non-Galaxy `IAlarmSource` like AB CIP ALMD) route to AVEVA Historian via the Wonderware sidecar: -- `Phase7Composer.ResolveHistorianSink` resolves an - `IAlarmHistorianWriter` from either a driver that natively - implements it or the DI-registered `WonderwareHistorianClient` - (the sidecar IPC client). Driver-provided wins when both are - present. +- `IAlarmHistorianSink` is the DI-registered intake contract. The + default binding is `NullAlarmHistorianSink` (registered in + `ServiceCollectionExtensions.AddOtOpcUaRuntime`). Production + deployments override it with `SqliteStoreAndForwardSink` wrapping + `WonderwareHistorianClient` (the AVEVA Historian sidecar IPC client) + — see [ServiceHosting.md](ServiceHosting.md) for the sidecar setup. - `SqliteStoreAndForwardSink` queues each transition to a local - SQLite database and drains in the background via the resolved - writer. **The durability guarantee is bounded**: the queue capacity - defaults to 1,000,000 rows; under a sustained historian outage, - older non-dead-lettered rows are evicted (oldest first) to make - room for new events. The `HistorianSinkStatus.EvictedCount` counter - surfaces lifetime eviction events to the Admin UI - `/alarms/historian` diagnostics page so operators can detect silent - data loss without log scraping. -- Sidecar (PR C.1 + C.2) forwards the events to `aahClientManaged`'s - alarm-event write API; the live SDK call site is pinned during - PR D.1's deploy-rig validation. + SQLite database and drains in the background via an + `IAlarmHistorianWriter`. **The durability guarantee is bounded**: the + queue capacity defaults to 1,000,000 rows; under a sustained + historian outage, older non-dead-lettered rows are evicted (oldest + first) to make room for new events. The `HistorianSinkStatus.EvictedCount` + counter surfaces lifetime eviction events so operators can detect + silent data loss without log scraping. +- `HistorianAdapterActor` + (`src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Historian/HistorianAdapterActor.cs`) + bridges Akka cluster messages from `ScriptedAlarmActor` into the + sink's `EnqueueAsync`; fire-and-forget so the actor loop is never + blocked on historian reachability. Galaxy-native alarms with `$Alarm*` extensions reach AVEVA Historian directly via System Platform's `HistorizeToAveva` toggle on the @@ -133,4 +135,4 @@ exclusively for non-Galaxy alarm producers. - v1 archive: [docs/v1/AlarmTracking.md](v1/AlarmTracking.md) - Galaxy driver: [docs/drivers/Galaxy.md](drivers/Galaxy.md) - Phase 7 scripting + alarming: [docs/v2/implementation/phase-7-scripting-and-alarming.md](v2/implementation/phase-7-scripting-and-alarming.md) -- Security + ACL: [docs/Security.md](Security.md) +- Security + ACL: [docs/security.md](security.md)