Skip to content

Commit f0a5630

Browse files
dcjcayossarianclaude
committed
changelog: record the MqttTransport / MqttControllerTransport typing (#8)
Bill's #12 typed the bring-your-own-transport injection points with narrow Protocols; add the [Unreleased] entry (merged main in first so it sits with the other unreleased entries rather than conflicting). Co-Authored-By: Bill Flood <cayossarian@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 195d3d8 commit f0a5630

1 file changed

Lines changed: 1 addition & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ All notable changes to `ebus-sdk` are recorded here. Format follows [Keep a Chan
99
- `Device` bring-your-own-transport: `Device(..., mqttc=<client>)` accepts a pre-built MQTT client instead of constructing one from `mqtt_cfg`, so a host that already owns its MQTT connection (e.g. a Home Assistant integration, whose MQTT integration is `single_config_entry` and forbids background threads) can publish an eBus device tree over its own transport and event loop. This is the producer-side mirror of the `Controller` seam added in 0.13.0. An injected client is used as-is: the SDK never `start()`s or `stop()`s it, and `stop()` publishes a final retained `$state=disconnected` through it and returns without flushing or closing (non-blocking on the caller's loop). Root-only, and mutually exclusive with `mqtt_cfg=` / `parent=`. Property publishing now gates on connectivity (`is_connected()`) rather than only the SDK-owned run flag, so a caller-driven client that never calls the SDK's `start()` still publishes property values (owned behavior is unchanged: there, connected implies running). Because an injected client bypasses the SDK's connect path (where the LWT, the reconnect republish, and the disconnect hook are wired), the caller wires the Homie-correctness pieces itself using `Device.will()` and `Device.refresh_tree()` (below); `on_disconnect=` is inert for an injected client (documented, and warned at construction). Additive: the default (no `mqttc`) path constructs, starts, owns, and stops a client exactly as before. Thanks to @cayossarian (GH #7). (#14)
1010
- `Device.will()`: returns the tree root's Last Will and Testament descriptor (topic ending in `/$state`, payload `lost`), exposed so a bring-your-own-transport caller can set it on their client before connecting: the will rides the MQTT CONNECT packet, so the SDK cannot add it to a client it is merely handed. The SDK uses it for any client it builds. `Device.refresh_tree()` (which republishes the whole tree) is documented as the companion on-connect hook a BYO caller wires so the retained tree re-announces after a reconnect. Additive. (#13)
1111
- `Controller.resync()`: the tree-rooted discovery bookkeeping reset, extracted from the owned-client on-connect handler and made public so a bring-your-own-transport tree-rooted controller can re-walk the tree from a broker reconnect it drives itself (an injected client bypasses the SDK's on-connect, where the reset is otherwise wired). A no-op in wildcard and single-device modes. Additive. (#13)
12+
- Bring-your-own-transport injection points are now typed by narrow structural `Protocol`s instead of the concrete `MqttClient`: `MqttTransport` (the shared `publish` + `subscribe` base) and `MqttControllerTransport` (which adds `unsubscribe`, the only member the `Controller` path reaches beyond the base), both re-exported from `ebus_sdk`. `Controller`'s `mqttc=` now accepts any object satisfying `MqttControllerTransport`, so a consumer injecting its own client keeps type-checking once `ebus-mqtt-client` ships `py.typed` (until then `MqttClient` resolves to `Any`, so injection already type-checks; the protocol keeps it working past that release, which is the whole point). The protocols deliberately omit `start` / `stop`; the SDK keeps the client it constructs on a separate `_owned_client` handle, so those lifecycle methods resolve on the concrete type and "the SDK never starts or stops a client it did not build" is a property of the types rather than a convention. Additive: the default (SDK-owned) path is unchanged. Thanks to @cayossarian (GH #8). (#12)
1213

1314
## [0.15.0] — 2026-08-02
1415

0 commit comments

Comments
 (0)