Skip to main content

Async Python client for the Duco ventilation API

Project description

python-duco-client

Async Python client for the DUCO ventilation box local REST API.

The client uses the unauthenticated Connectivity Board API surface. On some firmware versions this means optional fields like node temperature, reported_api_version, endpoint inventory details, and extended diagnostics may be unavailable.

Installation

pip install python-duco-client

Quick start

import asyncio
import aiohttp
from duco import DucoClient

async def main():
    async with aiohttp.ClientSession() as session:
        client = DucoClient(session=session, host="192.168.1.100")

        board = await client.async_get_board_info()
        print(f"Box: {board.box_name} ({board.box_sub_type_name})")

        nodes = await client.async_get_nodes()
        for node in nodes:
            print(f"Node {node.node_id}: {node.general.node_type}")
            if node.sensor and node.sensor.co2 is not None:
                print(f"  CO2: {node.sensor.co2} ppm")

        await client.async_set_ventilation_state(1, "MAN2")

asyncio.run(main())

CLI

duco --host 192.168.1.100 info
duco --host 192.168.1.100 nodes
duco --host 192.168.1.100 set 1 MAN2

Documentation

See the docs/ folder for the full documentation:

License

MIT. See LICENSE for details.

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.6.1 - 2026-05-09

Documentation

  • Add ACKNOWLEDGEMENTS.md and link it from README.md to document the historical attribution for the removed API key generation implementation.

0.6.0 - 2026-05-08

Removed

  • Remove API key generation and authenticated request support from DucoClient. The library now uses the unauthenticated Connectivity Board API subset only.
  • Remove DucoAuthenticationError from the public exception surface.

Changed

  • Document that some firmware versions return a reduced unauthenticated dataset. In practice this can affect optional node temperature values, extended diagnostics, reported_api_version, and endpoint inventory data.

0.5.0 - 2026-05-08

Added

  • async_detect_board_family(host, session, ssl_context, timeout) — standalone async helper that detects the board family of a Duco box without requiring a DucoClient instance. Probes HTTPS first (/info?module=General&submodule=Board) and falls back to HTTP (/nodeinfoget?node=1) when HTTPS fails with a transport or protocol error.
  • BoardFamily StrEnum (CONNECTIVITY_BOARD, COMMUNICATION_PRINT) returned by the detection helper. Both are exported from the top-level duco package.
  • Both symbols are documented in docs/api-reference.md.

Changed

  • When the HTTPS probe returns any HTTP response (including 404), the host is considered reachable. A subsequent HTTP transport failure in that case now raises DucoError instead of DucoConnectionError, so callers can correctly distinguish "host unreachable" from "host reachable but board type unrecognised".

0.4.2 - 2026-05-07

Added

  • DucoClient now enforces a per-request timeout via a new request_timeout constructor parameter (default 10.0 seconds). A request that exceeds the timeout is raised as DucoConnectionError, consistent with other connection failures. Callers no longer need to wrap individual calls in their own asyncio.timeout().

0.4.1 - 2026-05-07

Fixed

  • Add WI (Wi-Fi) to NetworkType enum so Duco nodes connected over Wi-Fi no longer raise ValueError: 'WI' is not a valid NetworkType. Any future unrecognised network type values now fall back to NetworkType.UNKNOWN instead of crashing.

0.4.0 - 2026-05-04

Added

  • Expose typed API metadata via ApiEndpointInfo and the expanded ApiInfo model. /api responses now include public_api_version, optional reported_api_version, and typed endpoint inventory data.

Enhanced

  • Extend BoardInfo with optional public_api_version and software_version fields.
  • Parse optional version metadata defensively so older and newer firmware variants remain compatible.
  • Expand unit and focused live integration coverage for API and board metadata.
  • Update the published package description so PyPI includes both README.md and CHANGELOG.md.

0.3.10 - 2026-05-03

Fixed

  • _ensure_api_key: DucoConnectionError is no longer wrapped as DucoAuthenticationError. Previously, a connection failure during API key generation was caught by the generic except DucoError handler and re-raised as DucoAuthenticationError, bypassing callers that correctly handle DucoConnectionError. The exception is now re-raised unchanged; only genuine API failures are wrapped as DucoAuthenticationError.

Enhanced

  • Fixed ruff code quality warnings across src/ and tests/: sorted __all__ (RUF022), removed unused noqa directive (RUF100), combined elif branches (SIM114), replaced EN dashes with hyphens in docstrings/comments (RUF002, RUF003), used next(iter(...)) instead of list slice (RUF015), combined nested with statements (SIM117).
  • Fixed ruff docstring style (D413, COM812) across src/duco/. Added per-file-ignore for T201 in cli.pyprint() is intentional CLI output.

0.3.9 - 2026-04-26

Added

  • build_ssl_context() is now part of the public API (exported from duco).
  • DucoClient.__init__ accepts an optional ssl_context parameter. When provided the caller controls when the context is built (e.g. in an executor so blocking I/O stays off the asyncio event loop). When omitted the behaviour is identical to previous releases.
  • build_ssl_context() now caches its result so repeated calls are free of blocking I/O.

0.3.8 - 2026-04-26

Changed

  • DucoClient.__init__: default scheme changed from "http" to "https". All Duco Connectivity Board 2.0 boxes use HTTPS, and since v0.3.7 the client automatically constructs a valid SSL context using the bundled Duco CA certificate chain. Callers that need plain HTTP must now pass scheme="http" explicitly.

Breaking change

Code that instantiates DucoClient without a scheme= argument and expects HTTP behaviour must now pass scheme="http" explicitly.

0.3.7 - 2026-04-25

Added

  • Bundle the Duco device CA certificate chain so HTTPS connections are verified without requiring verify_ssl=False in callers. The bundled chain contains ServerDeviceCert + Duco Intermediate COM CA + Duco Root CA.
  • build_ssl_context() helper in duco._ssl builds a ready-to-use ssl.SSLContext with certificate verification enabled and hostname verification disabled (device cert SAN contains factory IP 192.168.4.1, not the user-assigned IP).
  • DucoClient automatically uses the SSL context for HTTPS connections and passes ssl=True (default behaviour) for plain HTTP connections.
  • CLI: add --https flag (and DUCO_HTTPS=1 env var) to select HTTPS; add temp and RH columns to nodes output; require --host (removed hardcoded default IP).

Fixed

  • Fix missing if __name__ == "__main__": guard in cli.py.

Internal

  • Add tests/test_ssl.py with 7 unit tests covering SSL context construction and wiring in DucoClient.

0.3.6 - 2026-04-25

Added

  • Add temperature reading support for room nodes (NodeTemperatureData).
  • New DucoClient.get_node_temperature() method.

0.3.5 - 2026-04-21

Added

  • Initial release with basic node info retrieval and action control.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_duco_client-0.6.1.tar.gz (33.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_duco_client-0.6.1-py3-none-any.whl (23.7 kB view details)

Uploaded Python 3

File details

Details for the file python_duco_client-0.6.1.tar.gz.

File metadata

  • Download URL: python_duco_client-0.6.1.tar.gz
  • Upload date:
  • Size: 33.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for python_duco_client-0.6.1.tar.gz
Algorithm Hash digest
SHA256 63e2ef4211f677d320c242a0a4bf548ecf023e6b1209d60fc79cef892a0289eb
MD5 0cc054eaaf39fa1a22e5f000a8c69c4b
BLAKE2b-256 ec9bf4dd132a7a0ec371faf29f0182c4fed5dd2c229cc21f146c3f280d11dc71

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_duco_client-0.6.1.tar.gz:

Publisher: ci.yml on ronaldvdmeer/python-duco-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file python_duco_client-0.6.1-py3-none-any.whl.

File metadata

File hashes

Hashes for python_duco_client-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 00a50f40aad717392773cc1b8edba7597240772cd2d0bfa1e535f04218204aaf
MD5 3c83b993004ce5377d74bc8ce134775e
BLAKE2b-256 58b1468f9ef55012dd4ee1b35f365caedbdb85076bf5b8444d3c728e8609ace4

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_duco_client-0.6.1-py3-none-any.whl:

Publisher: ci.yml on ronaldvdmeer/python-duco-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page