From be53cc70682ca55ec983630d283d3afbe2736a02 Mon Sep 17 00:00:00 2001 From: nordeep Date: Tue, 23 May 2017 21:08:12 +0300 Subject: [PATCH] Don't initialize mqtt components which have already been discovered (#7625) * Don't initialize mqtt components which have already been discovered * Fix string length * Fix blank lines, fix constant name * Remove globals. Remove JSON dump * Add tests. Update grammar * PEP8 style issue * Add hyphen to object_id regex * PEP8 style fix --- homeassistant/components/mqtt/discovery.py | 18 +++++++++++++++++- tests/components/mqtt/test_discovery.py | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index dbee9dce571f..3ead94dca14c 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -17,7 +17,8 @@ from homeassistant.components.mqtt import CONF_STATE_TOPIC _LOGGER = logging.getLogger(__name__) TOPIC_MATCHER = re.compile( - r'(?P\w+)/(?P\w+)/(?P\w+)/config') + r'(?P\w+)/(?P\w+)/(?P[a-zA-Z0-9_-]+)' + '/config') SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor', 'switch'] @@ -28,6 +29,8 @@ ALLOWED_PLATFORMS = { 'switch': ['mqtt'], } +ALREADY_DISCOVERED = 'mqtt_discovered_components' + @asyncio.coroutine def async_start(hass, discovery_topic, hass_config): @@ -65,6 +68,19 @@ def async_start(hass, discovery_topic, hass_config): payload[CONF_STATE_TOPIC] = '{}/{}/{}/state'.format( discovery_topic, component, object_id) + if ALREADY_DISCOVERED not in hass.data: + hass.data[ALREADY_DISCOVERED] = set() + + discovery_hash = (component, object_id) + if discovery_hash in hass.data[ALREADY_DISCOVERED]: + _LOGGER.info("Component has already been discovered: %s %s", + component, object_id) + return + + hass.data[ALREADY_DISCOVERED].add(discovery_hash) + + _LOGGER.info("Found new component: %s %s", component, object_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 134b679daeae..04ea0f34fd5d 100644 --- a/tests/components/mqtt/test_discovery.py +++ b/tests/components/mqtt/test_discovery.py @@ -73,3 +73,24 @@ def test_correct_config_discovery(hass, mqtt_mock, caplog): assert state is not None assert state.name == 'Beer' + + +@asyncio.coroutine +def test_non_duplicate_discovery(hass, mqtt_mock, caplog): + """Test for a non duplicate component.""" + yield from async_start(hass, 'homeassistant', {}) + + async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/config', + '{ "name": "Beer" }') + async_fire_mqtt_message(hass, 'homeassistant/binary_sensor/bla/config', + '{ "name": "Beer" }') + yield from hass.async_block_till_done() + + state = hass.states.get('binary_sensor.beer') + state_duplicate = hass.states.get('binary_sensor.beer1') + + assert state is not None + assert state.name == 'Beer' + assert state_duplicate is None + assert 'Component has already been discovered: ' \ + 'binary_sensor bla' in caplog.text