Skip to main content

ampio-mqtt

Beta - 0.x.x. This library exists to back the home-assistant/core ampio integration currently in development. Anything below 1.0.0 is unstable by design: the public surface (dataclass fields, exported names, method signatures) can and will change between any two 0.x.x releases without migration shims. 1.0.0 is reserved for the moment the integration PR is accepted upstream; until then, breaking changes are expected and pins should be exact.

Async Python client for the Ampio Smart Home local MQTT protocol exposed by the Ampio M-SERV controller. Built to back a Home Assistant integration; the library itself is Home Assistant agnostic.

Account tiers. Any Ampio account works; what the library can see is decided by the account's administrator bit. Per-user app permissions do not change it (verified with a standard account granted every app permission):

  • Administrator - the full catalogue: every DB object, the module list (AmpioClient.modules with names, models, firmware), and the global raw-channel topics that deliver input events with minimal latency.
  • Standard user (the recommended shape for a dedicated Home Assistant account) - the app-sync surface: the objects the administrator granted the account in the Ampio app, with names, classification metadata, visibility flags, rooms, and the server identity (AmpioClient.server_info). No module list (so mserv_id stays None) and no raw input topics - input events arrive about 100-140 ms later, through the per-object republish.

AmpioClient.access_tier reports the detected tier once discovery completes, and AmpioClient.test_connection reports it at validation time so a setup flow can reject an unsuitable account up front. docs/account-tiers.md has the full capability table, the measured latency difference, and when an administrator account is worth it.

The grant bounds reads and object commands alike. An account can only read and only command the objects it was granted in the app; a command aimed at anything else is dropped, and no state for it reaches the account's namespace.

Bus events are not bounded that way. Any account can raise any event number, regardless of the per-event rights the app shows, and the logic behind an event runs with full authority. A dedicated standard account is a real boundary for direct object control, not for whatever the installer wired to an event - see docs/account-tiers.md.

Status

Beta, iterated alongside the home-assistant/core ampio integration (see the stability note above). Currently supports:

  • TCP connection to the Ampio MQTT broker with username/password auth and auto-reconnect with capped exponential backoff and jitter,
  • discovery of physical modules and logical DB objects from the M-SERV,
  • two-tier discovery: administrator accounts read the full config catalogue; standard accounts fall back to the app-sync data surface (grant-filtered objects with full metadata, plus the params_devices visibility table). The detected tier is exposed as AmpioClient.access_tier,
  • replacement-stable per-object identity via AmpioObject.stable_key (the Designer leafId), identical on both tiers - see docs/identity.md,
  • live push of object state changes via per-object MQTT topics, plus a bulk states snapshot at startup,
  • classification of sensor objects (temperature and M-SENS environmental channels) with Home-Assistant-compatible device/state class hints, and the parsed reading as AmpioObject.numeric_value (None when the value is missing, unparseable, or non-finite),
  • M-SERV identification (mac, firmware versions, local IP),
  • bus events: send_event() raises one on either tier, and subscribing to BusEvent reports the ones Ampio's own logic raises (panel presses and the like, administrator-only),
  • scene catalogue and control via fetch_scenes() / run_scene() / turn_scene_off() / undo_scene() (undo restores what the objects held before the scene ran),
  • per-module health on the admin tier (AmpioModule.supply_voltage, temperature) from each module's own diagnostics broadcast, with ModuleUpdated events for updates,
  • best-effort LAN discovery via discover() (explicit multicast DNS A-record lookup of ampio.local driven by python-zeroconf, followed by a TCP probe of the resolved address). Home Assistant integrations can pass their shared AsyncZeroconf instance via discover(zeroconf=...).
  • per-object room mapping via AmpioClient.fetch_rooms() ({object_id: room_name}), backed by the M-SERV's MQTT data/groups + data/group_devices endpoints. Intended for a Home Assistant integration to forward as DeviceInfo.suggested_area at first import; reassignment is the user's call after that.
  • per-module capability classification on AmpioModule.capabilities (a frozenset[Capability]): DIGITAL_OUTPUT, DIGITAL_INPUT, ANALOG_INPUT, TEMPERATURE_INPUT, ENV_SENSOR, ROLLER_OUTPUT, RGBW_OUTPUT, IR_OUTPUT, UI_PANEL, BRIDGE, HUB, ALARM, AUDIO_VIDEO. Most modules carry several flags (e.g. M-OC-4s = {DIGITAL_OUTPUT, ANALOG_INPUT, RGBW_OUTPUT}). Drives HA platform selection and bundle/split decisions in the integration.
  • object control via AmpioClient.command() plus typed helpers (turn_on, turn_off, toggle, set_value, set_color, open_cover, close_cover, set_cover_position, set_cover_tilt). Works on both account tiers - see docs/protocol.md,
  • output-object classification via classify() / OutputKind (AmpioObject.kind, is_output, supports_tilt): relays, dimmers, RGBW lights, and the three cover types, each flagged with the command verbs it answers so a consumer picks a platform without its own type table. Tilt-capable blinds also report their slat angle as AmpioObject.tilt_position,
  • input-object classification via classify() / InputKind (AmpioObject.kind, is_input, is_on): flags map to a generic boolean, motion detection to binary_sensor.motion. Live flag/button events are delivered with minimal latency through the same ObjectUpdated event pipeline by routing the decoded raw per-channel topics (which fire ahead of the per-object republish) to the owning object,
  • eviction of objects and modules the authoritative catalogue stops listing, surfaced as ObjectRemoved / ModuleRemoved events so a consumer can drop the entities it built. Objects deleted in the Ampio app soft-delete on the admin catalogue instead (the params hidden bit) and disappear through the visible filter - see the changelog for the observed server behavior,
  • per-connect subscription diagnostics via ConnectionStats.subscribe_failures: filters the broker rejected in the SUBACK, which on the baseline server doubles as confirmation of a standard account's raw-tree denial.

Protocol reference notes live under docs/; src/ampio_mqtt/endpoints.py remains the canonical source for the topic helpers.

Supported M-SERV versions

The library is developed and live-tested against an M-SERV self-reporting serverVersion 1865 (serverRevision 409, mqttVersion 5.133.11). That baseline is the compatibility floor; wire behavior documented in this repo is verified against that install unless a tracking issue marks the claim open. Older servers are not supported, and the library logs a warning when the connected server reports a lower or missing serverVersion. If something misbehaves on an older server, upgrade the M-SERV first.

Installation

pip install ampio-mqtt

discover() resolves ampio.local over multicast DNS from inside the process via python-zeroconf, which is a hard runtime dependency. The lookup works identically on macOS, HAOS, plain Linux, and Docker - no dependency on nss-mdns/avahi being configured on the host.

Usage

import asyncio

from ampio_mqtt import AmpioClient, ObjectUpdated, discover


async def main() -> None:
    # Find the M-SERV on the LAN via mDNS.
    candidates = await discover()
    if not candidates:
        raise SystemExit("No Ampio M-SERV found on the LAN")
    host = candidates[0].address or candidates[0].host

    client = AmpioClient(host, username="user", password="secret")
    client.subscribe(
        lambda e: print(e.object.id, e.object.kind, e.object.value),
        of=ObjectUpdated,
    )
    await client.start()  # connects, subscribes, requests discovery

    # Per-object room map. A Home Assistant integration would forward each
    # value as `DeviceInfo.suggested_area` at first device creation.
    rooms = await client.fetch_rooms()
    for obj_id, room in rooms.items():
        print(f"object {obj_id} -> {room}")

    await asyncio.sleep(30)
    await client.stop()


asyncio.run(main())

License

MIT

Download files

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

Source Distribution

ampio_mqtt-0.19.0.tar.gz (123.9 kB view details)

Uploaded Source

Built Distribution

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

ampio_mqtt-0.19.0-py3-none-any.whl (56.4 kB view details)

Uploaded Python 3

File details

Details for the file ampio_mqtt-0.19.0.tar.gz.

File metadata

  • Download URL: ampio_mqtt-0.19.0.tar.gz
  • Upload date:
  • Size: 123.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ampio_mqtt-0.19.0.tar.gz
Algorithm Hash digest
SHA256 4de0227f2d60e854816193948fcdb9c59a01944281a9d9c47716d45afb42fe01
MD5 6f999cdb579c65f0646f13e1c4c41553
BLAKE2b-256 735f5a17f9b170e58b3d68fba6a2d1399c300547c07f014781b32cbd29c7813e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ampio_mqtt-0.19.0.tar.gz:

Publisher: release.yml on pszypowicz/ampio-mqtt

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

File details

Details for the file ampio_mqtt-0.19.0-py3-none-any.whl.

File metadata

  • Download URL: ampio_mqtt-0.19.0-py3-none-any.whl
  • Upload date:
  • Size: 56.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ampio_mqtt-0.19.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8693a5e4d8f0e6917bcdd01ea0f9da07e130ec66afbb5721bde38d45f81980a3
MD5 c19e81baf652eae832470d2f082919d2
BLAKE2b-256 362890e9e72f6875e3658cb250c54fa03d36b98c608933758d15fd5877ba1cb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for ampio_mqtt-0.19.0-py3-none-any.whl:

Publisher: release.yml on pszypowicz/ampio-mqtt

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

Release history Release notifications | RSS feed

0.58.0

2 files

0.57.0

2 files

0.56.0

2 files

0.55.0

2 files

0.54.1

2 files

0.54.0

2 files

0.53.0

2 files

0.52.0

2 files

0.51.0

2 files

0.50.0

2 files

0.49.0

2 files

0.48.0

2 files

0.47.0

2 files

0.46.0

2 files

0.45.0

2 files

0.44.0

2 files

0.43.0

2 files

0.42.0

2 files

0.41.0

2 files

0.40.0

2 files

0.39.0

2 files

0.38.0

2 files

0.37.0

2 files

0.36.1

2 files

0.36.0

2 files

0.35.0

2 files

0.34.0

2 files

0.33.0

2 files

0.32.0

2 files

0.31.0

2 files

0.30.0

2 files

0.29.0

2 files

0.28.0

2 files

0.27.0

2 files

0.26.1

2 files

0.26.0

2 files

0.25.0

2 files

0.24.0

2 files

0.23.0

2 files

0.22.0

2 files

0.21.0

2 files

0.20.0

2 files

This release

0.19.0 This release

2 files

0.18.0

2 files

0.17.0

2 files

0.16.0

2 files

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.1

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

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