added optional node_id to MQTT discovery (#8096)

This commit is contained in:
Alex Mekkering 2017-06-24 09:46:41 +02:00 committed by Paulus Schoutsen
parent 2a1f8af10a
commit c1095665e9
2 changed files with 31 additions and 9 deletions

View File

@ -17,8 +17,8 @@ from homeassistant.components.mqtt import CONF_STATE_TOPIC
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
TOPIC_MATCHER = re.compile( TOPIC_MATCHER = re.compile(
r'(?P<prefix_topic>\w+)/(?P<component>\w+)/(?P<object_id>[a-zA-Z0-9_-]+)' r'(?P<prefix_topic>\w+)/(?P<component>\w+)/'
'/config') r'(?:(?P<node_id>[a-zA-Z0-9_-]+)/)?(?P<object_id>[a-zA-Z0-9_-]+)/config')
SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor', 'switch'] SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor', 'switch']
@ -44,7 +44,7 @@ def async_start(hass, discovery_topic, hass_config):
if not match: if not match:
return return
prefix_topic, component, object_id = match.groups() prefix_topic, component, node_id, object_id = match.groups()
try: try:
payload = json.loads(payload) payload = json.loads(payload)
@ -65,21 +65,25 @@ def async_start(hass, discovery_topic, hass_config):
payload[CONF_PLATFORM] = platform payload[CONF_PLATFORM] = platform
if CONF_STATE_TOPIC not in payload: if CONF_STATE_TOPIC not in payload:
payload[CONF_STATE_TOPIC] = '{}/{}/{}/state'.format( payload[CONF_STATE_TOPIC] = '{}/{}/{}{}/state'.format(
discovery_topic, component, object_id) discovery_topic, component, '%s/' % node_id if node_id else '',
object_id)
if ALREADY_DISCOVERED not in hass.data: if ALREADY_DISCOVERED not in hass.data:
hass.data[ALREADY_DISCOVERED] = set() 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]: if discovery_hash in hass.data[ALREADY_DISCOVERED]:
_LOGGER.info("Component has already been discovered: %s %s", _LOGGER.info("Component has already been discovered: %s %s",
component, object_id) component, discovery_id)
return return
hass.data[ALREADY_DISCOVERED].add(discovery_hash) 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( yield from async_load_platform(
hass, component, platform, payload, hass_config) hass, component, platform, payload, hass_config)

View File

@ -2,7 +2,8 @@
import asyncio import asyncio
from unittest.mock import patch 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 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 is not None
assert state.name == 'Beer' 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 @asyncio.coroutine