Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion homeassistant/components/alarm_control_panel/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ def message_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/binary_sensor/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ def state_message_received(_topic, payload, _qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAttributes.async_will_remove_from_hass(self)
await MqttAvailability.async_will_remove_from_hass(self)

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/climate/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ def handle_hold_mode_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/cover/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ def position_message_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/fan/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ def oscillation_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/light/mqtt/schema_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,8 @@ def xy_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/light/mqtt/schema_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ def state_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/light/mqtt/schema_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ def state_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/mqtt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,8 @@ def attributes_message_received(topic: str,
async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
from .subscription import async_unsubscribe_topics
await async_unsubscribe_topics(self.hass, self._attributes_sub_state)
self._attributes_sub_state = await async_unsubscribe_topics(
self.hass, self._attributes_sub_state)

@property
def device_state_attributes(self):
Expand Down Expand Up @@ -947,7 +948,8 @@ def availability_message_received(topic: str,
async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
from .subscription import async_unsubscribe_topics
await async_unsubscribe_topics(self.hass, self._availability_sub_state)
self._availability_sub_state = await async_unsubscribe_topics(
self.hass, self._availability_sub_state)

@property
def available(self) -> bool:
Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/mqtt/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,4 @@ async def async_subscribe_topics(hass: HomeAssistantType,
@bind_hass
async def async_unsubscribe_topics(hass: HomeAssistantType, sub_state: dict):
"""Unsubscribe from all MQTT topics managed by async_subscribe_topics."""
await async_subscribe_topics(hass, sub_state, {})

return sub_state
return await async_subscribe_topics(hass, sub_state, {})
3 changes: 2 additions & 1 deletion homeassistant/components/sensor/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ def message_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAttributes.async_will_remove_from_hass(self)
await MqttAvailability.async_will_remove_from_hass(self)

Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/switch/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ def state_message_received(topic, payload, qos):

async def async_will_remove_from_hass(self):
"""Unsubscribe when removed."""
await subscription.async_unsubscribe_topics(self.hass, self._sub_state)
self._sub_state = await subscription.async_unsubscribe_topics(
self.hass, self._sub_state)
await MqttAvailability.async_will_remove_from_hass(self)

@property
Expand Down
40 changes: 38 additions & 2 deletions tests/components/binary_sensor/test_mqtt.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""The tests for the MQTT binary sensor platform."""
import json
import unittest
from unittest.mock import Mock, patch
from unittest.mock import ANY, Mock, patch
from datetime import timedelta

import homeassistant.core as ha
Expand All @@ -16,7 +16,7 @@

from tests.common import (
get_test_home_assistant, fire_mqtt_message, async_fire_mqtt_message,
fire_time_changed, mock_component, mock_mqtt_component,
fire_time_changed, mock_component, mock_mqtt_component, mock_registry,
async_mock_mqtt_component, MockConfigEntry)


Expand Down Expand Up @@ -457,3 +457,39 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
assert device.name == 'Beer'
assert device.model == 'Glass'
assert device.sw_version == '0.1-beta'


async def test_entity_id_update(hass, mqtt_mock):
"""Test MQTT subscriptions are managed when entity_id is updated."""
registry = mock_registry(hass, {})
mock_mqtt = await async_mock_mqtt_component(hass)
assert await async_setup_component(hass, binary_sensor.DOMAIN, {
binary_sensor.DOMAIN: [{
'platform': 'mqtt',
'name': 'beer',
'state_topic': 'test-topic',
'availability_topic': 'avty-topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})

state = hass.states.get('binary_sensor.beer')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.reset_mock()

registry.async_update_entity(
'binary_sensor.beer', new_entity_id='binary_sensor.milk')
await hass.async_block_till_done()
await hass.async_block_till_done()

state = hass.states.get('binary_sensor.beer')
assert state is None

state = hass.states.get('binary_sensor.milk')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
39 changes: 38 additions & 1 deletion tests/components/cover/test_mqtt.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""The tests for the MQTT cover platform."""
import json
import unittest
from unittest.mock import ANY

from homeassistant.components import cover, mqtt
from homeassistant.components.cover import (ATTR_POSITION, ATTR_TILT_POSITION)
Expand All @@ -16,7 +17,8 @@

from tests.common import (
get_test_home_assistant, mock_mqtt_component, async_fire_mqtt_message,
fire_mqtt_message, MockConfigEntry, async_mock_mqtt_component)
fire_mqtt_message, MockConfigEntry, async_mock_mqtt_component,
mock_registry)


class TestCoverMQTT(unittest.TestCase):
Expand Down Expand Up @@ -1156,3 +1158,38 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
assert device.name == 'Beer'
assert device.model == 'Glass'
assert device.sw_version == '0.1-beta'


async def test_entity_id_update(hass, mqtt_mock):
"""Test MQTT subscriptions are managed when entity_id is updated."""
registry = mock_registry(hass, {})
mock_mqtt = await async_mock_mqtt_component(hass)
assert await async_setup_component(hass, cover.DOMAIN, {
cover.DOMAIN: [{
'platform': 'mqtt',
'name': 'beer',
'state_topic': 'test-topic',
'availability_topic': 'avty-topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})

state = hass.states.get('cover.beer')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.reset_mock()

registry.async_update_entity('cover.beer', new_entity_id='cover.milk')
await hass.async_block_till_done()
await hass.async_block_till_done()

state = hass.states.get('cover.beer')
assert state is None

state = hass.states.get('cover.milk')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
39 changes: 38 additions & 1 deletion tests/components/fan/test_mqtt.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"""Test MQTT fans."""
import json
from unittest.mock import ANY

from homeassistant.setup import async_setup_component
from homeassistant.components import fan
from homeassistant.components.mqtt.discovery import async_start
from homeassistant.const import ATTR_ASSUMED_STATE, STATE_UNAVAILABLE

from tests.common import async_fire_mqtt_message, MockConfigEntry, \
async_mock_mqtt_component
async_mock_mqtt_component, mock_registry


async def test_fail_setup_if_no_command_topic(hass, mqtt_mock):
Expand Down Expand Up @@ -224,3 +225,39 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
assert device.name == 'Beer'
assert device.model == 'Glass'
assert device.sw_version == '0.1-beta'


async def test_entity_id_update(hass, mqtt_mock):
"""Test MQTT subscriptions are managed when entity_id is updated."""
registry = mock_registry(hass, {})
mock_mqtt = await async_mock_mqtt_component(hass)
assert await async_setup_component(hass, fan.DOMAIN, {
fan.DOMAIN: [{
'platform': 'mqtt',
'name': 'beer',
'state_topic': 'test-topic',
'command_topic': 'command-topic',
'availability_topic': 'avty-topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})

state = hass.states.get('fan.beer')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.reset_mock()

registry.async_update_entity('fan.beer', new_entity_id='fan.milk')
await hass.async_block_till_done()
await hass.async_block_till_done()

state = hass.states.get('fan.beer')
assert state is None

state = hass.states.get('fan.milk')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
42 changes: 39 additions & 3 deletions tests/components/light/test_mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
"""
import json
from unittest import mock
from unittest.mock import patch
from unittest.mock import ANY, patch

from homeassistant.setup import async_setup_component
from homeassistant.const import (
Expand All @@ -165,8 +165,8 @@
import homeassistant.core as ha

from tests.common import (
assert_setup_component, async_fire_mqtt_message,
async_mock_mqtt_component, mock_coro, MockConfigEntry)
assert_setup_component, async_fire_mqtt_message, async_mock_mqtt_component,
mock_coro, MockConfigEntry, mock_registry)
from tests.components.light import common


Expand Down Expand Up @@ -1180,3 +1180,39 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
assert device.name == 'Beer'
assert device.model == 'Glass'
assert device.sw_version == '0.1-beta'


async def test_entity_id_update(hass, mqtt_mock):
"""Test MQTT subscriptions are managed when entity_id is updated."""
registry = mock_registry(hass, {})
mock_mqtt = await async_mock_mqtt_component(hass)
assert await async_setup_component(hass, light.DOMAIN, {
light.DOMAIN: [{
'platform': 'mqtt',
'name': 'beer',
'state_topic': 'test-topic',
'command_topic': 'command-topic',
'availability_topic': 'avty-topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})

state = hass.states.get('light.beer')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.reset_mock()

registry.async_update_entity('light.beer', new_entity_id='light.milk')
await hass.async_block_till_done()
await hass.async_block_till_done()

state = hass.states.get('light.beer')
assert state is None

state = hass.states.get('light.milk')
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 2
mock_mqtt.async_subscribe.assert_any_call('test-topic', ANY, 0, 'utf-8')
mock_mqtt.async_subscribe.assert_any_call('avty-topic', ANY, 0, 'utf-8')
Loading