From c1095665e996d59245d9f9a24135bf3d6d4f0b65 Mon Sep 17 00:00:00 2001 From: Alex Mekkering Date: Sat, 24 Jun 2017 09:46:41 +0200 Subject: [PATCH] added optional node_id to MQTT discovery (#8096) --- homeassistant/components/mqtt/discovery.py | 20 ++++++++++++-------- tests/components/mqtt/test_discovery.py | 20 +++++++++++++++++++- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index 3ead94dca14..f76c4e9d527 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -17,8 +17,8 @@ from homeassistant.components.mqtt import CONF_STATE_TOPIC _LOGGER = logging.getLogger(__name__) TOPIC_MATCHER = re.compile( - r'(?P\w+)/(?P\w+)/(?P[a-zA-Z0-9_-]+)' - '/config') + r'(?P\w+)/(?P\w+)/' + r'(?:(?P[a-zA-Z0-9_-]+)/)?(?P[a-zA-Z0-9_-]+)/config') SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor', 'switch'] @@ -44,7 +44,7 @@ def async_start(hass, discovery_topic, hass_config): if not match: return - prefix_topic, component, object_id = match.groups() + prefix_topic, component, node_id, object_id = match.groups() try: payload = json.loads(payload) @@ -65,21 +65,25 @@ def async_start(hass, discovery_topic, hass_config): payload[CONF_PLATFORM] = platform if CONF_STATE_TOPIC not in payload: - payload[CONF_STATE_TOPIC] = '{}/{}/{}/state'.format( - discovery_topic, component, object_id) + 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() - discovery_hash = (component, object_id) + # 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 + + discovery_hash = (component, discovery_id) if discovery_hash in hass.data[ALREADY_DISCOVERED]: _LOGGER.info("Component has already been discovered: %s %s", - component, object_id) + component, discovery_id) return hass.data[ALREADY_DISCOVERED].add(discovery_hash) - _LOGGER.info("Found new component: %s %s", component, object_id) + _LOGGER.info("Found new component: %s %s", component, discovery_id) yield from async_load_platform( hass, component, platform, payload, hass_config) diff --git a/tests/components/mqtt/test_discovery.py b/tests/components/mqtt/test_discovery.py index 04ea0f34fd5..e865b524f85 100644 --- a/tests/components/mqtt/test_discovery.py +++ b/tests/components/mqtt/test_discovery.py @@ -2,7 +2,8 @@ import asyncio from unittest.mock import patch -from homeassistant.components.mqtt.discovery import async_start +from homeassistant.components.mqtt.discovery import async_start, \ + ALREADY_DISCOVERED from tests.common import async_fire_mqtt_message, mock_coro @@ -73,6 +74,23 @@ def test_correct_config_discovery(hass, mqtt_mock, caplog): assert state is not None assert state.name == 'Beer' + assert ('binary_sensor', 'bla') in hass.data[ALREADY_DISCOVERED] + + +@asyncio.coroutine +def test_discovery_incl_nodeid(hass, mqtt_mock, caplog): + """Test sending in correct JSON with optional node_id included.""" + yield from async_start(hass, 'homeassistant', {}) + + async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/my_node_id/bla' + '/config', '{ "name": "Beer" }') + yield from hass.async_block_till_done() + + state = hass.states.get('binary_sensor.beer') + + assert state is not None + assert state.name == 'Beer' + assert ('binary_sensor', 'my_node_id_bla') in hass.data[ALREADY_DISCOVERED] @asyncio.coroutine