docs: close native-alarm spec gaps surfaced by docs audit

The native alarms feature merged with 7 component docs updated, but the
spec layer drifted: HighLevelReqs, Commons, and ManagementService had no
native-alarm coverage and the README table flagged it on only one row.
Add HighLevelReqs §3.4.2 (+ validation), document the Commons
types/entities/messages and the 7 ManagementService commands, sync the
README rows + link the TreeView sub-component, fix 2 broken plan links,
and drop the one-off native-alarms RESUME scratchpad.
This commit is contained in:
Joseph Doherty
2026-05-31 07:41:49 -04:00
parent 9afcdc996e
commit f428804bef
6 changed files with 64 additions and 90 deletions
+25 -9
View File
@@ -34,6 +34,11 @@ Commons must define shared primitive and utility types used across multiple comp
- **`AlarmState` enum**: Active, Normal.
- **`AlarmLevel` enum**: None, Low, LowLow, High, HighHigh. Severity level for an active alarm; always `None` for binary trigger types, set by `HiLo` triggers.
- **`AlarmTriggerType` enum**: ValueMatch, RangeViolation, RateOfChange, HiLo.
- **`AlarmKind` enum**: Computed, NativeOpcUa, NativeMxAccess. Discriminates how an alarm's state is produced — evaluated at the site by an `AlarmActor` from attribute triggers (`Computed`) vs. mirrored read-only from a native source (OPC UA Alarms & Conditions / MxAccess Gateway).
- **`AlarmShelveState` enum**: Unshelved, OneShotShelved, TimedShelved, PermanentShelved. OPC UA Part 9 shelving sub-state of an alarm condition; mirrored read-only from the source. Computed alarms are always `Unshelved`.
- **`AlarmTransitionKind` enum**: Snapshot, SnapshotComplete, Raise, Acknowledge, Clear, Retrigger, StateChange. Classifies a `NativeAlarmTransition`; `Snapshot`/`SnapshotComplete` carry the initial active-condition replay produced on every (re)subscribe so consumers can re-seed state.
- **`AlarmConditionState`**: The unified, read-only alarm condition state. The OPC UA Part 9 sub-conditions are orthogonal (and MxAccess's ACTIVE / ACTIVE_ACKED / INACTIVE map cleanly onto them), so they are modeled as independent flags — `Active`, `Acknowledged`, `Confirmed` (`bool?`; null when not confirmable), `Shelve` (`AlarmShelveState`), `Suppressed` — plus a `Severity` on the unified 01000 scale. Computed alarms populate it from State + Priority; native alarms mirror it from the source. (Helper `AlarmConditionStateFactory` builds the computed-alarm projection.)
- **`NativeAlarmTransition`**: The protocol-neutral alarm transition emitted by an `IAlarmSubscribableConnection` adapter — `SourceReference` (stable per-condition key), `SourceObjectReference` (owning source object, used for instance routing), `AlarmTypeName`, `Kind` (`AlarmTransitionKind`), `Condition` (`AlarmConditionState`), source taxonomy/operator/value metadata (`Category`, `Description`, `Message`, `OperatorUser`, `OperatorComment`, `CurrentValue`, `LimitValue`), and `OriginalRaiseTime?` / `TransitionTime`.
- **`ConnectionHealth` enum**: Connected, Disconnected, Connecting, Error.
- **`TrackedOperationId`**: A GUID identifying a tracked store-and-forward operation (`ExternalSystem.CachedCall`, `Database.CachedWrite`, `Notify.Send`). Generated caller-side at the site at call time, returned to the script as a tracking handle, and reused as the idempotency key for telemetry sent to central. The notification domain's existing `NotificationId` is the notification-specific name for this same concept.
- **`TrackedOperationKind` enum**: ExternalCall, DatabaseWrite. Discriminates the two cached-call kinds carried by a tracked operation (notifications are tracked separately via the `NotificationType` enum).
@@ -54,6 +59,7 @@ Types defined here must be immutable and thread-safe.
Commons must define the protocol abstraction interfaces that the Data Connection Layer implements and other components consume:
- **`IDataConnection`**: The common interface for reading, writing, and subscribing to device data regardless of the underlying protocol (OPC UA, custom legacy, etc.).
- **`IAlarmSubscribableConnection`**: An **optional capability interface** an `IDataConnection` implementation *may also* implement when its source can mirror native alarms (OPC UA Alarms & Conditions, MxAccess Gateway). Exposes `SubscribeAlarmsAsync(sourceReference, conditionFilter, callback, ct)` (returns a subscription id; replays a snapshot of currently-active conditions on every (re)subscribe) and `UnsubscribeAlarmsAsync(subscriptionId, ct)`. Transitions are delivered via the `AlarmTransitionCallback` delegate as protocol-neutral `NativeAlarmTransition` records. Mirrors the `IBrowsableDataConnection` capability-interface pattern; consumed by the Data Connection Layer's `DataConnectionActor` only.
- **Related types**: Tag identifiers, read/write results, subscription callbacks, connection status enums, and quality codes.
These interfaces must not reference any specific protocol implementation.
@@ -69,8 +75,8 @@ Commons must define persistence-ignorant POCO entity classes for all configurati
Entity classes are organized by domain area:
- **Template & Modeling**: `Template`, `TemplateAttribute`, `TemplateAlarm`, `TemplateScript`, `TemplateComposition`, `TemplateFolder`.
- **Instances**: `Instance`, `InstanceAttributeOverride`, `InstanceConnectionBinding`, `InstanceAlarmOverride`, `Area`.
- **Template & Modeling**: `Template`, `TemplateAttribute`, `TemplateAlarm`, `TemplateNativeAlarmSource`, `TemplateScript`, `TemplateComposition`, `TemplateFolder`. `TemplateNativeAlarmSource` is a read-only binding (Name, Description, ConnectionName, SourceReference, optional ConditionFilter, plus `IsLocked`/`IsInherited`/`LockedInDerived` lock flags) to a native alarm source; inheritance/lock semantics mirror `TemplateAlarm`.
- **Instances**: `Instance`, `InstanceAttributeOverride`, `InstanceConnectionBinding`, `InstanceAlarmOverride`, `InstanceNativeAlarmSourceOverride`, `Area`. `InstanceNativeAlarmSourceOverride` retargets an inherited native alarm source per physical instance, keyed by `SourceCanonicalName`; its `ConnectionNameOverride` / `SourceReferenceOverride` / `ConditionFilterOverride` fields each apply only when non-null (null keeps the inherited value), mirroring `InstanceAlarmOverride`.
- **Shared Scripts**: `SharedScript`.
- **Sites & Data Connections**: `Site`, `DataConnection`.
- **External Systems & Database Connections**: `ExternalSystemDefinition`, `ExternalSystemMethod`, `DatabaseConnectionDefinition`.
@@ -86,7 +92,7 @@ The **`Notification`** entity is the persistence-ignorant POCO for a row of the
Commons must define repository interfaces that consuming components use for data access. Each interface is tailored to the data needs of its consuming component:
- `ITemplateEngineRepository` — Templates, attributes, alarms, scripts, compositions, template folders, instances, overrides, alarm overrides, connection bindings, areas.
- `ITemplateEngineRepository` — Templates, attributes, alarms, native alarm sources, scripts, compositions, template folders, instances, overrides, alarm overrides, native alarm source overrides, connection bindings, areas.
- `IDeploymentManagerRepository` — Deployment records, deployed configuration snapshots, system-wide artifact deployment records.
- `ISecurityRepository` — LDAP group mappings, site scoping rules.
- `IInboundApiRepository` — API keys, API method definitions.
@@ -134,7 +140,8 @@ Commons must define the shared DTOs and message contracts used for inter-compone
- **Instance Lifecycle DTOs**: Disable, enable, delete commands and responses.
- **Health DTOs**: Health check results, site status reports, heartbeat messages. Includes script error rates and alarm evaluation error rates.
- **Communication DTOs**: Site identity, connection state, routing metadata.
- **Attribute Stream DTOs**: Attribute value change messages (instance name, attribute path, value, quality, timestamp) and alarm state change messages (instance name, alarm name, state, priority, timestamp) for the site-wide Akka stream.
- **Attribute Stream DTOs**: Attribute value change messages (instance name, attribute path, value, quality, timestamp) and alarm state change messages (instance name, alarm name, state, priority, timestamp) for the site-wide Akka stream. The alarm state change message (`AlarmStateChanged`) is **additively enriched** to carry both computed and native alarms on one shape: an `AlarmKind` discriminator, the unified `AlarmConditionState`, and native metadata (`SourceReference`, `AlarmTypeName`, `Category`, `OperatorUser`, `OperatorComment`, `OriginalRaiseTime`, `CurrentValue`, `LimitValue`) — defaulted/empty for computed alarms. Subject to the additive-only evolution rules in REQ-COM-5a, since it crosses the site→central gRPC stream.
- **Native Alarm DTOs** (`Messages/DataConnection/`): the read-only native alarm mirror messages between the Site Runtime and the Data Connection Layer — `SubscribeAlarmsRequest` / `SubscribeAlarmsResponse` (subscribe a source binding; response carries success + optional error), `UnsubscribeAlarmsRequest`, `NativeAlarmTransitionUpdate` (`ConnectionName`, `Transition` — one routed `NativeAlarmTransition`, including snapshot replay), and `NativeAlarmSourceUnavailable` (`ConnectionName`, `SourceReference`, `Timestamp` — the feed dropped on connection loss).
- **Debug View DTOs**: Subscribe/unsubscribe requests, one-shot snapshot request (`DebugSnapshotRequest`), initial snapshot, stream filter criteria.
- **Script Execution DTOs**: Script call requests (with recursion depth), return values, error results.
- **System-Wide Artifact DTOs**: Shared script packages, external system definitions, database connection definitions, notification list definitions.
@@ -174,13 +181,17 @@ ZB.MOM.WW.ScadaBridge.Commons/
│ ├── SiteCallOperational.cs # SiteCalls operational-row projection
│ ├── TrackingStatusSnapshot.cs # site-local Tracking.Status(id) projection
│ ├── Enums/ # InstanceState, DeploymentStatus, AlarmState,
│ │ # AlarmLevel, AlarmTriggerType, ConnectionHealth,
│ │ # AlarmLevel, AlarmTriggerType, AlarmKind,
│ │ # AlarmShelveState, AlarmTransitionKind,
│ │ # ConnectionHealth,
│ │ # DataType, StoreAndForwardCategory,
│ │ # StoreAndForwardMessageStatus,
│ │ # NotificationType, NotificationStatus,
│ │ # TrackedOperationKind, TrackedOperationStatus,
│ │ # AuditChannel, AuditKind, AuditStatus,
│ │ # AuditForwardState
│ ├── Alarms/ # AlarmConditionState, AlarmConditionStateFactory,
│ │ # NativeAlarmTransition (unified read-only condition model)
│ ├── Audit/ # AuditLogPaging, AuditLogQueryFilter,
│ │ # AuditQueryParamParsers, ExecutionTreeNode,
│ │ # SiteCallKpiSnapshot, SiteCallPaging,
@@ -199,7 +210,9 @@ ZB.MOM.WW.ScadaBridge.Commons/
├── Interfaces/ # Shared interfaces by concern
│ ├── IOperationTrackingStore.cs # site-local tracked-operation status store
│ ├── IPartitionMaintenance.cs # central partition-switch / retention purge hook
│ ├── Protocol/ # REQ-COM-2: Protocol abstraction (IDataConnection, etc.)
│ ├── Protocol/ # REQ-COM-2: Protocol abstraction (IDataConnection,
│ │ # IBrowsableDataConnection, IAlarmSubscribableConnection,
│ │ # AlarmTransitionCallback)
│ ├── Repositories/ # REQ-COM-4: Per-component repository interfaces
│ │ ├── ITemplateEngineRepository.cs
│ │ ├── IDeploymentManagerRepository.cs
@@ -231,9 +244,11 @@ ZB.MOM.WW.ScadaBridge.Commons/
│ └── IBundleSessionStore.cs
├── Entities/ # REQ-COM-3: Domain entity POCOs, by domain area
│ ├── Templates/ # Template, TemplateAttribute, TemplateAlarm,
│ │ # TemplateScript, TemplateComposition, TemplateFolder
│ │ # TemplateNativeAlarmSource, TemplateScript,
│ │ # TemplateComposition, TemplateFolder
│ ├── Instances/ # Instance, InstanceAttributeOverride,
│ │ # InstanceConnectionBinding, InstanceAlarmOverride, Area
│ │ # InstanceConnectionBinding, InstanceAlarmOverride,
│ │ # InstanceNativeAlarmSourceOverride, Area
│ ├── Sites/ # Site, DataConnection
│ ├── ExternalSystems/ # ExternalSystemDefinition, ExternalSystemMethod,
│ │ # DatabaseConnectionDefinition
@@ -256,7 +271,8 @@ ZB.MOM.WW.ScadaBridge.Commons/
│ ├── DebugView/
│ ├── ScriptExecution/
│ ├── Artifacts/
│ ├── DataConnection/ # data-connection subscribe/write/health messages
│ ├── DataConnection/ # data-connection subscribe/write/health messages,
│ │ # native alarm subscribe/transition messages
│ ├── Instance/ # attribute get/set request/command messages
│ ├── Integration/ # external-integration call request/response,
│ │ # cached-call tracking telemetry + reconcile,
@@ -105,6 +105,8 @@ Both endpoints honour any site-scope rules attached to the caller's audit role b
- **AddTemplateAttribute** / **UpdateTemplateAttribute** / **DeleteTemplateAttribute**: Manage attributes on a template.
- **AddTemplateAlarm** / **UpdateTemplateAlarm** / **DeleteTemplateAlarm**: Manage alarm definitions on a template.
- **AddTemplateNativeAlarmSource** / **UpdateTemplateNativeAlarmSource** / **DeleteTemplateNativeAlarmSource**: Manage native alarm source bindings (the read-only OPC UA Alarms & Conditions / MxAccess Gateway mirror) on a template — `Name`, `ConnectionName`, `SourceReference`, optional `ConditionFilter` / `Description`, `IsLocked`. Mutations gated to the **Design** role; handlers write through `ITemplateEngineRepository` directly.
- **ListTemplateNativeAlarmSources** (`TemplateId`): List a template's native alarm source bindings (read-only; any authenticated user).
- **AddTemplateScript** / **UpdateTemplateScript** / **DeleteTemplateScript**: Manage scripts on a template.
- **AddTemplateComposition** / **DeleteTemplateComposition**: Manage feature module compositions on a template.
@@ -113,6 +115,9 @@ Both endpoints honour any site-scope rules attached to the caller's audit role b
- **ListInstances** / **GetInstance**: Query instances, with filtering by site and area.
- **CreateInstance**: Create a new instance from a template.
- **UpdateInstanceOverrides**: Set attribute overrides on an instance.
- **SetInstanceAlarmOverride** / **DeleteInstanceAlarmOverride** / **ListInstanceAlarmOverrides**: Manage per-instance computed-alarm overrides.
- **SetInstanceNativeAlarmSourceOverride** / **DeleteInstanceNativeAlarmSourceOverride**: Retarget or clear a per-instance native alarm source binding, keyed by `SourceCanonicalName``ConnectionNameOverride` / `SourceReferenceOverride` / `ConditionFilterOverride` each apply only when non-null. Gated to the **Deployment** role.
- **ListInstanceNativeAlarmSourceOverrides** (`InstanceId`): List an instance's native alarm source overrides (read-only).
- **SetInstanceBindings** / **BindDataConnections**: Bind data connections to instance attributes.
- **AssignArea**: Assign an instance to an area.
- **EnableInstance** / **DisableInstance** / **DeleteInstance**: Instance lifecycle commands.
@@ -193,8 +198,8 @@ Both endpoints honour any site-scope rules attached to the caller's audit role b
Every incoming message carries the authenticated user's identity and roles. The ManagementActor enforces the same role-based authorization rules as the Central UI:
- **Admin** role required for: site management, area management, API key management, role mapping management, scope rule management, system configuration.
- **Design** role required for: template authoring (including template member management: attributes, alarms, scripts, compositions), shared scripts, external system definitions, database connection definitions, notification lists, inbound API method definitions.
- **Deployment** role required for: instance management, deployments, debug view, debug snapshot, parked message queries, site event log queries. Site scoping is enforced for site-scoped Deployment users.
- **Design** role required for: template authoring (including template member management: attributes, alarms, native alarm sources, scripts, compositions), shared scripts, external system definitions, database connection definitions, notification lists, inbound API method definitions.
- **Deployment** role required for: instance management (including instance alarm overrides and native alarm source overrides), deployments, debug view, debug snapshot, parked message queries, site event log queries. Site scoping is enforced for site-scoped Deployment users.
- **Read-only access** (any authenticated role): health summary, health site, site event log queries, parked message queries.
Unauthorized commands receive an `Unauthorized` response message. Failed authorization attempts are not audit logged (consistent with existing behavior).
+23
View File
@@ -119,6 +119,28 @@ Each alarm has:
- Alarm state is **not persisted** — on restart, alarm states are re-evaluated from incoming values.
- Alarm state changes are published to the site-wide Akka stream as `[InstanceUniqueName].[AlarmName]`, alarm state (active/normal), alarm level, priority, timestamp.
### 3.4.2 Native Alarms (Read-Only Mirror)
Sections 3.4 and 3.4.1 describe **computed alarms** — alarms ScadaBridge evaluates at the site from attribute triggers. The system additionally **mirrors native alarms** already raised by upstream systems — **OPC UA Alarms & Conditions** servers and the **MxAccess Gateway**. Native alarms are surfaced read-only alongside computed alarms; ScadaBridge reflects source-reported state but **never acknowledges, confirms, shelves, suppresses, or otherwise writes back** to the source — the source system owns the alarm lifecycle.
**Native alarm source bindings** are first-class template members alongside attributes, alarms, and scripts, following the same **inheritance, override, and lock rules**. Each binding has:
- **Name**: Identifier for the source binding within the template.
- **Description** *(optional)*.
- **Connection**: The data connection that carries the native alarms (must be alarm-capable — an OPC UA A&C or MxAccess Gateway connection).
- **Source Reference**: The source-side address the alarms are read from — an OPC UA `SourceNode`/notifier nodeId, or an MxAccess object/area.
- **Condition Filter** *(optional)*: Narrows which conditions under the source are mirrored; when omitted, **all** conditions under the source are mirrored.
- **Lock Flag**: Controls whether the binding can be overridden downstream.
Because the source reference typically varies per physical instance (e.g. `Tank01` vs `Tank02`), an instance may **override** a non-locked binding's connection, source reference, and/or condition filter individually — a null override field keeps the inherited value. Bindings cannot be added or removed at the instance level, only retargeted.
**Unified condition model.** Computed and native alarms share one **condition state** so they present uniformly: orthogonal **Active**, **Acknowledged**, **Confirmed** (when confirmable), **Shelved**, and **Suppressed** flags plus a **01000 severity**. An **alarm kind** discriminator distinguishes `Computed`, `NativeOpcUa`, and `NativeMxAccess`. Computed alarms project onto this model as auto-acknowledged with severity equal to their priority; native alarms mirror the source condition directly.
**Runtime behavior:**
- Native alarm sources are **discovered and subscribed at runtime** — at deploy time the site subscribes each resolved binding through the Data Connection Layer, which opens **one alarm feed per connection** and routes transitions to instances by source-object reference. A site-side actor (peer to the computed alarm actor) mirrors each source binding.
- On every (re)subscribe the source **replays a snapshot** of currently-active conditions so state is reconciled after a reconnect. On connection loss, mirrored conditions are **marked uncertain rather than cleared**, so a transient disconnect does not flap every condition to normal.
- Unlike computed alarm state (not persisted, re-evaluated on restart), mirrored native alarm state **is persisted at the site** so it survives restart/failover; it is **cleared on redeployment/undeployment** (mirroring static attribute overrides).
- Native alarm state is streamed to the central cluster over the **existing real-time gRPC stream** (additively, alongside computed alarm state) and is surfaced **only in the on-demand debug view** — there is no dedicated operator/alarm-summary page and **no central alarm tables**. The debug view shows the alarm kind, unified severity, and condition sub-state badges, but offers **no ack-back or command actions** for native alarms.
### 3.5 Template Relationships
Templates participate in two distinct relationship types:
@@ -192,6 +214,7 @@ Before any deployment is sent to a site, the central cluster performs **comprehe
- **Naming collision detection**: No duplicate attribute, alarm, or script names exist in the flattened configuration.
- **Script compilation**: All instance scripts and alarm on-trigger scripts are test-compiled and must compile without errors.
- **Alarm trigger references**: Alarm trigger definitions reference attributes that exist in the flattened configuration.
- **Native alarm source bindings**: Each resolved native alarm source has a non-empty source reference and connection name, and — when the alarm-capable connection set is supplied — the bound connection exists and is alarm-capable (an OPC UA A&C or MxAccess Gateway connection).
- **Script trigger references**: Script triggers (value change, conditional) reference attributes that exist in the flattened configuration.
- **Data connection binding completeness**: Every attribute with a data source reference has a data connection binding assigned on the instance, and the bound data connection name exists as a defined connection at the instance's site.
- **Exception**: Validation does **not** verify that data source relative paths resolve to real tags on physical devices — that is a runtime concern that can only be determined at the site.