Correct MQTT device trigger reconfiguration with same topic (#36234)
This commit is contained in:
parent
31250eafe8
commit
f1af5b71e2
3 changed files with 70 additions and 5 deletions
|
@ -887,6 +887,7 @@ class MQTT:
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
|
_LOGGER.debug("Unsubscribing from %s", topic)
|
||||||
async with self._paho_lock:
|
async with self._paho_lock:
|
||||||
result: int = None
|
result: int = None
|
||||||
result, _ = await self.hass.async_add_executor_job(
|
result, _ = await self.hass.async_add_executor_job(
|
||||||
|
|
|
@ -138,11 +138,15 @@ class Trigger:
|
||||||
self.remove_signal = remove_signal
|
self.remove_signal = remove_signal
|
||||||
self.type = config[CONF_TYPE]
|
self.type = config[CONF_TYPE]
|
||||||
self.subtype = config[CONF_SUBTYPE]
|
self.subtype = config[CONF_SUBTYPE]
|
||||||
self.topic = config[CONF_TOPIC]
|
|
||||||
self.payload = config[CONF_PAYLOAD]
|
self.payload = config[CONF_PAYLOAD]
|
||||||
self.qos = config[CONF_QOS]
|
self.qos = config[CONF_QOS]
|
||||||
|
topic_changed = self.topic != config[CONF_TOPIC]
|
||||||
|
self.topic = config[CONF_TOPIC]
|
||||||
|
|
||||||
# Unsubscribe+subscribe if this trigger is in use
|
# Unsubscribe+subscribe if this trigger is in use and topic has changed
|
||||||
|
# If topic is same unsubscribe+subscribe will execute in the wrong order
|
||||||
|
# because unsubscribe is done with help of async_create_task
|
||||||
|
if topic_changed:
|
||||||
for trig in self.trigger_instances:
|
for trig in self.trigger_instances:
|
||||||
await trig.async_attach_trigger()
|
await trig.async_attach_trigger()
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ from tests.common import (
|
||||||
assert_lists_same,
|
assert_lists_same,
|
||||||
async_fire_mqtt_message,
|
async_fire_mqtt_message,
|
||||||
async_get_device_automations,
|
async_get_device_automations,
|
||||||
|
async_mock_mqtt_component,
|
||||||
async_mock_service,
|
async_mock_service,
|
||||||
mock_device_registry,
|
mock_device_registry,
|
||||||
mock_registry,
|
mock_registry,
|
||||||
|
@ -456,7 +457,7 @@ async def test_if_fires_on_mqtt_message_after_update(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(calls) == 1
|
assert len(calls) == 1
|
||||||
|
|
||||||
# Update the trigger
|
# Update the trigger with different topic
|
||||||
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla1/config", data2)
|
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla1/config", data2)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
@ -468,6 +469,65 @@ async def test_if_fires_on_mqtt_message_after_update(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(calls) == 2
|
assert len(calls) == 2
|
||||||
|
|
||||||
|
# Update the trigger with same topic
|
||||||
|
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla1/config", data2)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "foobar/triggers/button1", "")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(calls) == 2
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "foobar/triggers/buttonOne", "")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(calls) == 3
|
||||||
|
|
||||||
|
|
||||||
|
async def test_no_resubscribe_same_topic(hass, device_reg, mqtt_mock):
|
||||||
|
"""Test subscription to topics without change."""
|
||||||
|
mock_mqtt = await async_mock_mqtt_component(hass)
|
||||||
|
config_entry = MockConfigEntry(domain=DOMAIN, data={})
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
await async_start(hass, "homeassistant", {}, config_entry)
|
||||||
|
|
||||||
|
data1 = (
|
||||||
|
'{ "automation_type":"trigger",'
|
||||||
|
' "device":{"identifiers":["0AFFD2"]},'
|
||||||
|
' "topic": "foobar/triggers/button1",'
|
||||||
|
' "type": "button_short_press",'
|
||||||
|
' "subtype": "button_1" }'
|
||||||
|
)
|
||||||
|
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla1/config", data1)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
device_entry = device_reg.async_get_device({("mqtt", "0AFFD2")}, set())
|
||||||
|
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
automation.DOMAIN,
|
||||||
|
{
|
||||||
|
automation.DOMAIN: [
|
||||||
|
{
|
||||||
|
"trigger": {
|
||||||
|
"platform": "device",
|
||||||
|
"domain": DOMAIN,
|
||||||
|
"device_id": device_entry.id,
|
||||||
|
"discovery_id": "bla1",
|
||||||
|
"type": "button_short_press",
|
||||||
|
"subtype": "button_1",
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {"some": ("short_press")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
call_count = mock_mqtt.async_subscribe.call_count
|
||||||
|
async_fire_mqtt_message(hass, "homeassistant/device_automation/bla1/config", data1)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert mock_mqtt.async_subscribe.call_count == call_count
|
||||||
|
|
||||||
|
|
||||||
async def test_not_fires_on_mqtt_message_after_remove_by_mqtt(
|
async def test_not_fires_on_mqtt_message_after_remove_by_mqtt(
|
||||||
hass, device_reg, calls, mqtt_mock
|
hass, device_reg, calls, mqtt_mock
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue