mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 07:07:28 +00:00
deCONZ - Option to load or not to load clip sensors on start (#14480)
* Option to load or not to load clip sensors on start * Full flow * Fix config flow and add tests * Fix attribute dark reporting properly * Imported and properly configured deCONZ shouldn't need extra input to create config entry
This commit is contained in:
parent
3b38de63ea
commit
8c93b484c4
@ -6,7 +6,8 @@ https://home-assistant.io/components/binary_sensor.deconz/
|
|||||||
"""
|
"""
|
||||||
from homeassistant.components.binary_sensor import BinarySensorDevice
|
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||||
from homeassistant.components.deconz import (
|
from homeassistant.components.deconz import (
|
||||||
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID, DATA_DECONZ_UNSUB)
|
CONF_ALLOW_CLIP_SENSOR, DOMAIN as DATA_DECONZ, DATA_DECONZ_ID,
|
||||||
|
DATA_DECONZ_UNSUB)
|
||||||
from homeassistant.const import ATTR_BATTERY_LEVEL
|
from homeassistant.const import ATTR_BATTERY_LEVEL
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
@ -27,10 +28,13 @@ async def async_setup_entry(hass, config_entry, async_add_devices):
|
|||||||
"""Add binary sensor from deCONZ."""
|
"""Add binary sensor from deCONZ."""
|
||||||
from pydeconz.sensor import DECONZ_BINARY_SENSOR
|
from pydeconz.sensor import DECONZ_BINARY_SENSOR
|
||||||
entities = []
|
entities = []
|
||||||
|
allow_clip_sensor = config_entry.data.get(CONF_ALLOW_CLIP_SENSOR, True)
|
||||||
for sensor in sensors:
|
for sensor in sensors:
|
||||||
if sensor.type in DECONZ_BINARY_SENSOR:
|
if sensor.type in DECONZ_BINARY_SENSOR and \
|
||||||
|
not (not allow_clip_sensor and sensor.type.startswith('CLIP')):
|
||||||
entities.append(DeconzBinarySensor(sensor))
|
entities.append(DeconzBinarySensor(sensor))
|
||||||
async_add_devices(entities, True)
|
async_add_devices(entities, True)
|
||||||
|
|
||||||
hass.data[DATA_DECONZ_UNSUB].append(
|
hass.data[DATA_DECONZ_UNSUB].append(
|
||||||
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
|
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
|
||||||
|
|
||||||
@ -103,6 +107,6 @@ class DeconzBinarySensor(BinarySensorDevice):
|
|||||||
attr = {}
|
attr = {}
|
||||||
if self._sensor.battery:
|
if self._sensor.battery:
|
||||||
attr[ATTR_BATTERY_LEVEL] = self._sensor.battery
|
attr[ATTR_BATTERY_LEVEL] = self._sensor.battery
|
||||||
if self._sensor.type in PRESENCE and self._sensor.dark:
|
if self._sensor.type in PRESENCE and self._sensor.dark is not None:
|
||||||
attr['dark'] = self._sensor.dark
|
attr['dark'] = self._sensor.dark
|
||||||
return attr
|
return attr
|
||||||
|
@ -19,8 +19,14 @@
|
|||||||
"link": {
|
"link": {
|
||||||
"description": "Unlock your deCONZ gateway to register with Home Assistant.\n\n1. Go to deCONZ system settings\n2. Press \"Unlock Gateway\" button",
|
"description": "Unlock your deCONZ gateway to register with Home Assistant.\n\n1. Go to deCONZ system settings\n2. Press \"Unlock Gateway\" button",
|
||||||
"title": "Link with deCONZ"
|
"title": "Link with deCONZ"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"title": "Extra configuration options for deCONZ",
|
||||||
|
"data": {
|
||||||
|
"allow_clip_sensor": "Allow importing virtual sensors"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"title": "deCONZ"
|
"title": "deCONZ Zigbee gateway"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,8 +19,8 @@ from homeassistant.util.json import load_json
|
|||||||
# Loading the config flow file will register the flow
|
# Loading the config flow file will register the flow
|
||||||
from .config_flow import configured_hosts
|
from .config_flow import configured_hosts
|
||||||
from .const import (
|
from .const import (
|
||||||
CONFIG_FILE, DATA_DECONZ_EVENT, DATA_DECONZ_ID,
|
CONF_ALLOW_CLIP_SENSOR, CONFIG_FILE, DATA_DECONZ_EVENT,
|
||||||
DATA_DECONZ_UNSUB, DOMAIN, _LOGGER)
|
DATA_DECONZ_ID, DATA_DECONZ_UNSUB, DOMAIN, _LOGGER)
|
||||||
|
|
||||||
REQUIREMENTS = ['pydeconz==38']
|
REQUIREMENTS = ['pydeconz==38']
|
||||||
|
|
||||||
@ -104,8 +104,10 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
def async_add_remote(sensors):
|
def async_add_remote(sensors):
|
||||||
"""Setup remote from deCONZ."""
|
"""Setup remote from deCONZ."""
|
||||||
from pydeconz.sensor import SWITCH as DECONZ_REMOTE
|
from pydeconz.sensor import SWITCH as DECONZ_REMOTE
|
||||||
|
allow_clip_sensor = config_entry.data.get(CONF_ALLOW_CLIP_SENSOR, True)
|
||||||
for sensor in sensors:
|
for sensor in sensors:
|
||||||
if sensor.type in DECONZ_REMOTE:
|
if sensor.type in DECONZ_REMOTE and \
|
||||||
|
not (not allow_clip_sensor and sensor.type.startswith('CLIP')):
|
||||||
hass.data[DATA_DECONZ_EVENT].append(DeconzEvent(hass, sensor))
|
hass.data[DATA_DECONZ_EVENT].append(DeconzEvent(hass, sensor))
|
||||||
hass.data[DATA_DECONZ_UNSUB].append(
|
hass.data[DATA_DECONZ_UNSUB].append(
|
||||||
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_remote))
|
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_remote))
|
||||||
|
@ -8,13 +8,15 @@ from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PORT
|
|||||||
from homeassistant.helpers import aiohttp_client
|
from homeassistant.helpers import aiohttp_client
|
||||||
from homeassistant.util.json import load_json
|
from homeassistant.util.json import load_json
|
||||||
|
|
||||||
from .const import CONFIG_FILE, DOMAIN
|
from .const import CONF_ALLOW_CLIP_SENSOR, CONFIG_FILE, DOMAIN
|
||||||
|
|
||||||
|
CONF_BRIDGEID = 'bridgeid'
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def configured_hosts(hass):
|
def configured_hosts(hass):
|
||||||
"""Return a set of the configured hosts."""
|
"""Return a set of the configured hosts."""
|
||||||
return set(entry.data['host'] for entry
|
return set(entry.data[CONF_HOST] for entry
|
||||||
in hass.config_entries.async_entries(DOMAIN))
|
in hass.config_entries.async_entries(DOMAIN))
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +32,12 @@ class DeconzFlowHandler(data_entry_flow.FlowHandler):
|
|||||||
self.deconz_config = {}
|
self.deconz_config = {}
|
||||||
|
|
||||||
async def async_step_init(self, user_input=None):
|
async def async_step_init(self, user_input=None):
|
||||||
"""Handle a deCONZ config flow start."""
|
"""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.
|
||||||
|
"""
|
||||||
from pydeconz.utils import async_discovery
|
from pydeconz.utils import async_discovery
|
||||||
|
|
||||||
if configured_hosts(self.hass):
|
if configured_hosts(self.hass):
|
||||||
@ -65,7 +72,7 @@ class DeconzFlowHandler(data_entry_flow.FlowHandler):
|
|||||||
|
|
||||||
async def async_step_link(self, user_input=None):
|
async def async_step_link(self, user_input=None):
|
||||||
"""Attempt to link with the deCONZ bridge."""
|
"""Attempt to link with the deCONZ bridge."""
|
||||||
from pydeconz.utils import async_get_api_key, async_get_bridgeid
|
from pydeconz.utils import async_get_api_key
|
||||||
errors = {}
|
errors = {}
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
@ -75,13 +82,7 @@ class DeconzFlowHandler(data_entry_flow.FlowHandler):
|
|||||||
api_key = await async_get_api_key(session, **self.deconz_config)
|
api_key = await async_get_api_key(session, **self.deconz_config)
|
||||||
if api_key:
|
if api_key:
|
||||||
self.deconz_config[CONF_API_KEY] = api_key
|
self.deconz_config[CONF_API_KEY] = api_key
|
||||||
if 'bridgeid' not in self.deconz_config:
|
return await self.async_step_options()
|
||||||
self.deconz_config['bridgeid'] = await async_get_bridgeid(
|
|
||||||
session, **self.deconz_config)
|
|
||||||
return self.async_create_entry(
|
|
||||||
title='deCONZ-' + self.deconz_config['bridgeid'],
|
|
||||||
data=self.deconz_config
|
|
||||||
)
|
|
||||||
errors['base'] = 'no_key'
|
errors['base'] = 'no_key'
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
@ -89,6 +90,34 @@ class DeconzFlowHandler(data_entry_flow.FlowHandler):
|
|||||||
errors=errors,
|
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.
|
||||||
|
"""
|
||||||
|
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]
|
||||||
|
|
||||||
|
if CONF_BRIDGEID not in self.deconz_config:
|
||||||
|
session = aiohttp_client.async_get_clientsession(self.hass)
|
||||||
|
self.deconz_config[CONF_BRIDGEID] = await async_get_bridgeid(
|
||||||
|
session, **self.deconz_config)
|
||||||
|
|
||||||
|
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): bool,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
async def async_step_discovery(self, discovery_info):
|
async def async_step_discovery(self, discovery_info):
|
||||||
"""Prepare configuration for a discovered deCONZ bridge.
|
"""Prepare configuration for a discovered deCONZ bridge.
|
||||||
|
|
||||||
@ -97,7 +126,7 @@ class DeconzFlowHandler(data_entry_flow.FlowHandler):
|
|||||||
deconz_config = {}
|
deconz_config = {}
|
||||||
deconz_config[CONF_HOST] = discovery_info.get(CONF_HOST)
|
deconz_config[CONF_HOST] = discovery_info.get(CONF_HOST)
|
||||||
deconz_config[CONF_PORT] = discovery_info.get(CONF_PORT)
|
deconz_config[CONF_PORT] = discovery_info.get(CONF_PORT)
|
||||||
deconz_config['bridgeid'] = discovery_info.get('serial')
|
deconz_config[CONF_BRIDGEID] = discovery_info.get('serial')
|
||||||
|
|
||||||
config_file = await self.hass.async_add_job(
|
config_file = await self.hass.async_add_job(
|
||||||
load_json, self.hass.config.path(CONFIG_FILE))
|
load_json, self.hass.config.path(CONFIG_FILE))
|
||||||
@ -121,19 +150,15 @@ class DeconzFlowHandler(data_entry_flow.FlowHandler):
|
|||||||
Otherwise we will delegate to `link` step which
|
Otherwise we will delegate to `link` step which
|
||||||
will ask user to link the bridge.
|
will ask user to link the bridge.
|
||||||
"""
|
"""
|
||||||
from pydeconz.utils import async_get_bridgeid
|
|
||||||
|
|
||||||
if configured_hosts(self.hass):
|
if configured_hosts(self.hass):
|
||||||
return self.async_abort(reason='one_instance_only')
|
return self.async_abort(reason='one_instance_only')
|
||||||
elif CONF_API_KEY not in import_config:
|
|
||||||
self.deconz_config = import_config
|
self.deconz_config = import_config
|
||||||
|
if CONF_API_KEY not in import_config:
|
||||||
return await self.async_step_link()
|
return await self.async_step_link()
|
||||||
|
|
||||||
if 'bridgeid' not in import_config:
|
self.deconz_config[CONF_ALLOW_CLIP_SENSOR] = True
|
||||||
session = aiohttp_client.async_get_clientsession(self.hass)
|
|
||||||
import_config['bridgeid'] = await async_get_bridgeid(
|
|
||||||
session, **import_config)
|
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title='deCONZ-' + import_config['bridgeid'],
|
title='deCONZ-' + self.deconz_config[CONF_BRIDGEID],
|
||||||
data=import_config
|
data=self.deconz_config
|
||||||
)
|
)
|
||||||
|
@ -8,3 +8,5 @@ CONFIG_FILE = 'deconz.conf'
|
|||||||
DATA_DECONZ_EVENT = 'deconz_events'
|
DATA_DECONZ_EVENT = 'deconz_events'
|
||||||
DATA_DECONZ_ID = 'deconz_entities'
|
DATA_DECONZ_ID = 'deconz_entities'
|
||||||
DATA_DECONZ_UNSUB = 'deconz_dispatchers'
|
DATA_DECONZ_UNSUB = 'deconz_dispatchers'
|
||||||
|
|
||||||
|
CONF_ALLOW_CLIP_SENSOR = 'allow_clip_sensor'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"title": "deCONZ",
|
"title": "deCONZ Zigbee gateway",
|
||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
"title": "Define deCONZ gateway",
|
"title": "Define deCONZ gateway",
|
||||||
@ -12,6 +12,12 @@
|
|||||||
"link": {
|
"link": {
|
||||||
"title": "Link with deCONZ",
|
"title": "Link with deCONZ",
|
||||||
"description": "Unlock your deCONZ gateway to register with Home Assistant.\n\n1. Go to deCONZ system settings\n2. Press \"Unlock Gateway\" button"
|
"description": "Unlock your deCONZ gateway to register with Home Assistant.\n\n1. Go to deCONZ system settings\n2. Press \"Unlock Gateway\" button"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"title": "Extra configuration options for deCONZ",
|
||||||
|
"data":{
|
||||||
|
"allow_clip_sensor": "Allow importing virtual sensors"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
|
@ -5,7 +5,8 @@ For more details about this component, please refer to the documentation at
|
|||||||
https://home-assistant.io/components/sensor.deconz/
|
https://home-assistant.io/components/sensor.deconz/
|
||||||
"""
|
"""
|
||||||
from homeassistant.components.deconz import (
|
from homeassistant.components.deconz import (
|
||||||
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID, DATA_DECONZ_UNSUB)
|
CONF_ALLOW_CLIP_SENSOR, DOMAIN as DATA_DECONZ, DATA_DECONZ_ID,
|
||||||
|
DATA_DECONZ_UNSUB)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_BATTERY_LEVEL, ATTR_VOLTAGE, DEVICE_CLASS_BATTERY)
|
ATTR_BATTERY_LEVEL, ATTR_VOLTAGE, DEVICE_CLASS_BATTERY)
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
@ -33,14 +34,17 @@ async def async_setup_entry(hass, config_entry, async_add_devices):
|
|||||||
"""Add sensors from deCONZ."""
|
"""Add sensors from deCONZ."""
|
||||||
from pydeconz.sensor import DECONZ_SENSOR, SWITCH as DECONZ_REMOTE
|
from pydeconz.sensor import DECONZ_SENSOR, SWITCH as DECONZ_REMOTE
|
||||||
entities = []
|
entities = []
|
||||||
|
allow_clip_sensor = config_entry.data.get(CONF_ALLOW_CLIP_SENSOR, True)
|
||||||
for sensor in sensors:
|
for sensor in sensors:
|
||||||
if sensor.type in DECONZ_SENSOR:
|
if sensor.type in DECONZ_SENSOR and \
|
||||||
|
not (not allow_clip_sensor and sensor.type.startswith('CLIP')):
|
||||||
if sensor.type in DECONZ_REMOTE:
|
if sensor.type in DECONZ_REMOTE:
|
||||||
if sensor.battery:
|
if sensor.battery:
|
||||||
entities.append(DeconzBattery(sensor))
|
entities.append(DeconzBattery(sensor))
|
||||||
else:
|
else:
|
||||||
entities.append(DeconzSensor(sensor))
|
entities.append(DeconzSensor(sensor))
|
||||||
async_add_devices(entities, True)
|
async_add_devices(entities, True)
|
||||||
|
|
||||||
hass.data[DATA_DECONZ_UNSUB].append(
|
hass.data[DATA_DECONZ_UNSUB].append(
|
||||||
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
|
async_dispatcher_connect(hass, 'deconz_new_sensor', async_add_sensor))
|
||||||
|
|
||||||
@ -114,9 +118,12 @@ class DeconzSensor(Entity):
|
|||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the state attributes of the sensor."""
|
"""Return the state attributes of the sensor."""
|
||||||
|
from pydeconz.sensor import LIGHTLEVEL
|
||||||
attr = {}
|
attr = {}
|
||||||
if self._sensor.battery:
|
if self._sensor.battery:
|
||||||
attr[ATTR_BATTERY_LEVEL] = self._sensor.battery
|
attr[ATTR_BATTERY_LEVEL] = self._sensor.battery
|
||||||
|
if self._sensor.type in LIGHTLEVEL and self._sensor.dark is not None:
|
||||||
|
attr['dark'] = self._sensor.dark
|
||||||
if self.unit_of_measurement == 'Watts':
|
if self.unit_of_measurement == 'Watts':
|
||||||
attr[ATTR_CURRENT] = self._sensor.current
|
attr[ATTR_CURRENT] = self._sensor.current
|
||||||
attr[ATTR_VOLTAGE] = self._sensor.voltage
|
attr[ATTR_VOLTAGE] = self._sensor.voltage
|
||||||
|
@ -26,7 +26,7 @@ SENSOR = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def setup_bridge(hass, data):
|
async def setup_bridge(hass, data, allow_clip_sensor=True):
|
||||||
"""Load the deCONZ binary sensor platform."""
|
"""Load the deCONZ binary sensor platform."""
|
||||||
from pydeconz import DeconzSession
|
from pydeconz import DeconzSession
|
||||||
loop = Mock()
|
loop = Mock()
|
||||||
@ -41,7 +41,8 @@ async def setup_bridge(hass, data):
|
|||||||
hass.data[deconz.DATA_DECONZ_UNSUB] = []
|
hass.data[deconz.DATA_DECONZ_UNSUB] = []
|
||||||
hass.data[deconz.DATA_DECONZ_ID] = {}
|
hass.data[deconz.DATA_DECONZ_ID] = {}
|
||||||
config_entry = config_entries.ConfigEntry(
|
config_entry = config_entries.ConfigEntry(
|
||||||
1, deconz.DOMAIN, 'Mock Title', {'host': 'mock-host'}, 'test')
|
1, deconz.DOMAIN, 'Mock Title',
|
||||||
|
{'host': 'mock-host', 'allow_clip_sensor': allow_clip_sensor}, 'test')
|
||||||
await hass.config_entries.async_forward_entry_setup(
|
await hass.config_entries.async_forward_entry_setup(
|
||||||
config_entry, 'binary_sensor')
|
config_entry, 'binary_sensor')
|
||||||
# To flush out the service call to update the group
|
# To flush out the service call to update the group
|
||||||
@ -77,3 +78,16 @@ async def test_add_new_sensor(hass):
|
|||||||
async_dispatcher_send(hass, 'deconz_new_sensor', [sensor])
|
async_dispatcher_send(hass, 'deconz_new_sensor', [sensor])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert "binary_sensor.name" in hass.data[deconz.DATA_DECONZ_ID]
|
assert "binary_sensor.name" in hass.data[deconz.DATA_DECONZ_ID]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_do_not_allow_clip_sensor(hass):
|
||||||
|
"""Test that clip sensors can be ignored."""
|
||||||
|
data = {}
|
||||||
|
await setup_bridge(hass, data, allow_clip_sensor=False)
|
||||||
|
sensor = Mock()
|
||||||
|
sensor.name = 'name'
|
||||||
|
sensor.type = 'CLIPPresence'
|
||||||
|
sensor.register_async_callback = Mock()
|
||||||
|
async_dispatcher_send(hass, 'deconz_new_sensor', [sensor])
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(hass.data[deconz.DATA_DECONZ_ID]) == 0
|
||||||
|
@ -21,7 +21,9 @@ async def test_flow_works(hass, aioclient_mock):
|
|||||||
flow = config_flow.DeconzFlowHandler()
|
flow = config_flow.DeconzFlowHandler()
|
||||||
flow.hass = hass
|
flow.hass = hass
|
||||||
await flow.async_step_init()
|
await flow.async_step_init()
|
||||||
result = await flow.async_step_link(user_input={})
|
await flow.async_step_link(user_input={})
|
||||||
|
result = await flow.async_step_options(
|
||||||
|
user_input={'allow_clip_sensor': True})
|
||||||
|
|
||||||
assert result['type'] == 'create_entry'
|
assert result['type'] == 'create_entry'
|
||||||
assert result['title'] == 'deCONZ-id'
|
assert result['title'] == 'deCONZ-id'
|
||||||
@ -29,7 +31,8 @@ async def test_flow_works(hass, aioclient_mock):
|
|||||||
'bridgeid': 'id',
|
'bridgeid': 'id',
|
||||||
'host': '1.2.3.4',
|
'host': '1.2.3.4',
|
||||||
'port': 80,
|
'port': 80,
|
||||||
'api_key': '1234567890ABCDEF'
|
'api_key': '1234567890ABCDEF',
|
||||||
|
'allow_clip_sensor': True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -146,14 +149,14 @@ async def test_bridge_discovery_config_file(hass):
|
|||||||
'port': 80,
|
'port': 80,
|
||||||
'serial': 'id'
|
'serial': 'id'
|
||||||
})
|
})
|
||||||
|
|
||||||
assert result['type'] == 'create_entry'
|
assert result['type'] == 'create_entry'
|
||||||
assert result['title'] == 'deCONZ-id'
|
assert result['title'] == 'deCONZ-id'
|
||||||
assert result['data'] == {
|
assert result['data'] == {
|
||||||
'bridgeid': 'id',
|
'bridgeid': 'id',
|
||||||
'host': '1.2.3.4',
|
'host': '1.2.3.4',
|
||||||
'port': 80,
|
'port': 80,
|
||||||
'api_key': '1234567890ABCDEF'
|
'api_key': '1234567890ABCDEF',
|
||||||
|
'allow_clip_sensor': True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -214,12 +217,34 @@ async def test_import_with_api_key(hass):
|
|||||||
'port': 80,
|
'port': 80,
|
||||||
'api_key': '1234567890ABCDEF'
|
'api_key': '1234567890ABCDEF'
|
||||||
})
|
})
|
||||||
|
|
||||||
assert result['type'] == 'create_entry'
|
assert result['type'] == 'create_entry'
|
||||||
assert result['title'] == 'deCONZ-id'
|
assert result['title'] == 'deCONZ-id'
|
||||||
assert result['data'] == {
|
assert result['data'] == {
|
||||||
'bridgeid': 'id',
|
'bridgeid': 'id',
|
||||||
'host': '1.2.3.4',
|
'host': '1.2.3.4',
|
||||||
'port': 80,
|
'port': 80,
|
||||||
'api_key': '1234567890ABCDEF'
|
'api_key': '1234567890ABCDEF',
|
||||||
|
'allow_clip_sensor': True
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_options(hass, aioclient_mock):
|
||||||
|
"""Test that options work and that bridgeid can be requested."""
|
||||||
|
aioclient_mock.get('http://1.2.3.4:80/api/1234567890ABCDEF/config',
|
||||||
|
json={"bridgeid": "id"})
|
||||||
|
flow = config_flow.DeconzFlowHandler()
|
||||||
|
flow.hass = hass
|
||||||
|
flow.deconz_config = {'host': '1.2.3.4',
|
||||||
|
'port': 80,
|
||||||
|
'api_key': '1234567890ABCDEF'}
|
||||||
|
result = await flow.async_step_options(
|
||||||
|
user_input={'allow_clip_sensor': False})
|
||||||
|
assert result['type'] == 'create_entry'
|
||||||
|
assert result['title'] == 'deCONZ-id'
|
||||||
|
assert result['data'] == {
|
||||||
|
'bridgeid': 'id',
|
||||||
|
'host': '1.2.3.4',
|
||||||
|
'port': 80,
|
||||||
|
'api_key': '1234567890ABCDEF',
|
||||||
|
'allow_clip_sensor': False
|
||||||
}
|
}
|
||||||
|
@ -172,3 +172,21 @@ async def test_add_new_remote(hass):
|
|||||||
async_dispatcher_send(hass, 'deconz_new_sensor', [remote])
|
async_dispatcher_send(hass, 'deconz_new_sensor', [remote])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(hass.data[deconz.DATA_DECONZ_EVENT]) == 1
|
assert len(hass.data[deconz.DATA_DECONZ_EVENT]) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_do_not_allow_clip_sensor(hass):
|
||||||
|
"""Test that clip sensors can be ignored."""
|
||||||
|
entry = Mock()
|
||||||
|
entry.data = {'host': '1.2.3.4', 'port': 80,
|
||||||
|
'api_key': '1234567890ABCDEF', 'allow_clip_sensor': False}
|
||||||
|
remote = Mock()
|
||||||
|
remote.name = 'name'
|
||||||
|
remote.type = 'CLIPSwitch'
|
||||||
|
remote.register_async_callback = Mock()
|
||||||
|
with patch('pydeconz.DeconzSession.async_load_parameters',
|
||||||
|
return_value=mock_coro(True)):
|
||||||
|
assert await deconz.async_setup_entry(hass, entry) is True
|
||||||
|
|
||||||
|
async_dispatcher_send(hass, 'deconz_new_sensor', [remote])
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(hass.data[deconz.DATA_DECONZ_EVENT]) == 0
|
||||||
|
@ -41,7 +41,7 @@ SENSOR = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def setup_bridge(hass, data):
|
async def setup_bridge(hass, data, allow_clip_sensor=True):
|
||||||
"""Load the deCONZ sensor platform."""
|
"""Load the deCONZ sensor platform."""
|
||||||
from pydeconz import DeconzSession
|
from pydeconz import DeconzSession
|
||||||
loop = Mock()
|
loop = Mock()
|
||||||
@ -57,7 +57,8 @@ async def setup_bridge(hass, data):
|
|||||||
hass.data[deconz.DATA_DECONZ_EVENT] = []
|
hass.data[deconz.DATA_DECONZ_EVENT] = []
|
||||||
hass.data[deconz.DATA_DECONZ_ID] = {}
|
hass.data[deconz.DATA_DECONZ_ID] = {}
|
||||||
config_entry = config_entries.ConfigEntry(
|
config_entry = config_entries.ConfigEntry(
|
||||||
1, deconz.DOMAIN, 'Mock Title', {'host': 'mock-host'}, 'test')
|
1, deconz.DOMAIN, 'Mock Title',
|
||||||
|
{'host': 'mock-host', 'allow_clip_sensor': allow_clip_sensor}, 'test')
|
||||||
await hass.config_entries.async_forward_entry_setup(config_entry, 'sensor')
|
await hass.config_entries.async_forward_entry_setup(config_entry, 'sensor')
|
||||||
# To flush out the service call to update the group
|
# To flush out the service call to update the group
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -97,3 +98,16 @@ async def test_add_new_sensor(hass):
|
|||||||
async_dispatcher_send(hass, 'deconz_new_sensor', [sensor])
|
async_dispatcher_send(hass, 'deconz_new_sensor', [sensor])
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert "sensor.name" in hass.data[deconz.DATA_DECONZ_ID]
|
assert "sensor.name" in hass.data[deconz.DATA_DECONZ_ID]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_do_not_allow_clipsensor(hass):
|
||||||
|
"""Test that clip sensors can be ignored."""
|
||||||
|
data = {}
|
||||||
|
await setup_bridge(hass, data, allow_clip_sensor=False)
|
||||||
|
sensor = Mock()
|
||||||
|
sensor.name = 'name'
|
||||||
|
sensor.type = 'CLIPTemperature'
|
||||||
|
sensor.register_async_callback = Mock()
|
||||||
|
async_dispatcher_send(hass, 'deconz_new_sensor', [sensor])
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(hass.data[deconz.DATA_DECONZ_ID]) == 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user