Support multiple deCONZ gateways (#22449)
* Store gateways inside a dict in deconz domain * Make reachable events gateway specific * Gateway shall always exist * Adapt new device signalling to support multiple gateways * Services follow gateway master * Working on unload entry * Make unload and master handover work Improve tests for init * Fix config flow * Fix linting * Clean up init tests * Clean up hassio discovery to fit with the rest * Store gateways inside a dict in deconz domain * Make reachable events gateway specific * Gateway shall always exist * Adapt new device signalling to support multiple gateways * Services follow gateway master * Working on unload entry * Make unload and master handover work Improve tests for init * Fix config flow * Fix linting * Clean up init tests * Clean up hassio discovery to fit with the rest * Add support for services to specify bridgeid
This commit is contained in:
parent
b9ec623ad9
commit
b50afec5f1
22 changed files with 535 additions and 426 deletions
|
@ -9,10 +9,7 @@ from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
|
|||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
|
||||
from .const import (
|
||||
CONF_ALLOW_CLIP_SENSOR, CONF_ALLOW_DECONZ_GROUPS, CONF_BRIDGEID,
|
||||
DEFAULT_ALLOW_CLIP_SENSOR, DEFAULT_ALLOW_DECONZ_GROUPS, DEFAULT_PORT,
|
||||
DOMAIN)
|
||||
from .const import CONF_BRIDGEID, DEFAULT_PORT, DOMAIN
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -22,6 +19,14 @@ def configured_hosts(hass):
|
|||
in hass.config_entries.async_entries(DOMAIN))
|
||||
|
||||
|
||||
@callback
|
||||
def get_master_gateway(hass):
|
||||
"""Return a bool telling if this is the master gateway."""
|
||||
for gateway in hass.data[DOMAIN].values():
|
||||
if gateway.master:
|
||||
return gateway
|
||||
|
||||
|
||||
@config_entries.HANDLERS.register(DOMAIN)
|
||||
class DeconzFlowHandler(config_entries.ConfigFlow):
|
||||
"""Handle a deCONZ config flow."""
|
||||
|
@ -39,16 +44,12 @@ class DeconzFlowHandler(config_entries.ConfigFlow):
|
|||
async def async_step_user(self, user_input=None):
|
||||
"""Handle a deCONZ config flow start.
|
||||
|
||||
Only allows one instance to be set up.
|
||||
If only one bridge is found go to link step.
|
||||
If more than one bridge is found let user choose bridge to link.
|
||||
If no bridge is found allow user to manually input configuration.
|
||||
"""
|
||||
from pydeconz.utils import async_discovery
|
||||
|
||||
if configured_hosts(self.hass):
|
||||
return self.async_abort(reason='one_instance_only')
|
||||
|
||||
if user_input is not None:
|
||||
for bridge in self.bridges:
|
||||
if bridge[CONF_HOST] == user_input[CONF_HOST]:
|
||||
|
@ -99,9 +100,6 @@ class DeconzFlowHandler(config_entries.ConfigFlow):
|
|||
errors = {}
|
||||
|
||||
if user_input is not None:
|
||||
if configured_hosts(self.hass):
|
||||
return self.async_abort(reason='one_instance_only')
|
||||
|
||||
session = aiohttp_client.async_get_clientsession(self.hass)
|
||||
|
||||
try:
|
||||
|
@ -114,51 +112,32 @@ class DeconzFlowHandler(config_entries.ConfigFlow):
|
|||
|
||||
else:
|
||||
self.deconz_config[CONF_API_KEY] = api_key
|
||||
return await self.async_step_options()
|
||||
return await self._create_entry()
|
||||
|
||||
return self.async_show_form(
|
||||
step_id='link',
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_options(self, user_input=None):
|
||||
"""Extra options for deCONZ.
|
||||
|
||||
CONF_CLIP_SENSOR -- Allow user to choose if they want clip sensors.
|
||||
CONF_DECONZ_GROUPS -- Allow user to choose if they want deCONZ groups.
|
||||
"""
|
||||
async def _create_entry(self):
|
||||
"""Create entry for gateway."""
|
||||
from pydeconz.utils import async_get_bridgeid
|
||||
|
||||
if user_input is not None:
|
||||
self.deconz_config[CONF_ALLOW_CLIP_SENSOR] = \
|
||||
user_input[CONF_ALLOW_CLIP_SENSOR]
|
||||
self.deconz_config[CONF_ALLOW_DECONZ_GROUPS] = \
|
||||
user_input[CONF_ALLOW_DECONZ_GROUPS]
|
||||
if CONF_BRIDGEID not in self.deconz_config:
|
||||
session = aiohttp_client.async_get_clientsession(self.hass)
|
||||
|
||||
if CONF_BRIDGEID not in self.deconz_config:
|
||||
session = aiohttp_client.async_get_clientsession(self.hass)
|
||||
try:
|
||||
with async_timeout.timeout(10):
|
||||
self.deconz_config[CONF_BRIDGEID] = \
|
||||
await async_get_bridgeid(
|
||||
session, **self.deconz_config)
|
||||
try:
|
||||
with async_timeout.timeout(10):
|
||||
self.deconz_config[CONF_BRIDGEID] = \
|
||||
await async_get_bridgeid(
|
||||
session, **self.deconz_config)
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
return self.async_abort(reason='no_bridges')
|
||||
except asyncio.TimeoutError:
|
||||
return self.async_abort(reason='no_bridges')
|
||||
|
||||
return self.async_create_entry(
|
||||
title='deCONZ-' + self.deconz_config[CONF_BRIDGEID],
|
||||
data=self.deconz_config
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id='options',
|
||||
data_schema=vol.Schema({
|
||||
vol.Optional(CONF_ALLOW_CLIP_SENSOR,
|
||||
default=DEFAULT_ALLOW_CLIP_SENSOR): bool,
|
||||
vol.Optional(CONF_ALLOW_DECONZ_GROUPS,
|
||||
default=DEFAULT_ALLOW_DECONZ_GROUPS): bool,
|
||||
}),
|
||||
return self.async_create_entry(
|
||||
title='deCONZ-' + self.deconz_config[CONF_BRIDGEID],
|
||||
data=self.deconz_config
|
||||
)
|
||||
|
||||
async def async_step_discovery(self, discovery_info):
|
||||
|
@ -166,10 +145,14 @@ class DeconzFlowHandler(config_entries.ConfigFlow):
|
|||
|
||||
This flow is triggered by the discovery component.
|
||||
"""
|
||||
deconz_config = {}
|
||||
deconz_config[CONF_HOST] = discovery_info.get(CONF_HOST)
|
||||
deconz_config[CONF_PORT] = discovery_info.get(CONF_PORT)
|
||||
deconz_config[CONF_BRIDGEID] = discovery_info.get('serial')
|
||||
deconz_config = {
|
||||
CONF_HOST: discovery_info[CONF_HOST],
|
||||
CONF_PORT: discovery_info[CONF_PORT],
|
||||
CONF_BRIDGEID: discovery_info['serial']
|
||||
}
|
||||
|
||||
if deconz_config[CONF_HOST] in configured_hosts(self.hass):
|
||||
return self.async_abort(reason='one_instance_only')
|
||||
|
||||
return await self.async_step_import(deconz_config)
|
||||
|
||||
|
@ -186,16 +169,11 @@ class DeconzFlowHandler(config_entries.ConfigFlow):
|
|||
Otherwise we will delegate to `link` step which
|
||||
will ask user to link the bridge.
|
||||
"""
|
||||
if configured_hosts(self.hass):
|
||||
return self.async_abort(reason='one_instance_only')
|
||||
|
||||
self.deconz_config = import_config
|
||||
if CONF_API_KEY not in import_config:
|
||||
return await self.async_step_link()
|
||||
|
||||
user_input = {CONF_ALLOW_CLIP_SENSOR: True,
|
||||
CONF_ALLOW_DECONZ_GROUPS: True}
|
||||
return await self.async_step_options(user_input=user_input)
|
||||
return await self._create_entry()
|
||||
|
||||
async def async_step_hassio(self, user_input=None):
|
||||
"""Prepare configuration for a Hass.io deCONZ bridge.
|
||||
|
@ -212,29 +190,18 @@ class DeconzFlowHandler(config_entries.ConfigFlow):
|
|||
async def async_step_hassio_confirm(self, user_input=None):
|
||||
"""Confirm a Hass.io discovery."""
|
||||
if user_input is not None:
|
||||
data = self._hassio_discovery
|
||||
self.deconz_config = {
|
||||
CONF_HOST: self._hassio_discovery[CONF_HOST],
|
||||
CONF_PORT: self._hassio_discovery[CONF_PORT],
|
||||
CONF_BRIDGEID: self._hassio_discovery['serial'],
|
||||
CONF_API_KEY: self._hassio_discovery[CONF_API_KEY]
|
||||
}
|
||||
|
||||
return self.async_create_entry(
|
||||
title=data['addon'], data={
|
||||
CONF_HOST: data[CONF_HOST],
|
||||
CONF_PORT: data[CONF_PORT],
|
||||
CONF_BRIDGEID: data['serial'],
|
||||
CONF_API_KEY: data[CONF_API_KEY],
|
||||
CONF_ALLOW_CLIP_SENSOR:
|
||||
user_input[CONF_ALLOW_CLIP_SENSOR],
|
||||
CONF_ALLOW_DECONZ_GROUPS:
|
||||
user_input[CONF_ALLOW_DECONZ_GROUPS],
|
||||
})
|
||||
return await self._create_entry()
|
||||
|
||||
return self.async_show_form(
|
||||
step_id='hassio_confirm',
|
||||
description_placeholders={
|
||||
'addon': self._hassio_discovery['addon']
|
||||
},
|
||||
data_schema=vol.Schema({
|
||||
vol.Optional(CONF_ALLOW_CLIP_SENSOR,
|
||||
default=DEFAULT_ALLOW_CLIP_SENSOR): bool,
|
||||
vol.Optional(CONF_ALLOW_DECONZ_GROUPS,
|
||||
default=DEFAULT_ALLOW_DECONZ_GROUPS): bool,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue