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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions homeassistant/components/alarm_control_panel/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,25 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_discover(discovery_payload):
"""Discover and add an MQTT alarm control panel."""
config = PLATFORM_SCHEMA(discovery_payload)
await _async_setup_entity(config, async_add_entities,
await _async_setup_entity(config, async_add_entities, config_entry,
discovery_payload[ATTR_DISCOVERY_HASH])

async_dispatcher_connect(
hass, MQTT_DISCOVERY_NEW.format(alarm.DOMAIN, 'mqtt'),
async_discover)


async def _async_setup_entity(config, async_add_entities,
async def _async_setup_entity(config, async_add_entities, config_entry=None,
discovery_hash=None):
"""Set up the MQTT Alarm Control Panel platform."""
async_add_entities([MqttAlarm(config, discovery_hash)])
async_add_entities([MqttAlarm(config, config_entry, discovery_hash)])


class MqttAlarm(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
alarm.AlarmControlPanel):
"""Representation of a MQTT alarm status."""

def __init__(self, config, discovery_hash):
def __init__(self, config, config_entry, discovery_hash):
"""Init the MQTT Alarm Control Panel."""
self._state = STATE_UNKNOWN
self._config = config
Expand All @@ -98,7 +98,7 @@ def __init__(self, config, discovery_hash):
payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash,
self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config)
MqttEntityDeviceInfo.__init__(self, device_config, config_entry)

async def async_added_to_hass(self):
"""Subscribe mqtt events."""
Expand All @@ -110,6 +110,7 @@ async def discovery_update(self, discovery_payload):
config = PLATFORM_SCHEMA(discovery_payload)
self._config = config
await self.availability_discovery_update(config)
await self.device_info_discovery_update(config)
await self._subscribe_topics()
self.async_schedule_update_ha_state()

Expand Down
34 changes: 31 additions & 3 deletions homeassistant/components/mqtt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

from homeassistant import config_entries
from homeassistant.const import (
CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_PROTOCOL, CONF_USERNAME,
CONF_VALUE_TEMPLATE, EVENT_HOMEASSISTANT_STOP, CONF_NAME)
CONF_DEVICE, CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_PROTOCOL,
CONF_USERNAME, CONF_VALUE_TEMPLATE, EVENT_HOMEASSISTANT_STOP, CONF_NAME)
from homeassistant.core import Event, ServiceCall, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv
Expand Down Expand Up @@ -1000,9 +1000,37 @@ def discovery_callback(payload):
class MqttEntityDeviceInfo(Entity):
"""Mixin used for mqtt platforms that support the device registry."""

def __init__(self, device_config: Optional[ConfigType]) -> None:
def __init__(self, device_config: Optional[ConfigType],
config_entry=None) -> None:
"""Initialize the device mixin."""
self._device_config = device_config
self._config_entry = config_entry

async def device_info_discovery_update(self, config: dict):
"""Handle updated discovery message."""
self._device_config = config.get(CONF_DEVICE)
device_registry = await \
self.hass.helpers.device_registry.async_get_registry()
config_entry_id = self._config_entry.entry_id
device_info = self.device_info

if config_entry_id is not None and device_info is not None:
processed_dev_info = {
'config_entry_id': config_entry_id
}
for key in (
'connections',
'identifiers',
'manufacturer',
'model',
'name',
'sw_version',
'via_hub',
):
if key in device_info:
processed_dev_info[key] = device_info[key]

device_registry.async_get_or_create(**processed_dev_info)

@property
def device_info(self):
Expand Down
5 changes: 4 additions & 1 deletion homeassistant/components/switch/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_discover(discovery_payload):
"""Discover and add a MQTT switch."""
config = PLATFORM_SCHEMA(discovery_payload)
config['config_entry'] = config_entry
await _async_setup_entity(config, async_add_entities,
discovery_payload[ATTR_DISCOVERY_HASH])

Expand Down Expand Up @@ -99,12 +100,13 @@ def __init__(self, config, discovery_hash):
payload_not_available = config.get(CONF_PAYLOAD_NOT_AVAILABLE)
qos = config.get(CONF_QOS)
device_config = config.get(CONF_DEVICE)
config_entry = config.get('config_entry')

MqttAvailability.__init__(self, availability_topic, qos,
payload_available, payload_not_available)
MqttDiscoveryUpdate.__init__(self, discovery_hash,
self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config)
MqttEntityDeviceInfo.__init__(self, device_config, config_entry)

async def async_added_to_hass(self):
"""Subscribe to MQTT events."""
Expand All @@ -116,6 +118,7 @@ async def discovery_update(self, discovery_payload):
config = PLATFORM_SCHEMA(discovery_payload)
self._setup_from_config(config)
await self.availability_discovery_update(config)
await self.device_info_discovery_update(config)
await self._subscribe_topics()
self.async_schedule_update_ha_state()

Expand Down
47 changes: 47 additions & 0 deletions tests/components/alarm_control_panel/test_mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,53 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
assert device.sw_version == '0.1-beta'


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',
'state_topic': 'test-topic',
'command_topic': 'test-command-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'
}

data = json.dumps(config)
async_fire_mqtt_message(
hass, 'homeassistant/alarm_control_panel/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.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()
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."""
registry = mock_registry(hass, {})
Expand Down
49 changes: 48 additions & 1 deletion tests/components/switch/test_mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ async def test_discovery_update_switch(hass, mqtt_mock, caplog):


async def test_entity_device_info_with_identifier(hass, mqtt_mock):
"""Test MQTT switch device registry integration."""
"""Test device registry integration."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
entry.add_to_hass(hass)
await async_start(hass, 'homeassistant', {}, entry)
Expand Down Expand Up @@ -437,6 +437,53 @@ async def test_entity_device_info_with_identifier(hass, mqtt_mock):
assert device.sw_version == '0.1-beta'


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',
'state_topic': 'test-topic',
'command_topic': 'test-command-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'
}

data = json.dumps(config)
async_fire_mqtt_message(hass, 'homeassistant/switch/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.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()
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."""
registry = mock_registry(hass, {})
Expand Down