mirror of
https://github.com/home-assistant/core.git
synced 2025-12-25 05:26:47 +00:00
Remove discovered MQTT Switch device when discovery topic is cleared (#16605)
* Remove discovered device when discovery topic is cleared * Move entity removal away from mqtt discovery * Move discovery update to mixin class * Add testcase * Review comments
This commit is contained in:
committed by
Fabian Affolter
parent
a5cb4e6c2b
commit
5ee4718e24
@@ -9,9 +9,10 @@ import logging
|
||||
import re
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
from homeassistant.components.mqtt import CONF_STATE_TOPIC
|
||||
from homeassistant.components.mqtt import CONF_STATE_TOPIC, ATTR_DISCOVERY_HASH
|
||||
from homeassistant.const import CONF_PLATFORM
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -38,6 +39,7 @@ ALLOWED_PLATFORMS = {
|
||||
}
|
||||
|
||||
ALREADY_DISCOVERED = 'mqtt_discovered_components'
|
||||
MQTT_DISCOVERY_UPDATED = 'mqtt_discovery_updated_{}'
|
||||
|
||||
|
||||
async def async_start(hass, discovery_topic, hass_config):
|
||||
@@ -51,47 +53,53 @@ async def async_start(hass, discovery_topic, hass_config):
|
||||
|
||||
_prefix_topic, component, node_id, object_id = match.groups()
|
||||
|
||||
try:
|
||||
payload = json.loads(payload)
|
||||
except ValueError:
|
||||
_LOGGER.warning("Unable to parse JSON %s: %s", object_id, payload)
|
||||
return
|
||||
|
||||
if component not in SUPPORTED_COMPONENTS:
|
||||
_LOGGER.warning("Component %s is not supported", component)
|
||||
return
|
||||
|
||||
payload = dict(payload)
|
||||
platform = payload.get(CONF_PLATFORM, 'mqtt')
|
||||
if platform not in ALLOWED_PLATFORMS.get(component, []):
|
||||
_LOGGER.warning("Platform %s (component %s) is not allowed",
|
||||
platform, component)
|
||||
return
|
||||
|
||||
payload[CONF_PLATFORM] = platform
|
||||
if CONF_STATE_TOPIC not in payload:
|
||||
payload[CONF_STATE_TOPIC] = '{}/{}/{}{}/state'.format(
|
||||
discovery_topic, component, '%s/' % node_id if node_id else '',
|
||||
object_id)
|
||||
|
||||
if ALREADY_DISCOVERED not in hass.data:
|
||||
hass.data[ALREADY_DISCOVERED] = set()
|
||||
|
||||
# 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
|
||||
|
||||
if ALREADY_DISCOVERED not in hass.data:
|
||||
hass.data[ALREADY_DISCOVERED] = {}
|
||||
|
||||
discovery_hash = (component, discovery_id)
|
||||
|
||||
if discovery_hash in hass.data[ALREADY_DISCOVERED]:
|
||||
_LOGGER.info("Component has already been discovered: %s %s",
|
||||
component, discovery_id)
|
||||
return
|
||||
_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
|
||||
try:
|
||||
payload = json.loads(payload)
|
||||
except ValueError:
|
||||
_LOGGER.warning("Unable to parse JSON %s: '%s'",
|
||||
object_id, payload)
|
||||
return
|
||||
|
||||
hass.data[ALREADY_DISCOVERED].add(discovery_hash)
|
||||
payload = dict(payload)
|
||||
platform = payload.get(CONF_PLATFORM, 'mqtt')
|
||||
if platform not in ALLOWED_PLATFORMS.get(component, []):
|
||||
_LOGGER.warning("Platform %s (component %s) is not allowed",
|
||||
platform, component)
|
||||
return
|
||||
|
||||
_LOGGER.info("Found new component: %s %s", component, discovery_id)
|
||||
payload[CONF_PLATFORM] = platform
|
||||
if CONF_STATE_TOPIC not in payload:
|
||||
payload[CONF_STATE_TOPIC] = '{}/{}/{}{}/state'.format(
|
||||
discovery_topic, component,
|
||||
'%s/' % node_id if node_id else '', object_id)
|
||||
|
||||
await async_load_platform(
|
||||
hass, component, platform, payload, hass_config)
|
||||
hass.data[ALREADY_DISCOVERED][discovery_hash] = None
|
||||
payload[ATTR_DISCOVERY_HASH] = discovery_hash
|
||||
|
||||
_LOGGER.info("Found new component: %s %s", component, discovery_id)
|
||||
|
||||
await async_load_platform(
|
||||
hass, component, platform, payload, hass_config)
|
||||
|
||||
await mqtt.async_subscribe(
|
||||
hass, discovery_topic + '/#', async_device_message_received, 0)
|
||||
|
||||
Reference in New Issue
Block a user