Skip to main content

weider-modbus

Async Python library for the Modbus TCP interface of Weider WT16 heat pumps, built on modbus-connection.

The library only reads and writes registers. It takes a ModbusUnit and never opens a connection itself, so it works over any modbus-connection backend (tmodbus, pymodbus, or the in-memory mock). It is used by the Weider WT16 Home Assistant integration.

Installation

pip install weider-modbus

The library depends only on the backend-neutral modbus-connection interface. To open a connection yourself, also install a backend:

pip install "modbus-connection[tmodbus]"

Usage

import asyncio

from modbus_connection import ModbusTcpParams
from modbus_connection.tmodbus import ModbusConnection

from weider_modbus import WeiderWT16, plausible_temperature


async def main() -> None:
    connection = ModbusConnection(ModbusTcpParams(host="192.168.1.50", port=502))
    try:
        device = WeiderWT16(connection.for_unit(1))
        await device.async_update()

        print("Hot water:", device.measurements.hot_water_temperature)
        print("Room:", device.current_room_temperature)
        outdoor = plausible_temperature(device.measurements.outdoor_temperature)
        print("Outdoor:", outdoor)
        print("Compressor running:", device.digital_inputs.compressor)
        print("SG Ready mode:", device.sg_ready_mode)

        await device.async_set_hot_water_target(47.5)
    finally:
        await connection.close()


asyncio.run(main())

Components

Attribute Modbus space Content
device.measurements Input registers (FC04) Temperatures, volume flow, runtimes, mixer position, active error text
device.settings Holding registers (FC03/FC16) Hot water and room target temperatures
device.digital_inputs Discrete inputs (FC02) Compressor, pumps, valves, blocks, SG Ready inputs

A value reads as None until the first successful poll, or if the device does not provide the register.

Optional registers

The room temperature is read from input register 12 (BET.T.A.1, the measured sensor value) of the standard Modbus map. Some heat pumps have a custom Modbus map that Weider configures on request. Such a map answers 0 at register 12 and provides the room temperature at register 724 instead (measurements.custom_map_room_temperature). Use device.current_room_temperature for the value to display: register 12 if it is non-zero, otherwise register 724 if it is non-zero, otherwise None.

Some firmware versions do not provide every register. The room temperature, room target, mixer position, runtimes, active error text and any digital input are optional. If the device rejects one of them with an illegal data address, the library drops that register on the first poll and stops reading it. Any other register error still raises, so real problems are not hidden.

Errors

async_update() raises a modbus_connection.ModbusError subclass (or TimeoutError / OSError from the transport) when a poll fails. The shared connection reopens on the next request, so the caller can simply retry.

The target setters raise ValueError for a value outside the allowed range (hot water 15–55 °C, room 15–35 °C), before anything is written.

Helpers

  • plausible_temperature(value) returns None for the placeholder values the device reports for an unconnected sensor (outside −45 to 150 °C).
  • clean_error_text(value) strips the padding from the active error text and returns None when there is no error.
  • sg_ready_mode(...) and device.sg_ready_mode derive the SG Ready operating state (BZ1–BZ4) from the digital inputs.

Hardware verification

The register addresses, the signed 0.1 °C temperature format and the multi-register word order come from the existing integration. Confirm them against your WT16 documentation, especially for negative temperatures. The test simulator checks the software against this map, not the map against a real heat pump.

Development

Requires Python 3.13 or newer and uv.

uv sync
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run mypy

To run the synthetic WT16 on port 5020 for manual testing:

uv run python -m tests.simulator

Releasing

Releases are published to PyPI from GitHub Actions with trusted publishing.

  1. Set the new version in pyproject.toml and merge it to main.
  2. Create a GitHub release with a tag equal to that version (for example 0.1.0).
  3. The Publish workflow builds the package and uploads it to PyPI.

A version number can be published only once.

License

MIT. See LICENSE.

Metadata

Release files for weider-modbus 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for weider-modbus 0.1.2
File Size Uploaded Provenance
weider_modbus-0.1.2.tar.gz 14.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for weider-modbus 0.1.2
File Interpreter ABI Platform
weider_modbus-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 25.5 kB

Release files / weider_modbus-0.1.2.tar.gz

Download URL weider_modbus-0.1.2.tar.gz
Size 14.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3522ad032f0c36234733886b527153e6179772b0488894682c93e28fccfa30e9
BLAKE2b-256 checksum
How to use checksums
84e2263a376db8885ff6414e1a9f5b71dbc4aeb8246743ff405829119cf0beb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / weider_modbus-0.1.2-py3-none-any.whl

Download URL weider_modbus-0.1.2-py3-none-any.whl
Size 10.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3dc342e8a19506948b07e7cb1948c7f6396f164999c0b631e53ffcac0ee71a08
BLAKE2b-256 checksum
How to use checksums
ed63127838af77d288297d52d67b6f08fd422f0488bfd6edd162d5917d45e6c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for weider-modbus 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for weider_modbus-0.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page