Browse Source

fix topic of birth & last will message `homeassistant/{switchbot_mqtt->switchbot-mqtt}/status` (old kept for backward compatibility)

Fabian Peter Hammerle 1 year ago
parent
commit
9947875774
3 changed files with 30 additions and 17 deletions
  1. 5 0
      CHANGELOG.md
  2. 15 11
      switchbot_mqtt/__init__.py
  3. 10 6
      tests/test_mqtt.py

+ 5 - 0
CHANGELOG.md

@@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Fixed
+- Publish birth and last will message on expected/documented topic
+  `homeassistant/switchbot-mqtt/status`
+  (old/undocumented topic `homeassistant/switchbot_mqtt/status` kept for
+  backward compatibility until next major release)
 
 ## [3.3.0] - 2022-08-30
 ### Added

+ 15 - 11
switchbot_mqtt/__init__.py

@@ -27,7 +27,9 @@ from switchbot_mqtt._actors.base import _MQTTCallbackUserdata
 
 _LOGGER = logging.getLogger(__name__)
 
-_MQTT_AVAILABILITY_TOPIC = "switchbot_mqtt/status"
+_MQTT_AVAILABILITY_TOPIC = "switchbot-mqtt/status"
+# for backward compatability, will be removed in next major release:
+_MQTT_AVAILABILITY_TOPIC_LEGACY = "switchbot_mqtt/status"
 # "online" and "offline" to match home assistant's default settings
 # https://www.home-assistant.io/integrations/switch.mqtt/#payload_available
 _MQTT_BIRTH_PAYLOAD = "online"
@@ -52,11 +54,12 @@ def _mqtt_on_connect(
         else mqtt_broker_host,
         mqtt_broker_port,
     )
-    mqtt_client.publish(
-        topic=userdata.mqtt_topic_prefix + _MQTT_AVAILABILITY_TOPIC,
-        payload=_MQTT_BIRTH_PAYLOAD,
-        retain=True,
-    )
+    for topic in (_MQTT_AVAILABILITY_TOPIC, _MQTT_AVAILABILITY_TOPIC_LEGACY):
+        mqtt_client.publish(
+            topic=userdata.mqtt_topic_prefix + topic,
+            payload=_MQTT_BIRTH_PAYLOAD,
+            retain=True,
+        )
     _ButtonAutomator.mqtt_subscribe(mqtt_client=mqtt_client, settings=userdata)
     _CurtainMotor.mqtt_subscribe(mqtt_client=mqtt_client, settings=userdata)
 
@@ -95,11 +98,12 @@ def _run(
         mqtt_client.username_pw_set(username=mqtt_username, password=mqtt_password)
     elif mqtt_password:
         raise ValueError("Missing MQTT username")
-    mqtt_client.will_set(
-        topic=mqtt_topic_prefix + _MQTT_AVAILABILITY_TOPIC,
-        payload=_MQTT_LAST_WILL_PAYLOAD,
-        retain=True,
-    )
+    for topic in (_MQTT_AVAILABILITY_TOPIC, _MQTT_AVAILABILITY_TOPIC_LEGACY):
+        mqtt_client.will_set(
+            topic=mqtt_topic_prefix + topic,
+            payload=_MQTT_LAST_WILL_PAYLOAD,
+            retain=True,
+        )
     mqtt_client.connect(host=mqtt_host, port=mqtt_port)
     # https://github.com/eclipse/paho.mqtt.python/blob/master/src/paho/mqtt/client.py#L1740
     mqtt_client.loop_forever()

+ 10 - 6
tests/test_mqtt.py

@@ -65,9 +65,10 @@ def test__mqtt_on_connect(
             {},
             0,
         )
-    mqtt_client.publish.assert_called_once_with(
-        topic="whatever/switchbot_mqtt/status", payload="online", retain=True
-    )
+    assert mqtt_client.publish.call_args_list == [
+        unittest.mock.call(topic=f"whatever/{t}/status", payload="online", retain=True)
+        for t in ("switchbot-mqtt", "switchbot_mqtt")
+    ]
     assert mqtt_client.subscribe.call_args_list == [
         unittest.mock.call("whatever/switch/switchbot/+/set"),
         unittest.mock.call("whatever/cover/switchbot-curtain/+/set"),
@@ -141,9 +142,12 @@ def test__run(
     )
     assert not mqtt_client_mock().username_pw_set.called
     mqtt_client_mock().tls_set.assert_called_once_with(ca_certs=None)
-    mqtt_client_mock().will_set.assert_called_once_with(
-        topic="homeassistant/switchbot_mqtt/status", payload="offline", retain=True
-    )
+    assert mqtt_client_mock().will_set.call_args_list == [
+        unittest.mock.call(
+            topic=f"homeassistant/{t}/status", payload="offline", retain=True
+        )
+        for t in ("switchbot-mqtt", "switchbot_mqtt")
+    ]
     mqtt_client_mock().connect.assert_called_once_with(host=mqtt_host, port=mqtt_port)
     mqtt_client_mock().socket().getpeername.return_value = (mqtt_host, mqtt_port)
     with caplog.at_level(logging.DEBUG):