Migrate to generic discovery method (#2271)
* Migrate to generic discovery method * Add tests for discovery
This commit is contained in:
parent
c9756c40e2
commit
30f74bb3ca
32 changed files with 322 additions and 540 deletions
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
86
homeassistant/helpers/discovery.py
Normal file
86
homeassistant/helpers/discovery.py
Normal 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)
|
|
@ -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.
|
||||||
|
|
90
tests/helpers/test_discovery.py
Normal file
90
tests/helpers/test_discovery.py
Normal 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
|
|
@ -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')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue