Deduplicate MQTT mixin tests (#32563)
* Deduplicate MQTT mixin tests * Remove test of not yet merged functionpull/32618/head
parent
743833e5f3
commit
4bb9f1800d
|
@ -266,7 +266,9 @@ class MqttVacuum(
|
|||
|
||||
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)
|
||||
await MqttDiscoveryUpdate.async_will_remove_from_hass(self)
|
||||
|
|
|
@ -231,7 +231,9 @@ class MqttStateVacuum(
|
|||
|
||||
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)
|
||||
await MqttDiscoveryUpdate.async_will_remove_from_hass(self)
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
"""Common test objects."""
|
||||
import json
|
||||
from unittest.mock import ANY
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
async_setup_component,
|
||||
mock_registry,
|
||||
)
|
||||
|
||||
|
||||
async def help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, domain, config
|
||||
):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(hass, domain, config,)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get(f"{domain}.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, domain, config
|
||||
):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(hass, domain, config,)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get(f"{domain}.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, domain, config
|
||||
):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(hass, domain, config,)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get(f"{domain}.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, domain, data1, data2
|
||||
):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
|
||||
|
||||
async def help_test_unique_id(hass, domain, config):
|
||||
"""Test unique id option only creates one alarm per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(hass, domain, config,)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(domain)) == 1
|
||||
|
||||
|
||||
async def help_test_discovery_removal(hass, mqtt_mock, caplog, domain, data):
|
||||
"""Test removal of discovered component."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def help_test_discovery_update(hass, mqtt_mock, caplog, domain, data1, data2):
|
||||
"""Test update of discovered component."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
|
||||
state = hass.states.get(f"{domain}.milk")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def help_test_discovery_broken(hass, mqtt_mock, caplog, domain, data1, data2):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def help_test_entity_device_info_with_identifier(hass, mqtt_mock, domain, data):
|
||||
"""Test MQTT alarm control panel device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
|
||||
|
||||
async def help_test_entity_device_info_update(hass, mqtt_mock, domain, config):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
|
||||
|
||||
async def help_test_entity_id_update(hass, mqtt_mock, domain, config):
|
||||
"""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, domain, config,)
|
||||
|
||||
state = hass.states.get(f"{domain}.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(f"{domain}.beer", new_entity_id=f"{domain}.milk")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(f"{domain}.beer")
|
||||
assert state is None
|
||||
|
||||
state = hass.states.get(f"{domain}.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")
|
|
@ -1,9 +1,7 @@
|
|||
"""The tests the MQTT alarm control panel component."""
|
||||
import json
|
||||
from unittest.mock import ANY
|
||||
|
||||
from homeassistant.components import alarm_control_panel, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components import alarm_control_panel
|
||||
from homeassistant.const import (
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
|
@ -15,13 +13,24 @@ from homeassistant.const import (
|
|||
STATE_UNKNOWN,
|
||||
)
|
||||
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_setup_component,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
async_setup_component,
|
||||
mock_registry,
|
||||
)
|
||||
from tests.components.alarm_control_panel import common
|
||||
|
||||
|
@ -489,25 +498,19 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
alarm_control_panel.DOMAIN,
|
||||
{
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, alarm_control_panel.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("alarm_control_panel.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_state_via_state_topic_template(hass, mqtt_mock):
|
||||
"""Test updating with template_value via state topic."""
|
||||
|
@ -541,54 +544,38 @@ async def test_update_state_via_state_topic_template(hass, mqtt_mock):
|
|||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
alarm_control_panel.DOMAIN,
|
||||
{
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, alarm_control_panel.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("alarm_control_panel.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
alarm_control_panel.DOMAIN,
|
||||
{
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, alarm_control_panel.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("alarm_control_panel.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -599,86 +586,48 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, alarm_control_panel.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one alarm per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
alarm_control_panel.DOMAIN,
|
||||
{
|
||||
alarm_control_panel.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(alarm_control_panel.DOMAIN)) == 1
|
||||
config = {
|
||||
alarm_control_panel.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, alarm_control_panel.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_alarm(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered alarm_control_panel."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(
|
||||
hass, mqtt_mock, caplog, alarm_control_panel.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_update_alarm(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered alarm_control_panel."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -689,66 +638,32 @@ async def test_discovery_update_alarm(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
|
||||
state = hass.states.get("alarm_control_panel.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, alarm_control_panel.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = (
|
||||
'{ "name": "Milk",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, alarm_control_panel.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT alarm control panel device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test-topic",
|
||||
"command_topic": "test-command-topic",
|
||||
"device": {
|
||||
"identifiers": ["helloworld"],
|
||||
"connections": [["mac", "02:5b:26:a8:dc:12"]],
|
||||
|
@ -760,26 +675,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, alarm_control_panel.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -795,63 +697,25 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(
|
||||
hass, mqtt_mock, alarm_control_panel.DOMAIN, config
|
||||
)
|
||||
|
||||
|
||||
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,
|
||||
alarm_control_panel.DOMAIN,
|
||||
{
|
||||
alarm_control_panel.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
},
|
||||
config = {
|
||||
alarm_control_panel.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(
|
||||
hass, mqtt_mock, alarm_control_panel.DOMAIN, config
|
||||
)
|
||||
|
||||
state = hass.states.get("alarm_control_panel.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(
|
||||
"alarm_control_panel.beer", new_entity_id="alarm_control_panel.milk"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("alarm_control_panel.beer")
|
||||
assert state is None
|
||||
|
||||
state = hass.states.get("alarm_control_panel.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")
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
"""The tests for the MQTT binary sensor platform."""
|
||||
from datetime import datetime, timedelta
|
||||
import json
|
||||
from unittest.mock import ANY, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components import binary_sensor, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components import binary_sensor
|
||||
from homeassistant.const import (
|
||||
EVENT_STATE_CHANGED,
|
||||
STATE_OFF,
|
||||
|
@ -15,14 +14,22 @@ import homeassistant.core as ha
|
|||
from homeassistant.setup import async_setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_fire_time_changed,
|
||||
async_mock_mqtt_component,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message, async_fire_time_changed
|
||||
|
||||
|
||||
async def test_setting_sensor_value_expires_availability_topic(hass, mqtt_mock, caplog):
|
||||
"""Test the expiration of the value."""
|
||||
|
@ -417,73 +424,51 @@ async def test_off_delay(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
binary_sensor.DOMAIN,
|
||||
{
|
||||
binary_sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
binary_sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, binary_sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("binary_sensor.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
binary_sensor.DOMAIN,
|
||||
{
|
||||
binary_sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
binary_sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, binary_sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("binary_sensor.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
binary_sensor.DOMAIN,
|
||||
{
|
||||
binary_sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
binary_sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, binary_sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("binary_sensor.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -494,78 +479,46 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, binary_sensor.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one sensor per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
binary_sensor.DOMAIN,
|
||||
{
|
||||
binary_sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_all()) == 1
|
||||
config = {
|
||||
binary_sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, binary_sensor.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_binary_sensor(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered binary_sensor."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "availability_topic": "availability_topic" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(
|
||||
hass, mqtt_mock, caplog, binary_sensor.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_update_binary_sensor(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered binary_sensor."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -576,52 +529,22 @@ async def test_discovery_update_binary_sensor(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic2",'
|
||||
' "availability_topic": "availability_topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
|
||||
state = hass.states.get("binary_sensor.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, binary_sensor.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "off_delay": -1 }'
|
||||
data2 = '{ "name": "Milk",' ' "state_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("binary_sensor.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("binary_sensor.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, binary_sensor.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT binary sensor device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -638,26 +561,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, binary_sensor.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -672,62 +582,22 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(
|
||||
hass, mqtt_mock, binary_sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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")
|
||||
config = {
|
||||
binary_sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, binary_sensor.DOMAIN, config)
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
import copy
|
||||
import json
|
||||
import unittest
|
||||
from unittest.mock import ANY
|
||||
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.climate import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
||||
from homeassistant.components.climate.const import (
|
||||
DOMAIN as CLIMATE_DOMAIN,
|
||||
|
@ -25,16 +23,23 @@ from homeassistant.components.climate.const import (
|
|||
SUPPORT_TARGET_TEMPERATURE,
|
||||
SUPPORT_TARGET_TEMPERATURE_RANGE,
|
||||
)
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.const import STATE_OFF, STATE_UNAVAILABLE
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
async_setup_component,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message, async_setup_component
|
||||
from tests.components.climate import common
|
||||
|
||||
ENTITY_CLIMATE = "climate.test"
|
||||
|
@ -768,76 +773,54 @@ async def test_temp_step_custom(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
{
|
||||
CLIMATE_DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
CLIMATE_DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, CLIMATE_DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("climate.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
{
|
||||
CLIMATE_DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
CLIMATE_DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, CLIMATE_DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("climate.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
{
|
||||
CLIMATE_DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
CLIMATE_DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, CLIMATE_DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("climate.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "power_state_topic": "test-topic",'
|
||||
|
@ -850,127 +833,60 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "power_command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, CLIMATE_DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one climate per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
{
|
||||
CLIMATE_DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(CLIMATE_DOMAIN)) == 1
|
||||
config = {
|
||||
CLIMATE_DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"power_state_topic": "test-topic",
|
||||
"power_command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, CLIMATE_DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_climate(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered climate."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data = '{ "name": "Beer" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, CLIMATE_DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_climate(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered climate."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = '{ "name": "Milk" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
|
||||
state = hass.states.get("climate.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, CLIMATE_DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "power_command_topic": "test_topic#" }'
|
||||
data2 = '{ "name": "Milk", ' ' "power_command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, CLIMATE_DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT climate device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -986,26 +902,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, CLIMATE_DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -1021,63 +924,23 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/climate/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, CLIMATE_DOMAIN, config)
|
||||
|
||||
|
||||
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,
|
||||
CLIMATE_DOMAIN,
|
||||
{
|
||||
CLIMATE_DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"mode_state_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
state = hass.states.get("climate.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("climate.beer", new_entity_id="climate.milk")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("climate.beer")
|
||||
assert state is None
|
||||
|
||||
state = hass.states.get("climate.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")
|
||||
config = {
|
||||
CLIMATE_DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"mode_state_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, CLIMATE_DOMAIN, config)
|
||||
|
||||
|
||||
async def test_precision_default(hass, mqtt_mock):
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
"""The tests for the MQTT cover platform."""
|
||||
import json
|
||||
from unittest.mock import ANY
|
||||
|
||||
from homeassistant.components import cover, mqtt
|
||||
from homeassistant.components import cover
|
||||
from homeassistant.components.cover import ATTR_POSITION, ATTR_TILT_POSITION
|
||||
from homeassistant.components.mqtt.cover import MqttCover
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
ATTR_ENTITY_ID,
|
||||
|
@ -27,13 +25,22 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message
|
||||
|
||||
|
||||
async def test_state_via_state_topic(hass, mqtt_mock):
|
||||
"""Test the controlling state via topic."""
|
||||
|
@ -1693,73 +1700,51 @@ async def test_invalid_device_class(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
cover.DOMAIN,
|
||||
{
|
||||
cover.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
cover.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, cover.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("cover.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
cover.DOMAIN,
|
||||
{
|
||||
cover.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
cover.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, cover.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("cover.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
cover.DOMAIN,
|
||||
{
|
||||
cover.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
cover.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, cover.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("cover.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -1770,126 +1755,58 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
|
||||
|
||||
async def test_discovery_removal_cover(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered cover."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_update_cover(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered cover."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
|
||||
state = hass.states.get("cover.milk")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic#" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("cover.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("cover.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, cover.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique_id option only creates one cover per id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
cover.DOMAIN,
|
||||
{
|
||||
cover.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
config = {
|
||||
cover.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, cover.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_cover(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered cover."""
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, cover.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_cover(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered cover."""
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, cover.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
|
||||
assert len(hass.states.async_entity_ids(cover.DOMAIN)) == 1
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic#" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, cover.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT cover device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -1907,26 +1824,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, cover.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -1942,60 +1846,20 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/cover/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, cover.DOMAIN, config)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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")
|
||||
config = {
|
||||
cover.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, cover.DOMAIN, config)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
"""Test MQTT fans."""
|
||||
import json
|
||||
from unittest.mock import ANY
|
||||
|
||||
from homeassistant.components import fan, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components import fan
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
STATE_OFF,
|
||||
|
@ -12,12 +10,21 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message
|
||||
from tests.components.fan import common
|
||||
|
||||
|
||||
|
@ -438,138 +445,53 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
assert state.state is not STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_discovery_removal_fan(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered fan."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_update_fan(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered fan."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("fan.milk")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("fan.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
fan.DOMAIN,
|
||||
{
|
||||
fan.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
fan.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, fan.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("fan.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
fan.DOMAIN,
|
||||
{
|
||||
fan.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
fan.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, fan.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("fan.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
fan.DOMAIN,
|
||||
{
|
||||
fan.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
fan.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, fan.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("fan.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -580,65 +502,56 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("fan.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, fan.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique_id option only creates one fan per id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
fan.DOMAIN,
|
||||
{
|
||||
fan.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
config = {
|
||||
fan.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, fan.DOMAIN, config)
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
|
||||
assert len(hass.states.async_entity_ids(fan.DOMAIN)) == 1
|
||||
async def test_discovery_removal_fan(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered fan."""
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, fan.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_fan(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered fan."""
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_update(hass, mqtt_mock, caplog, fan.DOMAIN, data1, data2)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_broken(hass, mqtt_mock, caplog, fan.DOMAIN, data1, data2)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT fan device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -656,26 +569,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, fan.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -691,61 +591,21 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/fan/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, fan.DOMAIN, config)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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")
|
||||
config = {
|
||||
fan.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, fan.DOMAIN, config)
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
from copy import deepcopy
|
||||
import json
|
||||
|
||||
from homeassistant.components import mqtt, vacuum
|
||||
from homeassistant.components import vacuum
|
||||
from homeassistant.components.mqtt import CONF_COMMAND_TOPIC
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components.mqtt.vacuum import schema_legacy as mqttvacuum
|
||||
from homeassistant.components.mqtt.vacuum.schema import services_to_strings
|
||||
from homeassistant.components.mqtt.vacuum.schema_legacy import (
|
||||
|
@ -26,11 +25,21 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message
|
||||
from tests.components.vacuum import common
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
|
@ -514,142 +523,50 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_discovery_removal_vacuum(hass, mqtt_mock):
|
||||
"""Test removal of discovered vacuum."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic#" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_update_vacuum(hass, mqtt_mock):
|
||||
"""Test update of discovered vacuum."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("vacuum.milk")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, vacuum.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("vacuum.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("vacuum.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_json(hass, mqtt_mock, caplog):
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("vacuum.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -660,63 +577,58 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass, mqtt_mock):
|
||||
"""Test unique id option only creates one vacuum per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, vacuum.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_vacuum(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered vacuum."""
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, vacuum.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_vacuum(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered vacuum."""
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
|
||||
assert len(hass.states.async_entity_ids()) == 1
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic#" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT vacuum device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -733,26 +645,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, vacuum.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -767,20 +666,22 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, vacuum.DOMAIN, config)
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
async def test_entity_id_update(hass, mqtt_mock):
|
||||
"""Test MQTT subscriptions are managed when entity_id is updated."""
|
||||
config = {
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"battery_level_topic": "test-topic",
|
||||
"battery_level_template": "{{ value_json.battery_level }}",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, vacuum.DOMAIN, config)
|
||||
|
|
|
@ -155,7 +155,7 @@ light:
|
|||
"""
|
||||
import json
|
||||
from unittest import mock
|
||||
from unittest.mock import ANY, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components import light, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
|
@ -168,13 +168,25 @@ from homeassistant.const import (
|
|||
import homeassistant.core as ha
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_setup_component,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_coro,
|
||||
mock_registry,
|
||||
)
|
||||
from tests.components.light import common
|
||||
|
||||
|
@ -1063,73 +1075,51 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("light.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("light.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("light.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -1140,79 +1130,42 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one light per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(light.DOMAIN)) == 1
|
||||
config = {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, light.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_light(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered light."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, light.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_deprecated(hass, mqtt_mock, caplog):
|
||||
|
@ -1231,9 +1184,6 @@ async def test_discovery_deprecated(hass, mqtt_mock, caplog):
|
|||
|
||||
async def test_discovery_update_light(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered light."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -1244,59 +1194,26 @@ async def test_discovery_update_light(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("light.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = (
|
||||
'{ "name": "Milk",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT light device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -1314,26 +1231,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, light.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -1349,61 +1253,21 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, light.DOMAIN, config)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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")
|
||||
config = {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, light.DOMAIN, config)
|
||||
|
|
|
@ -89,7 +89,7 @@ light:
|
|||
"""
|
||||
import json
|
||||
from unittest import mock
|
||||
from unittest.mock import ANY, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components import light, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
|
@ -103,13 +103,21 @@ from homeassistant.const import (
|
|||
import homeassistant.core as ha
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_coro,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_mqtt_message, mock_coro
|
||||
from tests.components.light import common
|
||||
|
||||
|
||||
|
@ -913,76 +921,54 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("light.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("light.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "json",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("light.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "json",'
|
||||
|
@ -995,72 +981,40 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one light per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"schema": "json",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"schema": "json",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(light.DOMAIN)) == 1
|
||||
config = {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"schema": "json",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"schema": "json",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, light.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered mqtt_json lights."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {"mqtt": {}}, entry)
|
||||
data = '{ "name": "Beer",' ' "schema": "json",' ' "command_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, light.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_deprecated(hass, mqtt_mock, caplog):
|
||||
|
@ -1081,9 +1035,6 @@ async def test_discovery_deprecated(hass, mqtt_mock, caplog):
|
|||
|
||||
async def test_discovery_update_light(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered light."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "json",'
|
||||
|
@ -1096,29 +1047,13 @@ async def test_discovery_update_light(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("light.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = (
|
||||
'{ "name": "Milk",'
|
||||
|
@ -1126,30 +1061,13 @@ async def test_discovery_broken(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT light device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -1168,26 +1086,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, light.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -1204,62 +1109,22 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, light.DOMAIN, config)
|
||||
|
||||
|
||||
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",
|
||||
"schema": "json",
|
||||
"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()
|
||||
|
||||
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")
|
||||
config = {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"schema": "json",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, light.DOMAIN, config)
|
||||
|
|
|
@ -27,7 +27,7 @@ If your light doesn't support white value feature, omit `white_value_template`.
|
|||
If your light doesn't support RGB feature, omit `(red|green|blue)_template`.
|
||||
"""
|
||||
import json
|
||||
from unittest.mock import ANY, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components import light, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
|
@ -40,13 +40,25 @@ from homeassistant.const import (
|
|||
import homeassistant.core as ha
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_setup_component,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_coro,
|
||||
mock_registry,
|
||||
)
|
||||
|
||||
|
||||
|
@ -510,82 +522,60 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("light.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("light.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
light.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "template",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("light.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "template",'
|
||||
|
@ -602,64 +592,40 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_off_template": "off",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("light.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one light per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
light.DOMAIN,
|
||||
{
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"schema": "template",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"schema": "template",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(light.DOMAIN)) == 1
|
||||
config = {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"schema": "template",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"schema": "template",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, light.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered mqtt_json lights."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {"mqtt": {}}, entry)
|
||||
data = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "template",'
|
||||
|
@ -667,15 +633,7 @@ async def test_discovery_removal(hass, mqtt_mock, caplog):
|
|||
' "command_on_template": "on",'
|
||||
' "command_off_template": "off"}'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, light.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_deprecated(hass, mqtt_mock, caplog):
|
||||
|
@ -698,9 +656,6 @@ async def test_discovery_deprecated(hass, mqtt_mock, caplog):
|
|||
|
||||
async def test_discovery_update_light(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered light."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "template",'
|
||||
|
@ -717,29 +672,13 @@ async def test_discovery_update_light(hass, mqtt_mock, caplog):
|
|||
' "command_on_template": "on",'
|
||||
' "command_off_template": "off"}'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("light.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = (
|
||||
'{ "name": "Milk",'
|
||||
|
@ -749,30 +688,13 @@ async def test_discovery_broken(hass, mqtt_mock, caplog):
|
|||
' "command_on_template": "on",'
|
||||
' "command_off_template": "off"}'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("light.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("light.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, light.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT light device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -793,26 +715,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, light.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -831,64 +740,24 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, light.DOMAIN, config)
|
||||
|
||||
|
||||
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",
|
||||
"schema": "template",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"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()
|
||||
|
||||
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")
|
||||
config = {
|
||||
light.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"schema": "template",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"command_on_template": "on,{{ transition }}",
|
||||
"command_off_template": "off,{{ transition|d }}",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, light.DOMAIN, config)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
"""The tests for the MQTT lock platform."""
|
||||
import json
|
||||
from unittest.mock import ANY
|
||||
|
||||
from homeassistant.components import lock, mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components import lock
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
STATE_LOCKED,
|
||||
|
@ -12,12 +10,21 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message
|
||||
from tests.components.lock import common
|
||||
|
||||
|
||||
|
@ -309,73 +316,51 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
lock.DOMAIN,
|
||||
{
|
||||
lock.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
lock.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, lock.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("lock.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
lock.DOMAIN,
|
||||
{
|
||||
lock.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
lock.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, lock.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("lock.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
lock.DOMAIN,
|
||||
{
|
||||
lock.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
lock.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, lock.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("lock.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -386,100 +371,42 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, lock.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one light per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
lock.DOMAIN,
|
||||
{
|
||||
lock.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
assert len(hass.states.async_entity_ids(lock.DOMAIN)) == 1
|
||||
"""Test unique id option only creates one lock per unique_id."""
|
||||
config = {
|
||||
lock.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test_topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, lock.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_lock(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered lock."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("lock.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, lock.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_lock(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered lock."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -492,28 +419,18 @@ async def test_discovery_update_lock(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "command_topic",'
|
||||
' "availability_topic": "availability_topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
await help_test_discovery_update(hass, mqtt_mock, caplog, lock.DOMAIN, data1, data2)
|
||||
|
||||
state = hass.states.get("lock.milk")
|
||||
assert state is None
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic" }'
|
||||
await help_test_discovery_broken(hass, mqtt_mock, caplog, lock.DOMAIN, data1, data2)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT lock device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -531,26 +448,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, lock.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -566,61 +470,21 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/lock/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, lock.DOMAIN, config)
|
||||
|
||||
|
||||
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,
|
||||
lock.DOMAIN,
|
||||
{
|
||||
lock.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
state = hass.states.get("lock.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("lock.beer", new_entity_id="lock.milk")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("lock.beer")
|
||||
assert state is None
|
||||
|
||||
state = hass.states.get("lock.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")
|
||||
config = {
|
||||
lock.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, lock.DOMAIN, config)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""The tests for the MQTT sensor platform."""
|
||||
from datetime import datetime, timedelta
|
||||
import json
|
||||
from unittest.mock import ANY, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
|
@ -11,12 +11,24 @@ import homeassistant.core as ha
|
|||
from homeassistant.setup import async_setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_fire_time_changed,
|
||||
async_mock_mqtt_component,
|
||||
mock_registry,
|
||||
)
|
||||
|
||||
|
||||
|
@ -395,24 +407,18 @@ async def test_valid_device_class(hass, mqtt_mock):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
sensor.DOMAIN,
|
||||
{
|
||||
sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("sensor.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_setting_attribute_with_template(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
|
@ -441,52 +447,36 @@ async def test_setting_attribute_with_template(hass, mqtt_mock):
|
|||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
sensor.DOMAIN,
|
||||
{
|
||||
sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("sensor.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
sensor.DOMAIN,
|
||||
{
|
||||
sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
sensor.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, sensor.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("sensor.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -497,127 +487,58 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, sensor.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one sensor per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
sensor.DOMAIN,
|
||||
{
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
|
||||
assert len(hass.states.async_all()) == 1
|
||||
config = {
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, sensor.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_sensor(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered sensor."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data = '{ "name": "Beer",' ' "state_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, sensor.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_sensor(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered sensor."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = '{ "name": "Beer",' ' "state_topic": "test_topic" }'
|
||||
data2 = '{ "name": "Milk",' ' "state_topic": "test_topic" }'
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
|
||||
state = hass.states.get("sensor.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, sensor.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "state_topic": "test_topic#" }'
|
||||
data2 = '{ "name": "Milk",' ' "state_topic": "test_topic" }'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, sensor.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT sensor device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -634,26 +555,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, sensor.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -668,63 +576,23 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, sensor.DOMAIN, config)
|
||||
|
||||
|
||||
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,
|
||||
sensor.DOMAIN,
|
||||
{
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
state = hass.states.get("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("sensor.beer", new_entity_id="sensor.milk")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.beer")
|
||||
assert state is None
|
||||
|
||||
state = hass.states.get("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")
|
||||
config = {
|
||||
sensor.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, sensor.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_hub(hass, mqtt_mock):
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
from copy import deepcopy
|
||||
import json
|
||||
|
||||
from homeassistant.components import mqtt, vacuum
|
||||
from homeassistant.components import vacuum
|
||||
from homeassistant.components.mqtt import CONF_COMMAND_TOPIC, CONF_STATE_TOPIC
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components.mqtt.vacuum import CONF_SCHEMA, schema_state as mqttvacuum
|
||||
from homeassistant.components.mqtt.vacuum.schema import services_to_strings
|
||||
from homeassistant.components.mqtt.vacuum.schema_state import SERVICE_TO_STRING
|
||||
|
@ -32,11 +31,21 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message
|
||||
from tests.components.vacuum import common
|
||||
|
||||
COMMAND_TOPIC = "vacuum/command"
|
||||
|
@ -340,212 +349,123 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_discovery_removal_vacuum(hass, mqtt_mock):
|
||||
"""Test removal of discovered vacuum."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data = '{ "name": "Beer",' ' "command_topic": "test_topic"}'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic#"}'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic"}'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_discovery_update_vacuum(hass, mqtt_mock):
|
||||
"""Test update of discovered vacuum."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer",' ' "command_topic": "test_topic"}'
|
||||
data2 = '{ "name": "Milk",' ' "command_topic": "test_topic"}'
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("vacuum.milk")
|
||||
assert state is None
|
||||
|
||||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, vacuum.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("vacuum.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("vacuum.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_json(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "test",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("vacuum.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "state",'
|
||||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic1" }'
|
||||
)
|
||||
data2 = (
|
||||
'{ "name": "Beer",'
|
||||
' "schema": "state",'
|
||||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("vacuum.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass, mqtt_mock):
|
||||
"""Test unique id option only creates one vacuum per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
vacuum.DOMAIN,
|
||||
{
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
config = {
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "Test 1",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "Test 2",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, vacuum.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_vacuum(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered vacuum."""
|
||||
data = '{ "schema": "state", "name": "Beer",' ' "command_topic": "test_topic"}'
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, vacuum.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_vacuum(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered vacuum."""
|
||||
data1 = '{ "schema": "state", "name": "Beer",' ' "command_topic": "test_topic"}'
|
||||
data2 = '{ "schema": "state", "name": "Milk",' ' "command_topic": "test_topic"}'
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
|
||||
assert len(hass.states.async_entity_ids()) == 1
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
data1 = '{ "schema": "state", "name": "Beer",' ' "command_topic": "test_topic#"}'
|
||||
data2 = '{ "schema": "state", "name": "Milk",' ' "command_topic": "test_topic"}'
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, vacuum.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT vacuum device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "Test 1",
|
||||
"command_topic": "test-command-topic",
|
||||
"device": {
|
||||
|
@ -559,28 +479,16 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, vacuum.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "Test 1",
|
||||
"command_topic": "test-command-topic",
|
||||
"device": {
|
||||
|
@ -593,20 +501,22 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, vacuum.DOMAIN, config)
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/vacuum/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
async def test_entity_id_update(hass, mqtt_mock):
|
||||
"""Test MQTT subscriptions are managed when entity_id is updated."""
|
||||
config = {
|
||||
vacuum.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"schema": "state",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, vacuum.DOMAIN, config)
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
"""The tests for the MQTT switch platform."""
|
||||
import json
|
||||
from unittest.mock import ANY
|
||||
|
||||
from asynctest import patch
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import mqtt, switch
|
||||
from homeassistant.components.mqtt.discovery import async_start
|
||||
from homeassistant.components import switch
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
STATE_OFF,
|
||||
|
@ -16,13 +14,21 @@ from homeassistant.const import (
|
|||
import homeassistant.core as ha
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_mqtt_message,
|
||||
async_mock_mqtt_component,
|
||||
mock_coro,
|
||||
mock_registry,
|
||||
from .common import (
|
||||
help_test_discovery_broken,
|
||||
help_test_discovery_removal,
|
||||
help_test_discovery_update,
|
||||
help_test_discovery_update_attr,
|
||||
help_test_entity_device_info_update,
|
||||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_unique_id,
|
||||
help_test_update_with_json_attrs_bad_JSON,
|
||||
help_test_update_with_json_attrs_not_dict,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_mqtt_message, async_mock_mqtt_component, mock_coro
|
||||
from tests.components.switch import common
|
||||
|
||||
|
||||
|
@ -265,73 +271,51 @@ async def test_custom_state_payload(hass, mock_publish):
|
|||
|
||||
async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
|
||||
"""Test the setting of attribute via MQTT with JSON payload."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
switch.DOMAIN,
|
||||
{
|
||||
switch.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
switch.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_setting_attribute_via_mqtt_json_message(
|
||||
hass, mqtt_mock, switch.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '{ "val": "100" }')
|
||||
state = hass.states.get("switch.test")
|
||||
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
switch.DOMAIN,
|
||||
{
|
||||
switch.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
switch.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_not_dict(
|
||||
hass, mqtt_mock, caplog, switch.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", '[ "list", "of", "things"]')
|
||||
state = hass.states.get("switch.test")
|
||||
|
||||
assert state.attributes.get("val") is None
|
||||
assert "JSON result was not a dictionary" in caplog.text
|
||||
|
||||
|
||||
async def test_update_with_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
|
||||
"""Test attributes get extracted from a JSON result."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
switch.DOMAIN,
|
||||
{
|
||||
switch.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
},
|
||||
config = {
|
||||
switch.DOMAIN: {
|
||||
"platform": "mqtt",
|
||||
"name": "test",
|
||||
"command_topic": "test-topic",
|
||||
"json_attributes_topic": "attr-topic",
|
||||
}
|
||||
}
|
||||
await help_test_update_with_json_attrs_bad_JSON(
|
||||
hass, mqtt_mock, caplog, switch.DOMAIN, config
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "attr-topic", "This is not JSON")
|
||||
|
||||
state = hass.states.get("switch.test")
|
||||
assert state.attributes.get("val") is None
|
||||
assert "Erroneous JSON: This is not JSON" in caplog.text
|
||||
|
||||
|
||||
async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered MQTTAttributes."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "command_topic": "test_topic",'
|
||||
|
@ -342,88 +326,46 @@ async def test_discovery_update_attr(hass, mqtt_mock, caplog):
|
|||
' "command_topic": "test_topic",'
|
||||
' "json_attributes_topic": "attr-topic2" }'
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "100" }')
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Change json_attributes_topic
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Verify we are no longer subscribing to the old topic
|
||||
async_fire_mqtt_message(hass, "attr-topic1", '{ "val": "50" }')
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state.attributes.get("val") == "100"
|
||||
|
||||
# Verify we are subscribing to the new topic
|
||||
async_fire_mqtt_message(hass, "attr-topic2", '{ "val": "75" }')
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state.attributes.get("val") == "75"
|
||||
await help_test_discovery_update_attr(
|
||||
hass, mqtt_mock, caplog, switch.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id(hass):
|
||||
"""Test unique id option only creates one switch per unique_id."""
|
||||
await async_mock_mqtt_component(hass)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
switch.DOMAIN,
|
||||
{
|
||||
switch.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "test-topic", "payload")
|
||||
|
||||
assert len(hass.states.async_entity_ids()) == 1
|
||||
config = {
|
||||
switch.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "Test 2",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
},
|
||||
]
|
||||
}
|
||||
await help_test_unique_id(hass, switch.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_discovery_removal_switch(hass, mqtt_mock, caplog):
|
||||
"""Test removal of discovered switch."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", "")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_removal(hass, mqtt_mock, caplog, switch.DOMAIN, data)
|
||||
|
||||
|
||||
async def test_discovery_update_switch(hass, mqtt_mock, caplog):
|
||||
"""Test update of discovered switch."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = (
|
||||
'{ "name": "Beer",'
|
||||
' "state_topic": "test_topic",'
|
||||
|
@ -434,59 +376,26 @@ async def test_discovery_update_switch(hass, mqtt_mock, caplog):
|
|||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Beer"
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("switch.milk")
|
||||
assert state is None
|
||||
await help_test_discovery_update(
|
||||
hass, mqtt_mock, caplog, switch.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_discovery_broken(hass, mqtt_mock, caplog):
|
||||
"""Test handling of bad discovery message."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
|
||||
data1 = '{ "name": "Beer" }'
|
||||
data2 = (
|
||||
'{ "name": "Milk",'
|
||||
' "state_topic": "test_topic",'
|
||||
' "command_topic": "test_topic" }'
|
||||
)
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is None
|
||||
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data2)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.milk")
|
||||
assert state is not None
|
||||
assert state.name == "Milk"
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is None
|
||||
await help_test_discovery_broken(
|
||||
hass, mqtt_mock, caplog, switch.DOMAIN, data1, data2
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
||||
"""Test MQTT switch device registry integration."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
"platform": "mqtt",
|
||||
|
@ -504,26 +413,13 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
|
|||
"unique_id": "veryunique",
|
||||
}
|
||||
)
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.identifiers == {("mqtt", "helloworld")}
|
||||
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
|
||||
assert device.manufacturer == "Whatever"
|
||||
assert device.name == "Beer"
|
||||
assert device.model == "Glass"
|
||||
assert device.sw_version == "0.1-beta"
|
||||
await help_test_entity_device_info_with_identifier(
|
||||
hass, mqtt_mock, switch.DOMAIN, data
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_device_info_update(hass, mqtt_mock):
|
||||
"""Test device registry update."""
|
||||
entry = MockConfigEntry(domain=mqtt.DOMAIN)
|
||||
entry.add_to_hass(hass)
|
||||
await async_start(hass, "homeassistant", {}, entry)
|
||||
registry = await hass.helpers.device_registry.async_get_registry()
|
||||
|
||||
config = {
|
||||
"platform": "mqtt",
|
||||
"name": "Test 1",
|
||||
|
@ -539,61 +435,21 @@ async def test_entity_device_info_update(hass, mqtt_mock):
|
|||
},
|
||||
"unique_id": "veryunique",
|
||||
}
|
||||
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Beer"
|
||||
|
||||
config["device"]["name"] = "Milk"
|
||||
data = json.dumps(config)
|
||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = registry.async_get_device({("mqtt", "helloworld")}, set())
|
||||
assert device is not None
|
||||
assert device.name == "Milk"
|
||||
await help_test_entity_device_info_update(hass, mqtt_mock, switch.DOMAIN, config)
|
||||
|
||||
|
||||
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,
|
||||
switch.DOMAIN,
|
||||
{
|
||||
switch.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("switch.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("switch.beer", new_entity_id="switch.milk")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("switch.beer")
|
||||
assert state is None
|
||||
|
||||
state = hass.states.get("switch.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")
|
||||
config = {
|
||||
switch.DOMAIN: [
|
||||
{
|
||||
"platform": "mqtt",
|
||||
"name": "beer",
|
||||
"state_topic": "test-topic",
|
||||
"command_topic": "command-topic",
|
||||
"availability_topic": "avty-topic",
|
||||
"unique_id": "TOTALLY_UNIQUE",
|
||||
}
|
||||
]
|
||||
}
|
||||
await help_test_entity_id_update(hass, mqtt_mock, switch.DOMAIN, config)
|
||||
|
|
Loading…
Reference in New Issue