Migrate to generic discovery method (#2271)

* Migrate to generic discovery method

* Add tests for discovery
This commit is contained in:
Paulus Schoutsen 2016-06-11 17:43:13 -07:00 committed by GitHub
parent c9756c40e2
commit 30f74bb3ca
32 changed files with 322 additions and 540 deletions

View file

@ -9,7 +9,6 @@ import os
import voluptuous as vol import voluptuous as vol
from homeassistant.components import verisure
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER, ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY) SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY)
@ -24,11 +23,6 @@ SCAN_INTERVAL = 30
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
verisure.DISCOVER_ALARMS: 'verisure'
}
SERVICE_TO_METHOD = { SERVICE_TO_METHOD = {
SERVICE_ALARM_DISARM: 'alarm_disarm', SERVICE_ALARM_DISARM: 'alarm_disarm',
SERVICE_ALARM_ARM_HOME: 'alarm_arm_home', SERVICE_ALARM_ARM_HOME: 'alarm_arm_home',
@ -50,8 +44,7 @@ ALARM_SERVICE_SCHEMA = vol.Schema({
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for sensors.""" """Track states and offer events for sensors."""
component = EntityComponent( component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)

View file

@ -9,8 +9,6 @@ import logging
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.const import (STATE_ON, STATE_OFF) from homeassistant.const import (STATE_ON, STATE_OFF)
from homeassistant.components import (
bloomsky, mysensors, zwave, vera, wemo, wink)
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
DOMAIN = 'binary_sensor' DOMAIN = 'binary_sensor'
@ -35,22 +33,11 @@ SENSOR_CLASSES = [
'vibration', # On means vibration detected, Off means no vibration 'vibration', # On means vibration detected, Off means no vibration
] ]
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
bloomsky.DISCOVER_BINARY_SENSORS: 'bloomsky',
mysensors.DISCOVER_BINARY_SENSORS: 'mysensors',
zwave.DISCOVER_BINARY_SENSORS: 'zwave',
vera.DISCOVER_BINARY_SENSORS: 'vera',
wemo.DISCOVER_BINARY_SENSORS: 'wemo',
wink.DISCOVER_BINARY_SENSORS: 'wink'
}
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for binary sensors.""" """Track states and offer events for binary sensors."""
component = EntityComponent( component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)

View file

@ -9,9 +9,8 @@ from datetime import timedelta
import requests import requests
from homeassistant.components import discovery
from homeassistant.const import CONF_API_KEY from homeassistant.const import CONF_API_KEY
from homeassistant.helpers import validate_config from homeassistant.helpers import validate_config, discovery
from homeassistant.util import Throttle from homeassistant.util import Throttle
DOMAIN = "bloomsky" DOMAIN = "bloomsky"
@ -23,10 +22,6 @@ _LOGGER = logging.getLogger(__name__)
# no point in polling the API more frequently # no point in polling the API more frequently
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=300) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=300)
DISCOVER_SENSORS = 'bloomsky.sensors'
DISCOVER_BINARY_SENSORS = 'bloomsky.binary_sensor'
DISCOVER_CAMERAS = 'bloomsky.camera'
# pylint: disable=unused-argument,too-few-public-methods # pylint: disable=unused-argument,too-few-public-methods
def setup(hass, config): def setup(hass, config):
@ -45,11 +40,8 @@ def setup(hass, config):
except RuntimeError: except RuntimeError:
return False return False
for component, discovery_service in ( for component in 'camera', 'binary_sensor', 'sensor':
('camera', DISCOVER_CAMERAS), ('sensor', DISCOVER_SENSORS), discovery.load_platform(hass, component, DOMAIN, {}, config)
('binary_sensor', DISCOVER_BINARY_SENSORS)):
discovery.discover(hass, discovery_service, component=component,
hass_config=config)
return True return True

View file

@ -9,7 +9,6 @@ import logging
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.components import bloomsky, netatmo
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
@ -18,12 +17,6 @@ DEPENDENCIES = ['http']
SCAN_INTERVAL = 30 SCAN_INTERVAL = 30
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
bloomsky.DISCOVER_CAMERAS: 'bloomsky',
netatmo.DISCOVER_CAMERAS: 'netatmo',
}
STATE_RECORDING = 'recording' STATE_RECORDING = 'recording'
STATE_STREAMING = 'streaming' STATE_STREAMING = 'streaming'
STATE_IDLE = 'idle' STATE_IDLE = 'idle'
@ -35,8 +28,7 @@ ENTITY_IMAGE_URL = '/api/camera_proxy/{0}?token={1}'
def setup(hass, config): def setup(hass, config):
"""Setup the camera component.""" """Setup the camera component."""
component = EntityComponent( component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
DISCOVERY_PLATFORMS)
hass.wsgi.register_view(CameraImageView(hass, component.entities)) hass.wsgi.register_view(CameraImageView(hass, component.entities))
hass.wsgi.register_view(CameraMjpegStream(hass, component.entities)) hass.wsgi.register_view(CameraMjpegStream(hass, component.entities))

View file

@ -12,10 +12,11 @@ import os
import threading import threading
from homeassistant.bootstrap import prepare_setup_platform from homeassistant.bootstrap import prepare_setup_platform
from homeassistant.components import discovery, group, zone from homeassistant.components import group, zone
from homeassistant.components.discovery import SERVICE_NETGEAR
from homeassistant.config import load_yaml_config_file from homeassistant.config import load_yaml_config_file
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_per_platform from homeassistant.helpers import config_per_platform, discovery
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
import homeassistant.util as util import homeassistant.util as util
@ -62,7 +63,7 @@ ATTR_GPS = 'gps'
ATTR_BATTERY = 'battery' ATTR_BATTERY = 'battery'
DISCOVERY_PLATFORMS = { DISCOVERY_PLATFORMS = {
discovery.SERVICE_NETGEAR: 'netgear', SERVICE_NETGEAR: 'netgear',
} }
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -95,8 +96,11 @@ def setup(hass, config):
yaml_path = hass.config.path(YAML_DEVICES) yaml_path = hass.config.path(YAML_DEVICES)
conf = config.get(DOMAIN, {}) conf = config.get(DOMAIN, {})
if isinstance(conf, list) and len(conf) > 0:
conf = conf[0] # Config can be an empty list. In that case, substitute a dict
if isinstance(conf, list):
conf = conf[0] if len(conf) > 0 else {}
consider_home = timedelta( consider_home = timedelta(
seconds=util.convert(conf.get(CONF_CONSIDER_HOME), int, seconds=util.convert(conf.get(CONF_CONSIDER_HOME), int,
DEFAULT_CONSIDER_HOME)) DEFAULT_CONSIDER_HOME))

View file

@ -9,100 +9,30 @@ loaded before the EVENT_PLATFORM_DISCOVERED is fired.
import logging import logging
import threading import threading
from homeassistant import bootstrap from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.const import ( from homeassistant.helpers.discovery import load_platform, discover
ATTR_DISCOVERED, ATTR_SERVICE, EVENT_HOMEASSISTANT_START,
EVENT_PLATFORM_DISCOVERED)
DOMAIN = "discovery" DOMAIN = "discovery"
REQUIREMENTS = ['netdisco==0.6.7'] REQUIREMENTS = ['netdisco==0.6.7']
SCAN_INTERVAL = 300 # seconds SCAN_INTERVAL = 300 # seconds
LOAD_PLATFORM = 'load_platform'
SERVICE_WEMO = 'belkin_wemo' SERVICE_WEMO = 'belkin_wemo'
SERVICE_HUE = 'philips_hue'
SERVICE_CAST = 'google_cast'
SERVICE_NETGEAR = 'netgear_router' SERVICE_NETGEAR = 'netgear_router'
SERVICE_SONOS = 'sonos'
SERVICE_PLEX = 'plex_mediaserver'
SERVICE_SQUEEZEBOX = 'logitech_mediaserver'
SERVICE_PANASONIC_VIERA = 'panasonic_viera'
SERVICE_ROKU = 'roku'
SERVICE_HANDLERS = { SERVICE_HANDLERS = {
SERVICE_WEMO: "wemo", SERVICE_NETGEAR: ('device_tracker', None),
SERVICE_CAST: "media_player", SERVICE_WEMO: ('wemo', None),
SERVICE_HUE: "light", 'philips_hue': ('light', 'hue'),
SERVICE_NETGEAR: 'device_tracker', 'google_cast': ('media_player', 'cast'),
SERVICE_SONOS: 'media_player', 'panasonic_viera': ('media_player', 'panasonic_viera'),
SERVICE_PLEX: 'media_player', 'plex_mediaserver': ('media_player', 'plex'),
SERVICE_SQUEEZEBOX: 'media_player', 'roku': ('media_player', 'roku'),
SERVICE_PANASONIC_VIERA: 'media_player', 'sonos': ('media_player', 'sonos'),
SERVICE_ROKU: 'media_player', 'logitech_mediaserver': ('media_player', 'squeezebox'),
} }
def listen(hass, service, callback):
"""Setup listener for discovery of specific service.
Service can be a string or a list/tuple.
"""
if isinstance(service, str):
service = (service,)
else:
service = tuple(service)
def discovery_event_listener(event):
"""Listen for discovery events."""
if ATTR_SERVICE in event.data and event.data[ATTR_SERVICE] in service:
callback(event.data[ATTR_SERVICE], event.data.get(ATTR_DISCOVERED))
hass.bus.listen(EVENT_PLATFORM_DISCOVERED, discovery_event_listener)
def discover(hass, service, discovered=None, component=None, hass_config=None):
"""Fire discovery event. Can ensure a component is loaded."""
if component is not None:
bootstrap.setup_component(hass, component, hass_config)
data = {
ATTR_SERVICE: service
}
if discovered is not None:
data[ATTR_DISCOVERED] = discovered
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, data)
def load_platform(hass, component, platform, info=None, hass_config=None):
"""Helper method for generic platform loading.
This method allows a platform to be loaded dynamically without it being
known at runtime (in the DISCOVERY_PLATFORMS list of the component).
Advantages of using this method:
- Any component & platforms combination can be dynamically added
- A component (i.e. light) does not have to import every component
that can dynamically add a platform (e.g. wemo, wink, insteon_hub)
- Custom user components can take advantage of discovery/loading
Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be
fired to load the platform. The event will contain:
{ ATTR_SERVICE = LOAD_PLATFORM + '.' + <<component>>
ATTR_DISCOVERED = {LOAD_PLATFORM: <<platform>>} }
* dev note: This listener can be found in entity_component.py
"""
if info is None:
info = {LOAD_PLATFORM: platform}
else:
info[LOAD_PLATFORM] = platform
discover(hass, LOAD_PLATFORM + '.' + component, info, component,
hass_config)
def setup(hass, config): def setup(hass, config):
"""Start a discovery service.""" """Start a discovery service."""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -119,20 +49,18 @@ def setup(hass, config):
with lock: with lock:
logger.info("Found new service: %s %s", service, info) logger.info("Found new service: %s %s", service, info)
component = SERVICE_HANDLERS.get(service) comp_plat = SERVICE_HANDLERS.get(service)
# We do not know how to handle this service. # We do not know how to handle this service.
if not component: if not comp_plat:
return return
# This component cannot be setup. component, platform = comp_plat
if not bootstrap.setup_component(hass, component, config):
return
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { if platform is None:
ATTR_SERVICE: service, discover(hass, service, info, component, config)
ATTR_DISCOVERED: info else:
}) load_platform(hass, component, platform, info, config)
# pylint: disable=unused-argument # pylint: disable=unused-argument
def start_discovery(event): def start_discovery(event):

View file

@ -8,15 +8,12 @@ import logging
import os import os
from datetime import timedelta from datetime import timedelta
from homeassistant import bootstrap from homeassistant.helpers import discovery
from homeassistant.const import ( from homeassistant.const import CONF_API_KEY
ATTR_DISCOVERED, ATTR_SERVICE, CONF_API_KEY, EVENT_PLATFORM_DISCOVERED)
from homeassistant.loader import get_component from homeassistant.loader import get_component
from homeassistant.util import Throttle from homeassistant.util import Throttle
DOMAIN = "ecobee" DOMAIN = "ecobee"
DISCOVER_THERMOSTAT = "ecobee.thermostat"
DISCOVER_SENSORS = "ecobee.sensor"
NETWORK = None NETWORK = None
HOLD_TEMP = 'hold_temp' HOLD_TEMP = 'hold_temp'
@ -70,23 +67,11 @@ def setup_ecobee(hass, network, config):
configurator = get_component('configurator') configurator = get_component('configurator')
configurator.request_done(_CONFIGURING.pop('ecobee')) configurator.request_done(_CONFIGURING.pop('ecobee'))
# Ensure component is loaded
bootstrap.setup_component(hass, 'thermostat', config)
bootstrap.setup_component(hass, 'sensor', config)
hold_temp = config[DOMAIN].get(HOLD_TEMP, False) hold_temp = config[DOMAIN].get(HOLD_TEMP, False)
# Fire thermostat discovery event discovery.load_platform(hass, 'thermostat', DOMAIN,
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { {'hold_temp': hold_temp}, config)
ATTR_SERVICE: DISCOVER_THERMOSTAT, discovery.load_platform(hass, 'sensor', DOMAIN, None, config)
ATTR_DISCOVERED: {'hold_temp': hold_temp}
})
# Fire sensor discovery event
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
ATTR_SERVICE: DISCOVER_SENSORS,
ATTR_DISCOVERED: {}
})
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods

View file

@ -17,7 +17,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
STATE_CLOSED, STATE_OPEN, STATE_UNKNOWN, SERVICE_CLOSE, SERVICE_OPEN, STATE_CLOSED, STATE_OPEN, STATE_UNKNOWN, SERVICE_CLOSE, SERVICE_OPEN,
ATTR_ENTITY_ID) ATTR_ENTITY_ID)
from homeassistant.components import (group, wink) from homeassistant.components import group
DOMAIN = 'garage_door' DOMAIN = 'garage_door'
SCAN_INTERVAL = 30 SCAN_INTERVAL = 30
@ -27,11 +27,6 @@ ENTITY_ID_ALL_GARAGE_DOORS = group.ENTITY_ID_FORMAT.format('all_garage_doors')
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
wink.DISCOVER_GARAGE_DOORS: 'wink'
}
GARAGE_DOOR_SERVICE_SCHEMA = vol.Schema({ GARAGE_DOOR_SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
}) })
@ -60,8 +55,7 @@ def open_door(hass, entity_id=None):
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for garage door.""" """Track states and offer events for garage door."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_GARAGE_DOORS)
GROUP_NAME_ALL_GARAGE_DOORS)
component.setup(config) component.setup(config)
def handle_garage_door_service(service): def handle_garage_door_service(service):

View file

@ -14,7 +14,6 @@ import homeassistant.util as util
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert from homeassistant.helpers.temperature import convert
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.components import zwave
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN, ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
TEMP_CELCIUS) TEMP_CELCIUS)
@ -57,10 +56,6 @@ ATTR_SWING_LIST = "swing_list"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DISCOVERY_PLATFORMS = {
zwave.DISCOVER_HVAC: 'zwave'
}
def set_away_mode(hass, away_mode, entity_id=None): def set_away_mode(hass, away_mode, entity_id=None):
"""Turn all or specified hvac away mode on.""" """Turn all or specified hvac away mode on."""
@ -139,8 +134,7 @@ def set_swing_mode(hass, swing_mode, entity_id=None):
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
def setup(hass, config): def setup(hass, config):
"""Setup hvacs.""" """Setup hvacs."""
component = EntityComponent(_LOGGER, DOMAIN, hass, component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
SCAN_INTERVAL, DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)
descriptions = load_yaml_config_file( descriptions = load_yaml_config_file(

View file

@ -6,17 +6,12 @@ https://home-assistant.io/components/insteon_hub/
""" """
import logging import logging
import homeassistant.bootstrap as bootstrap from homeassistant.const import CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import ( from homeassistant.helpers import validate_config, discovery
ATTR_DISCOVERED, ATTR_SERVICE, CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME,
EVENT_PLATFORM_DISCOVERED)
from homeassistant.helpers import validate_config
from homeassistant.loader import get_component
DOMAIN = "insteon_hub" DOMAIN = "insteon_hub"
REQUIREMENTS = ['insteon_hub==0.4.5'] REQUIREMENTS = ['insteon_hub==0.4.5']
INSTEON = None INSTEON = None
DISCOVER_LIGHTS = "insteon_hub.lights"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -44,11 +39,7 @@ def setup(hass, config):
_LOGGER.error("Could not connect to Insteon service.") _LOGGER.error("Could not connect to Insteon service.")
return return
comp_name = 'light' for component in 'light':
discovery = DISCOVER_LIGHTS discovery.load_platform(hass, component, DOMAIN, None, config)
component = get_component(comp_name)
bootstrap.setup_component(hass, component.DOMAIN, config)
hass.bus.fire(
EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery, ATTR_DISCOVERED: {}})
return True return True

View file

@ -7,19 +7,15 @@ https://home-assistant.io/components/isy994/
import logging import logging
from urllib.parse import urlparse from urllib.parse import urlparse
from homeassistant import bootstrap
from homeassistant.const import ( from homeassistant.const import (
ATTR_DISCOVERED, ATTR_SERVICE, CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_HOST, CONF_PASSWORD, CONF_USERNAME,
EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED) EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers import validate_config from homeassistant.helpers import validate_config, discovery
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.loader import get_component
DOMAIN = "isy994" DOMAIN = "isy994"
REQUIREMENTS = ['PyISY==1.0.6'] REQUIREMENTS = ['PyISY==1.0.6']
DISCOVER_LIGHTS = "isy994.lights"
DISCOVER_SWITCHES = "isy994.switches"
DISCOVER_SENSORS = "isy994.sensors"
ISY = None ISY = None
SENSOR_STRING = 'Sensor' SENSOR_STRING = 'Sensor'
HIDDEN_STRING = '{HIDE ME}' HIDDEN_STRING = '{HIDE ME}'
@ -76,15 +72,9 @@ def setup(hass, config):
# Listen for HA stop to disconnect. # Listen for HA stop to disconnect.
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop)
# Load components for the devices in the ISY controller that we support. # Load platforms for the devices in the ISY controller that we support.
for comp_name, discovery in ((('sensor', DISCOVER_SENSORS), for component in ('sensor', 'light', 'switch'):
('light', DISCOVER_LIGHTS), discovery.load_platform(hass, component, DOMAIN, None, config)
('switch', DISCOVER_SWITCHES))):
component = get_component(comp_name)
bootstrap.setup_component(hass, component.DOMAIN, config)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery,
ATTR_DISCOVERED: {}})
ISY.auto_update = True ISY.auto_update = True
return True return True

View file

@ -10,9 +10,7 @@ import csv
import voluptuous as vol import voluptuous as vol
from homeassistant.components import ( from homeassistant.components import group
group, discovery, wemo, wink, isy994,
zwave, insteon_hub, mysensors, tellstick, vera)
from homeassistant.config import load_yaml_config_file from homeassistant.config import load_yaml_config_file
from homeassistant.const import ( from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
@ -60,19 +58,6 @@ EFFECT_WHITE = "white"
LIGHT_PROFILES_FILE = "light_profiles.csv" LIGHT_PROFILES_FILE = "light_profiles.csv"
# Maps discovered services to their platforms.
DISCOVERY_PLATFORMS = {
wemo.DISCOVER_LIGHTS: 'wemo',
wink.DISCOVER_LIGHTS: 'wink',
insteon_hub.DISCOVER_LIGHTS: 'insteon_hub',
isy994.DISCOVER_LIGHTS: 'isy994',
discovery.SERVICE_HUE: 'hue',
zwave.DISCOVER_LIGHTS: 'zwave',
mysensors.DISCOVER_LIGHTS: 'mysensors',
tellstick.DISCOVER_LIGHTS: 'tellstick',
vera.DISCOVER_LIGHTS: 'vera',
}
PROP_TO_ATTR = { PROP_TO_ATTR = {
'brightness': ATTR_BRIGHTNESS, 'brightness': ATTR_BRIGHTNESS,
'color_temp': ATTR_COLOR_TEMP, 'color_temp': ATTR_COLOR_TEMP,
@ -172,8 +157,7 @@ def toggle(hass, entity_id=None, transition=None):
def setup(hass, config): def setup(hass, config):
"""Expose light control via statemachine and services.""" """Expose light control via statemachine and services."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LIGHTS)
GROUP_NAME_ALL_LIGHTS)
component.setup(config) component.setup(config)
# Load built-in profiles and custom profiles # Load built-in profiles and custom profiles

View file

@ -18,7 +18,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNLOCKED, ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNLOCKED,
STATE_UNKNOWN, SERVICE_LOCK, SERVICE_UNLOCK) STATE_UNKNOWN, SERVICE_LOCK, SERVICE_UNLOCK)
from homeassistant.components import (group, verisure, wink, zwave) from homeassistant.components import group
DOMAIN = 'lock' DOMAIN = 'lock'
SCAN_INTERVAL = 30 SCAN_INTERVAL = 30
@ -30,13 +30,6 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
wink.DISCOVER_LOCKS: 'wink',
verisure.DISCOVER_LOCKS: 'verisure',
zwave.DISCOVER_LOCKS: 'zwave',
}
LOCK_SERVICE_SCHEMA = vol.Schema({ LOCK_SERVICE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Optional(ATTR_CODE): cv.string, vol.Optional(ATTR_CODE): cv.string,
@ -76,8 +69,7 @@ def unlock(hass, entity_id=None, code=None):
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for locks.""" """Track states and offer events for locks."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LOCKS)
GROUP_NAME_ALL_LOCKS)
component.setup(config) component.setup(config)
def handle_lock_service(service): def handle_lock_service(service):

View file

@ -9,7 +9,6 @@ import os
import voluptuous as vol import voluptuous as vol
from homeassistant.components import discovery
from homeassistant.config import load_yaml_config_file from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
@ -30,15 +29,6 @@ SCAN_INTERVAL = 10
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
DISCOVERY_PLATFORMS = {
discovery.SERVICE_CAST: 'cast',
discovery.SERVICE_SONOS: 'sonos',
discovery.SERVICE_PLEX: 'plex',
discovery.SERVICE_SQUEEZEBOX: 'squeezebox',
discovery.SERVICE_PANASONIC_VIERA: 'panasonic_viera',
discovery.SERVICE_ROKU: 'roku',
}
SERVICE_PLAY_MEDIA = 'play_media' SERVICE_PLAY_MEDIA = 'play_media'
SERVICE_SELECT_SOURCE = 'select_source' SERVICE_SELECT_SOURCE = 'select_source'
@ -285,8 +275,7 @@ def select_source(hass, source, entity_id=None):
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for media_players.""" """Track states and offer events for media_players."""
component = EntityComponent( component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)

View file

@ -7,14 +7,11 @@ https://home-assistant.io/components/sensor.mysensors/
import logging import logging
import socket import socket
import homeassistant.bootstrap as bootstrap from homeassistant.const import (ATTR_BATTERY_LEVEL, CONF_OPTIMISTIC,
from homeassistant.const import (ATTR_BATTERY_LEVEL, ATTR_DISCOVERED,
ATTR_SERVICE, CONF_OPTIMISTIC,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
EVENT_PLATFORM_DISCOVERED, STATE_OFF, STATE_OFF, STATE_ON, TEMP_CELSIUS)
STATE_ON, TEMP_CELSIUS) from homeassistant.helpers import validate_config, discovery
from homeassistant.helpers import validate_config
CONF_GATEWAYS = 'gateways' CONF_GATEWAYS = 'gateways'
CONF_DEVICE = 'device' CONF_DEVICE = 'device'
@ -40,19 +37,6 @@ ATTR_DEVICE = 'device'
GATEWAYS = None GATEWAYS = None
DISCOVER_SENSORS = 'mysensors.sensors'
DISCOVER_SWITCHES = 'mysensors.switches'
DISCOVER_LIGHTS = 'mysensors.lights'
DISCOVER_BINARY_SENSORS = 'mysensors.binary_sensor'
# Maps discovered services to their platforms
DISCOVERY_COMPONENTS = [
('sensor', DISCOVER_SENSORS),
('switch', DISCOVER_SWITCHES),
('light', DISCOVER_LIGHTS),
('binary_sensor', DISCOVER_BINARY_SENSORS),
]
def setup(hass, config): # pylint: disable=too-many-locals def setup(hass, config): # pylint: disable=too-many-locals
"""Setup the MySensors component.""" """Setup the MySensors component."""
@ -124,14 +108,8 @@ def setup(hass, config): # pylint: disable=too-many-locals
GATEWAYS[device] = setup_gateway( GATEWAYS[device] = setup_gateway(
device, persistence_file, baud_rate, tcp_port) device, persistence_file, baud_rate, tcp_port)
for (component, discovery_service) in DISCOVERY_COMPONENTS: for component in 'sensor', 'switch', 'light', 'binary_sensor':
# Ensure component is loaded discovery.load_platform(hass, component, DOMAIN, None, config)
if not bootstrap.setup_component(hass, component, config):
return False
# Fire discovery event
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
ATTR_SERVICE: discovery_service,
ATTR_DISCOVERED: {}})
return True return True

View file

@ -6,10 +6,9 @@ https://home-assistant.io/components/netatmo/
""" """
import logging import logging
from urllib.error import HTTPError from urllib.error import HTTPError
from homeassistant.components import discovery
from homeassistant.const import ( from homeassistant.const import (
CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME) CONF_API_KEY, CONF_PASSWORD, CONF_USERNAME)
from homeassistant.helpers import validate_config from homeassistant.helpers import validate_config, discovery
REQUIREMENTS = [ REQUIREMENTS = [
'https://github.com/jabesq/netatmo-api-python/archive/' 'https://github.com/jabesq/netatmo-api-python/archive/'
@ -24,9 +23,6 @@ NETATMO_AUTH = None
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DISCOVER_SENSORS = 'netatmo.sensors'
DISCOVER_CAMERAS = 'netatmo.cameras'
def setup(hass, config): def setup(hass, config):
"""Setup the Netatmo devices.""" """Setup the Netatmo devices."""
@ -54,9 +50,7 @@ def setup(hass, config):
"Please check your settings for NatAtmo API.") "Please check your settings for NatAtmo API.")
return False return False
for component, discovery_service in ( for component in 'camera', 'sensor':
('camera', DISCOVER_CAMERAS), ('sensor', DISCOVER_SENSORS)): discovery.load_platform(hass, component, DOMAIN, None, config)
discovery.discover(hass, discovery_service, component=component,
hass_config=config)
return True return True

View file

@ -9,9 +9,8 @@ import logging
import time import time
import requests import requests
from homeassistant.components import discovery
from homeassistant.const import CONF_API_KEY, CONF_HOST from homeassistant.const import CONF_API_KEY, CONF_HOST
from homeassistant.helpers import validate_config from homeassistant.helpers import validate_config, discovery
DOMAIN = "octoprint" DOMAIN = "octoprint"
OCTOPRINT = None OCTOPRINT = None

View file

@ -29,9 +29,6 @@ ENTITY_ID_ALL_ROLLERSHUTTERS = group.ENTITY_ID_FORMAT.format(
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {}
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ATTR_CURRENT_POSITION = 'current_position' ATTR_CURRENT_POSITION = 'current_position'
@ -68,8 +65,7 @@ def stop(hass, entity_id=None):
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for roller shutters.""" """Track states and offer events for roller shutters."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_ROLLERSHUTTERS)
GROUP_NAME_ALL_ROLLERSHUTTERS)
component.setup(config) component.setup(config)
def handle_rollershutter_service(service): def handle_rollershutter_service(service):

View file

@ -8,35 +8,17 @@ import logging
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.components import (
wink, zwave, isy994, verisure, ecobee, tellduslive, mysensors,
bloomsky, vera, netatmo)
DOMAIN = 'sensor' DOMAIN = 'sensor'
SCAN_INTERVAL = 30 SCAN_INTERVAL = 30
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
bloomsky.DISCOVER_SENSORS: 'bloomsky',
wink.DISCOVER_SENSORS: 'wink',
zwave.DISCOVER_SENSORS: 'zwave',
isy994.DISCOVER_SENSORS: 'isy994',
verisure.DISCOVER_SENSORS: 'verisure',
ecobee.DISCOVER_SENSORS: 'ecobee',
tellduslive.DISCOVER_SENSORS: 'tellduslive',
mysensors.DISCOVER_SENSORS: 'mysensors',
vera.DISCOVER_SENSORS: 'vera',
netatmo.DISCOVER_SENSORS: 'netatmo',
}
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for sensors.""" """Track states and offer events for sensors."""
component = EntityComponent( component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)
DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)

View file

@ -18,9 +18,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE, STATE_ON, SERVICE_TURN_ON, SERVICE_TURN_OFF, SERVICE_TOGGLE,
ATTR_ENTITY_ID) ATTR_ENTITY_ID)
from homeassistant.components import ( from homeassistant.components import group
group, wemo, wink, isy994, verisure,
zwave, tellduslive, tellstick, mysensors, vera)
DOMAIN = 'switch' DOMAIN = 'switch'
SCAN_INTERVAL = 30 SCAN_INTERVAL = 30
@ -35,19 +33,6 @@ ATTR_CURRENT_POWER_MWH = "current_power_mwh"
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
# Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {
wemo.DISCOVER_SWITCHES: 'wemo',
wink.DISCOVER_SWITCHES: 'wink',
isy994.DISCOVER_SWITCHES: 'isy994',
verisure.DISCOVER_SWITCHES: 'verisure',
zwave.DISCOVER_SWITCHES: 'zwave',
tellduslive.DISCOVER_SWITCHES: 'tellduslive',
mysensors.DISCOVER_SWITCHES: 'mysensors',
tellstick.DISCOVER_SWITCHES: 'tellstick',
vera.DISCOVER_SWITCHES: 'vera',
}
PROP_TO_ATTR = { PROP_TO_ATTR = {
'current_power_mwh': ATTR_CURRENT_POWER_MWH, 'current_power_mwh': ATTR_CURRENT_POWER_MWH,
'today_power_mw': ATTR_TODAY_MWH, 'today_power_mw': ATTR_TODAY_MWH,
@ -87,8 +72,7 @@ def toggle(hass, entity_id=None):
def setup(hass, config): def setup(hass, config):
"""Track states and offer events for switches.""" """Track states and offer events for switches."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS, _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_SWITCHES)
GROUP_NAME_ALL_SWITCHES)
component.setup(config) component.setup(config)
def handle_switch_service(service): def handle_switch_service(service):

View file

@ -7,11 +7,7 @@ https://home-assistant.io/components/tellduslive/
import logging import logging
from datetime import timedelta from datetime import timedelta
from homeassistant import bootstrap from homeassistant.helpers import validate_config, discovery
from homeassistant.const import (
ATTR_DISCOVERED, ATTR_SERVICE, EVENT_PLATFORM_DISCOVERED)
from homeassistant.helpers import validate_config
from homeassistant.loader import get_component
from homeassistant.util import Throttle from homeassistant.util import Throttle
DOMAIN = "tellduslive" DOMAIN = "tellduslive"
@ -20,12 +16,6 @@ REQUIREMENTS = ['tellive-py==0.5.2']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DISCOVER_SENSORS = "tellduslive.sensors"
DISCOVER_SWITCHES = "tellduslive.switches"
DISCOVERY_TYPES = {"sensor": DISCOVER_SENSORS,
"switch": DISCOVER_SWITCHES}
CONF_PUBLIC_KEY = "public_key" CONF_PUBLIC_KEY = "public_key"
CONF_PRIVATE_KEY = "private_key" CONF_PRIVATE_KEY = "private_key"
CONF_TOKEN = "token" CONF_TOKEN = "token"
@ -101,16 +91,8 @@ class TelldusLiveData(object):
_LOGGER.info("discovered %d new %s devices", _LOGGER.info("discovered %d new %s devices",
len(found_devices), component_name) len(found_devices), component_name)
component = get_component(component_name) discovery.load_platform(self._hass, component_name, DOMAIN,
bootstrap.setup_component(self._hass, found_devices, self._config)
component.DOMAIN,
self._config)
discovery_type = DISCOVERY_TYPES[component_name]
self._hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery_type,
ATTR_DISCOVERED: found_devices})
def request(self, what, **params): def request(self, what, **params):
"""Send a request to the Tellstick Live API.""" """Send a request to the Tellstick Live API."""

View file

@ -8,11 +8,8 @@ import logging
import threading import threading
import voluptuous as vol import voluptuous as vol
from homeassistant import bootstrap from homeassistant.helpers import discovery
from homeassistant.const import ( from homeassistant.const import EVENT_HOMEASSISTANT_STOP
ATTR_DISCOVERED, ATTR_SERVICE,
EVENT_PLATFORM_DISCOVERED, EVENT_HOMEASSISTANT_STOP)
from homeassistant.loader import get_component
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
DOMAIN = "tellstick" DOMAIN = "tellstick"
@ -24,11 +21,6 @@ _LOGGER = logging.getLogger(__name__)
ATTR_SIGNAL_REPETITIONS = "signal_repetitions" ATTR_SIGNAL_REPETITIONS = "signal_repetitions"
DEFAULT_SIGNAL_REPETITIONS = 1 DEFAULT_SIGNAL_REPETITIONS = 1
DISCOVER_SWITCHES = "tellstick.switches"
DISCOVER_LIGHTS = "tellstick.lights"
DISCOVERY_TYPES = {"switch": DISCOVER_SWITCHES,
"light": DISCOVER_LIGHTS}
ATTR_DISCOVER_DEVICES = "devices" ATTR_DISCOVER_DEVICES = "devices"
ATTR_DISCOVER_CONFIG = "config" ATTR_DISCOVER_CONFIG = "config"
@ -57,17 +49,11 @@ def _discover(hass, config, found_devices, component_name):
_LOGGER.info("discovered %d new %s devices", _LOGGER.info("discovered %d new %s devices",
len(found_devices), component_name) len(found_devices), component_name)
component = get_component(component_name)
bootstrap.setup_component(hass, component.DOMAIN,
config)
signal_repetitions = config[DOMAIN].get(ATTR_SIGNAL_REPETITIONS) signal_repetitions = config[DOMAIN].get(ATTR_SIGNAL_REPETITIONS)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, discovery.load_platform(hass, component_name, DOMAIN, {
{ATTR_SERVICE: DISCOVERY_TYPES[component_name], ATTR_DISCOVER_DEVICES: found_devices,
ATTR_DISCOVERED: {ATTR_DISCOVER_DEVICES: found_devices, ATTR_DISCOVER_CONFIG: signal_repetitions}, config)
ATTR_DISCOVER_CONFIG:
signal_repetitions}})
def setup(hass, config): def setup(hass, config):

View file

@ -15,7 +15,6 @@ from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert from homeassistant.helpers.temperature import convert
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.components import (ecobee, zwave)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN, ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
@ -45,11 +44,6 @@ ATTR_OPERATION = "current_operation"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DISCOVERY_PLATFORMS = {
ecobee.DISCOVER_THERMOSTAT: 'ecobee',
zwave.DISCOVER_THERMOSTATS: 'zwave'
}
SET_AWAY_MODE_SCHEMA = vol.Schema({ SET_AWAY_MODE_SCHEMA = vol.Schema({
vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Optional(ATTR_ENTITY_ID): cv.entity_ids,
vol.Required(ATTR_AWAY_MODE): cv.boolean, vol.Required(ATTR_AWAY_MODE): cv.boolean,
@ -101,8 +95,7 @@ def set_fan_mode(hass, fan_mode, entity_id=None):
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
def setup(hass, config): def setup(hass, config):
"""Setup thermostats.""" """Setup thermostats."""
component = EntityComponent(_LOGGER, DOMAIN, hass, component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL)
SCAN_INTERVAL, DISCOVERY_PLATFORMS)
component.setup(config) component.setup(config)
descriptions = load_yaml_config_file( descriptions = load_yaml_config_file(

View file

@ -5,16 +5,13 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/vera/ https://home-assistant.io/components/vera/
""" """
import logging import logging
from collections import defaultdict from collections import defaultdict
from requests.exceptions import RequestException from requests.exceptions import RequestException
from homeassistant import bootstrap from homeassistant.helpers import discovery
from homeassistant.const import ( from homeassistant.const import EVENT_HOMEASSISTANT_STOP
ATTR_SERVICE, ATTR_DISCOVERED,
EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED)
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.loader import get_component
REQUIREMENTS = ['pyvera==0.2.10'] REQUIREMENTS = ['pyvera==0.2.10']
@ -27,28 +24,18 @@ VERA_CONTROLLER = None
CONF_EXCLUDE = 'exclude' CONF_EXCLUDE = 'exclude'
CONF_LIGHTS = 'lights' CONF_LIGHTS = 'lights'
BINARY_SENSOR = 'binary_sensor'
SENSOR = 'sensor'
LIGHT = 'light'
SWITCH = 'switch'
DEVICE_CATEGORIES = { DEVICE_CATEGORIES = {
'Sensor': BINARY_SENSOR, 'Sensor': 'binary_sensor',
'Temperature Sensor': SENSOR, 'Temperature Sensor': 'sensor',
'Light Sensor': SENSOR, 'Light Sensor': 'sensor',
'Humidity Sensor': SENSOR, 'Humidity Sensor': 'sensor',
'Dimmable Switch': LIGHT, 'Dimmable Switch': 'light',
'Switch': SWITCH, 'Switch': 'switch',
'Armable Sensor': SWITCH, 'Armable Sensor': 'switch',
'On/Off Switch': SWITCH, 'On/Off Switch': 'switch',
# 'Window Covering': NOT SUPPORTED YET # 'Window Covering': NOT SUPPORTED YET
} }
DISCOVER_BINARY_SENSORS = 'vera.binary_sensors'
DISCOVER_SENSORS = 'vera.sensors'
DISCOVER_LIGHTS = 'vera.lights'
DISCOVER_SWITCHES = 'vera.switchs'
VERA_DEVICES = defaultdict(list) VERA_DEVICES = defaultdict(list)
@ -100,19 +87,13 @@ def setup(hass, base_config):
dev_type = DEVICE_CATEGORIES.get(device.category) dev_type = DEVICE_CATEGORIES.get(device.category)
if dev_type is None: if dev_type is None:
continue continue
if dev_type == SWITCH and device.device_id in lights_ids: if dev_type == 'switch' and device.device_id in lights_ids:
dev_type = LIGHT dev_type = 'light'
VERA_DEVICES[dev_type].append(device) VERA_DEVICES[dev_type].append(device)
for comp_name, discovery in (((BINARY_SENSOR, DISCOVER_BINARY_SENSORS), for component in 'binary_sensor', 'sensor', 'light', 'switch':
(SENSOR, DISCOVER_SENSORS), discovery.load_platform(hass, component, DOMAIN, None, base_config)
(LIGHT, DISCOVER_LIGHTS),
(SWITCH, DISCOVER_SWITCHES))):
component = get_component(comp_name)
bootstrap.setup_component(hass, component.DOMAIN, base_config)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery,
ATTR_DISCOVERED: {}})
return True return True

View file

@ -9,19 +9,11 @@ import threading
import time import time
from datetime import timedelta from datetime import timedelta
from homeassistant import bootstrap from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import ( from homeassistant.helpers import validate_config, discovery
ATTR_DISCOVERED, ATTR_SERVICE, CONF_PASSWORD, CONF_USERNAME,
EVENT_PLATFORM_DISCOVERED)
from homeassistant.helpers import validate_config
from homeassistant.loader import get_component
from homeassistant.util import Throttle from homeassistant.util import Throttle
DOMAIN = "verisure" DOMAIN = "verisure"
DISCOVER_SENSORS = 'verisure.sensors'
DISCOVER_SWITCHES = 'verisure.switches'
DISCOVER_ALARMS = 'verisure.alarm_control_panel'
DISCOVER_LOCKS = 'verisure.lock'
REQUIREMENTS = ['vsure==0.8.1'] REQUIREMENTS = ['vsure==0.8.1']
@ -43,15 +35,8 @@ def setup(hass, config):
if not HUB.login(): if not HUB.login():
return False return False
for comp_name, discovery in ((('sensor', DISCOVER_SENSORS), for component in ('sensor', 'switch', 'alarm_control_panel', 'lock'):
('switch', DISCOVER_SWITCHES), discovery.load_platform(hass, component, DOMAIN, None, config)
('alarm_control_panel', DISCOVER_ALARMS),
('lock', DISCOVER_LOCKS))):
component = get_component(comp_name)
bootstrap.setup_component(hass, component.DOMAIN, config)
hass.bus.fire(EVENT_PLATFORM_DISCOVERED,
{ATTR_SERVICE: discovery,
ATTR_DISCOVERED: {}})
return True return True

View file

@ -6,29 +6,22 @@ https://home-assistant.io/components/wemo/
""" """
import logging import logging
from homeassistant.components import discovery from homeassistant.components.discovery import SERVICE_WEMO
from homeassistant.helpers import discovery
from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.const import EVENT_HOMEASSISTANT_STOP
REQUIREMENTS = ['pywemo==0.4.3'] REQUIREMENTS = ['pywemo==0.4.3']
DOMAIN = 'wemo' DOMAIN = 'wemo'
DISCOVER_LIGHTS = 'wemo.light'
DISCOVER_BINARY_SENSORS = 'wemo.binary_sensor'
DISCOVER_SWITCHES = 'wemo.switch'
# Mapping from Wemo model_name to service. # Mapping from Wemo model_name to component.
WEMO_MODEL_DISPATCH = { WEMO_MODEL_DISPATCH = {
'Bridge': DISCOVER_LIGHTS, 'Bridge': 'light',
'Insight': DISCOVER_SWITCHES, 'Insight': 'switch',
'Maker': DISCOVER_SWITCHES, 'Maker': 'switch',
'Sensor': DISCOVER_BINARY_SENSORS, 'Sensor': 'binary_sensor',
'Socket': DISCOVER_SWITCHES, 'Socket': 'switch',
'LightSwitch': DISCOVER_SWITCHES 'LightSwitch': 'switch'
}
WEMO_SERVICE_DISPATCH = {
DISCOVER_LIGHTS: 'light',
DISCOVER_BINARY_SENSORS: 'binary_sensor',
DISCOVER_SWITCHES: 'switch',
} }
SUBSCRIPTION_REGISTRY = None SUBSCRIPTION_REGISTRY = None
@ -64,13 +57,12 @@ def setup(hass, config):
_LOGGER.debug('Discovered unique device %s', serial) _LOGGER.debug('Discovered unique device %s', serial)
KNOWN_DEVICES.append(serial) KNOWN_DEVICES.append(serial)
service = WEMO_MODEL_DISPATCH.get(model_name) or DISCOVER_SWITCHES component = WEMO_MODEL_DISPATCH.get(model_name, 'switch')
component = WEMO_SERVICE_DISPATCH.get(service)
discovery.discover(hass, service, discovery_info, discovery.load_platform(hass, component, DOMAIN, discovery_info,
component, config) config)
discovery.listen(hass, discovery.SERVICE_WEMO, discovery_dispatch) discovery.listen(hass, SERVICE_WEMO, discovery_dispatch)
_LOGGER.info("Scanning for WeMo devices.") _LOGGER.info("Scanning for WeMo devices.")
devices = [(device.host, device) for device in pywemo.discover_devices()] devices = [(device.host, device) for device in pywemo.discover_devices()]
@ -92,5 +84,5 @@ def setup(hass, config):
discovery_info = (device.name, device.model_name, url, device.mac, discovery_info = (device.name, device.model_name, url, device.mac,
device.serialnumber) device.serialnumber)
discovery.discover(hass, discovery.SERVICE_WEMO, discovery_info) discovery.discover(hass, SERVICE_WEMO, discovery_info)
return True return True

View file

@ -6,24 +6,13 @@ https://home-assistant.io/components/wink/
""" """
import logging import logging
from homeassistant import bootstrap from homeassistant.const import CONF_ACCESS_TOKEN, ATTR_BATTERY_LEVEL
from homeassistant.const import ( from homeassistant.helpers import validate_config, discovery
ATTR_DISCOVERED, ATTR_SERVICE, CONF_ACCESS_TOKEN,
EVENT_PLATFORM_DISCOVERED, ATTR_BATTERY_LEVEL)
from homeassistant.helpers import validate_config
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.loader import get_component
DOMAIN = "wink" DOMAIN = "wink"
REQUIREMENTS = ['python-wink==0.7.6'] REQUIREMENTS = ['python-wink==0.7.6']
DISCOVER_LIGHTS = "wink.lights"
DISCOVER_SWITCHES = "wink.switches"
DISCOVER_SENSORS = "wink.sensors"
DISCOVER_BINARY_SENSORS = "wink.binary_sensors"
DISCOVER_LOCKS = "wink.locks"
DISCOVER_GARAGE_DOORS = "wink.garage_doors"
def setup(hass, config): def setup(hass, config):
"""Setup the Wink component.""" """Setup the Wink component."""
@ -36,28 +25,17 @@ def setup(hass, config):
pywink.set_bearer_token(config[DOMAIN][CONF_ACCESS_TOKEN]) pywink.set_bearer_token(config[DOMAIN][CONF_ACCESS_TOKEN])
# Load components for the devices in the Wink that we support # Load components for the devices in the Wink that we support
for component_name, func_exists, discovery_type in ( for component_name, func_exists in (
('light', pywink.get_bulbs, DISCOVER_LIGHTS), ('light', pywink.get_bulbs),
('switch', lambda: pywink.get_switches or ('switch', lambda: pywink.get_switches or pywink.get_sirens or
pywink.get_sirens or pywink.get_powerstrip_outlets),
pywink.get_powerstrip_outlets, DISCOVER_SWITCHES), ('binary_sensor', pywink.get_sensors),
('binary_sensor', pywink.get_sensors, DISCOVER_BINARY_SENSORS), ('sensor', lambda: pywink.get_sensors or pywink.get_eggtrays),
('sensor', lambda: pywink.get_sensors or ('lock', pywink.get_locks),
pywink.get_eggtrays, DISCOVER_SENSORS), ('garage_door', pywink.get_garage_doors)):
('lock', pywink.get_locks, DISCOVER_LOCKS),
('garage_door', pywink.get_garage_doors, DISCOVER_GARAGE_DOORS)):
if func_exists(): if func_exists():
component = get_component(component_name) discovery.load_platform(hass, component_name, DOMAIN, None, config)
# Ensure component is loaded
bootstrap.setup_component(hass, component.DOMAIN, config)
# Fire discovery event
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
ATTR_SERVICE: discovery_type,
ATTR_DISCOVERED: {}
})
return True return True

View file

@ -9,11 +9,11 @@ import os.path
import time import time
from pprint import pprint from pprint import pprint
from homeassistant import bootstrap from homeassistant.helpers import discovery
from homeassistant.const import ( from homeassistant.const import (
ATTR_BATTERY_LEVEL, ATTR_DISCOVERED, ATTR_ENTITY_ID, ATTR_LOCATION, ATTR_BATTERY_LEVEL, ATTR_ENTITY_ID, ATTR_LOCATION,
ATTR_SERVICE, CONF_CUSTOMIZE, EVENT_HOMEASSISTANT_START, CONF_CUSTOMIZE, EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED) EVENT_HOMEASSISTANT_STOP)
from homeassistant.helpers.event import track_time_change from homeassistant.helpers.event import track_time_change
from homeassistant.util import convert, slugify from homeassistant.util import convert, slugify
@ -37,14 +37,6 @@ SERVICE_HEAL_NETWORK = "heal_network"
SERVICE_SOFT_RESET = "soft_reset" SERVICE_SOFT_RESET = "soft_reset"
SERVICE_TEST_NETWORK = "test_network" SERVICE_TEST_NETWORK = "test_network"
DISCOVER_SENSORS = "zwave.sensors"
DISCOVER_SWITCHES = "zwave.switch"
DISCOVER_LIGHTS = "zwave.light"
DISCOVER_BINARY_SENSORS = 'zwave.binary_sensor'
DISCOVER_THERMOSTATS = 'zwave.thermostat'
DISCOVER_HVAC = 'zwave.hvac'
DISCOVER_LOCKS = 'zwave.lock'
EVENT_SCENE_ACTIVATED = "zwave.scene_activated" EVENT_SCENE_ACTIVATED = "zwave.scene_activated"
COMMAND_CLASS_SWITCH_MULTILEVEL = 38 COMMAND_CLASS_SWITCH_MULTILEVEL = 38
@ -71,39 +63,32 @@ TYPE_DECIMAL = "Decimal"
# value type). # value type).
DISCOVERY_COMPONENTS = [ DISCOVERY_COMPONENTS = [
('sensor', ('sensor',
DISCOVER_SENSORS,
[COMMAND_CLASS_SENSOR_MULTILEVEL, [COMMAND_CLASS_SENSOR_MULTILEVEL,
COMMAND_CLASS_METER, COMMAND_CLASS_METER,
COMMAND_CLASS_ALARM], COMMAND_CLASS_ALARM],
TYPE_WHATEVER, TYPE_WHATEVER,
GENRE_USER), GENRE_USER),
('light', ('light',
DISCOVER_LIGHTS,
[COMMAND_CLASS_SWITCH_MULTILEVEL], [COMMAND_CLASS_SWITCH_MULTILEVEL],
TYPE_BYTE, TYPE_BYTE,
GENRE_USER), GENRE_USER),
('switch', ('switch',
DISCOVER_SWITCHES,
[COMMAND_CLASS_SWITCH_BINARY], [COMMAND_CLASS_SWITCH_BINARY],
TYPE_BOOL, TYPE_BOOL,
GENRE_USER), GENRE_USER),
('binary_sensor', ('binary_sensor',
DISCOVER_BINARY_SENSORS,
[COMMAND_CLASS_SENSOR_BINARY], [COMMAND_CLASS_SENSOR_BINARY],
TYPE_BOOL, TYPE_BOOL,
GENRE_USER), GENRE_USER),
('thermostat', ('thermostat',
DISCOVER_THERMOSTATS,
[COMMAND_CLASS_THERMOSTAT_SETPOINT], [COMMAND_CLASS_THERMOSTAT_SETPOINT],
TYPE_WHATEVER, TYPE_WHATEVER,
GENRE_WHATEVER), GENRE_WHATEVER),
('hvac', ('hvac',
DISCOVER_HVAC,
[COMMAND_CLASS_THERMOSTAT_FAN_MODE], [COMMAND_CLASS_THERMOSTAT_FAN_MODE],
TYPE_WHATEVER, TYPE_WHATEVER,
GENRE_WHATEVER), GENRE_WHATEVER),
('lock', ('lock',
DISCOVER_LOCKS,
[COMMAND_CLASS_DOOR_LOCK], [COMMAND_CLASS_DOOR_LOCK],
TYPE_BOOL, TYPE_BOOL,
GENRE_USER), GENRE_USER),
@ -235,7 +220,6 @@ def setup(hass, config):
def value_added(node, value): def value_added(node, value):
"""Called when a value is added to a node on the network.""" """Called when a value is added to a node on the network."""
for (component, for (component,
discovery_service,
command_ids, command_ids,
value_type, value_type,
value_genre) in DISCOVERY_COMPONENTS: value_genre) in DISCOVERY_COMPONENTS:
@ -247,9 +231,6 @@ def setup(hass, config):
if value_genre is not None and value_genre != value.genre: if value_genre is not None and value_genre != value.genre:
continue continue
# Ensure component is loaded
bootstrap.setup_component(hass, component, config)
# Configure node # Configure node
name = "{}.{}".format(component, _object_id(value)) name = "{}.{}".format(component, _object_id(value))
@ -261,14 +242,10 @@ def setup(hass, config):
else: else:
value.disable_poll() value.disable_poll()
# Fire discovery event discovery.load_platform(hass, component, DOMAIN, {
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
ATTR_SERVICE: discovery_service,
ATTR_DISCOVERED: {
ATTR_NODE_ID: node.node_id, ATTR_NODE_ID: node.node_id,
ATTR_VALUE_ID: value.value_id, ATTR_VALUE_ID: value.value_id,
} }, config)
})
def scene_activated(node, scene_id): def scene_activated(node, scene_id):
"""Called when a scene is activated on any node in the network.""" """Called when a scene is activated on any node in the network."""

View file

@ -0,0 +1,86 @@
"""Helper methods to help with platform discovery."""
from homeassistant import bootstrap
from homeassistant.const import (
ATTR_DISCOVERED, ATTR_SERVICE, EVENT_PLATFORM_DISCOVERED)
EVENT_LOAD_PLATFORM = 'load_platform.{}'
ATTR_PLATFORM = 'platform'
def listen(hass, service, callback):
"""Setup listener for discovery of specific service.
Service can be a string or a list/tuple.
"""
if isinstance(service, str):
service = (service,)
else:
service = tuple(service)
def discovery_event_listener(event):
"""Listen for discovery events."""
if ATTR_SERVICE in event.data and event.data[ATTR_SERVICE] in service:
callback(event.data[ATTR_SERVICE], event.data.get(ATTR_DISCOVERED))
hass.bus.listen(EVENT_PLATFORM_DISCOVERED, discovery_event_listener)
def discover(hass, service, discovered=None, component=None, hass_config=None):
"""Fire discovery event. Can ensure a component is loaded."""
if component is not None:
bootstrap.setup_component(hass, component, hass_config)
data = {
ATTR_SERVICE: service
}
if discovered is not None:
data[ATTR_DISCOVERED] = discovered
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, data)
def listen_platform(hass, component, callback):
"""Register a platform loader listener."""
service = EVENT_LOAD_PLATFORM.format(component)
def discovery_platform_listener(event):
"""Listen for platform discovery events."""
if event.data.get(ATTR_SERVICE) != service:
return
platform = event.data.get(ATTR_PLATFORM)
if not platform:
return
callback(platform, event.data.get(ATTR_DISCOVERED))
hass.bus.listen(EVENT_PLATFORM_DISCOVERED, discovery_platform_listener)
def load_platform(hass, component, platform, discovered=None,
hass_config=None):
"""Load a component and platform dynamically.
Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be
fired to load the platform. The event will contain:
{ ATTR_SERVICE = LOAD_PLATFORM + '.' + <<component>>
ATTR_PLATFORM = <<platform>>
ATTR_DISCOVERED = <<discovery info>> }
Use `listen_platform` to register a callback for these events.
"""
if component is not None:
bootstrap.setup_component(hass, component, hass_config)
data = {
ATTR_SERVICE: EVENT_LOAD_PLATFORM.format(component),
ATTR_PLATFORM: platform,
}
if discovered is not None:
data[ATTR_DISCOVERED] = discovered
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, data)

View file

@ -2,11 +2,11 @@
from threading import Lock from threading import Lock
from homeassistant.bootstrap import prepare_setup_platform from homeassistant.bootstrap import prepare_setup_platform
from homeassistant.components import discovery, group from homeassistant.components import group
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, CONF_SCAN_INTERVAL, CONF_ENTITY_NAMESPACE, ATTR_ENTITY_ID, CONF_SCAN_INTERVAL, CONF_ENTITY_NAMESPACE,
DEVICE_DEFAULT_NAME) DEVICE_DEFAULT_NAME)
from homeassistant.helpers import config_per_platform from homeassistant.helpers import config_per_platform, discovery
from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers.event import track_utc_time_change from homeassistant.helpers.event import track_utc_time_change
from homeassistant.helpers.service import extract_entity_ids from homeassistant.helpers.service import extract_entity_ids
@ -20,8 +20,7 @@ class EntityComponent(object):
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
def __init__(self, logger, domain, hass, def __init__(self, logger, domain, hass,
scan_interval=DEFAULT_SCAN_INTERVAL, scan_interval=DEFAULT_SCAN_INTERVAL, group_name=None):
discovery_platforms=None, group_name=None):
"""Initialize an entity component.""" """Initialize an entity component."""
self.logger = logger self.logger = logger
self.hass = hass self.hass = hass
@ -29,7 +28,6 @@ class EntityComponent(object):
self.domain = domain self.domain = domain
self.entity_id_format = domain + '.{}' self.entity_id_format = domain + '.{}'
self.scan_interval = scan_interval self.scan_interval = scan_interval
self.discovery_platforms = discovery_platforms
self.group_name = group_name self.group_name = group_name
self.entities = {} self.entities = {}
@ -54,23 +52,14 @@ class EntityComponent(object):
for p_type, p_config in config_per_platform(config, self.domain): for p_type, p_config in config_per_platform(config, self.domain):
self._setup_platform(p_type, p_config) self._setup_platform(p_type, p_config)
if self.discovery_platforms:
# Discovery listener for all items in discovery_platforms array
# passed from a component's setup method (e.g. light/__init__.py)
discovery.listen(
self.hass, self.discovery_platforms.keys(),
lambda service, info:
self._setup_platform(self.discovery_platforms[service], {},
info))
# Generic discovery listener for loading platform dynamically # Generic discovery listener for loading platform dynamically
# Refer to: homeassistant.components.discovery.load_platform() # Refer to: homeassistant.components.discovery.load_platform()
def load_platform_callback(service, info): def component_platform_discovered(platform, info):
"""Callback to load a platform.""" """Callback to load a platform."""
platform = info.pop(discovery.LOAD_PLATFORM) self._setup_platform(platform, {}, info)
self._setup_platform(platform, {}, info if info else None)
discovery.listen(self.hass, discovery.LOAD_PLATFORM + '.' + discovery.listen_platform(self.hass, self.domain,
self.domain, load_platform_callback) component_platform_discovered)
def extract_from_service(self, service): def extract_from_service(self, service):
"""Extract all known entities from a service call. """Extract all known entities from a service call.

View file

@ -0,0 +1,90 @@
"""Test discovery helpers."""
from unittest.mock import patch
from homeassistant.helpers import discovery
from tests.common import get_test_home_assistant
class TestHelpersDiscovery:
"""Tests for discovery helper methods."""
def setup_method(self, method):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
def teardown_method(self, method):
"""Stop everything that was started."""
self.hass.stop()
@patch('homeassistant.bootstrap.setup_component')
def test_listen(self, mock_setup_component):
"""Test discovery listen/discover combo."""
calls_single = []
calls_multi = []
def callback_single(service, info):
"""Service discovered callback."""
calls_single.append((service, info))
def callback_multi(service, info):
"""Service discovered callback."""
calls_multi.append((service, info))
discovery.listen(self.hass, 'test service', callback_single)
discovery.listen(self.hass, ['test service', 'another service'],
callback_multi)
discovery.discover(self.hass, 'test service', 'discovery info',
'test_component')
self.hass.pool.block_till_done()
discovery.discover(self.hass, 'another service', 'discovery info',
'test_component')
self.hass.pool.block_till_done()
assert mock_setup_component.called
assert mock_setup_component.call_args[0] == \
(self.hass, 'test_component', None)
assert len(calls_single) == 1
assert calls_single[0] == ('test service', 'discovery info')
assert len(calls_single) == 1
assert len(calls_multi) == 2
assert ['test service', 'another service'] == [info[0] for info
in calls_multi]
@patch('homeassistant.bootstrap.setup_component')
def test_platform(self, mock_setup_component):
"""Test discover platform method."""
calls = []
def platform_callback(platform, info):
"""Platform callback method."""
calls.append((platform, info))
discovery.listen_platform(self.hass, 'test_component',
platform_callback)
discovery.load_platform(self.hass, 'test_component', 'test_platform',
'discovery info')
assert mock_setup_component.called
assert mock_setup_component.call_args[0] == \
(self.hass, 'test_component', None)
self.hass.pool.block_till_done()
discovery.load_platform(self.hass, 'test_component_2', 'test_platform',
'discovery info')
self.hass.pool.block_till_done()
assert len(calls) == 1
assert calls[0] == ('test_platform', 'discovery info')
self.hass.bus.fire(discovery.EVENT_PLATFORM_DISCOVERED, {
discovery.ATTR_SERVICE:
discovery.EVENT_LOAD_PLATFORM.format('test_component')
})
self.hass.pool.block_till_done()
assert len(calls) == 1

View file

@ -9,7 +9,7 @@ import homeassistant.core as ha
import homeassistant.loader as loader import homeassistant.loader as loader
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.components import discovery from homeassistant.helpers import discovery
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import ( from tests.common import (
@ -228,22 +228,17 @@ class TestHelpersEntityComponent(unittest.TestCase):
'._setup_platform') '._setup_platform')
def test_setup_does_discovery(self, mock_setup): def test_setup_does_discovery(self, mock_setup):
"""Test setup for discovery.""" """Test setup for discovery."""
component = EntityComponent( component = EntityComponent(_LOGGER, DOMAIN, self.hass)
_LOGGER, DOMAIN, self.hass, discovery_platforms={
'discovery.test': 'platform_test',
})
component.setup({}) component.setup({})
self.hass.bus.fire(discovery.EVENT_PLATFORM_DISCOVERED, { discovery.load_platform(self.hass, DOMAIN, 'platform_test',
discovery.ATTR_SERVICE: 'discovery.test', {'msg': 'discovery_info'})
discovery.ATTR_DISCOVERED: 'discovery_info',
})
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
assert mock_setup.called assert mock_setup.called
assert ('platform_test', {}, 'discovery_info') == \ assert ('platform_test', {}, {'msg': 'discovery_info'}) == \
mock_setup.call_args[0] mock_setup.call_args[0]
@patch('homeassistant.helpers.entity_component.track_utc_time_change') @patch('homeassistant.helpers.entity_component.track_utc_time_change')