mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-02 12:15:36 +02:00
Users integrating a Shelly plug through an external MQTT broker (ioBroker, Zigbee2MQTT, HA's MQTT broker, etc.) lost the plug's power/state/energy readings after every Bambuddy restart. The only fix was opening Settings → Smart Plugs, renaming the topic to a dummy value, saving, renaming back, and saving again. Root cause: three code paths configure an MQTT smart plug's subscriptions — the startup restore in main.py, the create route, and the update route — and they had drifted. The create/update routes used the newer per-type model (mqtt_power_topic / mqtt_energy_topic / mqtt_state_topic with per-type paths, multipliers and mqtt_state_on_value) while the startup restore was still on the legacy single-topic model. Worse, the restore loop short-circuited on `if plug.mqtt_topic:`, skipping any plug whose topics were only set in the new per-type fields — exactly the shape of a Shelly-via-ioBroker config, which publishes power and state on separate topics. The "rename, save, rename back" workaround routed through the update endpoint and re-established the subscription the correct way. Extracted the topic-resolution + service.subscribe() call into subscribe_plug_to_mqtt() in mqtt_smart_plug.py and routed all three paths through it so the schema can't drift again. The helper keeps the legacy `mqtt_topic` field working as a fallback for all three data types — matching the behaviour the startup restore used to have via subscribe()'s internal `effective_*_topic or topic` collapsing, and matching the change-detection dict already used during updates. Regression tests cover: per-type topics restored without a legacy topic, legacy single-topic backward compat, per-type multipliers overriding legacy, per-type winning when both are set, the empty-config skip case, and topic-list de-duplication.