Skip to content

Talk to the heat pump through modbus-connection (v1.18.0) - #10

Merged
MattieGit merged 1 commit into
mainfrom
modbus-connection
Nov 3, 2026
Merged

MattieGit merged 1 commit into
mainfrom
modbus-connection

Conversation

@MattieGit

Copy link
Copy Markdown
Owner

Replaces pymodbus with modbus-connection on its tmodbus backend. This is the Modbus layer Home Assistant core shares between integrations (homeassistant.components.modbus.async_get_unit). Core pins modbus-connection[tmodbus]==4.12.7 and tmodbus==1.1.0; this requires >=4.12.7.

API

  • QubeClient(host, port, unit_id) works as before and opens its own connection.
  • New: QubeClient(host, unit=unit) takes a caller's ModbusUnit. connect() returns True and close() leaves the connection alone; host only labels messages.
  • close() now drops the link with disconnect(). The client stays usable and the next request reconnects.
  • Not breaking, so this is a minor release. Core stays on ==1.17.0 until a bump PR.

Behaviour changes

  • Read retry. modbus-connection never replays a request, while pymodbus retried by default. A block read that times out or gets a garbled reply is now tried once more. If it times out again, the poll stops straight away: every value is None, get_all_data() returns None and the link is dropped. An error reply or a short response still falls back to single reads. Writes are never retried.
  • Timeouts. Requests and connects time out after 3 s, as pymodbus did. A shared unit uses its own connection's timeout.
  • connect() without asyncio error logs. The attempt runs in its own task and waits with asyncio.wait. A caller's asyncio.timeout around connect() (both config flows have one) used to cancel modbus-connection's shielded connect. On an unreachable host, Python 3.14 then logged "exception in shielded future" about 10 s later.
  • Reconnects happen on the next request. The library's own reconnect code and the workaround for pymodbus not closing the old transport are gone. The backoff before get_all_data() reconnects stays for owned connections.

Tests

  • The pymodbus mocks are replaced by the modbus-connection pytest plugin (mock_modbus_unit), with helpers in tests/helpers.py.
  • 160 tests, up from 102 (plus two modules that no longer import).
  • New tests cover the retry, the abort after two timeouts, errors that are not retried, writes that are never retried, and shared versus owned connections.
  • mypy --strict and ruff 0.14.14 are clean.
  • The HACS integration's suite passes against this branch: 386 tests, 263 snapshots.

Not done yet

  • Device test. The Mac was not on the home LAN. The plan is a HACS pre-release that requires 1.18.0 (MattieGit/qube_heatpump), polling on the Qube for a few days.

Replace pymodbus with modbus-connection on its tmodbus backend, the Modbus
layer Home Assistant core shares between integrations. QubeClient keeps its
constructor and opens its own connection, or takes a caller's ModbusUnit
(QubeClient(host, unit=unit)) and leaves that connection alone.

modbus-connection never replays a request, so a block read whose response
went missing or arrived garbled is tried once more; writes are never
retried. connect() gives up after 3 s without cancelling the shared connect
task, so a caller's own timeout no longer makes asyncio log an error.

Tests run on the modbus-connection in-memory mock.
@MattieGit
MattieGit merged commit 2421206 into main Nov 3, 2026
3 checks passed
@MattieGit
MattieGit deleted the modbus-connection branch November 3, 2026 20:05
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