Metadata-Version: 2.5
Name: pydimplex-nwpm
Version: 0.1.0
Summary: Asynchronous client for the Dimplex NWPM Touch heat pump gateway (MQTT and Modbus TCP)
Project-URL: Homepage, https://github.com/p-atr/pydimplex-nwpm
Project-URL: Repository, https://github.com/p-atr/pydimplex-nwpm
Project-URL: Issues, https://github.com/p-atr/pydimplex-nwpm/issues
Project-URL: Changelog, https://github.com/p-atr/pydimplex-nwpm/blob/main/CHANGELOG.md
Author: patr_
License-Expression: MIT
License-File: LICENSE
Keywords: dimplex,heat pump,home-assistant,modbus,mqtt,nwpm
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Home Automation
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: paho-mqtt>=2.1.0
Requires-Dist: pymodbus>=3.10.0
Provides-Extra: dev
Requires-Dist: mypy>=1.14; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.25; extra == 'dev'
Requires-Dist: pytest>=8.3; extra == 'dev'
Requires-Dist: ruff>=0.9; extra == 'dev'
Description-Content-Type: text/markdown

# pydimplex-nwpm

Asynchronous Python client for the **Dimplex NWPM Touch** heat pump gateway
(also built into Dimplex *System M* heat pumps). The gateway exposes the heat
pump manager (WPM) over a local MQTT broker and optionally over Modbus TCP;
this library wraps both transports with an asyncio-native API and no cloud
dependency.

It is the protocol layer of the Home Assistant `dimplex_nwpm` integration but
has no Home Assistant dependency and can be used on its own.

## Features

- MQTT v5 request/response (`get_value` / `set_value` / `clear_prev_val_cache`)
  using response-topic and correlation-data, driven directly from the asyncio
  event loop (paho-mqtt without a network thread).
- Push updates: changed datapoints, device twin (`twin_reported_state`), fault
  and lock history, appliance time configuration.
- Datapoint helpers: range expansion (`1300-1308u`), canonical names
  (`714u` ≡ `714i`), typed parsing of digital/integer/analog values.
- Automatic reconnect with exponential backoff and a distinct authentication
  error for wrong passwords.
- Thin asynchronous Modbus TCP client for registers the MQTT interface does
  not expose.
- Fully typed (`py.typed`).

## Installation

```bash
pip install pydimplex-nwpm
```

Requires Python 3.12 or newer.

## Usage

```python
import asyncio

from pydimplex_nwpm import DimplexMqttClient


async def main() -> None:
    client = DimplexMqttClient("192.168.1.42", "80B56598")
    client.add_values_listener(lambda changed: print("changed:", changed))

    await client.connect()
    twin = await client.wait_for_twin()
    print("serial:", twin.appliance_serial, "software:", twin.appliance_version)

    values = await client.get_values("1285-1305a")
    print("outdoor temperature:", values["1301a"], "°C")

    # Ask the gateway to re-send everything it has cached so the listener
    # receives a complete snapshot.
    await client.clear_cache()
    await asyncio.sleep(30)

    await client.disconnect()


asyncio.run(main())
```

Writing a datapoint:

```python
await client.set_value("714u", 1)  # operating mode: auto
```

Modbus TCP (network services must be enabled in the gateway web interface):

```python
from pydimplex_nwpm import DimplexModbusClient

modbus = DimplexModbusClient("192.168.1.42")
print(await modbus.read_software_version())  # e.g. "M3.13"
print(await modbus.read_coils(177))  # Smart-RTC valve
await modbus.close()
```

## Datapoint naming

Datapoints are addressed by the pCO variable index followed by a type suffix:

| Suffix | Type | Value |
| --- | --- | --- |
| `d` | digital | `True` / `False` |
| `i` | signed 16 bit integer | `int` |
| `u` | unsigned 16 bit integer | `int` (same variable as `i`) |
| `a` | analog | `float`, already scaled by the gateway |

Ranges such as `1500-1502d` read several consecutive variables in one request.
`canonical_name()` normalises `u` to `i` so values from push updates (which
use `i`) and from documentation (which mostly uses `u`) end up under one key.

The gateway password is shown on the heat pump display under
*Analytics → Hardware and software → Network → Gateway access*; the MQTT user
name is always `mqtt`.

## Development

```bash
pip install -e ".[dev]"
ruff check . && ruff format --check .
mypy
pytest
```

## References

- [Dimplex Wiki: MQTT Anbindung](https://dimplex.atlassian.net/wiki/spaces/DW/pages/3021930597/MQTT+Anbindung)
- [Dimplex Wiki: Modbus TCP Anbindung](https://dimplex.atlassian.net/wiki/spaces/DW/pages/3303571457/Modbus+TCP+Anbindung)

## License

MIT — see [LICENSE](LICENSE).
