134 lines
4.2 KiB
Python
134 lines
4.2 KiB
Python
"""
|
|
This component provides basic support for the Philips Hue system.
|
|
|
|
For more details about this component, please refer to the documentation at
|
|
https://home-assistant.io/components/hue/
|
|
"""
|
|
import ipaddress
|
|
import logging
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.const import CONF_FILENAME, CONF_HOST
|
|
from homeassistant.helpers import aiohttp_client, config_validation as cv
|
|
|
|
from .const import DOMAIN, API_NUPNP
|
|
from .bridge import HueBridge
|
|
# Loading the config flow file will register the flow
|
|
from .config_flow import configured_hosts
|
|
|
|
REQUIREMENTS = ['aiohue==1.3.0']
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
CONF_BRIDGES = "bridges"
|
|
|
|
CONF_ALLOW_UNREACHABLE = 'allow_unreachable'
|
|
DEFAULT_ALLOW_UNREACHABLE = False
|
|
|
|
PHUE_CONFIG_FILE = 'phue.conf'
|
|
|
|
CONF_ALLOW_HUE_GROUPS = "allow_hue_groups"
|
|
DEFAULT_ALLOW_HUE_GROUPS = True
|
|
|
|
BRIDGE_CONFIG_SCHEMA = vol.Schema({
|
|
# Validate as IP address and then convert back to a string.
|
|
vol.Required(CONF_HOST): vol.All(ipaddress.ip_address, cv.string),
|
|
# This is for legacy reasons and is only used for importing auth.
|
|
vol.Optional(CONF_FILENAME, default=PHUE_CONFIG_FILE): cv.string,
|
|
vol.Optional(CONF_ALLOW_UNREACHABLE,
|
|
default=DEFAULT_ALLOW_UNREACHABLE): cv.boolean,
|
|
vol.Optional(CONF_ALLOW_HUE_GROUPS,
|
|
default=DEFAULT_ALLOW_HUE_GROUPS): cv.boolean,
|
|
})
|
|
|
|
CONFIG_SCHEMA = vol.Schema({
|
|
DOMAIN: vol.Schema({
|
|
vol.Optional(CONF_BRIDGES):
|
|
vol.All(cv.ensure_list, [BRIDGE_CONFIG_SCHEMA]),
|
|
}),
|
|
}, extra=vol.ALLOW_EXTRA)
|
|
|
|
|
|
async def async_setup(hass, config):
|
|
"""Set up the Hue platform."""
|
|
conf = config.get(DOMAIN)
|
|
if conf is None:
|
|
conf = {}
|
|
|
|
hass.data[DOMAIN] = {}
|
|
configured = configured_hosts(hass)
|
|
|
|
# User has configured bridges
|
|
if CONF_BRIDGES in conf:
|
|
bridges = conf[CONF_BRIDGES]
|
|
|
|
# Component is part of config but no bridges specified, discover.
|
|
elif DOMAIN in config:
|
|
# discover from nupnp
|
|
websession = aiohttp_client.async_get_clientsession(hass)
|
|
|
|
async with websession.get(API_NUPNP) as req:
|
|
hosts = await req.json()
|
|
|
|
bridges = []
|
|
for entry in hosts:
|
|
# Filter out already configured hosts
|
|
if entry['internalipaddress'] in configured:
|
|
continue
|
|
|
|
# Run through config schema to populate defaults
|
|
bridges.append(BRIDGE_CONFIG_SCHEMA({
|
|
CONF_HOST: entry['internalipaddress'],
|
|
# Careful with using entry['id'] for other reasons. The
|
|
# value is in lowercase but is returned uppercase from hub.
|
|
CONF_FILENAME: '.hue_{}.conf'.format(entry['id']),
|
|
}))
|
|
else:
|
|
# Component not specified in config, we're loaded via discovery
|
|
bridges = []
|
|
|
|
if not bridges:
|
|
return True
|
|
|
|
for bridge_conf in bridges:
|
|
host = bridge_conf[CONF_HOST]
|
|
|
|
# Store config in hass.data so the config entry can find it
|
|
hass.data[DOMAIN][host] = bridge_conf
|
|
|
|
# If configured, the bridge will be set up during config entry phase
|
|
if host in configured:
|
|
continue
|
|
|
|
# No existing config entry found, try importing it or trigger link
|
|
# config flow if no existing auth. Because we're inside the setup of
|
|
# this component we'll have to use hass.async_add_job to avoid a
|
|
# deadlock: creating a config entry will set up the component but the
|
|
# setup would block till the entry is created!
|
|
hass.async_add_job(hass.config_entries.flow.async_init(
|
|
DOMAIN, source='import', data={
|
|
'host': bridge_conf[CONF_HOST],
|
|
'path': bridge_conf[CONF_FILENAME],
|
|
}
|
|
))
|
|
|
|
return True
|
|
|
|
|
|
async def async_setup_entry(hass, entry):
|
|
"""Set up a bridge from a config entry."""
|
|
host = entry.data['host']
|
|
config = hass.data[DOMAIN].get(host)
|
|
|
|
if config is None:
|
|
allow_unreachable = DEFAULT_ALLOW_UNREACHABLE
|
|
allow_groups = DEFAULT_ALLOW_HUE_GROUPS
|
|
else:
|
|
allow_unreachable = config[CONF_ALLOW_UNREACHABLE]
|
|
allow_groups = config[CONF_ALLOW_HUE_GROUPS]
|
|
|
|
bridge = HueBridge(hass, entry, allow_unreachable, allow_groups)
|
|
hass.data[DOMAIN][host] = bridge
|
|
return await bridge.async_setup()
|