Skip to main content

aiocomexio

Asyncio-native Python client for the Comexio IO-Server, a local building-automation controller.

No dependency on Home Assistant or any other framework — usable as a standalone library. It will provide the communication layer of the homeassistant-comexio integration.

Status: pre-alpha. The code is being moved over from the integration step by step. So far: admin login, read access (including live values of physical IOs and system info — free storage, time server settings, uptime), value writes, the Web-IO lifecycle (including the command protocol, HTTP or HTTPS), marker / KNX object management and function plan editing — plans, elements, wires, block instance settings, scene blocks and Quantum modules with their configs, run / stop (ComexioClient), admin page scraping (aiocomexio.scrape), config parsing (aiocomexio.config, including Quickbus devices such as Multitouch panels and their IOs), KNX DPT tables (aiocomexio.knx), Web-IO command builders (aiocomexio.webio, with a separate class for Quickbus IOs), function plan rendering (with block settings in the hover text) and diffing (aiocomexio.function_plan) and the block-type reference catalog that resolves Comexio catalog ids per server by stable key (aiocomexio.reference_catalog). The API may still change.

Installation

pip install aiocomexio

Usage

The client works on an aiohttp.ClientSession you create and close yourself. session_kwargs() gives it the settings Comexio needs (a cookie jar that keeps the admin login for an IP-address host, a request timeout; progress_log_interval=10 adds a "still waiting" log line for slow requests). Give every client its own session: login() clears the session's cookie jar. Value writes (set_marker_value, set_io_value, set_knx_value) go through Comexio's /api/ with a separate API user: pass api_username / api_password to the client. Every call either returns data or raises a ComexioError subclass (ComexioAuthenticationError, ComexioConnectionError, ComexioResponseError, ComexioDataError, ComexioRequestRejectedError for a write the server refused, ComexioCreatedWithoutIdError for a create the server confirmed but whose id could not be read back — the object exists, do not create it again). One exception: the value setters raise a plain ValueError, which is not a ComexioError, for a non-finite float (nan, inf) before sending anything — catch it separately if your values can be non-finite.

HTTPS with a pinned certificate

Comexio serves HTTPS with a self-signed certificate, so the client pins its SHA-256 fingerprint instead of verifying a CA. fetch_certificate_fingerprint(host) reads it from a bare TLS handshake — no HTTP request, no credentials. Pass it as fingerprint= and every request goes over HTTPS; a server presenting any other certificate raises ComexioCertificateMismatchError (not a ComexioConnectionError: retrying cannot help, the certificate was replaced or something else answers) before the request that met it is sent — if that request was a redirect hop, the hops before it did reach the pinned server. Without fingerprint the client uses plain HTTP.

Fetching the fingerprint is trust on first use: whatever answers that one handshake gets pinned. So fetch it once, at setup, store it, and pass the stored value on every later start — fetching it anew on each start would accept whatever certificate answers. If you want to rule out an impostor at setup too, compare format_fingerprint() with the SHA-256 value Comexio's admin page lists under its certificate hashes. A pinned client follows redirects only within its HTTPS origin (same scheme, host and port). For a host name that resolves to several addresses, aiohttp reports only the last failure, so a mismatch there can arrive as ComexioConnectionError; compare a fresh fetch_certificate_fingerprint() with the pin to tell the two apart.

import asyncio

import aiohttp

from aiocomexio import ComexioClient, fetch_certificate_fingerprint, format_fingerprint, session_kwargs
from aiocomexio.config import parse_config

HOST = "192.168.0.20"


async def setup() -> str:
    """Run once: read the fingerprint, check it, store it with the rest of your configuration."""
    fingerprint = await fetch_certificate_fingerprint(HOST)
    print("Comexio certificate:", format_fingerprint(fingerprint))
    return fingerprint


async def main(stored_fingerprint: str) -> None:
    """Every later start: use the stored fingerprint, never a freshly fetched one."""
    async with aiohttp.ClientSession(**session_kwargs()) as session:
        client = ComexioClient(HOST, "admin", "secret", session=session, fingerprint=stored_fingerprint)
        await client.login()
        raw = await client.get_raw_config()
        config = parse_config(raw.variables, io_types=raw.io_types, io_input_types=raw.io_input_types)
        print(len(config["markers"]), "markers on Comexio", raw.comexio_version)


asyncio.run(main(stored_fingerprint="<the value setup() returned>"))

Development

pip install -e ".[dev]"
pre-commit install

ruff check .            # lint
ruff format --check .   # formatting check; drop --check to auto-format
mypy                    # strict type check (src/aiocomexio)
pytest                  # tests

License

MIT

Metadata

Release files for aiocomexio 0.8.0

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

Source distribution (sdist)

Source distribution for aiocomexio 0.8.0
File Size Uploaded Provenance
aiocomexio-0.8.0.tar.gz 246.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for aiocomexio 0.8.0
File Interpreter ABI Platform
aiocomexio-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 402.7 kB

Release files / aiocomexio-0.8.0.tar.gz

Download URL aiocomexio-0.8.0.tar.gz
Size 246.5 kB
Tags Source
SHA-256 checksum
How to use checksums
6cfb165b50d13e0e625960360f05f827a6129c4a1f331beb6aed5b9de4a862cc
BLAKE2b-256 checksum
How to use checksums
837179ea888c1168874b80c2343d1bdf0525b6af03874f61171cb7eedf7f1251
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 23, 2026.

Transparency log

Release files / aiocomexio-0.8.0-py3-none-any.whl

Download URL aiocomexio-0.8.0-py3-none-any.whl
Size 156.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6565847bb89b67ee4d40d7e728ebc01fc439002ee61367ac7106db7c6eeac3a3
BLAKE2b-256 checksum
How to use checksums
3384305a97ff7511d856f9d062104ccfafa9ffc7f09b10828e91b78edbf27a0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 23, 2026.

Transparency log

Security for aiocomexio 0.8.0

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 aiocomexio-0.8.0.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 23, 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