Skip to content

Commit 8676b4b

Browse files
dcjclaude
andcommitted
docs(changelog): order 0.16.0 Added bullets feature-first, group transport typing
The 0.16.0 Added bullets landed in merge order rather than reading order: MqttDeviceTransport (a derived type) led the list, ahead of the Device BYO feature it serves and its own MqttTransport base, which trailed at the bottom. Reorder to: Device BYO, will(), resync(), the MqttTransport/MqttControllerTransport base typing, then MqttDeviceTransport right after it. Doc-only; 0.16.0 is already released. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent bdb613a commit 8676b4b

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ All notable changes to `ebus-sdk` are recorded here. Format follows [Keep a Chan
88

99
### Added
1010

11-
- `MqttDeviceTransport`: the structural (`Protocol`) type for a client injected into a root `Device`, re-exported from `ebus_sdk`. It derives from the shared `MqttTransport` base (`publish` + `subscribe`) and adds `is_connected` + `is_running`, the members the device publish path reads; it omits `start` / `stop` / `publish_and_flush`, which are owned-only. `Device`'s `mqttc=` parameter is now annotated with it instead of the concrete `MqttClient` (parallel to `Controller`'s `MqttControllerTransport`), so a consumer injecting its own client type-checks once `ebus-mqtt-client` ships `py.typed` (today `MqttClient` resolves to `Any`, so injection already type-checks; the protocol keeps it working past that release). The SDK keeps the client it builds on a separate `Device._owned_client` handle, so the owned-only lifecycle methods resolve on the concrete type and "the SDK never starts or stops a client it did not build" is enforced by the types rather than a convention. Additive.
1211
- `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)
1312
- `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)
1413
- `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)
1514
- 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)
15+
- `MqttDeviceTransport`: the structural (`Protocol`) type for a client injected into a root `Device`, re-exported from `ebus_sdk`. It derives from the shared `MqttTransport` base (`publish` + `subscribe`) and adds `is_connected` + `is_running`, the members the device publish path reads; it omits `start` / `stop` / `publish_and_flush`, which are owned-only. `Device`'s `mqttc=` parameter is now annotated with it instead of the concrete `MqttClient` (parallel to `Controller`'s `MqttControllerTransport`), so a consumer injecting its own client type-checks once `ebus-mqtt-client` ships `py.typed` (today `MqttClient` resolves to `Any`, so injection already type-checks; the protocol keeps it working past that release). The SDK keeps the client it builds on a separate `Device._owned_client` handle, so the owned-only lifecycle methods resolve on the concrete type and "the SDK never starts or stops a client it did not build" is enforced by the types rather than a convention. Additive.
1616

1717
### Changed
1818

0 commit comments

Comments
 (0)