Phase 3 PR 50 -- DL260 bit-memory helpers (Y/C/X/SP) + coil integration tests #49

Merged
dohertj2 merged 1 commits from phase-3-pr50-dl205-coil-mapping into v2 2026-04-18 22:35:19 -04:00
Owner

Summary

Adds DL260 I/O-memory address helpers to DirectLogicAddress:

  • YOutputToCoil (Y0 → coil 2048)
  • CRelayToCoil (C0 → coil 3072)
  • XInputToDiscrete (X0 → DI 0)
  • SpecialToDiscrete (SP0 → DI 1024)

Each adds the octal-decoded offset to its Modbus base; rejects non-octal digits (8/9). Fixes a pymodbus-config bug surfaced during validation: pymodbus divides bit-addresses by 16 before cell indexing, so the dl205.json bits entries at cells 2048/3072/4000 were unreachable via FC01. Relocated to cells 128/192/250 and updated the write range.

Validation

  • 48/48 Modbus.Tests pass (includes full Y/C/X/SP sweep + non-octal rejection)
  • 9/9 DL205 integration tests pass — Y0, C0, and scratch-C write round-trip against the fixed sim

Test plan

  • Octal parsing for each bank
  • Error messages for invalid input
  • Live FC01 read of Y0=ON, C0=ON
  • FC05 write + FC01 read round-trip on scratch C
## Summary Adds DL260 I/O-memory address helpers to `DirectLogicAddress`: - `YOutputToCoil` (Y0 → coil 2048) - `CRelayToCoil` (C0 → coil 3072) - `XInputToDiscrete` (X0 → DI 0) - `SpecialToDiscrete` (SP0 → DI 1024) Each adds the octal-decoded offset to its Modbus base; rejects non-octal digits (8/9). Fixes a pymodbus-config bug surfaced during validation: pymodbus divides bit-addresses by 16 before cell indexing, so the dl205.json bits entries at cells 2048/3072/4000 were unreachable via FC01. Relocated to cells 128/192/250 and updated the write range. ## Validation - 48/48 Modbus.Tests pass (includes full Y/C/X/SP sweep + non-octal rejection) - 9/9 DL205 integration tests pass — Y0, C0, and scratch-C write round-trip against the fixed sim ## Test plan - [x] Octal parsing for each bank - [x] Error messages for invalid input - [x] Live FC01 read of Y0=ON, C0=ON - [x] FC05 write + FC01 read round-trip on scratch C
dohertj2 added 1 commit 2026-04-18 22:35:15 -04:00
Phase 3 PR 50 -- DL260 bit-memory address helpers (Y/C/X/SP) + live coil integration tests. Adds four new static helpers to DirectLogicAddress covering every discrete-memory bank on the DL260: YOutputToCoil (Y0=coil 2048), CRelayToCoil (C0=coil 3072), XInputToDiscrete (X0=DI 0), SpecialToDiscrete (SP0=DI 1024). Each helper takes the DirectLOGIC ladder-logic address (e.g. 'Y0', 'Y17', 'C1777') and adds the octal-decoded offset to the bank's Modbus base per the DL260 user manual's I/O-configuration chapter table. Uses the same 'octal-walk + reject 8/9' pattern as UserVMemoryToPdu so misaligned addresses fail loudly with a clear ArgumentException rather than silently hitting the wrong coil. Fixes a pymodbus-config bug surfaced during integration-test validation: dl205.json had bits entries at cell indices 2048 / 3072 / 4000, but pymodbus's ModbusSimulatorContext.validate divides bit addresses by 16 before indexing into the shared cell array -- so Modbus coil 2048 reads cell 128, not cell 2048. The sim was returning Illegal Data Address (exception 02) for every bit read in the Y/C/scratch range. Moved bits entries to cells 128 (Y bank marker = 0b101 for Y0=ON, Y1=OFF, Y2=ON), 192 (C bank marker = 0b101 for C0/C1/C2), 250 (scratch cell covering coils 4000..4015). write list updated to the correct cell addresses. Unit tests: YOutputToCoil theory sweep (Y0->2048, Y1->2049, Y7->2055, Y10->2056 octal-to-decimal, Y17->2063, Y777->2559 top of DL260 Y range), CRelayToCoil theory (C0->3072 through C1777->4095), XInputToDiscrete theory, SpecialToDiscrete theory (with case-insensitive 'SP' prefix). Bit_address_rejects_non_octal_digits (Y8/C9/X18), Bit_address_rejects_empty, accepts_lowercase_prefix, accepts_bare_octal_without_prefix. 48/48 Modbus.Tests pass. Integration tests: DL205CoilMappingTests with three facts -- DL260_Y0_maps_to_coil_2048 (FC01 at Y0 returns ON), DL260_C0_maps_to_coil_3072 (FC01 at C0 returns ON), DL260_scratch_Crelay_supports_write_then_read (FC05 write + FC01 read round-trip at coil 4000 proves the DL-mapped coil bank is fully read/write capable end-to-end). 9/9 DL205 integration tests pass against the pymodbus dl205 profile with MODBUS_SIM_PROFILE=dl205. Caller opts into the helpers per tag the same way as PR 47's V-memory helper -- pass DirectLogicAddress.YOutputToCoil("Y0") as the ModbusTagDefinition Address; no driver-wide DL-family flag. PR 51 adds the X-input read-side integration test (there's nothing to write since X-inputs are FC02 discrete inputs, read-only); PR 52 exception-code translation; PR 53 transport reconnect-on-drop since DL260 doesn't send TCP keepalives. b5464f11ee
dohertj2 merged commit 9fb3cf7512 into v2 2026-04-18 22:35:19 -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#49