core/homeassistant/components/discovery.py

99 lines
2.7 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
# pylint: disable=no-name-in-module, import-error
import homeassistant.external.netdisco.netdisco.const as services
from homeassistant import bootstrap
from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_PLATFORM_DISCOVERED,
ATTR_SERVICE, ATTR_DISCOVERED)
DOMAIN = "discovery"
DEPENDENCIES = []
SCAN_INTERVAL = 300 # seconds
SERVICE_HANDLERS = {
services.BELKIN_WEMO: "switch",
services.GOOGLE_CAST: "media_player",
services.PHILIPS_HUE: "light",
}
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):
""" Listens for discovery events. """
if event.data[ATTR_SERVICE] in service:
callback(event.data[ATTR_SERVICE], event.data[ATTR_DISCOVERED])
hass.bus.listen(EVENT_PLATFORM_DISCOVERED, discovery_event_listener)
def setup(hass, config):
""" Starts a discovery service. """
logger = logging.getLogger(__name__)
try:
2015-03-01 09:39:12 +00:00
from homeassistant.external.netdisco.netdisco.service import \
DiscoveryService
except ImportError:
logger.exception(
"Unable to import netdisco. "
"Did you install all the zeroconf dependency?")
return False
# 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
})
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