Black
This commit is contained in:
parent
da05dfe708
commit
4de97abc3a
2676 changed files with 163166 additions and 140084 deletions
|
@ -15,14 +15,15 @@ from .bridge import get_bridge
|
|||
from .const import DOMAIN, LOGGER
|
||||
from .errors import AuthenticationRequired, CannotConnect
|
||||
|
||||
HUE_MANUFACTURERURL = 'http://www.philips.com'
|
||||
HUE_MANUFACTURERURL = "http://www.philips.com"
|
||||
|
||||
|
||||
@callback
|
||||
def configured_hosts(hass):
|
||||
"""Return a set of the configured hosts."""
|
||||
return set(entry.data['host'] for entry
|
||||
in hass.config_entries.async_entries(DOMAIN))
|
||||
return set(
|
||||
entry.data["host"] for entry in hass.config_entries.async_entries(DOMAIN)
|
||||
)
|
||||
|
||||
|
||||
def _find_username_from_config(hass, filename):
|
||||
|
@ -37,7 +38,7 @@ def _find_username_from_config(hass, filename):
|
|||
|
||||
with open(path) as inp:
|
||||
try:
|
||||
return list(json.load(inp).values())[0]['username']
|
||||
return list(json.load(inp).values())[0]["username"]
|
||||
except ValueError:
|
||||
# If we get invalid JSON
|
||||
return None
|
||||
|
@ -61,7 +62,7 @@ class HueFlowHandler(config_entries.ConfigFlow):
|
|||
async def async_step_init(self, user_input=None):
|
||||
"""Handle a flow start."""
|
||||
if user_input is not None:
|
||||
self.host = user_input['host']
|
||||
self.host = user_input["host"]
|
||||
return await self.async_step_link()
|
||||
|
||||
websession = aiohttp_client.async_get_clientsession(self.hass)
|
||||
|
@ -70,35 +71,26 @@ class HueFlowHandler(config_entries.ConfigFlow):
|
|||
with async_timeout.timeout(5):
|
||||
bridges = await discover_nupnp(websession=websession)
|
||||
except asyncio.TimeoutError:
|
||||
return self.async_abort(
|
||||
reason='discover_timeout'
|
||||
)
|
||||
return self.async_abort(reason="discover_timeout")
|
||||
|
||||
if not bridges:
|
||||
return self.async_abort(
|
||||
reason='no_bridges'
|
||||
)
|
||||
return self.async_abort(reason="no_bridges")
|
||||
|
||||
# Find already configured hosts
|
||||
configured = configured_hosts(self.hass)
|
||||
|
||||
hosts = [bridge.host for bridge in bridges
|
||||
if bridge.host not in configured]
|
||||
hosts = [bridge.host for bridge in bridges if bridge.host not in configured]
|
||||
|
||||
if not hosts:
|
||||
return self.async_abort(
|
||||
reason='all_configured'
|
||||
)
|
||||
return self.async_abort(reason="all_configured")
|
||||
|
||||
if len(hosts) == 1:
|
||||
self.host = hosts[0]
|
||||
return await self.async_step_link()
|
||||
|
||||
return self.async_show_form(
|
||||
step_id='init',
|
||||
data_schema=vol.Schema({
|
||||
vol.Required('host'): vol.In(hosts)
|
||||
})
|
||||
step_id="init",
|
||||
data_schema=vol.Schema({vol.Required("host"): vol.In(hosts)}),
|
||||
)
|
||||
|
||||
async def async_step_link(self, user_input=None):
|
||||
|
@ -112,32 +104,27 @@ class HueFlowHandler(config_entries.ConfigFlow):
|
|||
# We will always try linking in case the user has already pressed
|
||||
# the link button.
|
||||
try:
|
||||
bridge = await get_bridge(
|
||||
self.hass, self.host, username=None
|
||||
)
|
||||
bridge = await get_bridge(self.hass, self.host, username=None)
|
||||
|
||||
return await self._entry_from_bridge(bridge)
|
||||
except AuthenticationRequired:
|
||||
errors['base'] = 'register_failed'
|
||||
errors["base"] = "register_failed"
|
||||
|
||||
except CannotConnect:
|
||||
LOGGER.error("Error connecting to the Hue bridge at %s", self.host)
|
||||
errors['base'] = 'linking'
|
||||
errors["base"] = "linking"
|
||||
|
||||
except Exception: # pylint: disable=broad-except
|
||||
LOGGER.exception(
|
||||
'Unknown error connecting with Hue bridge at %s',
|
||||
self.host)
|
||||
errors['base'] = 'linking'
|
||||
"Unknown error connecting with Hue bridge at %s", self.host
|
||||
)
|
||||
errors["base"] = "linking"
|
||||
|
||||
# If there was no user input, do not show the errors.
|
||||
if user_input is None:
|
||||
errors = {}
|
||||
|
||||
return self.async_show_form(
|
||||
step_id='link',
|
||||
errors=errors,
|
||||
)
|
||||
return self.async_show_form(step_id="link", errors=errors)
|
||||
|
||||
async def async_step_ssdp(self, discovery_info):
|
||||
"""Handle a discovered Hue bridge.
|
||||
|
@ -148,49 +135,47 @@ class HueFlowHandler(config_entries.ConfigFlow):
|
|||
from homeassistant.components.ssdp import ATTR_MANUFACTURERURL
|
||||
|
||||
if discovery_info[ATTR_MANUFACTURERURL] != HUE_MANUFACTURERURL:
|
||||
return self.async_abort(reason='not_hue_bridge')
|
||||
return self.async_abort(reason="not_hue_bridge")
|
||||
|
||||
# Filter out emulated Hue
|
||||
if "HASS Bridge" in discovery_info.get('name', ''):
|
||||
return self.async_abort(reason='already_configured')
|
||||
if "HASS Bridge" in discovery_info.get("name", ""):
|
||||
return self.async_abort(reason="already_configured")
|
||||
|
||||
# pylint: disable=unsupported-assignment-operation
|
||||
host = self.context['host'] = discovery_info.get('host')
|
||||
host = self.context["host"] = discovery_info.get("host")
|
||||
|
||||
if any(host == flow['context']['host']
|
||||
for flow in self._async_in_progress()):
|
||||
return self.async_abort(reason='already_in_progress')
|
||||
if any(host == flow["context"]["host"] for flow in self._async_in_progress()):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
|
||||
if host in configured_hosts(self.hass):
|
||||
return self.async_abort(reason='already_configured')
|
||||
return self.async_abort(reason="already_configured")
|
||||
|
||||
# This value is based off host/description.xml and is, weirdly, missing
|
||||
# 4 characters in the middle of the serial compared to results returned
|
||||
# from the NUPNP API or when querying the bridge API for bridgeid.
|
||||
# (on first gen Hue hub)
|
||||
serial = discovery_info.get('serial')
|
||||
serial = discovery_info.get("serial")
|
||||
|
||||
return await self.async_step_import({
|
||||
'host': host,
|
||||
# This format is the legacy format that Hue used for discovery
|
||||
'path': 'phue-{}.conf'.format(serial)
|
||||
})
|
||||
return await self.async_step_import(
|
||||
{
|
||||
"host": host,
|
||||
# This format is the legacy format that Hue used for discovery
|
||||
"path": "phue-{}.conf".format(serial),
|
||||
}
|
||||
)
|
||||
|
||||
async def async_step_homekit(self, homekit_info):
|
||||
"""Handle HomeKit discovery."""
|
||||
# pylint: disable=unsupported-assignment-operation
|
||||
host = self.context['host'] = homekit_info.get('host')
|
||||
host = self.context["host"] = homekit_info.get("host")
|
||||
|
||||
if any(host == flow['context']['host']
|
||||
for flow in self._async_in_progress()):
|
||||
return self.async_abort(reason='already_in_progress')
|
||||
if any(host == flow["context"]["host"] for flow in self._async_in_progress()):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
|
||||
if host in configured_hosts(self.hass):
|
||||
return self.async_abort(reason='already_configured')
|
||||
return self.async_abort(reason="already_configured")
|
||||
|
||||
return await self.async_step_import({
|
||||
'host': host,
|
||||
})
|
||||
return await self.async_step_import({"host": host})
|
||||
|
||||
async def async_step_import(self, import_info):
|
||||
"""Import a new bridge as a config entry.
|
||||
|
@ -207,40 +192,36 @@ class HueFlowHandler(config_entries.ConfigFlow):
|
|||
and create an entry. Otherwise we will delegate to `link` step which
|
||||
will ask user to link the bridge.
|
||||
"""
|
||||
host = import_info['host']
|
||||
path = import_info.get('path')
|
||||
host = import_info["host"]
|
||||
path = import_info.get("path")
|
||||
|
||||
if path is not None:
|
||||
username = await self.hass.async_add_job(
|
||||
_find_username_from_config, self.hass,
|
||||
self.hass.config.path(path))
|
||||
_find_username_from_config, self.hass, self.hass.config.path(path)
|
||||
)
|
||||
else:
|
||||
username = None
|
||||
|
||||
try:
|
||||
bridge = await get_bridge(
|
||||
self.hass, host, username
|
||||
)
|
||||
bridge = await get_bridge(self.hass, host, username)
|
||||
|
||||
LOGGER.info('Imported authentication for %s from %s', host, path)
|
||||
LOGGER.info("Imported authentication for %s from %s", host, path)
|
||||
|
||||
return await self._entry_from_bridge(bridge)
|
||||
except AuthenticationRequired:
|
||||
self.host = host
|
||||
|
||||
LOGGER.info('Invalid authentication for %s, requesting link.',
|
||||
host)
|
||||
LOGGER.info("Invalid authentication for %s, requesting link.", host)
|
||||
|
||||
return await self.async_step_link()
|
||||
|
||||
except CannotConnect:
|
||||
LOGGER.error("Error connecting to the Hue bridge at %s", host)
|
||||
return self.async_abort(reason='cannot_connect')
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
|
||||
except Exception: # pylint: disable=broad-except
|
||||
LOGGER.exception('Unknown error connecting with Hue bridge at %s',
|
||||
host)
|
||||
return self.async_abort(reason='unknown')
|
||||
LOGGER.exception("Unknown error connecting with Hue bridge at %s", host)
|
||||
return self.async_abort(reason="unknown")
|
||||
|
||||
async def _entry_from_bridge(self, bridge):
|
||||
"""Return a config entry from an initialized bridge."""
|
||||
|
@ -248,20 +229,21 @@ class HueFlowHandler(config_entries.ConfigFlow):
|
|||
host = bridge.host
|
||||
bridge_id = bridge.config.bridgeid
|
||||
|
||||
same_hub_entries = [entry.entry_id for entry
|
||||
in self.hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.data['bridge_id'] == bridge_id or
|
||||
entry.data['host'] == host]
|
||||
same_hub_entries = [
|
||||
entry.entry_id
|
||||
for entry in self.hass.config_entries.async_entries(DOMAIN)
|
||||
if entry.data["bridge_id"] == bridge_id or entry.data["host"] == host
|
||||
]
|
||||
|
||||
if same_hub_entries:
|
||||
await asyncio.wait([self.hass.config_entries.async_remove(entry_id)
|
||||
for entry_id in same_hub_entries])
|
||||
await asyncio.wait(
|
||||
[
|
||||
self.hass.config_entries.async_remove(entry_id)
|
||||
for entry_id in same_hub_entries
|
||||
]
|
||||
)
|
||||
|
||||
return self.async_create_entry(
|
||||
title=bridge.config.name,
|
||||
data={
|
||||
'host': host,
|
||||
'bridge_id': bridge_id,
|
||||
'username': bridge.username,
|
||||
}
|
||||
data={"host": host, "bridge_id": bridge_id, "username": bridge.username},
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue