A connection abstraction: the abstract ModbusConnection class and the
ModbusUnit Protocol. Your code types against these, not against a specific
Modbus library. Two interchangeable backends implement them:
tmodbus and
pymodbus.
An optional device-modelling framework (modbus_connection.model). It
maps a device’s registers and coils to typed Python attributes. It reads the
whole device, or one sub-system, in as few Modbus calls as possible.
The package imports no Modbus library at the top level and nothing from Home
Assistant. You can build a device library once and let the consumer choose the
backend.
The link to a Modbus network, shared by every unit on it. It is
owner-held: construct it from a backend-neutral parameter object, and
only the owner tears it down with close(). The first request connects on
demand. A dropped link is re-established.
ModbusUnit
One device on that link, from connection.for_unit(unit_id). It carries the
read and write operations for that unit id and holds no state. Hand this, not
the connection, to a device library.
The backend serializes requests on one connection, so concurrent unit calls
cannot interleave. Many consumers can share one connection instead of each
opening a competing socket. This abstraction makes that sharing possible while
keeping the backend swappable.