2019-04-03 15:40:03 +00:00
|
|
|
"""Support for MQTT discovery."""
|
2018-10-08 08:59:43 +00:00
|
|
|
import asyncio
|
2017-02-07 17:13:24 +00:00
|
|
|
import json
|
|
|
|
import logging
|
|
|
|
import re
|
|
|
|
|
2018-07-18 09:54:27 +00:00
|
|
|
from homeassistant.components import mqtt
|
2019-02-04 18:54:40 +00:00
|
|
|
from homeassistant.const import CONF_DEVICE, CONF_PLATFORM
|
2018-09-18 12:59:39 +00:00
|
|
|
from homeassistant.helpers.discovery import async_load_platform
|
2018-09-24 08:11:49 +00:00
|
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
2018-09-27 14:07:56 +00:00
|
|
|
from homeassistant.helpers.typing import HomeAssistantType
|
2017-02-07 17:13:24 +00:00
|
|
|
|
2019-04-09 22:42:44 +00:00
|
|
|
from .const import ATTR_DISCOVERY_HASH, CONF_STATE_TOPIC
|
2019-03-21 05:56:46 +00:00
|
|
|
|
2017-02-07 17:13:24 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
TOPIC_MATCHER = re.compile(
|
2019-07-01 17:23:01 +00:00
|
|
|
r'(?P<component>\w+)/(?:(?P<node_id>[a-zA-Z0-9_-]+)/)'
|
|
|
|
r'?(?P<object_id>[a-zA-Z0-9_-]+)/config')
|
2017-02-14 07:54:13 +00:00
|
|
|
|
2017-11-15 04:19:15 +00:00
|
|
|
SUPPORTED_COMPONENTS = [
|
2019-04-14 03:25:45 +00:00
|
|
|
'alarm_control_panel',
|
2018-11-27 13:00:05 +00:00
|
|
|
'binary_sensor',
|
|
|
|
'camera',
|
2019-04-14 03:25:45 +00:00
|
|
|
'climate',
|
2018-11-27 13:00:05 +00:00
|
|
|
'cover',
|
2019-04-14 03:25:45 +00:00
|
|
|
'fan',
|
2018-11-27 13:00:05 +00:00
|
|
|
'light',
|
|
|
|
'lock',
|
|
|
|
'sensor',
|
|
|
|
'switch',
|
2019-04-14 03:25:45 +00:00
|
|
|
'vacuum',
|
|
|
|
]
|
|
|
|
|
|
|
|
CONFIG_ENTRY_COMPONENTS = [
|
2018-11-27 13:00:05 +00:00
|
|
|
'alarm_control_panel',
|
2019-04-14 03:25:45 +00:00
|
|
|
'binary_sensor',
|
|
|
|
'camera',
|
|
|
|
'climate',
|
|
|
|
'cover',
|
2018-11-27 13:00:05 +00:00
|
|
|
'fan',
|
2019-04-14 03:25:45 +00:00
|
|
|
'light',
|
|
|
|
'lock',
|
|
|
|
'sensor',
|
|
|
|
'switch',
|
2019-01-06 16:05:04 +00:00
|
|
|
'vacuum',
|
2018-11-27 13:00:05 +00:00
|
|
|
]
|
2017-02-07 17:13:24 +00:00
|
|
|
|
2018-11-27 13:00:05 +00:00
|
|
|
DEPRECATED_PLATFORM_TO_SCHEMA = {
|
2018-12-24 13:28:26 +00:00
|
|
|
'light': {
|
|
|
|
'mqtt_json': 'json',
|
|
|
|
'mqtt_template': 'template',
|
|
|
|
}
|
2018-09-27 14:07:56 +00:00
|
|
|
}
|
|
|
|
|
2019-04-14 03:25:45 +00:00
|
|
|
# These components require state_topic to be set.
|
|
|
|
# If not specified, infer state_topic from discovery topic.
|
|
|
|
IMPLICIT_STATE_TOPIC_COMPONENTS = [
|
|
|
|
'alarm_control_panel',
|
|
|
|
'binary_sensor',
|
|
|
|
'sensor',
|
|
|
|
]
|
|
|
|
|
2018-11-27 13:00:05 +00:00
|
|
|
|
2017-05-23 18:08:12 +00:00
|
|
|
ALREADY_DISCOVERED = 'mqtt_discovered_components'
|
2018-10-08 08:59:43 +00:00
|
|
|
DATA_CONFIG_ENTRY_LOCK = 'mqtt_config_entry_lock'
|
2018-09-27 14:07:56 +00:00
|
|
|
CONFIG_ENTRY_IS_SETUP = 'mqtt_config_entry_is_setup'
|
2018-09-24 08:11:49 +00:00
|
|
|
MQTT_DISCOVERY_UPDATED = 'mqtt_discovery_updated_{}'
|
2018-09-27 14:07:56 +00:00
|
|
|
MQTT_DISCOVERY_NEW = 'mqtt_discovery_new_{}_{}'
|
2017-05-23 18:08:12 +00:00
|
|
|
|
2018-10-12 06:51:16 +00:00
|
|
|
TOPIC_BASE = '~'
|
|
|
|
|
|
|
|
ABBREVIATIONS = {
|
|
|
|
'aux_cmd_t': 'aux_command_topic',
|
|
|
|
'aux_stat_tpl': 'aux_state_template',
|
|
|
|
'aux_stat_t': 'aux_state_topic',
|
|
|
|
'avty_t': 'availability_topic',
|
|
|
|
'away_mode_cmd_t': 'away_mode_command_topic',
|
|
|
|
'away_mode_stat_tpl': 'away_mode_state_template',
|
|
|
|
'away_mode_stat_t': 'away_mode_state_topic',
|
2019-06-06 16:10:23 +00:00
|
|
|
'b_tpl': 'blue_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'bri_cmd_t': 'brightness_command_topic',
|
|
|
|
'bri_scl': 'brightness_scale',
|
|
|
|
'bri_stat_t': 'brightness_state_topic',
|
2019-06-06 16:10:23 +00:00
|
|
|
'bri_tpl': 'brightness_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'bri_val_tpl': 'brightness_value_template',
|
2019-01-01 14:42:41 +00:00
|
|
|
'clr_temp_cmd_tpl': 'color_temp_command_template',
|
2019-01-06 16:05:04 +00:00
|
|
|
'bat_lev_t': 'battery_level_topic',
|
|
|
|
'bat_lev_tpl': 'battery_level_template',
|
|
|
|
'chrg_t': 'charging_topic',
|
|
|
|
'chrg_tpl': 'charging_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'clr_temp_cmd_t': 'color_temp_command_topic',
|
|
|
|
'clr_temp_stat_t': 'color_temp_state_topic',
|
|
|
|
'clr_temp_val_tpl': 'color_temp_value_template',
|
2019-01-06 16:05:04 +00:00
|
|
|
'cln_t': 'cleaning_topic',
|
|
|
|
'cln_tpl': 'cleaning_template',
|
2019-06-06 16:10:23 +00:00
|
|
|
'cmd_off_tpl': 'command_off_template',
|
|
|
|
'cmd_on_tpl': 'command_on_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'cmd_t': 'command_topic',
|
|
|
|
'curr_temp_t': 'current_temperature_topic',
|
2019-05-07 06:27:35 +00:00
|
|
|
'curr_temp_tpl': 'current_temperature_template',
|
2019-02-04 18:54:40 +00:00
|
|
|
'dev': 'device',
|
2018-10-12 06:51:16 +00:00
|
|
|
'dev_cla': 'device_class',
|
2019-01-06 16:05:04 +00:00
|
|
|
'dock_t': 'docked_topic',
|
|
|
|
'dock_tpl': 'docked_template',
|
|
|
|
'err_t': 'error_topic',
|
|
|
|
'err_tpl': 'error_template',
|
|
|
|
'fanspd_t': 'fan_speed_topic',
|
|
|
|
'fanspd_tpl': 'fan_speed_template',
|
|
|
|
'fanspd_lst': 'fan_speed_list',
|
2018-10-12 06:51:16 +00:00
|
|
|
'fx_cmd_t': 'effect_command_topic',
|
|
|
|
'fx_list': 'effect_list',
|
|
|
|
'fx_stat_t': 'effect_state_topic',
|
2019-06-06 16:10:23 +00:00
|
|
|
'fx_tpl': 'effect_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'fx_val_tpl': 'effect_value_template',
|
|
|
|
'exp_aft': 'expire_after',
|
|
|
|
'fan_mode_cmd_t': 'fan_mode_command_topic',
|
|
|
|
'fan_mode_stat_tpl': 'fan_mode_state_template',
|
|
|
|
'fan_mode_stat_t': 'fan_mode_state_topic',
|
|
|
|
'frc_upd': 'force_update',
|
2019-06-06 16:10:23 +00:00
|
|
|
'g_tpl': 'green_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'hold_cmd_t': 'hold_command_topic',
|
|
|
|
'hold_stat_tpl': 'hold_state_template',
|
|
|
|
'hold_stat_t': 'hold_state_topic',
|
|
|
|
'ic': 'icon',
|
|
|
|
'init': 'initial',
|
|
|
|
'json_attr': 'json_attributes',
|
2019-02-04 18:54:40 +00:00
|
|
|
'json_attr_t': 'json_attributes_topic',
|
2018-10-12 06:51:16 +00:00
|
|
|
'max_temp': 'max_temp',
|
|
|
|
'min_temp': 'min_temp',
|
|
|
|
'mode_cmd_t': 'mode_command_topic',
|
|
|
|
'mode_stat_tpl': 'mode_state_template',
|
|
|
|
'mode_stat_t': 'mode_state_topic',
|
|
|
|
'name': 'name',
|
|
|
|
'on_cmd_type': 'on_command_type',
|
|
|
|
'opt': 'optimistic',
|
|
|
|
'osc_cmd_t': 'oscillation_command_topic',
|
|
|
|
'osc_stat_t': 'oscillation_state_topic',
|
|
|
|
'osc_val_tpl': 'oscillation_value_template',
|
|
|
|
'pl_arm_away': 'payload_arm_away',
|
|
|
|
'pl_arm_home': 'payload_arm_home',
|
|
|
|
'pl_avail': 'payload_available',
|
|
|
|
'pl_cls': 'payload_close',
|
|
|
|
'pl_disarm': 'payload_disarm',
|
|
|
|
'pl_hi_spd': 'payload_high_speed',
|
|
|
|
'pl_lock': 'payload_lock',
|
|
|
|
'pl_lo_spd': 'payload_low_speed',
|
|
|
|
'pl_med_spd': 'payload_medium_speed',
|
|
|
|
'pl_not_avail': 'payload_not_available',
|
|
|
|
'pl_off': 'payload_off',
|
|
|
|
'pl_on': 'payload_on',
|
|
|
|
'pl_open': 'payload_open',
|
|
|
|
'pl_osc_off': 'payload_oscillation_off',
|
|
|
|
'pl_osc_on': 'payload_oscillation_on',
|
|
|
|
'pl_stop': 'payload_stop',
|
|
|
|
'pl_unlk': 'payload_unlock',
|
|
|
|
'pow_cmd_t': 'power_command_topic',
|
2019-06-06 16:10:23 +00:00
|
|
|
'r_tpl': 'red_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'ret': 'retain',
|
|
|
|
'rgb_cmd_tpl': 'rgb_command_template',
|
|
|
|
'rgb_cmd_t': 'rgb_command_topic',
|
|
|
|
'rgb_stat_t': 'rgb_state_topic',
|
|
|
|
'rgb_val_tpl': 'rgb_value_template',
|
2019-01-06 16:05:04 +00:00
|
|
|
'send_cmd_t': 'send_command_topic',
|
2018-10-12 06:51:16 +00:00
|
|
|
'send_if_off': 'send_if_off',
|
|
|
|
'set_pos_tpl': 'set_position_template',
|
|
|
|
'set_pos_t': 'set_position_topic',
|
2019-05-07 20:20:55 +00:00
|
|
|
'pos_t': 'position_topic',
|
2018-10-12 06:51:16 +00:00
|
|
|
'spd_cmd_t': 'speed_command_topic',
|
|
|
|
'spd_stat_t': 'speed_state_topic',
|
|
|
|
'spd_val_tpl': 'speed_value_template',
|
|
|
|
'spds': 'speeds',
|
|
|
|
'stat_clsd': 'state_closed',
|
|
|
|
'stat_off': 'state_off',
|
|
|
|
'stat_on': 'state_on',
|
|
|
|
'stat_open': 'state_open',
|
|
|
|
'stat_t': 'state_topic',
|
2019-06-06 16:10:23 +00:00
|
|
|
'stat_tpl': 'state_template',
|
2018-10-12 06:51:16 +00:00
|
|
|
'stat_val_tpl': 'state_value_template',
|
2019-01-06 16:05:04 +00:00
|
|
|
'sup_feat': 'supported_features',
|
2018-10-12 06:51:16 +00:00
|
|
|
'swing_mode_cmd_t': 'swing_mode_command_topic',
|
|
|
|
'swing_mode_stat_tpl': 'swing_mode_state_template',
|
|
|
|
'swing_mode_stat_t': 'swing_mode_state_topic',
|
|
|
|
'temp_cmd_t': 'temperature_command_topic',
|
|
|
|
'temp_stat_tpl': 'temperature_state_template',
|
|
|
|
'temp_stat_t': 'temperature_state_topic',
|
|
|
|
'tilt_clsd_val': 'tilt_closed_value',
|
|
|
|
'tilt_cmd_t': 'tilt_command_topic',
|
|
|
|
'tilt_inv_stat': 'tilt_invert_state',
|
|
|
|
'tilt_max': 'tilt_max',
|
|
|
|
'tilt_min': 'tilt_min',
|
|
|
|
'tilt_opnd_val': 'tilt_opened_value',
|
|
|
|
'tilt_status_opt': 'tilt_status_optimistic',
|
|
|
|
'tilt_status_t': 'tilt_status_topic',
|
|
|
|
't': 'topic',
|
|
|
|
'uniq_id': 'unique_id',
|
|
|
|
'unit_of_meas': 'unit_of_measurement',
|
|
|
|
'val_tpl': 'value_template',
|
|
|
|
'whit_val_cmd_t': 'white_value_command_topic',
|
2019-02-04 18:54:40 +00:00
|
|
|
'whit_val_scl': 'white_value_scale',
|
2018-10-12 06:51:16 +00:00
|
|
|
'whit_val_stat_t': 'white_value_state_topic',
|
|
|
|
'whit_val_tpl': 'white_value_template',
|
|
|
|
'xy_cmd_t': 'xy_command_topic',
|
|
|
|
'xy_stat_t': 'xy_state_topic',
|
|
|
|
'xy_val_tpl': 'xy_value_template',
|
|
|
|
}
|
|
|
|
|
2019-02-04 18:54:40 +00:00
|
|
|
DEVICE_ABBREVIATIONS = {
|
|
|
|
'cns': 'connections',
|
|
|
|
'ids': 'identifiers',
|
|
|
|
'name': 'name',
|
|
|
|
'mf': 'manufacturer',
|
|
|
|
'mdl': 'model',
|
|
|
|
'sw': 'sw_version',
|
|
|
|
}
|
|
|
|
|
2017-02-07 17:13:24 +00:00
|
|
|
|
2019-01-07 15:57:51 +00:00
|
|
|
def clear_discovery_hash(hass, discovery_hash):
|
|
|
|
"""Clear entry in ALREADY_DISCOVERED list."""
|
|
|
|
del hass.data[ALREADY_DISCOVERED][discovery_hash]
|
|
|
|
|
|
|
|
|
2019-04-29 20:45:53 +00:00
|
|
|
class MQTTConfig(dict):
|
|
|
|
"""Dummy class to allow adding attributes."""
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2018-09-27 14:07:56 +00:00
|
|
|
async def async_start(hass: HomeAssistantType, discovery_topic, hass_config,
|
|
|
|
config_entry=None) -> bool:
|
2017-05-02 16:18:47 +00:00
|
|
|
"""Initialize of MQTT Discovery."""
|
2019-03-13 19:58:20 +00:00
|
|
|
async def async_device_message_received(msg):
|
2017-02-07 17:13:24 +00:00
|
|
|
"""Process the received message."""
|
2019-03-13 19:58:20 +00:00
|
|
|
payload = msg.payload
|
|
|
|
topic = msg.topic
|
2019-07-01 17:23:01 +00:00
|
|
|
topic_trimmed = topic.replace('{}/'.format(discovery_topic), '', 1)
|
|
|
|
match = TOPIC_MATCHER.match(topic_trimmed)
|
2017-02-07 17:13:24 +00:00
|
|
|
|
|
|
|
if not match:
|
|
|
|
return
|
|
|
|
|
2019-07-01 17:23:01 +00:00
|
|
|
component, node_id, object_id = match.groups()
|
2017-02-07 17:13:24 +00:00
|
|
|
|
|
|
|
if component not in SUPPORTED_COMPONENTS:
|
2019-07-05 22:24:26 +00:00
|
|
|
_LOGGER.warning("Integration %s is not supported", component)
|
2017-02-07 17:13:24 +00:00
|
|
|
return
|
|
|
|
|
2018-10-12 06:51:16 +00:00
|
|
|
if payload:
|
|
|
|
try:
|
|
|
|
payload = json.loads(payload)
|
|
|
|
except ValueError:
|
|
|
|
_LOGGER.warning("Unable to parse JSON %s: '%s'",
|
|
|
|
object_id, payload)
|
|
|
|
return
|
|
|
|
|
2019-04-29 20:45:53 +00:00
|
|
|
payload = MQTTConfig(payload)
|
2018-10-12 06:51:16 +00:00
|
|
|
|
|
|
|
for key in list(payload.keys()):
|
|
|
|
abbreviated_key = key
|
|
|
|
key = ABBREVIATIONS.get(key, key)
|
|
|
|
payload[key] = payload.pop(abbreviated_key)
|
|
|
|
|
2019-02-04 18:54:40 +00:00
|
|
|
if CONF_DEVICE in payload:
|
|
|
|
device = payload[CONF_DEVICE]
|
|
|
|
for key in list(device.keys()):
|
|
|
|
abbreviated_key = key
|
|
|
|
key = DEVICE_ABBREVIATIONS.get(key, key)
|
|
|
|
device[key] = device.pop(abbreviated_key)
|
|
|
|
|
2019-03-09 00:48:54 +00:00
|
|
|
if TOPIC_BASE in payload:
|
|
|
|
base = payload.pop(TOPIC_BASE)
|
2018-10-12 06:51:16 +00:00
|
|
|
for key, value in payload.items():
|
2018-12-24 13:21:58 +00:00
|
|
|
if isinstance(value, str) and value:
|
2018-11-19 08:59:07 +00:00
|
|
|
if value[0] == TOPIC_BASE and key.endswith('_topic'):
|
|
|
|
payload[key] = "{}{}".format(base, value[1:])
|
|
|
|
if value[-1] == TOPIC_BASE and key.endswith('_topic'):
|
|
|
|
payload[key] = "{}{}".format(value[:-1], base)
|
2018-10-12 06:51:16 +00:00
|
|
|
|
2018-11-30 12:57:17 +00:00
|
|
|
# If present, the node_id will be included in the discovered object id
|
|
|
|
discovery_id = ' '.join((node_id, object_id)) if node_id else object_id
|
2018-09-24 08:11:49 +00:00
|
|
|
discovery_hash = (component, discovery_id)
|
2017-05-23 18:08:12 +00:00
|
|
|
|
2018-11-19 15:49:04 +00:00
|
|
|
if payload:
|
2019-04-29 20:45:53 +00:00
|
|
|
# Attach MQTT topic to the payload, used for debug prints
|
|
|
|
setattr(payload, '__configuration_source__',
|
|
|
|
"MQTT (topic: '{}')".format(topic))
|
|
|
|
|
2018-12-24 13:28:26 +00:00
|
|
|
if CONF_PLATFORM in payload and 'schema' not in payload:
|
2018-11-27 13:00:05 +00:00
|
|
|
platform = payload[CONF_PLATFORM]
|
2018-12-24 13:28:26 +00:00
|
|
|
if (component in DEPRECATED_PLATFORM_TO_SCHEMA and
|
|
|
|
platform in DEPRECATED_PLATFORM_TO_SCHEMA[component]):
|
|
|
|
schema = DEPRECATED_PLATFORM_TO_SCHEMA[component][platform]
|
2018-11-27 13:00:05 +00:00
|
|
|
payload['schema'] = schema
|
|
|
|
_LOGGER.warning('"platform": "%s" is deprecated, '
|
|
|
|
'replace with "schema":"%s"',
|
|
|
|
platform, schema)
|
|
|
|
payload[CONF_PLATFORM] = 'mqtt'
|
2018-11-19 15:49:04 +00:00
|
|
|
|
2019-04-14 03:25:45 +00:00
|
|
|
if (CONF_STATE_TOPIC not in payload and
|
|
|
|
component in IMPLICIT_STATE_TOPIC_COMPONENTS):
|
|
|
|
# state_topic not specified, infer from discovery topic
|
2018-09-24 08:11:49 +00:00
|
|
|
payload[CONF_STATE_TOPIC] = '{}/{}/{}{}/state'.format(
|
|
|
|
discovery_topic, component,
|
|
|
|
'%s/' % node_id if node_id else '', object_id)
|
2019-04-14 03:25:45 +00:00
|
|
|
_LOGGER.warning('implicit %s is deprecated, add "%s":"%s" to '
|
|
|
|
'%s discovery message',
|
|
|
|
CONF_STATE_TOPIC, CONF_STATE_TOPIC,
|
|
|
|
payload[CONF_STATE_TOPIC], topic)
|
2018-09-24 08:11:49 +00:00
|
|
|
|
|
|
|
payload[ATTR_DISCOVERY_HASH] = discovery_hash
|
|
|
|
|
2018-11-19 15:49:04 +00:00
|
|
|
if ALREADY_DISCOVERED not in hass.data:
|
|
|
|
hass.data[ALREADY_DISCOVERED] = {}
|
|
|
|
if discovery_hash in hass.data[ALREADY_DISCOVERED]:
|
|
|
|
# Dispatch update
|
|
|
|
_LOGGER.info(
|
|
|
|
"Component has already been discovered: %s %s, sending update",
|
|
|
|
component, discovery_id)
|
|
|
|
async_dispatcher_send(
|
|
|
|
hass, MQTT_DISCOVERY_UPDATED.format(discovery_hash), payload)
|
|
|
|
elif payload:
|
|
|
|
# Add component
|
2018-09-24 08:11:49 +00:00
|
|
|
_LOGGER.info("Found new component: %s %s", component, discovery_id)
|
2018-11-19 15:49:04 +00:00
|
|
|
hass.data[ALREADY_DISCOVERED][discovery_hash] = None
|
2018-09-24 08:11:49 +00:00
|
|
|
|
2018-11-27 13:00:05 +00:00
|
|
|
if component not in CONFIG_ENTRY_COMPONENTS:
|
2018-09-27 14:07:56 +00:00
|
|
|
await async_load_platform(
|
2018-11-27 13:00:05 +00:00
|
|
|
hass, component, 'mqtt', payload, hass_config)
|
2018-09-27 14:07:56 +00:00
|
|
|
return
|
|
|
|
|
2018-11-27 13:00:05 +00:00
|
|
|
config_entries_key = '{}.{}'.format(component, 'mqtt')
|
2018-10-08 08:59:43 +00:00
|
|
|
async with hass.data[DATA_CONFIG_ENTRY_LOCK]:
|
|
|
|
if config_entries_key not in hass.data[CONFIG_ENTRY_IS_SETUP]:
|
|
|
|
await hass.config_entries.async_forward_entry_setup(
|
|
|
|
config_entry, component)
|
|
|
|
hass.data[CONFIG_ENTRY_IS_SETUP].add(config_entries_key)
|
2018-09-27 14:07:56 +00:00
|
|
|
|
|
|
|
async_dispatcher_send(hass, MQTT_DISCOVERY_NEW.format(
|
2018-11-27 13:00:05 +00:00
|
|
|
component, 'mqtt'), payload)
|
2018-09-27 14:07:56 +00:00
|
|
|
|
2018-10-08 08:59:43 +00:00
|
|
|
hass.data[DATA_CONFIG_ENTRY_LOCK] = asyncio.Lock()
|
2018-09-27 14:07:56 +00:00
|
|
|
hass.data[CONFIG_ENTRY_IS_SETUP] = set()
|
2017-02-07 17:13:24 +00:00
|
|
|
|
2018-03-17 03:27:05 +00:00
|
|
|
await mqtt.async_subscribe(
|
2017-02-18 22:17:18 +00:00
|
|
|
hass, discovery_topic + '/#', async_device_message_received, 0)
|
2017-02-07 17:13:24 +00:00
|
|
|
|
|
|
|
return True
|