Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions homeassistant/components/mqtt/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
_LOGGER = logging.getLogger(__name__)

TOPIC_MATCHER = re.compile(
r'(?P<prefix_topic>\w+)/(?P<component>\w+)/(?P<object_id>[a-zA-Z0-9_-]+)'
'/config')
r'(?P<prefix_topic>\w+)/(?P<component>\w+)/'
r'(?:(?P<node_id>[a-zA-Z0-9_-]+)/)?(?P<object_id>[a-zA-Z0-9_-]+)/config')

SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor', 'switch']

Expand All @@ -44,7 +44,7 @@ def async_device_message_received(topic, payload, qos):
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)
Expand All @@ -65,21 +65,25 @@ def async_device_message_received(topic, payload, qos):

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)
Expand Down
20 changes: 19 additions & 1 deletion tests/components/mqtt/test_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down