Changelog

2.2.1 (2026-06-16)

Internal

  • add strict static typing with basedpyright across modpoll/; introduce modpoll/types.py and enforce make typecheck in local and CI quality gates

  • extract Device, Poller, and Reference into modpoll/modbus_models.py (orchestration remains in modbus_task.py)

  • replace black with ruff for format and lint

Documentation

  • add typing audit baseline in docs/typing-audit.md

  • extend contributor release checklist and harden the on-release-main workflow

Tests

  • import device models from modpoll.modbus_models in unit tests

2.2.0 (2026-06-16)

Features

  • MQTT on-demand read (get): subscribe on modpoll/+/get (--mqtt-get-topic-pattern); publish {"ref": null} to modpoll/{device}/get; response on modpoll/{device}/get/response with partial success (unknown or failed refs omitted); targeted Modbus reads via reference_read.py with adjacent register batching

  • Persistent Modbus connection: ModbusConnectionManager keeps the client open between poll cycles and MQTT commands; non-blocking exponential reconnect backoff (--modbus-backoff-base, --modbus-backoff-max); optional connection recycle (--modbus-max-connection-age)

  • enrich per-device MQTT diagnostics with config_source, get/set counters (get_count, get_errors, get_success, get_unknown_refs, get_read_errors, set_count, set_errors, set_success, set_unknown_refs)

  • publish process-wide health on modpoll/diagnostics (mqtt_connected, modbus_ok, devices_failing, last_cycle_s, Modbus connection state and reconnect metrics)

  • publish process presence on modpoll/status with last-will (online: false) and birth message (online: true); status is always retained

  • apply --mqtt-retain to diagnostics topics (same policy as data publishes)

BREAKING CHANGES

  • ``–interval`` default is now transport-aware: 0.0 s for TCP/UDP (was 0.5 s); serial/RTU derives the RTU 3.5-character frame gap from --serial-baud with a 0.005 s floor. Set --interval explicitly for slow devices.

  • Modbus connect/close per poll cycle removed: the client stays open until shutdown or a transport failure; on serial/RTU the port remains reserved while modpoll runs

  • MQTT multi-reference writes now use --interval between successive refs in one set message (was a fixed 0.1 s delay)

Documentation

  • document MQTT get, persistent connection, transport-aware --interval, and extended diagnostics in docs/usage.rst

Tests

  • add tests/test_modbus_connection.py, extend tests/test_main_get.py for backoff, connection reuse, and diagnostic counters

  • migrate Modbus lifecycle tests to ModbusConnectionManager

2.1.2 (2026-06-15)

Features

  • warn at config load when a reference is marked w/rw on a discrete_input or input_register poller (Modbus inputs are read-only)

Documentation

  • fix README MQTT write example for bool8 references (array of 8 booleans, not a scalar)

  • document export, diagnostics, mqtt-single, config sources, write constraints, and publish behavior in docs/usage.rst

  • expand docs/configure.rst with CSV schema, dtypes, poll limits, and validation rules

  • correct config_template.csv comment: dtype column is required

Tests

  • add contract tests in tests/test_handler_behavior.py for documented edge cases

  • consolidate handler regression/contract tests; share FakeModbusMaster in tests/helpers/modbus.py

2.1.1 (2026-06-11)

Features

  • add --mqtt-retain to set the MQTT retain flag on data publishes (diagnostics topics are never retained)

Documentation

  • add release documentation checklist for agents and maintainers in CONTRIBUTING.md

  • align narrative docs with MQTT reference-map write format and --mqtt-keys usage

Internal

  • centralize MQTT data publish policy (QoS and retain) in MqttHandler.publish_data_message

2.1.0 (2026-06-10)

Features

  • add --mqtt-keys name-only to publish MQTT JSON keys without the unit suffix (default key style remains name-with-unit)

  • MQTT writes on modpoll/{device}/set accept a map of references {"ref_a": val, "ref_b": val} in one message; unknown keys are skipped with a warning

BREAKING CHANGES

  • renamed --daemon / -d to --no-output (suppresses poll result tables only; does not fork)

  • MQTT write payload must be a reference map ({"ref": val}); ref/value object format removed

2.0.0 (2026-06-10)

Project

  • forked from modpoll; PyPI package renamed to modpoll2mqtt, repository yoch/modpoll2mqtt

  • CLI command and Python module remain modpoll

Features

  • semantic MQTT write by CSV reference on modpoll/{device}/set with payload ref and value (device from topic; scale, dtype, and endianness handled automatically)

  • subscribe pattern modpoll/+/set by default

BREAKING CHANGES

  • removed low-level MQTT write format (object_type, address, value); use topic + ref and value instead

  • duplicate reference names on the same device now abort config loading (previously warned and overwrote)