core/homeassistant/components/discovery.py

116 lines
3.1 KiB
Python
Raw Normal View History

"""
Starts a service to scan in intervals for new devices.
Will emit EVENT_PLATFORM_DISCOVERED whenever a new service has been discovered.
Knows which components handle certain types, will make sure they are
loaded before the EVENT_PLATFORM_DISCOVERED is fired.
"""
import logging
import threading
from homeassistant import bootstrap
from homeassistant.const import (
2016-02-19 05:27:50 +00:00
ATTR_DISCOVERED, ATTR_SERVICE, EVENT_HOMEASSISTANT_START,
EVENT_PLATFORM_DISCOVERED)
DOMAIN = "discovery"
2016-03-02 04:25:18 +00:00
REQUIREMENTS = ['netdisco==0.5.4']
SCAN_INTERVAL = 300 # seconds
SERVICE_WEMO = 'belkin_wemo'
SERVICE_HUE = 'philips_hue'
SERVICE_CAST = 'google_cast'
2015-08-24 00:20:09 +00:00
SERVICE_NETGEAR = 'netgear_router'
2015-09-13 14:48:50 +00:00
SERVICE_SONOS = 'sonos'
SERVICE_PLEX = 'plex_mediaserver'
SERVICE_HANDLERS = {
SERVICE_WEMO: "wemo",
SERVICE_CAST: "media_player",
SERVICE_HUE: "light",
2015-08-24 00:20:09 +00:00
SERVICE_NETGEAR: 'device_tracker',
2015-09-13 14:48:50 +00:00
SERVICE_SONOS: 'media_player',
2015-10-18 20:02:18 +00:00
SERVICE_PLEX: 'media_player',
}
def listen(hass, service, callback):
"""Setup listener for discovery of specific service.
Service can be a string or a list/tuple.
"""
2015-01-11 22:21:44 +00:00
if isinstance(service, str):
service = (service,)
2015-01-11 22:21:44 +00:00
else:
service = tuple(service)
def discovery_event_listener(event):
"""Listen for discovery events."""
if 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 setup(hass, config):
""" Starts a discovery service. """
logger = logging.getLogger(__name__)
from netdisco.service import DiscoveryService
# Disable zeroconf logging, it spams
logging.getLogger('zeroconf').setLevel(logging.CRITICAL)
lock = threading.Lock()
def new_service_listener(service, info):
""" Called when a new service is found. """
with lock:
logger.info("Found new service: %s %s", service, info)
component = SERVICE_HANDLERS.get(service)
# We do not know how to handle this service
if not component:
return
# This component cannot be setup.
if not bootstrap.setup_component(hass, component, config):
return
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
ATTR_SERVICE: service,
ATTR_DISCOVERED: info
})
2015-10-25 17:00:54 +00:00
# pylint: disable=unused-argument
def start_discovery(event):
""" Start discovering. """
netdisco = DiscoveryService(SCAN_INTERVAL)
netdisco.add_listener(new_service_listener)
netdisco.start()
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_discovery)
return True