Task #253 follow-up — driver-side e2e debug: port fixes + HR[200] scratch register #214

Merged
dohertj2 merged 1 commits from task-253c-e2e-debug-driver-side into v2 2026-04-21 10:34:24 -04:00
Owner

Summary

Ran the driver CLIs against the live docker compose fixtures to actually debug what the PR #207/#208 e2e scripts do. Two real bugs surfaced, plus a wider blocker that I've filed tracking issues for.

Driver-side bugs fixed

  1. Wrong simulator ports in e2e-config.sample.json:

    • Modbus: 5502 → 5020 (pymodbus compose binding)
    • S7: 102 → 1102 (python-snap7 needs non-priv)
    • AbCip: no port → explicit :44818

    test-modbus.ps1 default -ModbusHost also had 5502; fixed to 5020.

  2. Modbus HR[100] is auto-increment. pymodbus standard.json applies an increment action to HR[100], so every poll ticks the value. test-modbus.ps1 used HR[100] as its write target, causing wrote=4242 read=4244 (off by exactly +2, confirmed across 100/1000/10000/65535). Switched to HR[200] (scratch range per the profile).

  3. AbCip probe -t @raw_cpu_type rejected. Driver's TagPath parser returns malformed TagPath '@raw_cpu_type'. Probe now uses the user-supplied -TagPath for every family — works against both ab_server and real controllers.

Verified against live containers

docker compose -f .../Modbus.IntegrationTests/Docker/docker-compose.yml --profile standard    up -d
docker compose -f .../AbCip.IntegrationTests/Docker/docker-compose.yml  --profile controllogix up -d
docker compose -f .../S7.IntegrationTests/Docker/docker-compose.yml     --profile s7_1500     up -d
  • Modbus probe ✓, HR[200] write+read round-trip ✓
  • AB CIP probe ✓ (with TestDINT), TestDINT write+read round-trip ✓
  • S7 probe ✓, DB1.DBW0 write+read round-trip ✓

Stages 3-5 blocker (tracked, not fixed here)

src/ZB.MOM.WW.OtOpcUa.Server/Program.cs:98-104 only registers Galaxy + FOCAS driver factories. DriverInstanceBootstrapper silently skips any DriverType without a registered factory — so Modbus/AbCip/S7/AbLegacy rows in the Config DB are no-op'd even with a perfect seed.

Tracking issues opened:

  • #209 umbrella
  • #210 Modbus factory + seed SQL
  • #211 AB CIP factory + seed SQL
  • #212 S7 factory + seed SQL
  • #213 AB Legacy factory + seed SQL (hardware-gated — #222)

README flags this + links the issues so anyone running the scripts today knows stages 3-5 will fail on read failed until the wiring lands.

Test plan

  • Modbus CLI loopback against otopcua-pymodbus-standard on 5020 — ✓
  • AB CIP CLI loopback against otopcua-ab-server-controllogix on 44818 — ✓
  • S7 CLI loopback against otopcua-python-snap7-s7_1500 on 1102 — ✓
  • All scripts parse cleanly (UTF-8 BOM preserved)
  • Stages 3-5 end-to-end — blocked on #209-#213
## Summary Ran the driver CLIs against the live `docker compose` fixtures to actually debug what the PR #207/#208 e2e scripts do. Two real bugs surfaced, plus a wider blocker that I've filed tracking issues for. ## Driver-side bugs fixed 1. **Wrong simulator ports** in `e2e-config.sample.json`: - Modbus: 5502 → **5020** (pymodbus compose binding) - S7: 102 → **1102** (python-snap7 needs non-priv) - AbCip: no port → explicit **:44818** `test-modbus.ps1` default `-ModbusHost` also had 5502; fixed to 5020. 2. **Modbus HR[100] is auto-increment.** pymodbus `standard.json` applies an `increment` action to HR[100], so every poll ticks the value. `test-modbus.ps1` used HR[100] as its write target, causing `wrote=4242 read=4244` (off by exactly +2, confirmed across 100/1000/10000/65535). Switched to **HR[200]** (scratch range per the profile). 3. **AbCip probe `-t @raw_cpu_type` rejected.** Driver's TagPath parser returns `malformed TagPath '@raw_cpu_type'`. Probe now uses the user-supplied `-TagPath` for every family — works against both ab_server and real controllers. ## Verified against live containers ``` docker compose -f .../Modbus.IntegrationTests/Docker/docker-compose.yml --profile standard up -d docker compose -f .../AbCip.IntegrationTests/Docker/docker-compose.yml --profile controllogix up -d docker compose -f .../S7.IntegrationTests/Docker/docker-compose.yml --profile s7_1500 up -d ``` - Modbus probe ✓, HR[200] write+read round-trip ✓ - AB CIP probe ✓ (with TestDINT), TestDINT write+read round-trip ✓ - S7 probe ✓, DB1.DBW0 write+read round-trip ✓ ## Stages 3-5 blocker (tracked, not fixed here) `src/ZB.MOM.WW.OtOpcUa.Server/Program.cs:98-104` only registers Galaxy + FOCAS driver factories. `DriverInstanceBootstrapper` silently skips any `DriverType` without a registered factory — so Modbus/AbCip/S7/AbLegacy rows in the Config DB are no-op'd even with a perfect seed. Tracking issues opened: - **#209** umbrella - #210 Modbus factory + seed SQL - #211 AB CIP factory + seed SQL - #212 S7 factory + seed SQL - #213 AB Legacy factory + seed SQL (hardware-gated — #222) README flags this + links the issues so anyone running the scripts today knows stages 3-5 will fail on `read failed` until the wiring lands. ## Test plan - [x] Modbus CLI loopback against `otopcua-pymodbus-standard` on 5020 — ✓ - [x] AB CIP CLI loopback against `otopcua-ab-server-controllogix` on 44818 — ✓ - [x] S7 CLI loopback against `otopcua-python-snap7-s7_1500` on 1102 — ✓ - [x] All scripts parse cleanly (UTF-8 BOM preserved) - [ ] Stages 3-5 end-to-end — blocked on #209-#213
dohertj2 added 1 commit 2026-04-21 10:34:13 -04:00
Ran the driver CLIs against the live docker-compose fixtures to debug
what actually works. Two real bugs surfaced:

1. `e2e-config.sample.json` pointed at the wrong simulator ports:
     - Modbus: 5502 → **5020** (pymodbus compose binding)
     - S7:      102 → **1102** (python-snap7, non-priv port)
     - AbCip:   no port → now explicit **:44818**
   `test-modbus.ps1` default `-ModbusHost` also shipped with 5502;
   fixed to 5020.

2. Modbus loopback was off-by-2 because pymodbus `standard.json` makes
   HR[100] an auto-increment register (value ticks on every poll).
   Switched `test-modbus.ps1` to **HR[200]** (scratch range in the
   profile) + updated sample config `bridgeNodeId` to match.

Also fixed the AbCip probe: `-t @raw_cpu_type` was rejected by the
driver's TagPath parser ("malformed TagPath"). Probe now uses the
user-supplied `-TagPath` for every family. Works against both
ab_server and real controllers.

Verified driver-side against live containers:
 - Modbus  5020:  probe ✓, HR[200] write+read round-trip ✓
 - AB CIP  44818: probe ✓, TestDINT write+read round-trip ✓
 - S7      1102:  probe ✓, DB1.DBW0 write+read round-trip ✓

## Known blocker (stages 3-5)

README now flags — and the 4 child issues under umbrella #209 track —
that `src/ZB.MOM.WW.OtOpcUa.Server/Program.cs:98-104` only registers
Galaxy + FOCAS driver factories. `DriverInstanceBootstrapper` silently
skips any `DriverType` without a registered factory, so stages 3-5
(anything crossing the OPC UA server) can't work today even with a
perfect Config DB seed. Issues #210-213 scope the factory + seed SQL
work per driver.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dohertj2 merged commit 5834d62906 into v2 2026-04-21 10:34:24 -04:00
dohertj2 deleted branch task-253c-e2e-debug-driver-side 2026-04-21 10:34:24 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#214