pympacds-mqtt
MQTT client service for pympacds. Maintains a single MQTT connection to a broker and exposes publish/subscribe over D-Bus, with automatic reconnection.
Features
- A single, always-on MQTT connection with automatic reconnection using
exponential backoff (
reconnect_min_s…reconnect_max_s), re-subscribing all active topics after each reconnect. - Publish/subscribe over D-Bus:
publish,send,subscribe,unsubscribe,reconnect, andstatus, plus amessage_receivedsignal and a read-onlyconnectedproperty. - MQTT 3.1.1 and 5.0; TLS (CA cert, client cert/key, and a
development-only
tls_insecuremode); username/password auth; and Last Will & Testament (LWT). - A bounded inbound message queue (drop-oldest on overflow;
queue_size = 0means unbounded). - Runtime configuration:
[mqtt]keys are writable via the frameworkConfigContract; connection parameters are staged and applied with an explicitreconnect(). - Exports the framework
HealthContract(always) andConfigContract(opt-in via[dbus] contract_config = true) alongside the MQTT contract.
Why paho-mqtt
The service uses paho-mqtt as its MQTT engine
because it is the reference Eclipse Paho implementation: it supports MQTT 3.1,
3.1.1, and 5.0, and is pure Python with no transitive dependencies. No
third-party asyncio wrapper (e.g. aiomqtt) is used — the asyncio adapter is
owned by this project (see below), so the dependency surface stays minimal and
the framework keeps full control over its event loop.
Asyncio shim
paho-mqtt is a blocking, callback-driven library, so pympacds-mqtt wraps it in
an internal shim (pympacds_mqtt.shim) — the only module that imports
paho.mqtt. It adapts paho's "external event loop" mode to the framework's
single-asyncio-loop model:
- Socket integration —
on_socket_open/on_socket_close/on_socket_register_write/on_socket_unregister_writemap toloop.add_reader/loop.add_writer, soloop_read/loop_writerun on the event loop and never block it. - Non-blocking connect — the hostname is resolved with
await loop.getaddrinfo(...), thenconnect_async(...)drives the TCP/TLS handshake through the socket callbacks untilon_connectfires (bounded byconnect_timeout_s). - Loop cadence —
loop_misc()(pings, QoS retries) runs from a periodic task atloop_interval_s. - Message bridge —
on_messageenqueues into a boundedasyncio.Queue(drop-oldest, never blocking); the service drains it withasync for topic, payload in shim.messages(). - Reconnection —
on_disconnectstarts an exponential-backoff reconnect loop that re-subscribes all topics on success; a gracefuldisconnect()/stop()never triggers it.
Installation
Using PIP
pip install pympacds-mqtt
Using pip installs the Python package only — the D-Bus policy and systemd unit
are not installed. You can still run the service directly with
pympacds-mqtt -c /etc/pympacds/mqtt.ini, or register and enable it
system-wide with the admin script. Since there is no packaged unit, pass the
pip-installed executable via --program so the unit is generated:
sudo pympacds-admin setup # one-time: user, log dir, D-Bus policy
sudo pympacds-admin install mqtt \
--program "$(command -v pympacds-mqtt)" \
--config /etc/pympacds/mqtt.ini --start
Alternatively, install the Debian package (see below), which already ships the unit and policy.
Using PPA
Debian packages are provided through launchpad ppa (dargor0/mpacds):
sudo add-apt-repository ppa:dargor0/mpacds
sudo apt update
sudo apt install python3-pympacds-mqtt
The package installs the service system-wide (executable, systemd unit, D-Bus
policy, and the mqtt.ini.example config) and depends on python3-pympacds.
Repository has been tested on Ubuntu (plucky, resolute, stonking) and Debian (stable, testing, unstable).
Configuration
The service reads its parameters from the [mqtt] INI section (see
config/mqtt.ini.example). Key options:
| Key | Default | Description |
|---|---|---|
host |
localhost |
Broker hostname/IP |
port |
1883 |
Broker port |
keepalive |
60 |
Keep-alive interval (seconds) |
username / password |
"" |
Optional credentials |
use_tls |
false |
Enable TLS |
subscribe_topics |
"" |
Comma-separated topics subscribed at startup |
default_topic |
"" |
Topic used by send() (empty = send() fails) |
queue_size |
1000 |
Max queued inbound messages (0 = unbounded) |
Run with:
pympacds-mqtt -c /etc/pympacds/mqtt.ini
D-Bus API
Interface org.pympacds.MQTT at object path /org/pympacds/mqtt:
| Member | Type | Description |
|---|---|---|
publish(topic, payload) |
publish(ss) -> b |
Publish a message |
send(payload) |
send(s) -> b |
Publish to default_topic |
subscribe(topic) |
subscribe(s) -> b |
Subscribe at runtime |
unsubscribe(topic) |
unsubscribe(s) -> b |
Unsubscribe |
reconnect() |
reconnect() -> b |
Rebuild client and reconnect |
status() |
status() -> s |
JSON connection snapshot |
message_received(topic, payload) |
signal (ss) |
Emitted on each received message |
connected |
property (b) |
Connection state |
The framework HealthContract (at .../health) and ConfigContract
([dbus] contract_config = true) are also exported.
Metadata
Release files for pympacds-mqtt 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pympacds_mqtt-0.1.3.tar.gz | 18.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pympacds_mqtt-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.3 kB
Release files / pympacds_mqtt-0.1.3.tar.gz
| Download URL | pympacds_mqtt-0.1.3.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a10c345eee2911963615901a37c497ac623ada9132cb940b479aa4d5f0c8bf6e
|
|
BLAKE2b-256 checksum How to use checksums |
04ec0e4a7e40b87f6a84dc62d5784062a1f3b0b9c372e22170d8248d6a6c8ac1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / pympacds_mqtt-0.1.3-py3-none-any.whl
| Download URL | pympacds_mqtt-0.1.3-py3-none-any.whl |
|---|---|
| Size | 10.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0dd88d0ee9b1b4dafa2a32d256f1b16628951f9e24a7d589d5685c60cbd94d12
|
|
BLAKE2b-256 checksum How to use checksums |
2e50df47fe22b65097d506b0d0fe7fd834ecd2500a260607c59889d0585dbf99
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|