diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index e9904f0163a..22923602dc2 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -58,7 +58,7 @@ def is_locked(hass, entity_id=None): async def async_setup(hass, config): """Track states and offer events for locks.""" - component = EntityComponent( + component = hass.data[DOMAIN] = EntityComponent( _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LOCKS) await component.async_setup(config) @@ -79,6 +79,11 @@ async def async_setup(hass, config): return True +async def async_setup_entry(hass, entry): + """Set up a config entry.""" + return await hass.data[DOMAIN].async_setup_entry(entry) + + class LockDevice(Entity): """Representation of a lock.""" diff --git a/homeassistant/components/lock/mqtt.py b/homeassistant/components/lock/mqtt.py index ee43eb942c4..b62382e6dd1 100644 --- a/homeassistant/components/lock/mqtt.py +++ b/homeassistant/components/lock/mqtt.py @@ -16,8 +16,11 @@ from homeassistant.components.mqtt import ( CONF_QOS, CONF_RETAIN, MqttAvailability, MqttDiscoveryUpdate) from homeassistant.const import ( CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE) -from homeassistant.components import mqtt +from homeassistant.components import mqtt, lock +from homeassistant.components.mqtt.discovery import MQTT_DISCOVERY_NEW import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.typing import HomeAssistantType, ConfigType _LOGGER = logging.getLogger(__name__) @@ -40,20 +43,32 @@ PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({ }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema) -async def async_setup_platform(hass, config, async_add_entities, - discovery_info=None): - """Set up the MQTT lock.""" - if discovery_info is not None: - config = PLATFORM_SCHEMA(discovery_info) +async def async_setup_platform(hass: HomeAssistantType, config: ConfigType, + async_add_entities, discovery_info=None): + """Set up MQTT lock panel through configuration.yaml.""" + await _async_setup_entity(hass, config, async_add_entities) + +async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up MQTT lock dynamically through MQTT discovery.""" + async def async_discover(discovery_payload): + """Discover and add an MQTT lock.""" + config = PLATFORM_SCHEMA(discovery_payload) + await _async_setup_entity(hass, config, async_add_entities, + discovery_payload[ATTR_DISCOVERY_HASH]) + + async_dispatcher_connect( + hass, MQTT_DISCOVERY_NEW.format(lock.DOMAIN, 'mqtt'), + async_discover) + + +async def _async_setup_entity(hass, config, async_add_entities, + discovery_hash=None): + """Set up the MQTT Lock platform.""" value_template = config.get(CONF_VALUE_TEMPLATE) if value_template is not None: value_template.hass = hass - discovery_hash = None - if discovery_info is not None and ATTR_DISCOVERY_HASH in discovery_info: - discovery_hash = discovery_info[ATTR_DISCOVERY_HASH] - async_add_entities([MqttLock( config.get(CONF_NAME), config.get(CONF_STATE_TOPIC), diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index b8c8627c038..91f62cd0848 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -45,6 +45,7 @@ CONFIG_ENTRY_PLATFORMS = { 'camera': ['mqtt'], 'cover': ['mqtt'], 'light': ['mqtt'], + 'lock': ['mqtt'], 'sensor': ['mqtt'], 'switch': ['mqtt'], 'climate': ['mqtt'], diff --git a/tests/components/lock/test_mqtt.py b/tests/components/lock/test_mqtt.py index 347005c75ac..58f328c5b9d 100644 --- a/tests/components/lock/test_mqtt.py +++ b/tests/components/lock/test_mqtt.py @@ -2,10 +2,10 @@ from homeassistant.setup import async_setup_component from homeassistant.const import ( STATE_LOCKED, STATE_UNLOCKED, STATE_UNAVAILABLE, ATTR_ASSUMED_STATE) -import homeassistant.components.lock as lock +from homeassistant.components import lock, mqtt from homeassistant.components.mqtt.discovery import async_start -from tests.common import async_fire_mqtt_message +from tests.common import async_fire_mqtt_message, MockConfigEntry async def test_controlling_state_via_topic(hass, mqtt_mock): @@ -136,7 +136,8 @@ async def test_custom_availability_payload(hass, mqtt_mock): async def test_discovery_removal_lock(hass, mqtt_mock, caplog): """Test removal of discovered lock.""" - await async_start(hass, 'homeassistant', {'mqtt': {}}) + entry = MockConfigEntry(domain=mqtt.DOMAIN) + await async_start(hass, 'homeassistant', {}, entry) data = ( '{ "name": "Beer",' ' "command_topic": "test_topic" }'