Replace OTOPCUA_HISTORIAN_PIPE/OTOPCUA_ALLOWED_SID with TCP transport
env (OTOPCUA_HISTORIAN_TCP_PORT, OTOPCUA_HISTORIAN_BIND,
OTOPCUA_HISTORIAN_TLS_ENABLED, OTOPCUA_HISTORIAN_TLS_CERT/PASSWORD)
in Install-Services.ps1; add idempotent Windows Firewall inbound rule
for the TCP port. Add new params for all TCP/TLS options with cert
provisioning guidance. Update Refresh-Services.ps1 Step 4b comment
(PipeServer → TcpFrameServer) and add a Step 5 note clarifying that
TCP/TLS env is set at install time, not on refresh.
- Install-Services.ps1: installs OtOpcUaHost (single fused binary) replacing
the v1 OtOpcUa + OtOpcUaAdmin pair. Required -Roles param writes OTOPCUA_ROLES
to the service env so Program.cs decides what to mount (admin / driver / both).
-HttpPort param (default 9000) writes ASPNETCORE_URLS on admin-role nodes.
sc.exe restart-on-failure: 5s, 30s, 60s; reset counter after 24h clean run.
Wonderware historian sidecar install logic preserved from v1.
- Uninstall-Services.ps1: removes OtOpcUaHost + cleans up legacy v1 names
(OtOpcUa, OtOpcUaAdmin) and the long-retired OtOpcUaGalaxyHost.
- Refresh-Services.ps1: updated service names (OtOpcUa -> OtOpcUaHost), publish
path (ZB.MOM.WW.OtOpcUa.Server -> ZB.MOM.WW.OtOpcUa.Host), process names
(OtOpcUa.Server -> OtOpcUa.Host). Switched nssm stop/start calls to
Stop-Service/Start-Service so the script works whether the underlying
service was installed via nssm or sc.exe.
Fifth PR of the alarms-over-gateway epic
(docs/plans/alarms-over-gateway.md). Depends on PR C.1
(AahClientManagedAlarmEventWriter), already merged.
Today HistorianFrameHandler is constructed at Program.cs line 57
without an alarmWriter, so every WriteAlarmEvents frame replies
"Sidecar not configured with an alarm-event writer" and the lmxopcua
side keeps the row queued. C.2 wires a real writer behind a new
OTOPCUA_HISTORIAN_ALARM_WRITE_ENABLED toggle.
- Program.BuildAlarmWriter — gated on the env var (default true,
fail-open under accidental misconfiguration). Constructs an
AahClientManagedAlarmEventWriter wrapping a
SdkAlarmHistorianWriteBackend with the same connection config the
read path uses.
- Install-Services.ps1 — appends OTOPCUA_HISTORIAN_ALARM_WRITE_ENABLED=true
to the OtOpcUaWonderwareHistorian service env block when the
sidecar is installed. Read-only deployments flip it to false at
service-config edit time without re-installing.
- HistorianFrameHandler signature already accepts
IAlarmEventWriter? — supplying non-null at line 57 lights up
the WriteAlarmEvents reply path that's been dormant since PR 3.3.
Until PR D.1 pins the live aahClientManaged entry point, the
SdkAlarmHistorianWriteBackend reports RetryPlease for every event
with a structured diagnostic. The lmxopcua-side
SqliteStoreAndForwardSink retains queued events; same effective
behaviour as today's NullAlarmHistorianSink fallback but with
visible diagnostics rather than silent discard.
Tests:
- 6 BuildAlarmWriter env-var cases — unset / true / false /
unrecognized → default-on / capitalization variants.
- Full sidecar test suite: 56 passed (was 48; 8 new).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Matrix-gate satisfied (14 passed / 1 skipped / 0 failed on 2026-04-30
per docs/v2/Galaxy.ParityMatrix.md). Galaxy access flows through the
in-process GalaxyDriver → mxaccessgw exclusively. Legacy infrastructure
deleted in this commit:
Source projects (6):
- src/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host (.NET 4.8 x86 + MXAccess COM)
- src/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Proxy (in-process pipe client)
- src/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Shared (pipe-IPC contracts)
- tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Tests
- tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Proxy.Tests
- tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Shared.Tests
Test projects with no consumer after legacy retired (3):
- tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.E2E (drove Galaxy.Host EXE)
- tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests (drove both backends)
- tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.TestSupport (only consumed by Host/Proxy tests)
Edits:
- ZB.MOM.WW.OtOpcUa.slnx: drop nine project entries
- Server.csproj: drop Driver.Galaxy.Proxy ProjectReference
- Server/Program.cs: drop GalaxyProxyDriverFactoryExtensions.Register
+ the parallel-registration comment block; only GalaxyDriverFactoryExtensions
registers now under DriverType "GalaxyMxGateway"
- Install-Services.ps1: rewrite to drop OtOpcUaGalaxyHost service install +
the GalaxySharedSecret/ZbConnection/GalaxyClientName/GalaxyPipeName/
AvevaServiceDependencies/MxAccessInitialConnect* parameters that only
applied to the legacy host. Adds a closing note pointing operators at
the separate mxaccessgw install
- Uninstall-Services.ps1: keep OtOpcUaGalaxyHost in the cleanup loop so
pre-7.2 rigs upgrade-uninstall cleanly, plus add OtOpcUaWonderwareHistorian
- scripts/e2e/test-galaxy.ps1: deleted (drove the legacy E2E)
- scripts/e2e/e2e-config.sample.json: rewrite the galaxy section comment
to reflect the GalaxyMxGateway-only path
- scripts/e2e/README.md: drop OtOpcUaGalaxyHost references
- scripts/compliance/phase-7-compliance.ps1: drop Galaxy.Shared
HistorianAlarms* checks (those contracts moved to
Driver.Historian.Wonderware.Client in PR 3.4)
Live state: OtOpcUaGalaxyHost Windows service stopped + removed via
NSSM before this commit. The dev box's Galaxy access is now exclusively
through the running mxaccessgw (separate repo).
Stays out of scope for PR 7.2 (PR 7.3 territory):
- CLAUDE.md Galaxy section rewrite
- mxaccess_documentation.md deletion
- Memory entries for the now-retired Galaxy.Host service
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>