Add deconz option to disable automatic addition of new devices (#40545)

* Allow disabling automatic additions of new devices from deconz

* Fix black

* Fix review comment

* Remove assertion

* Verify entity registry is empty
This commit is contained in:
Robert Svensson 2020-09-29 11:07:19 +02:00 committed by GitHub
parent f3edec1191
commit 7e58bfe01d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 16 deletions

View file

@ -22,13 +22,13 @@ from homeassistant.helpers import aiohttp_client
from .const import ( from .const import (
CONF_ALLOW_CLIP_SENSOR, CONF_ALLOW_CLIP_SENSOR,
CONF_ALLOW_DECONZ_GROUPS, CONF_ALLOW_DECONZ_GROUPS,
CONF_ALLOW_NEW_DEVICES,
CONF_BRIDGE_ID, CONF_BRIDGE_ID,
DEFAULT_ALLOW_CLIP_SENSOR,
DEFAULT_ALLOW_DECONZ_GROUPS,
DEFAULT_PORT, DEFAULT_PORT,
DOMAIN, DOMAIN,
LOGGER, LOGGER,
) )
from .gateway import get_gateway_from_config_entry
DECONZ_MANUFACTURERURL = "http://www.dresden-elektronik.de" DECONZ_MANUFACTURERURL = "http://www.dresden-elektronik.de"
CONF_SERIAL = "serial" CONF_SERIAL = "serial"
@ -251,18 +251,17 @@ class DeconzOptionsFlowHandler(config_entries.OptionsFlow):
"""Initialize deCONZ options flow.""" """Initialize deCONZ options flow."""
self.config_entry = config_entry self.config_entry = config_entry
self.options = dict(config_entry.options) self.options = dict(config_entry.options)
self.gateway = None
async def async_step_init(self, user_input=None): async def async_step_init(self, user_input=None):
"""Manage the deCONZ options.""" """Manage the deCONZ options."""
self.gateway = get_gateway_from_config_entry(self.hass, self.config_entry)
return await self.async_step_deconz_devices() return await self.async_step_deconz_devices()
async def async_step_deconz_devices(self, user_input=None): async def async_step_deconz_devices(self, user_input=None):
"""Manage the deconz devices options.""" """Manage the deconz devices options."""
if user_input is not None: if user_input is not None:
self.options[CONF_ALLOW_CLIP_SENSOR] = user_input[CONF_ALLOW_CLIP_SENSOR] self.options.update(user_input)
self.options[CONF_ALLOW_DECONZ_GROUPS] = user_input[
CONF_ALLOW_DECONZ_GROUPS
]
return self.async_create_entry(title="", data=self.options) return self.async_create_entry(title="", data=self.options)
return self.async_show_form( return self.async_show_form(
@ -271,15 +270,15 @@ class DeconzOptionsFlowHandler(config_entries.OptionsFlow):
{ {
vol.Optional( vol.Optional(
CONF_ALLOW_CLIP_SENSOR, CONF_ALLOW_CLIP_SENSOR,
default=self.config_entry.options.get( default=self.gateway.option_allow_clip_sensor,
CONF_ALLOW_CLIP_SENSOR, DEFAULT_ALLOW_CLIP_SENSOR
),
): bool, ): bool,
vol.Optional( vol.Optional(
CONF_ALLOW_DECONZ_GROUPS, CONF_ALLOW_DECONZ_GROUPS,
default=self.config_entry.options.get( default=self.gateway.option_allow_deconz_groups,
CONF_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS ): bool,
), vol.Optional(
CONF_ALLOW_NEW_DEVICES,
default=self.gateway.option_allow_new_devices,
): bool, ): bool,
} }
), ),

View file

@ -11,9 +11,11 @@ CONF_GROUP_ID_BASE = "group_id_base"
DEFAULT_PORT = 80 DEFAULT_PORT = 80
DEFAULT_ALLOW_CLIP_SENSOR = False DEFAULT_ALLOW_CLIP_SENSOR = False
DEFAULT_ALLOW_DECONZ_GROUPS = True DEFAULT_ALLOW_DECONZ_GROUPS = True
DEFAULT_ALLOW_NEW_DEVICES = True
CONF_ALLOW_CLIP_SENSOR = "allow_clip_sensor" CONF_ALLOW_CLIP_SENSOR = "allow_clip_sensor"
CONF_ALLOW_DECONZ_GROUPS = "allow_deconz_groups" CONF_ALLOW_DECONZ_GROUPS = "allow_deconz_groups"
CONF_ALLOW_NEW_DEVICES = "allow_new_devices"
CONF_MASTER_GATEWAY = "master" CONF_MASTER_GATEWAY = "master"
SUPPORTED_PLATFORMS = [ SUPPORTED_PLATFORMS = [

View file

@ -14,9 +14,11 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
from .const import ( from .const import (
CONF_ALLOW_CLIP_SENSOR, CONF_ALLOW_CLIP_SENSOR,
CONF_ALLOW_DECONZ_GROUPS, CONF_ALLOW_DECONZ_GROUPS,
CONF_ALLOW_NEW_DEVICES,
CONF_MASTER_GATEWAY, CONF_MASTER_GATEWAY,
DEFAULT_ALLOW_CLIP_SENSOR, DEFAULT_ALLOW_CLIP_SENSOR,
DEFAULT_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS,
DEFAULT_ALLOW_NEW_DEVICES,
DOMAIN, DOMAIN,
LOGGER, LOGGER,
NEW_GROUP, NEW_GROUP,
@ -78,6 +80,13 @@ class DeconzGateway:
CONF_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS CONF_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS
) )
@property
def option_allow_new_devices(self) -> bool:
"""Allow automatic adding of new devices."""
return self.config_entry.options.get(
CONF_ALLOW_NEW_DEVICES, DEFAULT_ALLOW_NEW_DEVICES
)
async def async_update_device_registry(self) -> None: async def async_update_device_registry(self) -> None:
"""Update device registry.""" """Update device registry."""
device_registry = await self.hass.helpers.device_registry.async_get_registry() device_registry = await self.hass.helpers.device_registry.async_get_registry()
@ -204,8 +213,12 @@ class DeconzGateway:
@callback @callback
def async_add_device_callback(self, device_type, device) -> None: def async_add_device_callback(self, device_type, device) -> None:
"""Handle event of new device creation in deCONZ.""" """Handle event of new device creation in deCONZ."""
if not self.option_allow_new_devices:
return
if not isinstance(device, list): if not isinstance(device, list):
device = [device] device = [device]
async_dispatcher_send( async_dispatcher_send(
self.hass, self.async_signal_new_device(device_type), device self.hass, self.async_signal_new_device(device_type), device
) )

View file

@ -39,7 +39,8 @@
"deconz_devices": { "deconz_devices": {
"data": { "data": {
"allow_clip_sensor": "Allow deCONZ CLIP sensors", "allow_clip_sensor": "Allow deCONZ CLIP sensors",
"allow_deconz_groups": "Allow deCONZ light groups" "allow_deconz_groups": "Allow deCONZ light groups",
"allow_new_devices": "Allow automatic addition of new devices"
}, },
"description": "Configure visibility of deCONZ device types", "description": "Configure visibility of deCONZ device types",
"title": "deCONZ options" "title": "deCONZ options"
@ -100,4 +101,4 @@
"side_6": "Side 6" "side_6": "Side 6"
} }
} }
} }

View file

@ -93,7 +93,8 @@
"deconz_devices": { "deconz_devices": {
"data": { "data": {
"allow_clip_sensor": "Allow deCONZ CLIP sensors", "allow_clip_sensor": "Allow deCONZ CLIP sensors",
"allow_deconz_groups": "Allow deCONZ light groups" "allow_deconz_groups": "Allow deCONZ light groups",
"allow_new_devices": "Allow automatic addition of new devices"
}, },
"description": "Configure visibility of deCONZ device types", "description": "Configure visibility of deCONZ device types",
"title": "deCONZ options" "title": "deCONZ options"

View file

@ -7,6 +7,7 @@ from homeassistant.components.binary_sensor import (
DEVICE_CLASS_MOTION, DEVICE_CLASS_MOTION,
DEVICE_CLASS_VIBRATION, DEVICE_CLASS_VIBRATION,
) )
from homeassistant.helpers.entity_registry import async_entries_for_config_entry
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from .test_gateway import DECONZ_WEB_REQUEST, setup_deconz_integration from .test_gateway import DECONZ_WEB_REQUEST, setup_deconz_integration
@ -182,3 +183,34 @@ async def test_add_new_binary_sensor(hass):
presence_sensor = hass.states.get("binary_sensor.presence_sensor") presence_sensor = hass.states.get("binary_sensor.presence_sensor")
assert presence_sensor.state == "off" assert presence_sensor.state == "off"
async def test_add_new_binary_sensor_ignored(hass):
"""Test that adding a new binary sensor is not allowed."""
gateway = await setup_deconz_integration(
hass,
options={deconz.gateway.CONF_ALLOW_NEW_DEVICES: False},
)
assert len(hass.states.async_all()) == 0
state_added_event = {
"t": "event",
"e": "added",
"r": "sensors",
"id": "1",
"sensor": deepcopy(SENSORS["1"]),
}
gateway.api.event_handler(state_added_event)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 0
entity_registry = await hass.helpers.entity_registry.async_get_registry()
assert (
len(
async_entries_for_config_entry(
entity_registry, gateway.config_entry.entry_id
)
)
== 0
)

View file

@ -14,6 +14,7 @@ from homeassistant.components.deconz.config_flow import (
from homeassistant.components.deconz.const import ( from homeassistant.components.deconz.const import (
CONF_ALLOW_CLIP_SENSOR, CONF_ALLOW_CLIP_SENSOR,
CONF_ALLOW_DECONZ_GROUPS, CONF_ALLOW_DECONZ_GROUPS,
CONF_ALLOW_NEW_DEVICES,
CONF_MASTER_GATEWAY, CONF_MASTER_GATEWAY,
DOMAIN, DOMAIN,
) )
@ -561,12 +562,17 @@ async def test_option_flow(hass):
result = await hass.config_entries.options.async_configure( result = await hass.config_entries.options.async_configure(
result["flow_id"], result["flow_id"],
user_input={CONF_ALLOW_CLIP_SENSOR: False, CONF_ALLOW_DECONZ_GROUPS: False}, user_input={
CONF_ALLOW_CLIP_SENSOR: False,
CONF_ALLOW_DECONZ_GROUPS: False,
CONF_ALLOW_NEW_DEVICES: False,
},
) )
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["data"] == { assert result["data"] == {
CONF_ALLOW_CLIP_SENSOR: False, CONF_ALLOW_CLIP_SENSOR: False,
CONF_ALLOW_DECONZ_GROUPS: False, CONF_ALLOW_DECONZ_GROUPS: False,
CONF_ALLOW_NEW_DEVICES: False,
CONF_MASTER_GATEWAY: True, CONF_MASTER_GATEWAY: True,
} }

View file

@ -81,6 +81,7 @@ async def test_gateway_setup(hass):
assert gateway.master is True assert gateway.master is True
assert gateway.option_allow_clip_sensor is False assert gateway.option_allow_clip_sensor is False
assert gateway.option_allow_deconz_groups is True assert gateway.option_allow_deconz_groups is True
assert gateway.option_allow_new_devices is True
assert len(gateway.deconz_ids) == 0 assert len(gateway.deconz_ids) == 0
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_all()) == 0