Repository navigation
homie: Device bring-your-own-transport (inject mqttc on a root Device) - #18
Merged
Merged
Conversation
#14) Lets a root Device accept a caller-supplied MQTT client so the SDK can be embedded in a host that owns its connection (Home Assistant: single_config_entry makes a second SDK-owned connection impossible). Mirrors Controller's seam. - Device(mqttc=): root-only, mutually exclusive with mqtt_cfg= and parent=. _owns_client = mqttc is None gates lifecycle. Typed Optional[MqttClient] for now (the MqttDeviceTransport protocol widening rides #12). - start_mqtt_client() (Device and Property) no-ops for an injected client. - stop() branches on ownership: injected publishes a plain retained $state=disconnected and returns without flushing or closing (non-blocking). - publish_value()/clear_value() gate on connectivity (is_running OR is_connected) so a loop-owning host that never calls start() still publishes values; owned behavior is unchanged (connected implies running there). - on_disconnect= is documented and warned as inert for an injected client. - Presence-by-identity for the mqtt_cfg exclusivity guard. Caller wires the Homie-correctness pieces from #13: set will() before connecting and call refresh_tree() from their on-connect. docs: README Bring-your-own-transport section; CHANGELOG [Unreleased] entries (also backfills #13's will()/resync()). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Producer-side bring-your-own-transport: a root
Deviceaccepts a caller-supplied MQTT client so the SDK can be embedded in a host that already owns its connection. The driving case is Home Assistant, whose MQTT integration issingle_config_entry(a second SDK-owned connection is impossible) and forbids background threads. This mirrors theController(mqttc=...)seam shipped in 0.13.0.From discussion #7 (Bill Flood / @cayossarian). Consumes the wiring contract from #13. The
MqttDeviceTransportprotocol widening is a follow-up on #12 (Device'smqttcis typedOptional[MqttClient]for now, exactly asControllershipped pre-#12).What it does
Device(mqttc=<client>): root-only, mutually exclusive withmqtt_cfg=andparent=.self._owns_client = mqttc is Nonegates lifecycle.start_mqtt_client()(bothDeviceandProperty) no-ops for an injected client: the SDK never starts a client it was handed.stop()branches on ownership: owned = flush + close (unchanged); injected = plain retained$state=disconnectedthen return, no flush, no close (non-blocking on the caller's loop).publish_value()/clear_value()gate on connectivity (is_running or is_connected()), so a loop-owning host that never calls the SDK'sstart()still publishes property values. Owned behavior is unchanged (there, connected implies running).on_disconnect=is documented and warned as inert for an injected client (the caller registers disconnect handling on its own client, likeController).mqtt_cfgexclusivity guard (mqtt_cfg={}+parentnow raises rather than silently dropping).The caller wires the two Homie-correctness pieces from #13: set
Device.will()on the client before connecting, and callDevice.refresh_tree()from its on-connect. See the new README "Bring-your-own-transport" section.Review
Ran a 3-lens adversarial review (correctness / edge-cases / Controller-consistency) with a per-finding refutation pass; 5 of 13 findings confirmed and all fixed here. The load-bearing one:
publish_value/clear_valuegated onis_running(set only by the SDK'sstart()), which a loop-owning HA host never calls, so every property value would have silently dropped. Now gated on connectivity, with a regression test.Tests / docs
+11 tests (517 total, was 506 on
main), including the connected-but-not-running publish regression and the ownership/exclusivity/inert-hook cases.ruff check+ruff format --checkclean; the 3.10-3.13 matrix (#16) runs on this PR.README gains a Bring-your-own-transport subsection; CHANGELOG
[Unreleased]gets the Device BYO /will()/resync()entries (backfilling #13).🤖 Generated with Claude Code