2015-01-09 08:07:58 +00:00
|
|
|
"""
|
2015-05-13 17:18:30 +00:00
|
|
|
homeassistant.components.discovery
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2015-01-09 08:07:58 +00:00
|
|
|
Starts a service to scan in intervals for new devices.
|
|
|
|
|
2015-01-12 16:21:50 +00:00
|
|
|
Will emit EVENT_PLATFORM_DISCOVERED whenever a new service has been discovered.
|
2015-01-09 08:07:58 +00:00
|
|
|
|
|
|
|
Knows which components handle certain types, will make sure they are
|
2015-01-12 16:21:50 +00:00
|
|
|
loaded before the EVENT_PLATFORM_DISCOVERED is fired.
|
2015-01-09 08:07:58 +00:00
|
|
|
"""
|
|
|
|
import logging
|
|
|
|
import threading
|
|
|
|
|
|
|
|
from homeassistant import bootstrap
|
2015-01-11 07:47:23 +00:00
|
|
|
from homeassistant.const import (
|
2015-01-12 16:21:50 +00:00
|
|
|
EVENT_HOMEASSISTANT_START, EVENT_PLATFORM_DISCOVERED,
|
2015-01-11 07:47:23 +00:00
|
|
|
ATTR_SERVICE, ATTR_DISCOVERED)
|
2015-01-09 08:07:58 +00:00
|
|
|
|
|
|
|
DOMAIN = "discovery"
|
2015-11-28 09:36:42 +00:00
|
|
|
REQUIREMENTS = ['netdisco==0.5.2']
|
2015-01-09 08:07:58 +00:00
|
|
|
|
|
|
|
SCAN_INTERVAL = 300 # seconds
|
|
|
|
|
2015-07-20 07:07:01 +00:00
|
|
|
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'
|
2015-10-20 16:59:22 +00:00
|
|
|
SERVICE_PLEX = 'plex_mediaserver'
|
2015-07-20 07:07:01 +00:00
|
|
|
|
2015-01-09 08:07:58 +00:00
|
|
|
SERVICE_HANDLERS = {
|
2015-07-20 07:07:01 +00:00
|
|
|
SERVICE_WEMO: "switch",
|
|
|
|
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',
|
2015-01-09 08:07:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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):
|
2015-01-09 08:07:58 +00:00
|
|
|
service = (service,)
|
2015-01-11 22:21:44 +00:00
|
|
|
else:
|
|
|
|
service = tuple(service)
|
2015-01-09 08:07:58 +00:00
|
|
|
|
|
|
|
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])
|
|
|
|
|
2015-01-12 16:21:50 +00:00
|
|
|
hass.bus.listen(EVENT_PLATFORM_DISCOVERED, discovery_event_listener)
|
2015-01-09 08:07:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setup(hass, config):
|
|
|
|
""" Starts a discovery service. """
|
2015-03-01 05:06:59 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2015-07-20 07:07:01 +00:00
|
|
|
from netdisco.service import DiscoveryService
|
2015-01-09 08:07:58 +00:00
|
|
|
|
|
|
|
# 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:
|
2015-03-22 05:02:47 +00:00
|
|
|
logger.info("Found new service: %s %s", service, info)
|
|
|
|
|
2015-01-09 08:07:58 +00:00
|
|
|
component = SERVICE_HANDLERS.get(service)
|
|
|
|
|
2015-03-22 05:02:47 +00:00
|
|
|
# We do not know how to handle this service
|
|
|
|
if not component:
|
|
|
|
return
|
2015-01-09 08:07:58 +00:00
|
|
|
|
2015-03-22 05:02:47 +00:00
|
|
|
# This component cannot be setup.
|
|
|
|
if not bootstrap.setup_component(hass, component, config):
|
|
|
|
return
|
2015-01-09 08:07:58 +00:00
|
|
|
|
2015-01-12 16:21:50 +00:00
|
|
|
hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
|
2015-01-09 08:07:58 +00:00
|
|
|
ATTR_SERVICE: service,
|
|
|
|
ATTR_DISCOVERED: info
|
|
|
|
})
|
|
|
|
|
2015-10-25 17:00:54 +00:00
|
|
|
# pylint: disable=unused-argument
|
2015-01-09 08:07:58 +00:00
|
|
|
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
|