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.
Add a post-publish Step 4b that fails the refresh if the sidecar deploy
folder is missing any load-bearing file (System.Memory.dll, MessagePack.dll,
the .exe, or the net48 binding-redirect .exe.config). A partial/stale deploy
that bypasses `dotnet publish` drops System.Memory.dll, so the sidecar
JIT-load-faults in PipeServer.RunOneConnectionAsync (FileNotFoundException
'System.Memory, Version=4.0.1.2') and NSSM crash-loops it (exit 2 every
~2 min). Catching this at publish time beats discovering it as a production
crash-loop. Guarded by -WhatIf; throws before any service is started.
- 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.
Group all 69 projects into category subfolders under src/ and tests/ so the
Rider Solution Explorer mirrors the module structure. Folders: Core, Server,
Drivers (with a nested Driver CLIs subfolder), Client, Tooling.
- Move every project folder on disk with git mv (history preserved as renames).
- Recompute relative paths in 57 .csproj files: cross-category ProjectReferences,
the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external
mxaccessgw refs in Driver.Galaxy and its test project.
- Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders.
- Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL,
integration, install).
Build green (0 errors); unit tests pass. Docs left for a separate pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Seventeenth PR of the alarms-over-gateway epic
(docs/plans/alarms-over-gateway.md). Lands the script that the
plan calls for in Track D — the actual smoke-run validation
on the dev rig (publish, restart, fire alarms, capture artifacts)
remains operator work; this PR ships the automation that the
operator drives.
scripts/install/Refresh-Services.ps1 — single-shot refresh
script. Designed to run elevated on the deploy host
(DESKTOP-6JL3KKO today; production uses a separate runbook).
The script:
- Stops services in reverse-dependency order (OtOpcUa →
OtOpcUaWonderwareHistorian → MxAccessGw) and force-kills any
residual processes (avoids the publish-time MSB3027 file-lock
the original install script hit).
- Snapshots existing C:\publish trees to
C:\publish\.backup-YYYY-MM-DD-HHMMSS\ for rollback (skip with
-SkipBackup).
- Builds + copies mxaccessgw worker (x86 net48) + server (net10.0)
binaries from the sibling repo.
- Publishes OtOpcUa Server + Wonderware historian sidecar from
this repo.
- Ensures OTOPCUA_HISTORIAN_ALARM_WRITE_ENABLED=true is set on
the historian service env block (PR C.2 toggle).
- Starts services in forward-dependency order with the
inter-service waits the original install used.
- Smoke-verifies (service status, listening ports 5120 / 4840
/ 4841, recent log tails).
Supports -WhatIf for dry-run inspection without touching the
running services.
docs/v2/dev-environment.md — new "Service Refresh —
Refresh-Services.ps1" section between Credential Management
and Test Data Seed. Cross-references the plan's Track D
functional verification scenarios.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>