Driver.Cli.Common-007 + Driver.Cli.Common-008 resolution.
Driver.Cli.Common-007 (High, Correctness):
0x80550000 is the canonical OPC UA spec value for BadSecurityPolicyRejected,
not BadDeviceFailure. The correct spec value for BadDeviceFailure is
0x808B0000 (verified against OPC Foundation Opc.Ua.StatusCodes;
corroborated locally by Driver.Galaxy.Runtime.StatusCodeMap and both
Wonderware historian quality mappers which all hand-pin the correct
value).
The bug was duplicated across six driver modules:
- FocasStatusMapper.BadDeviceFailure
- AbCipStatusMapper.BadDeviceFailure
- AbLegacyStatusMapper.BadDeviceFailure
- TwinCATStatusMapper.BadDeviceFailure
- ModbusDriver.StatusBadDeviceFailure
- S7Driver.StatusBadDeviceFailure
Plus the SnapshotFormatter shortlist that named 0x80550000 as
BadDeviceFailure, and three downstream Modbus tests that asserted
against the wrong value (so CI was blind).
This commit fixes all six native-mapper constants, the formatter
shortlist, and the three Modbus tests in one pass. Added a regression
guard to FormatStatus_does_not_apply_pre_fix_wrong_names that pins
0x80550000 never renders as BadDeviceFailure (mirroring the existing
-001 wrong-name guards).
Behavior change: OPC UA clients consuming the native drivers now see
the canonical BadDeviceFailure (0x808B0000) on device-fault paths
instead of the misnamed BadSecurityPolicyRejected (0x80550000). Wire-
level status semantics now match operator-facing CLI labels.
Driver.Cli.Common-008 (Low, Testing):
Deleted the redundant FormatStatus_names_native_driver_emitted_codes
Theory — its five InlineData rows were already covered by the
well-known Theory in the same commit (5a9c459), and used a weaker
ShouldContain vs the well-known Theory's ShouldBe (exact match).
Verification:
- Driver.Cli.Common.Tests: 43/43 pass (was 48 after the -008 deletion).
- Driver.Modbus.Tests: 263/263 pass.
- Driver.AbCip.Tests: 262/262.
- Driver.AbLegacy.Tests: 157/157.
- Driver.FOCAS.Tests: 178/178.
- Driver.S7.Tests: 112/112.
- Driver.TwinCAT.Tests: 131/131.
Total: 1146 tests across the affected modules, all green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
OtOpcUa
OPC UA server (.NET 10 AnyCPU) that exposes a fleet of industrial drivers as a single OPC UA address space. Drivers ship in-process for AVEVA System Platform Galaxy (via the sibling mxaccessgw repo), Modbus TCP, Siemens S7, Allen-Bradley CIP (ControlLogix / CompactLogix), Allen-Bradley Legacy (SLC 500 / MicroLogix), Beckhoff TwinCAT (ADS), FANUC FOCAS, and OPC UA Client (gateway).
A cross-platform client stack (.NET 10) — shared library, CLI, and Avalonia desktop app — connects to any OPC UA server.
Architecture
OPC UA Clients (CLI, Desktop UI, 3rd-party)
|
v
+-------------------------------------+
| OtOpcUa.Server (.NET 10 AnyCPU) |
| address space + capability fan-out|
+-------------------------------------+
| | | | | | | |
Galaxy Modbus S7 AbCip AbLeg TwinCAT FOCAS OpcUaClient
|
v
mxaccessgw (sibling repo, gRPC)
|
v
MXAccess COM (x86 worker, on AVEVA box)
Galaxy is the only driver with an external runtime: it speaks gRPC to a separately installed mxaccessgw server (sibling repo at c:\Users\dohertj2\Desktop\mxaccessgw\) which owns the MXAccess COM apartment and the x86/STA bitness constraint server-side. Everything in this repo is platform-agnostic .NET 10.
Prerequisites
- .NET 10 SDK (server, drivers, clients all target .NET 10)
- SQL Server reachable for the central config DB
- For Galaxy specifically: a running
mxaccessgwdeployment — see docs/v2/Galaxy.ParityRig.md - For Wonderware Historian read-back: optional
OtOpcUaWonderwareHistoriansidecar — see docs/ServiceHosting.md
Quick Start
dotnet restore ZB.MOM.WW.OtOpcUa.slnx
dotnet build ZB.MOM.WW.OtOpcUa.slnx
dotnet test ZB.MOM.WW.OtOpcUa.slnx
# Run the server in dev (foreground)
dotnet run --project src/Server/ZB.MOM.WW.OtOpcUa.Server
The server starts on opc.tcp://localhost:4840 with the None security profile. Configure Security.Profiles in src/Server/ZB.MOM.WW.OtOpcUa.Server/appsettings.json to enable Basic256Sha256-Sign or Basic256Sha256-SignAndEncrypt. See docs/security.md.
Install as Windows Services
Production deployment is driven by scripts/install/Install-Services.ps1, which registers the OtOpcUa server service (and optionally the OtOpcUaWonderwareHistorian sidecar) under a chosen service account. Galaxy support requires a separately installed mxaccessgw — neither this repo nor the install script provisions it.
.\scripts\install\Install-Services.ps1 `
-InstallRoot 'C:\Program Files\OtOpcUa' `
-ServiceAccount 'DOMAIN\svc-otopcua'
Add -InstallWonderwareHistorian for the historian sidecar. See the script header and docs/ServiceHosting.md for full options.
Client CLI
dotnet run --project src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI -- connect -u opc.tcp://localhost:4840
dotnet run --project src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI -- browse -u opc.tcp://localhost:4840 -r -d 3
dotnet run --project src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI -- read -u opc.tcp://localhost:4840 -n "ns=2;s=SomeNode"
dotnet run --project src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI -- write -u opc.tcp://localhost:4840 -n "ns=2;s=SomeNode" -v 42
dotnet run --project src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI -- subscribe -u opc.tcp://localhost:4840 -n "ns=2;s=SomeNode" -i 500
See docs/Client.CLI.md and docs/Client.UI.md.
Documentation
Architecture deep-dives
| Topic | Doc |
|---|---|
| OPC UA server composition, namespace fan-out, Polly invoker | docs/OpcUaServer.md |
| Address space layout | docs/AddressSpace.md |
| Read / Write dispatch (driver vs virtual vs scripted-alarm) | docs/ReadWriteOperations.md |
| Incremental sync (driver-backend rediscovery + config publishes) | docs/IncrementalSync.md |
| Service hosting (Server + Admin + optional historian sidecar) | docs/ServiceHosting.md |
| Security (transport, LDAP, certificates) | docs/security.md |
| Redundancy | docs/Redundancy.md |
| Status dashboard | docs/StatusDashboard.md |
Drivers
| Topic | Doc |
|---|---|
| Driver specs (per-driver capability surface, config, addressing) | docs/v2/driver-specs.md |
| Galaxy driver | docs/drivers/Galaxy.md |
| Modbus / S7 / AbCip / AbLegacy / TwinCAT / FOCAS / OpcUaClient | docs/drivers/ |
| Galaxy parity rig (mxaccessgw setup) | docs/v2/Galaxy.ParityRig.md |
| Galaxy performance + tracing | docs/v2/Galaxy.Performance.md |
Clients
| Topic | Doc |
|---|---|
| Client CLI | docs/Client.CLI.md |
| Client UI (Avalonia desktop) | docs/Client.UI.md |
v1 archive
The original v1 in-process MXAccess docs (Galaxy.Host topology, Configuration env vars, AlarmTracking, DataTypeMapping, HistoricalDataAccess, Subscriptions, etc.) are preserved under docs/v1/ — historical reference only. PR 7.2 retired the v1 architecture on 2026-04-30; current state is documented in the sections above.
License
Internal use only.