driver-galaxy: GalaxyDriver implements IAlarmSource (PR B.2) #413

Merged
dohertj2 merged 1 commits from track-b2-galaxy-driver-ialarmsource into master 2026-04-30 17:18:22 -04:00
Owner

Summary

Twelfth PR of the alarms-over-gateway epic (docs/plans/alarms-over-gateway.md). Depends on PR B.1 (#409, merged) and PR E.2 (mxaccessgw#106, merged). Restores the v1 IAlarmSource capability that PR 7.2 retired with the legacy Galaxy.Host / Galaxy.Proxy projects.

GalaxyDriver gains:

  • IAlarmSource on the class declaration → eight capabilities total (IDriver / ITagDiscovery / IReadable / IWritable / ISubscribable / IRediscoverable / IHostConnectivityProbe / IAlarmSource).
  • SubscribeAlarmsAsync — returns a sentinel handle and starts the shared EventPump (alarm wiring is lazy on first sub). Multiple handles share the same gateway stream; the server-side AlarmConditionService dispatches per-source-node downstream.
  • UnsubscribeAlarmsAsync — symmetric handle removal; rejects handles not issued by this driver.
  • AcknowledgeAsync — issues one gateway RPC per acknowledgement through IGalaxyAlarmAcknowledger. ConditionId carries the alarm full reference; falls back to SourceNodeId when empty.
  • OnAlarmEvent — bridges EventPump.OnAlarmTransition (B.1) onto AlarmEventArgs. Suppressed when no alarm subscription is active so untracked transitions don't leak through.

New runtime types:

  • IGalaxyAlarmAcknowledger — test seam.
  • GatewayGalaxyAlarmAcknowledger — production wrapper around MxGatewayClient.AcknowledgeAlarmAsync (PR E.2). Maps native MxStatus failures to a logged warning rather than a thrown exception so a transient MxAccess hiccup doesn't fail the operator's Acknowledge.
  • GalaxyAlarmSubscriptionHandle — driver-side IAlarmSubscriptionHandle.

Test plan

  • 7 new tests in GalaxyDriverAlarmSourceTests — subscribe → event fire, suppress without subscription, unsubscribe stops flow, foreign-handle rejection, ack routes per-request, ack falls back to SourceNodeId, ack throws NotSupported without acknowledger
  • Full Driver.Galaxy.Tests: 203 passed (was 196; 7 new)
  • Driver.Galaxy build clean (net10.0)

Stub-ready behaviour

Runtime ack calls will return PERMISSION_DENIED until A.3 ships the gateway-side dispatch, and no alarm transitions will arrive until A.2 adds the worker MxAccess subscription. Both will activate this code path automatically when the gateway side lands.

Follow-up

  • B.3DriverNodeManager prefers IAlarmSource.OnAlarmEvent over the value-driven sub-attribute fallback when both are available.
  • E.7 — lmxopcua OPC UA-facing client surface refresh.
## Summary Twelfth PR of the **alarms-over-gateway** epic (docs/plans/alarms-over-gateway.md). Depends on PR B.1 (#409, merged) and PR E.2 (mxaccessgw#106, merged). Restores the v1 IAlarmSource capability that PR 7.2 retired with the legacy Galaxy.Host / Galaxy.Proxy projects. **GalaxyDriver gains:** - `IAlarmSource` on the class declaration → eight capabilities total (IDriver / ITagDiscovery / IReadable / IWritable / ISubscribable / IRediscoverable / IHostConnectivityProbe / IAlarmSource). - `SubscribeAlarmsAsync` — returns a sentinel handle and starts the shared EventPump (alarm wiring is lazy on first sub). Multiple handles share the same gateway stream; the server-side AlarmConditionService dispatches per-source-node downstream. - `UnsubscribeAlarmsAsync` — symmetric handle removal; rejects handles not issued by this driver. - `AcknowledgeAsync` — issues one gateway RPC per acknowledgement through `IGalaxyAlarmAcknowledger`. ConditionId carries the alarm full reference; falls back to SourceNodeId when empty. - `OnAlarmEvent` — bridges `EventPump.OnAlarmTransition` (B.1) onto `AlarmEventArgs`. Suppressed when no alarm subscription is active so untracked transitions don't leak through. **New runtime types:** - `IGalaxyAlarmAcknowledger` — test seam. - `GatewayGalaxyAlarmAcknowledger` — production wrapper around `MxGatewayClient.AcknowledgeAlarmAsync` (PR E.2). Maps native MxStatus failures to a logged warning rather than a thrown exception so a transient MxAccess hiccup doesn't fail the operator's Acknowledge. - `GalaxyAlarmSubscriptionHandle` — driver-side IAlarmSubscriptionHandle. ## Test plan - [x] 7 new tests in `GalaxyDriverAlarmSourceTests` — subscribe → event fire, suppress without subscription, unsubscribe stops flow, foreign-handle rejection, ack routes per-request, ack falls back to SourceNodeId, ack throws NotSupported without acknowledger - [x] Full `Driver.Galaxy.Tests`: 203 passed (was 196; 7 new) - [x] Driver.Galaxy build clean (net10.0) ## Stub-ready behaviour Runtime ack calls will return `PERMISSION_DENIED` until **A.3** ships the gateway-side dispatch, and no alarm transitions will arrive until **A.2** adds the worker MxAccess subscription. Both will activate this code path automatically when the gateway side lands. ## Follow-up - **B.3** — `DriverNodeManager` prefers `IAlarmSource.OnAlarmEvent` over the value-driven sub-attribute fallback when both are available. - **E.7** — lmxopcua OPC UA-facing client surface refresh.
dohertj2 added 1 commit 2026-04-30 17:18:19 -04:00
Twelfth PR of the alarms-over-gateway epic
(docs/plans/alarms-over-gateway.md). Depends on PR B.1 (EventPump
dispatch, merged) and PR E.2 (.NET SDK alarm methods, merged).
Restores the v1 IAlarmSource capability that PR 7.2 retired with the
legacy Galaxy.Host / Galaxy.Proxy projects.

GalaxyDriver gains:
- IAlarmSource on the class declaration → eight capabilities total
  (IDriver / ITagDiscovery / IReadable / IWritable / ISubscribable /
  IRediscoverable / IHostConnectivityProbe / IAlarmSource).
- SubscribeAlarmsAsync — returns a sentinel handle and starts the
  shared EventPump (alarm wiring is lazy on first sub).
  Multiple handles share the same gateway stream; the server-side
  AlarmConditionService dispatches per-source-node downstream.
- UnsubscribeAlarmsAsync — symmetric handle removal; rejects
  handles not issued by this driver.
- AcknowledgeAsync — issues one gateway RPC per acknowledgement
  through IGalaxyAlarmAcknowledger. ConditionId carries the alarm
  full reference; falls back to SourceNodeId when empty.
- OnAlarmEvent — bridges EventPump.OnAlarmTransition (B.1) onto
  AlarmEventArgs. Suppressed when no alarm subscription is active so
  untracked transitions don't leak through.

New runtime types:
- IGalaxyAlarmAcknowledger — test seam.
- GatewayGalaxyAlarmAcknowledger — production wrapper around
  MxGatewayClient.AcknowledgeAlarmAsync (PR E.2). Maps native
  MxStatus failures to a logged warning rather than a thrown
  exception so a transient MxAccess hiccup doesn't fail the
  operator's Acknowledge.
- GalaxyAlarmSubscriptionHandle — driver-side IAlarmSubscriptionHandle.

Production runtime construction in BuildProductionRuntimeAsync wires
the acknowledger when not pre-injected; tests inject a fake via the
internal ctor.

Tests:
- 7 new tests in GalaxyDriverAlarmSourceTests — subscribe → event
  fire path, suppress without subscription, unsubscribe stops flow,
  foreign-handle rejection, ack routes per-request, ack falls back
  to SourceNodeId, ack throws NotSupported without acknowledger.
- Full Driver.Galaxy.Tests: 203 passed (was 196; 7 new).

Operates as a "stub-ready" surface — runtime ack calls will return
PERMISSION_DENIED until A.3 ships the gateway-side dispatch, and no
alarm transitions will arrive until A.2 adds the worker MxAccess
subscription. Both will activate this code path automatically when
the gateway side lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dohertj2 merged commit 6126374594 into master 2026-04-30 17:18:22 -04:00
dohertj2 deleted branch track-b2-galaxy-driver-ialarmsource 2026-04-30 17:18:23 -04:00
Sign in to join this conversation.