diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index ac68cfaf367..421ba321c8d 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -7,6 +7,7 @@ Knows which components handle certain types, will make sure they are loaded before the EVENT_PLATFORM_DISCOVERED is fired. """ import asyncio +import json from datetime import timedelta import logging @@ -66,6 +67,7 @@ def async_setup(hass, config): logger = logging.getLogger(__name__) netdisco = NetworkDiscovery() + already_discovered = set() # Disable zeroconf logging, it spams logging.getLogger('zeroconf').setLevel(logging.CRITICAL) @@ -80,14 +82,20 @@ def async_setup(hass, config): logger.info("Ignoring service: %s %s", service, info) return - logger.info("Found new service: %s %s", service, info) - comp_plat = SERVICE_HANDLERS.get(service) # We do not know how to handle this service. if not comp_plat: return + discovery_hash = json.dumps([service, info], sort_keys=True) + if discovery_hash in already_discovered: + return + + already_discovered.add(discovery_hash) + + logger.info("Found new service: %s %s", service, info) + component, platform = comp_plat if platform is None: diff --git a/tests/components/test_discovery.py b/tests/components/test_discovery.py index bc2be3ed463..abffc3b17cd 100644 --- a/tests/components/test_discovery.py +++ b/tests/components/test_discovery.py @@ -126,3 +126,30 @@ def test_ignore_service(hass): assert not mock_discover.called assert not mock_platform.called + + +@asyncio.coroutine +def test_discover_duplicates(hass): + """Test load a component.""" + result = yield from async_setup_component(hass, 'discovery', BASE_CONFIG) + assert result + + def discover(netdisco): + """Fake discovery.""" + return [(SERVICE_NO_PLATFORM, SERVICE_INFO), + (SERVICE_NO_PLATFORM, SERVICE_INFO)] + + with patch.object(discovery, '_discover', discover), \ + patch('homeassistant.components.discovery.async_discover', + return_value=mock_coro()) as mock_discover, \ + patch('homeassistant.components.discovery.async_load_platform', + return_value=mock_coro()) as mock_platform: + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + yield from hass.async_block_till_done() + + assert mock_discover.called + assert mock_discover.call_count == 1 + assert not mock_platform.called + mock_discover.assert_called_with( + hass, SERVICE_NO_PLATFORM, SERVICE_INFO, + SERVICE_NO_PLATFORM_COMPONENT, BASE_CONFIG)