Skip to content

feat!: target Modbus extension 0.1.6 (devices, rates, 1-based addresses) - #5

Open
tkeairns wants to merge 9 commits into
mainfrom
feat/modbus-devices
Open

tkeairns wants to merge 9 commits into
mainfrom
feat/modbus-devices

Conversation

@tkeairns

@tkeairns tkeairns commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Companion to zeloscloud/zelos-extension-modbus#14. Requires zelos-extension-modbus 0.1.6 (released; #14 merged).

  • Modbus/ action paths, device selector (<connection>/<device>), list_devices; devices grouped under their connection with endpoint badge.
  • Per-device rate health: requested vs achieved, overload (amber > 100%), demoted with retry countdown, disconnected, not polled.
  • Raw rows store their address base; a base change blocks read/write with an inline "re-enter the address" error (prevents writing the neighbouring register). Single-word raw writes honor write_mode: fc16.
  • Codec parity with the extension: byte orders ABCD/DCBA/CDAB/BADC, exact 1/n scaling, half-up write rounding with range refusal. Action failures show the extension's reason.
  • A starting 0.1.6 extension (its standalone actions are listed before the live session) no longer reads as outdated; only legacy modbus/ paths do.
  • Saved rows move to watch-rows.v2; v1 rows held 0-based wire addresses and are intentionally not migrated.
  • "Word order" column renamed "Byte order".

Testing: 408 vitest; lint, tsc, build, format clean. The app's action layer (discovery, grouping, snapshots, named and raw writes) was driven against a live agent + extension; writes confirmed on the simulator to land only on the target unit. Not verified: rendering inside the Electron host.
Review follow-ups (5b49d14)

  • Unknown write outcome shown in amber (read back before retrying), refused in red with the reason; raw write controls disabled with the reason when the extension has raw writes off.
  • Device health shows map discovery pending/failed and refused blocks with retry.
  • Exact integer round-trip check mirrors the extension; string values display-only.
  • 408 vitest.
  • Auto-scanned devices (extension auto_scan): neutral scanning/found badge instead of "raw only"; discovered registers load as a catalog and refetch as the scan finds more.
  • Mock traces auto-scanned raw registers with the extension's raw naming (zelos-extension-modbus#22, which consolidates #23): holding_registers/<a>.hr_<a>, input_registers/<a>.ir_<a>, coils/<a>.coil_<a>, discrete_inputs/<a>.di_<a>.

@tkeairns tkeairns changed the title feat!: target Modbus extension 0.2.0 (devices, rates, 1-based addresses) feat!: target Modbus extension 0.1.6 (devices, rates, 1-based addresses) Sep 28, 2026
- Modbus/ action paths, device selector (<connection>/<device>),
  list_devices; devices grouped under their connection.
- Rate health per device: requested vs achieved, overload, demoted
  with retry countdown, disconnected, not polled.
- Raw rows store their address base and refuse read/write when the
  device's base changed; single-word raw writes honor write_mode fc16.
- Codec: byte orders match the extension (ABCD/DCBA/CDAB/BADC), exact
  1/n scaling, half-up write rounding with range refusal.
- A starting 0.2.0 extension (standalone actions listed first) no
  longer reads as outdated; only legacy modbus/ paths do.
- Saved rows move to watch-rows.v2; v1 rows held 0-based wire
  addresses and are intentionally not migrated.
- Requires zelos-extension-modbus >=0.2.0.

Claude-Session: https://claude.ai/code/session_01LjFqdigCe9fpCgr6Rot3vE
- Raw rows keep their address base; a base change blocks read/write
  with an inline reason. Saved rows move to watch-rows.v2.
- Write results: unknown outcome shown in amber (read back before
  retrying), refused in red with the reason. Raw writes disabled with
  an inline reason when the extension has them off.
- Device health: map discovery pending/failed, refused blocks with
  retry, disconnected, not polled.
- Codec: exact integer round-trip check, exact 1/n scaling, string
  values display-only.
- A starting 0.2.0 extension no longer reads as outdated; list_devices
  polled only once the action is registered.

Claude-Session: https://claude.ai/code/session_01LjFqdigCe9fpCgr6Rot3vE
A box can carry the marketplace install (0.1.5, `modbus/`) and a local
0.2.0 install (`Modbus/`). The resolver took the first listed, so status
and the Start/Stop target depended on list order.

Sort installs by id, prefer running over stopped, then one meeting the
version floor. When more than one runs, name them and tell the operator
to stop the unused one: no action path carries an install id.

Claude-Session: https://claude.ai/code/session_01LjFqdigCe9fpCgr6Rot3vE
The extension shipped these changes as 0.1.6, not 0.2.0: retarget the
[[requires]] floor, the runtime version floor, docs and tests.

Claude-Session: https://claude.ai/code/session_01LjFqdigCe9fpCgr6Rot3vE
A device with no map that auto-scans (auto_scan set) gets a neutral
scanning/found badge instead of "raw only", and its catalog loads and
refetches as register_count grows, so discovered registers are pickable
as named rows. Mock host gains an auto-scanning device.

Claude-Session: https://claude.ai/code/session_01LjFqdigCe9fpCgr6Rot3vE
Labels read Holding 4x / Input 3x / Coil 0x / Discrete 1x, with the full
spec name and read function code (e.g. Holding registers (4x, FC03)) in
tooltips and the scan badge. The mock traces raw holding registers under
holding_registers/, as the extension now does.
Auto-scanned registers trace hr_<a>, ir_<a>, coil_<a>, di_<a> instead of
<a>_value (extension #23).
This reverts commit de41b02: no UI label changes in this PR. The mock keeps the holding_registers/ events from 0df5084.
@tkeairns
tkeairns force-pushed the feat/modbus-devices branch from 8d83c16 to 647593c Compare October 3, 2026 00:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant