Add device registry to MQTT light (#19013)

This commit is contained in:
emontnemery 2018-12-13 15:51:50 +01:00 committed by Otto Winter
parent 6766d25e62
commit 7436c0fe42
6 changed files with 239 additions and 16 deletions

View file

@ -15,13 +15,13 @@ from homeassistant.components.light import (
ATTR_WHITE_VALUE, Light, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, ATTR_WHITE_VALUE, Light, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP,
SUPPORT_EFFECT, SUPPORT_COLOR, SUPPORT_WHITE_VALUE) SUPPORT_EFFECT, SUPPORT_COLOR, SUPPORT_WHITE_VALUE)
from homeassistant.const import ( from homeassistant.const import (
CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_EFFECT, CONF_HS, CONF_NAME, CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_DEVICE, CONF_EFFECT, CONF_HS,
CONF_OPTIMISTIC, CONF_PAYLOAD_OFF, CONF_PAYLOAD_ON, STATE_ON, CONF_NAME, CONF_OPTIMISTIC, CONF_PAYLOAD_OFF, CONF_PAYLOAD_ON, STATE_ON,
CONF_RGB, CONF_STATE, CONF_VALUE_TEMPLATE, CONF_WHITE_VALUE, CONF_XY) CONF_RGB, CONF_STATE, CONF_VALUE_TEMPLATE, CONF_WHITE_VALUE, CONF_XY)
from homeassistant.components.mqtt import ( from homeassistant.components.mqtt import (
CONF_AVAILABILITY_TOPIC, CONF_COMMAND_TOPIC, CONF_PAYLOAD_AVAILABLE, CONF_AVAILABILITY_TOPIC, CONF_COMMAND_TOPIC, CONF_PAYLOAD_AVAILABLE,
CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC,
MqttAvailability, MqttDiscoveryUpdate, subscription) MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, subscription)
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
@ -105,6 +105,7 @@ PLATFORM_SCHEMA_BASIC = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_ON_COMMAND_TYPE, default=DEFAULT_ON_COMMAND_TYPE): vol.Optional(CONF_ON_COMMAND_TYPE, default=DEFAULT_ON_COMMAND_TYPE):
vol.In(VALUES_ON_COMMAND_TYPE), vol.In(VALUES_ON_COMMAND_TYPE),
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema) }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema)
@ -117,7 +118,9 @@ async def async_setup_entity_basic(hass, config, async_add_entities,
async_add_entities([MqttLight(config, discovery_hash)]) async_add_entities([MqttLight(config, discovery_hash)])
class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light, RestoreEntity): # pylint: disable=too-many-ancestors
class MqttLight(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
Light, RestoreEntity):
"""Representation of a MQTT light.""" """Representation of a MQTT light."""
def __init__(self, config, discovery_hash): def __init__(self, config, discovery_hash):
@ -151,11 +154,13 @@ class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light, RestoreEntity):
payload_available = config.get(CONF_PAYLOAD_AVAILABLE) payload_available = config.get(CONF_PAYLOAD_AVAILABLE)
payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE) payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE)
qos = config.get(CONF_QOS) qos = config.get(CONF_QOS)
device_config = config.get(CONF_DEVICE)
MqttAvailability.__init__(self, availability_topic, qos, MqttAvailability.__init__(self, availability_topic, qos,
payload_available, payload_not_available) payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash, MqttDiscoveryUpdate.__init__(self, discovery_hash,
self.discovery_update) self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Subscribe to MQTT events.""" """Subscribe to MQTT events."""

View file

@ -18,10 +18,10 @@ from homeassistant.components.light import (
from homeassistant.components.mqtt import ( from homeassistant.components.mqtt import (
CONF_AVAILABILITY_TOPIC, CONF_COMMAND_TOPIC, CONF_PAYLOAD_AVAILABLE, CONF_AVAILABILITY_TOPIC, CONF_COMMAND_TOPIC, CONF_PAYLOAD_AVAILABLE,
CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC,
MqttAvailability, MqttDiscoveryUpdate, subscription) MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, subscription)
from homeassistant.const import ( from homeassistant.const import (
CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_EFFECT, CONF_NAME, CONF_OPTIMISTIC, CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_DEVICE, CONF_EFFECT, CONF_NAME,
CONF_RGB, CONF_WHITE_VALUE, CONF_XY, STATE_ON) CONF_OPTIMISTIC, CONF_RGB, CONF_WHITE_VALUE, CONF_XY, STATE_ON)
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
@ -80,6 +80,7 @@ PLATFORM_SCHEMA_JSON = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean, vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean,
vol.Optional(CONF_HS, default=DEFAULT_HS): cv.boolean, vol.Optional(CONF_HS, default=DEFAULT_HS): cv.boolean,
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema) }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema)
@ -89,8 +90,9 @@ async def async_setup_entity_json(hass: HomeAssistantType, config: ConfigType,
async_add_entities([MqttLightJson(config, discovery_hash)]) async_add_entities([MqttLightJson(config, discovery_hash)])
class MqttLightJson(MqttAvailability, MqttDiscoveryUpdate, Light, # pylint: disable=too-many-ancestors
RestoreEntity): class MqttLightJson(MqttAvailability, MqttDiscoveryUpdate,
MqttEntityDeviceInfo, Light, RestoreEntity):
"""Representation of a MQTT JSON light.""" """Representation of a MQTT JSON light."""
def __init__(self, config, discovery_hash): def __init__(self, config, discovery_hash):
@ -116,11 +118,13 @@ class MqttLightJson(MqttAvailability, MqttDiscoveryUpdate, Light,
payload_available = config.get(CONF_PAYLOAD_AVAILABLE) payload_available = config.get(CONF_PAYLOAD_AVAILABLE)
payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE) payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE)
qos = config.get(CONF_QOS) qos = config.get(CONF_QOS)
device_config = config.get(CONF_DEVICE)
MqttAvailability.__init__(self, availability_topic, qos, MqttAvailability.__init__(self, availability_topic, qos,
payload_available, payload_not_available) payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash, MqttDiscoveryUpdate.__init__(self, discovery_hash,
self.discovery_update) self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Subscribe to MQTT events.""" """Subscribe to MQTT events."""

View file

@ -14,11 +14,12 @@ from homeassistant.components.light import (
ATTR_HS_COLOR, ATTR_TRANSITION, ATTR_WHITE_VALUE, Light, ATTR_HS_COLOR, ATTR_TRANSITION, ATTR_WHITE_VALUE, Light,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_FLASH,
SUPPORT_COLOR, SUPPORT_TRANSITION, SUPPORT_WHITE_VALUE) SUPPORT_COLOR, SUPPORT_TRANSITION, SUPPORT_WHITE_VALUE)
from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, STATE_ON, STATE_OFF from homeassistant.const import (
CONF_DEVICE, CONF_NAME, CONF_OPTIMISTIC, STATE_ON, STATE_OFF)
from homeassistant.components.mqtt import ( from homeassistant.components.mqtt import (
CONF_AVAILABILITY_TOPIC, CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_AVAILABILITY_TOPIC, CONF_STATE_TOPIC, CONF_COMMAND_TOPIC,
CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_RETAIN, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_RETAIN,
MqttAvailability, MqttDiscoveryUpdate, subscription) MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, subscription)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
@ -43,6 +44,7 @@ CONF_GREEN_TEMPLATE = 'green_template'
CONF_RED_TEMPLATE = 'red_template' CONF_RED_TEMPLATE = 'red_template'
CONF_STATE_TEMPLATE = 'state_template' CONF_STATE_TEMPLATE = 'state_template'
CONF_WHITE_VALUE_TEMPLATE = 'white_value_template' CONF_WHITE_VALUE_TEMPLATE = 'white_value_template'
CONF_UNIQUE_ID = 'unique_id'
PLATFORM_SCHEMA_TEMPLATE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA_TEMPLATE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_BLUE_TEMPLATE): cv.template, vol.Optional(CONF_BLUE_TEMPLATE): cv.template,
@ -63,6 +65,8 @@ PLATFORM_SCHEMA_TEMPLATE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS): vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS):
vol.All(vol.Coerce(int), vol.In([0, 1, 2])), vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema) }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema)
@ -72,8 +76,9 @@ async def async_setup_entity_template(hass, config, async_add_entities,
async_add_entities([MqttTemplate(config, discovery_hash)]) async_add_entities([MqttTemplate(config, discovery_hash)])
class MqttTemplate(MqttAvailability, MqttDiscoveryUpdate, Light, # pylint: disable=too-many-ancestors
RestoreEntity): class MqttTemplate(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
Light, RestoreEntity):
"""Representation of a MQTT Template light.""" """Representation of a MQTT Template light."""
def __init__(self, config, discovery_hash): def __init__(self, config, discovery_hash):
@ -91,6 +96,7 @@ class MqttTemplate(MqttAvailability, MqttDiscoveryUpdate, Light,
self._white_value = None self._white_value = None
self._hs = None self._hs = None
self._effect = None self._effect = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config # Load config
self._setup_from_config(config) self._setup_from_config(config)
@ -99,11 +105,13 @@ class MqttTemplate(MqttAvailability, MqttDiscoveryUpdate, Light,
payload_available = config.get(CONF_PAYLOAD_AVAILABLE) payload_available = config.get(CONF_PAYLOAD_AVAILABLE)
payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE) payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE)
qos = config.get(CONF_QOS) qos = config.get(CONF_QOS)
device_config = config.get(CONF_DEVICE)
MqttAvailability.__init__(self, availability_topic, qos, MqttAvailability.__init__(self, availability_topic, qos,
payload_available, payload_not_available) payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash, MqttDiscoveryUpdate.__init__(self, discovery_hash,
self.discovery_update) self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Subscribe to MQTT events.""" """Subscribe to MQTT events."""
@ -302,6 +310,11 @@ class MqttTemplate(MqttAvailability, MqttDiscoveryUpdate, Light,
"""Return the name of the entity.""" """Return the name of the entity."""
return self._config.get(CONF_NAME) return self._config.get(CONF_NAME)
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def is_on(self): def is_on(self):
"""Return True if entity is on.""" """Return True if entity is on."""

View file

@ -153,6 +153,7 @@ light:
payload_off: "off" payload_off: "off"
""" """
import json
from unittest import mock from unittest import mock
from unittest.mock import patch from unittest.mock import patch
@ -165,7 +166,7 @@ import homeassistant.core as ha
from tests.common import ( from tests.common import (
assert_setup_component, async_fire_mqtt_message, assert_setup_component, async_fire_mqtt_message,
mock_coro, MockConfigEntry) async_mock_mqtt_component, mock_coro, MockConfigEntry)
from tests.components.light import common from tests.components.light import common
@ -1038,6 +1039,29 @@ async def test_custom_availability_payload(hass, mqtt_mock):
assert STATE_UNAVAILABLE == state.state assert STATE_UNAVAILABLE == state.state
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',
'status_topic': 'test-topic',
'command_topic': 'test_topic',
'unique_id': 'TOTALLY_UNIQUE'
}, {
'platform': 'mqtt',
'name': 'Test 2',
'status_topic': 'test-topic',
'command_topic': 'test_topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})
async_fire_mqtt_message(hass, 'test-topic', 'payload')
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids(light.DOMAIN)) == 1
async def test_discovery_removal_light(hass, mqtt_mock, caplog): async def test_discovery_removal_light(hass, mqtt_mock, caplog):
"""Test removal of discovered light.""" """Test removal of discovered light."""
entry = MockConfigEntry(domain=mqtt.DOMAIN) entry = MockConfigEntry(domain=mqtt.DOMAIN)
@ -1117,3 +1141,42 @@ async def test_discovery_update_light(hass, mqtt_mock, caplog):
assert state.name == 'Milk' assert state.name == 'Milk'
state = hass.states.get('light.milk') state = hass.states.get('light.milk')
assert state is None assert state is None
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',
'name': 'Test 1',
'state_topic': 'test-topic',
'command_topic': 'test-topic',
'device': {
'identifiers': ['helloworld'],
'connections': [
["mac", "02:5b:26:a8:dc:12"],
],
'manufacturer': 'Whatever',
'name': 'Beer',
'model': 'Glass',
'sw_version': '0.1-beta',
},
'unique_id': 'veryunique'
})
async_fire_mqtt_message(hass, 'homeassistant/light/bla/config',
data)
await hass.async_block_till_done()
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'

View file

@ -87,6 +87,7 @@ light:
brightness: true brightness: true
brightness_scale: 99 brightness_scale: 99
""" """
import json
from unittest.mock import patch from unittest.mock import patch
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -97,7 +98,9 @@ from homeassistant.components import light, mqtt
from homeassistant.components.mqtt.discovery import async_start from homeassistant.components.mqtt.discovery import async_start
import homeassistant.core as ha import homeassistant.core as ha
from tests.common import mock_coro, async_fire_mqtt_message, MockConfigEntry from tests.common import (
mock_coro, async_fire_mqtt_message, async_mock_mqtt_component,
MockConfigEntry)
async def test_fail_setup_if_no_command_topic(hass, mqtt_mock): async def test_fail_setup_if_no_command_topic(hass, mqtt_mock):
@ -533,6 +536,31 @@ async def test_custom_availability_payload(hass, mqtt_mock):
assert STATE_UNAVAILABLE == state.state assert STATE_UNAVAILABLE == state.state
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',
'status_topic': 'test-topic',
'command_topic': 'test_topic',
'unique_id': 'TOTALLY_UNIQUE'
}, {
'platform': 'mqtt',
'name': 'Test 2',
'schema': 'json',
'status_topic': 'test-topic',
'command_topic': 'test_topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})
async_fire_mqtt_message(hass, 'test-topic', 'payload')
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids(light.DOMAIN)) == 1
async def test_discovery_removal(hass, mqtt_mock, caplog): async def test_discovery_removal(hass, mqtt_mock, caplog):
"""Test removal of discovered mqtt_json lights.""" """Test removal of discovered mqtt_json lights."""
entry = MockConfigEntry(domain=mqtt.DOMAIN) entry = MockConfigEntry(domain=mqtt.DOMAIN)
@ -609,3 +637,43 @@ async def test_discovery_update_light(hass, mqtt_mock, caplog):
assert state.name == 'Milk' assert state.name == 'Milk'
state = hass.states.get('light.milk') state = hass.states.get('light.milk')
assert state is None assert state is None
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',
'name': 'Test 1',
'schema': 'json',
'state_topic': 'test-topic',
'command_topic': 'test-topic',
'device': {
'identifiers': ['helloworld'],
'connections': [
["mac", "02:5b:26:a8:dc:12"],
],
'manufacturer': 'Whatever',
'name': 'Beer',
'model': 'Glass',
'sw_version': '0.1-beta',
},
'unique_id': 'veryunique'
})
async_fire_mqtt_message(hass, 'homeassistant/light/bla/config',
data)
await hass.async_block_till_done()
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'

View file

@ -26,6 +26,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`. If your light doesn't support RGB feature, omit `(red|green|blue)_template`.
""" """
import json
from unittest.mock import patch from unittest.mock import patch
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -37,7 +38,7 @@ import homeassistant.core as ha
from tests.common import ( from tests.common import (
async_fire_mqtt_message, assert_setup_component, mock_coro, async_fire_mqtt_message, assert_setup_component, mock_coro,
MockConfigEntry) async_mock_mqtt_component, MockConfigEntry)
async def test_setup_fails(hass, mqtt_mock): async def test_setup_fails(hass, mqtt_mock):
@ -484,6 +485,33 @@ async def test_custom_availability_payload(hass, mqtt_mock):
assert STATE_UNAVAILABLE == state.state assert STATE_UNAVAILABLE == state.state
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',
'status_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',
'status_topic': 'test-topic',
'command_topic': 'test_topic',
'unique_id': 'TOTALLY_UNIQUE'
}]
})
async_fire_mqtt_message(hass, 'test-topic', 'payload')
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids(light.DOMAIN)) == 1
async def test_discovery(hass, mqtt_mock, caplog): async def test_discovery(hass, mqtt_mock, caplog):
"""Test removal of discovered mqtt_json lights.""" """Test removal of discovered mqtt_json lights."""
entry = MockConfigEntry(domain=mqtt.DOMAIN) entry = MockConfigEntry(domain=mqtt.DOMAIN)
@ -562,3 +590,45 @@ async def test_discovery_update_light(hass, mqtt_mock, caplog):
assert state.name == 'Milk' assert state.name == 'Milk'
state = hass.states.get('light.milk') state = hass.states.get('light.milk')
assert state is None assert state is None
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',
'name': 'Test 1',
'schema': 'template',
'state_topic': 'test-topic',
'command_topic': 'test-topic',
'command_on_template': 'on,{{ transition }}',
'command_off_template': 'off,{{ transition|d }}',
'device': {
'identifiers': ['helloworld'],
'connections': [
["mac", "02:5b:26:a8:dc:12"],
],
'manufacturer': 'Whatever',
'name': 'Beer',
'model': 'Glass',
'sw_version': '0.1-beta',
},
'unique_id': 'veryunique'
})
async_fire_mqtt_message(hass, 'homeassistant/light/bla/config',
data)
await hass.async_block_till_done()
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'