Improve tracking of existing entities in deconz (#40265)
* Store all entities in dict * Use stored unique id to select if to create entity or not * Remove unnecessary init * Change so same physical sensor doesnt try to create multiple battery sensors Change so groups get created properly * Add controls in tests that entities are logged correctly
This commit is contained in:
parent
e30acfbfee
commit
203c556ba3
16 changed files with 147 additions and 58 deletions
|
@ -8,6 +8,7 @@ from homeassistant.components.binary_sensor import (
|
|||
DEVICE_CLASS_OPENING,
|
||||
DEVICE_CLASS_SMOKE,
|
||||
DEVICE_CLASS_VIBRATION,
|
||||
DOMAIN,
|
||||
BinarySensorEntity,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE
|
||||
|
@ -39,17 +40,18 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the deCONZ binary sensor."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_sensor(sensors, new=True):
|
||||
def async_add_sensor(sensors):
|
||||
"""Add binary sensor from deCONZ."""
|
||||
entities = []
|
||||
|
||||
for sensor in sensors:
|
||||
|
||||
if (
|
||||
new
|
||||
and sensor.BINARY
|
||||
sensor.BINARY
|
||||
and sensor.uniqueid not in gateway.entities[DOMAIN]
|
||||
and (
|
||||
gateway.option_allow_clip_sensor
|
||||
or not sensor.type.startswith("CLIP")
|
||||
|
@ -73,6 +75,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class DeconzBinarySensor(DeconzDevice, BinarySensorEntity):
|
||||
"""Representation of a deCONZ binary sensor."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update=False, ignore_update=False):
|
||||
"""Update the sensor's state."""
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Support for deCONZ climate devices."""
|
||||
from pydeconz.sensor import Thermostat
|
||||
|
||||
from homeassistant.components.climate import ClimateEntity
|
||||
from homeassistant.components.climate import DOMAIN, ClimateEntity
|
||||
from homeassistant.components.climate.const import (
|
||||
HVAC_MODE_AUTO,
|
||||
HVAC_MODE_HEAT,
|
||||
|
@ -29,17 +29,18 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
Thermostats are based on the same device class as sensors in deCONZ.
|
||||
"""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_climate(sensors, new=True):
|
||||
def async_add_climate(sensors):
|
||||
"""Add climate devices from deCONZ."""
|
||||
entities = []
|
||||
|
||||
for sensor in sensors:
|
||||
|
||||
if (
|
||||
new
|
||||
and sensor.type in Thermostat.ZHATYPE
|
||||
sensor.type in Thermostat.ZHATYPE
|
||||
and sensor.uniqueid not in gateway.entities[DOMAIN]
|
||||
and (
|
||||
gateway.option_allow_clip_sensor
|
||||
or not sensor.type.startswith("CLIP")
|
||||
|
@ -61,6 +62,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class DeconzThermostat(DeconzDevice, ClimateEntity):
|
||||
"""Representation of a deCONZ thermostat."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
DEVICE_CLASS_WINDOW,
|
||||
DOMAIN,
|
||||
SUPPORT_CLOSE,
|
||||
SUPPORT_OPEN,
|
||||
SUPPORT_SET_POSITION,
|
||||
|
@ -23,9 +24,10 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up covers for deCONZ component.
|
||||
|
||||
Covers are based on same device class as lights in deCONZ.
|
||||
Covers are based on the same device class as lights in deCONZ.
|
||||
"""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_cover(lights):
|
||||
|
@ -33,7 +35,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
entities = []
|
||||
|
||||
for light in lights:
|
||||
if light.type in COVER_TYPES:
|
||||
if (
|
||||
light.type in COVER_TYPES
|
||||
and light.uniqueid not in gateway.entities[DOMAIN]
|
||||
):
|
||||
entities.append(DeconzCover(light, gateway))
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
@ -50,6 +55,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class DeconzCover(DeconzDevice, CoverEntity):
|
||||
"""Representation of a deCONZ cover."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
def __init__(self, device, gateway):
|
||||
"""Set up cover device."""
|
||||
super().__init__(device, gateway)
|
||||
|
|
|
@ -10,11 +10,17 @@ from .const import DOMAIN as DECONZ_DOMAIN
|
|||
class DeconzBase:
|
||||
"""Common base for deconz entities and events."""
|
||||
|
||||
TYPE = ""
|
||||
|
||||
def __init__(self, device, gateway):
|
||||
"""Set up device and add update callback to get data from websocket."""
|
||||
self._device = device
|
||||
self.gateway = gateway
|
||||
self.listeners = []
|
||||
self.gateway.entities[self.TYPE].add(self.unique_id)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Remove unique id."""
|
||||
self.gateway.entities[self.TYPE].remove(self.unique_id)
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
|
@ -51,12 +57,6 @@ class DeconzBase:
|
|||
class DeconzDevice(DeconzBase, Entity):
|
||||
"""Representation of a deCONZ device."""
|
||||
|
||||
def __init__(self, device, gateway):
|
||||
"""Set up device and add update callback to get data from websocket."""
|
||||
super().__init__(device, gateway)
|
||||
|
||||
self.unsub_dispatcher = None
|
||||
|
||||
@property
|
||||
def entity_registry_enabled_default(self):
|
||||
"""Return if the entity should be enabled when first added to the entity registry.
|
||||
|
@ -72,7 +72,7 @@ class DeconzDevice(DeconzBase, Entity):
|
|||
"""Subscribe to device events."""
|
||||
self._device.register_callback(self.async_update_callback)
|
||||
self.gateway.deconz_ids[self.entity_id] = self._device.deconz_id
|
||||
self.listeners.append(
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass, self.gateway.signal_reachable, self.async_update_callback
|
||||
)
|
||||
|
@ -83,8 +83,7 @@ class DeconzDevice(DeconzBase, Entity):
|
|||
self._device.remove_callback(self.async_update_callback)
|
||||
if self.entity_id in self.gateway.deconz_ids:
|
||||
del self.gateway.deconz_ids[self.entity_id]
|
||||
for unsub_dispatcher in self.listeners:
|
||||
unsub_dispatcher()
|
||||
await super().async_will_remove_from_hass()
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update=False, ignore_update=False):
|
||||
|
|
|
@ -11,19 +11,25 @@ from .deconz_device import DeconzBase
|
|||
|
||||
CONF_DECONZ_EVENT = "deconz_event"
|
||||
|
||||
EVENT = "Event"
|
||||
|
||||
|
||||
async def async_setup_events(gateway) -> None:
|
||||
"""Set up the deCONZ events."""
|
||||
gateway.entities[EVENT] = set()
|
||||
|
||||
@callback
|
||||
def async_add_sensor(sensors, new=True):
|
||||
def async_add_sensor(sensors):
|
||||
"""Create DeconzEvent."""
|
||||
for sensor in sensors:
|
||||
|
||||
if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"):
|
||||
continue
|
||||
|
||||
if not new or sensor.type not in Switch.ZHATYPE:
|
||||
if (
|
||||
sensor.type not in Switch.ZHATYPE
|
||||
or sensor.uniqueid in gateway.entities[EVENT]
|
||||
):
|
||||
continue
|
||||
|
||||
new_event = DeconzEvent(sensor, gateway)
|
||||
|
@ -44,7 +50,7 @@ async def async_setup_events(gateway) -> None:
|
|||
async def async_unload_events(gateway) -> None:
|
||||
"""Unload all deCONZ events."""
|
||||
for event in gateway.events:
|
||||
event.async_will_remove_from_hass()
|
||||
await event.async_will_remove_from_hass()
|
||||
|
||||
gateway.events.clear()
|
||||
|
||||
|
@ -56,6 +62,8 @@ class DeconzEvent(DeconzBase):
|
|||
instead of a sensor entity in hass.
|
||||
"""
|
||||
|
||||
TYPE = EVENT
|
||||
|
||||
def __init__(self, device, gateway):
|
||||
"""Register callback that will be used for signals."""
|
||||
super().__init__(device, gateway)
|
||||
|
@ -71,11 +79,10 @@ class DeconzEvent(DeconzBase):
|
|||
"""Return Event device."""
|
||||
return self._device
|
||||
|
||||
@callback
|
||||
def async_will_remove_from_hass(self) -> None:
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Disconnect event object when removed."""
|
||||
self._device.remove_callback(self.async_update_callback)
|
||||
self._device = None
|
||||
await super().async_will_remove_from_hass()
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update=False, ignore_update=False):
|
||||
|
|
|
@ -49,6 +49,8 @@ class DeconzGateway:
|
|||
self.events = []
|
||||
self.listeners = []
|
||||
|
||||
self.entities = {}
|
||||
|
||||
self._current_option_allow_clip_sensor = self.option_allow_clip_sensor
|
||||
self._current_option_allow_deconz_groups = self.option_allow_deconz_groups
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ from homeassistant.components.light import (
|
|||
ATTR_FLASH,
|
||||
ATTR_HS_COLOR,
|
||||
ATTR_TRANSITION,
|
||||
DOMAIN,
|
||||
EFFECT_COLORLOOP,
|
||||
FLASH_LONG,
|
||||
FLASH_SHORT,
|
||||
|
@ -40,6 +41,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the deCONZ lights and groups from a config entry."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_light(lights):
|
||||
|
@ -47,7 +49,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
entities = []
|
||||
|
||||
for light in lights:
|
||||
if light.type not in COVER_TYPES + SWITCH_TYPES:
|
||||
if (
|
||||
light.type not in COVER_TYPES + SWITCH_TYPES
|
||||
and light.uniqueid not in gateway.entities[DOMAIN]
|
||||
):
|
||||
entities.append(DeconzLight(light, gateway))
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
@ -67,8 +72,13 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
entities = []
|
||||
|
||||
for group in groups:
|
||||
if group.lights:
|
||||
entities.append(DeconzGroup(group, gateway))
|
||||
if not group.lights:
|
||||
continue
|
||||
|
||||
known_groups = list(gateway.entities[DOMAIN])
|
||||
new_group = DeconzGroup(group, gateway)
|
||||
if new_group.unique_id not in known_groups:
|
||||
entities.append(new_group)
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
@ -85,6 +95,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class DeconzBaseLight(DeconzDevice, LightEntity):
|
||||
"""Representation of a deCONZ light."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
def __init__(self, device, gateway):
|
||||
"""Set up light."""
|
||||
super().__init__(device, gateway)
|
||||
|
@ -223,14 +235,13 @@ class DeconzGroup(DeconzBaseLight):
|
|||
|
||||
def __init__(self, device, gateway):
|
||||
"""Set up group and create an unique id."""
|
||||
group_id_base = gateway.config_entry.unique_id
|
||||
if CONF_GROUP_ID_BASE in gateway.config_entry.data:
|
||||
group_id_base = gateway.config_entry.data[CONF_GROUP_ID_BASE]
|
||||
self._unique_id = f"{group_id_base}-{device.deconz_id}"
|
||||
|
||||
super().__init__(device, gateway)
|
||||
|
||||
group_id_base = self.gateway.config_entry.unique_id
|
||||
if CONF_GROUP_ID_BASE in self.gateway.config_entry.data:
|
||||
group_id_base = self.gateway.config_entry.data[CONF_GROUP_ID_BASE]
|
||||
|
||||
self._unique_id = f"{group_id_base}-{self._device.deconz_id}"
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique identifier for this device."""
|
||||
|
|
|
@ -12,6 +12,7 @@ from pydeconz.sensor import (
|
|||
Thermostat,
|
||||
)
|
||||
|
||||
from homeassistant.components.sensor import DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_TEMPERATURE,
|
||||
ATTR_VOLTAGE,
|
||||
|
@ -74,43 +75,43 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the deCONZ sensors."""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
batteries = set()
|
||||
battery_handler = DeconzBatteryHandler(gateway)
|
||||
|
||||
@callback
|
||||
def async_add_sensor(sensors, new=True):
|
||||
def async_add_sensor(sensors):
|
||||
"""Add sensors from deCONZ.
|
||||
|
||||
Create DeconzSensor if not a ZHAType and not a binary sensor.
|
||||
Create DeconzBattery if sensor has a battery attribute.
|
||||
If new is false it means an existing sensor has got a battery state reported.
|
||||
Create DeconzSensor if not a battery, switch or thermostat and not a binary sensor.
|
||||
"""
|
||||
entities = []
|
||||
|
||||
for sensor in sensors:
|
||||
|
||||
if (
|
||||
new
|
||||
and sensor.BINARY is False
|
||||
and sensor.type
|
||||
not in Battery.ZHATYPE + Switch.ZHATYPE + Thermostat.ZHATYPE
|
||||
and (
|
||||
gateway.option_allow_clip_sensor
|
||||
or not sensor.type.startswith("CLIP")
|
||||
)
|
||||
):
|
||||
entities.append(DeconzSensor(sensor, gateway))
|
||||
if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"):
|
||||
continue
|
||||
|
||||
if sensor.battery is not None:
|
||||
battery_handler.remove_tracker(sensor)
|
||||
|
||||
known_batteries = list(gateway.entities[DOMAIN])
|
||||
new_battery = DeconzBattery(sensor, gateway)
|
||||
if new_battery.unique_id not in batteries:
|
||||
batteries.add(new_battery.unique_id)
|
||||
if new_battery.unique_id not in known_batteries:
|
||||
entities.append(new_battery)
|
||||
battery_handler.remove_tracker(sensor)
|
||||
|
||||
else:
|
||||
battery_handler.create_tracker(sensor)
|
||||
|
||||
if (
|
||||
not sensor.BINARY
|
||||
and sensor.type
|
||||
not in Battery.ZHATYPE + Switch.ZHATYPE + Thermostat.ZHATYPE
|
||||
and sensor.uniqueid not in gateway.entities[DOMAIN]
|
||||
):
|
||||
entities.append(DeconzSensor(sensor, gateway))
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
||||
gateway.listeners.append(
|
||||
|
@ -127,6 +128,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class DeconzSensor(DeconzDevice):
|
||||
"""Representation of a deCONZ sensor."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update=False, ignore_update=False):
|
||||
"""Update the sensor's state."""
|
||||
|
@ -192,6 +195,8 @@ class DeconzSensor(DeconzDevice):
|
|||
class DeconzBattery(DeconzDevice):
|
||||
"""Battery class for when a device is only represented as an event."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update=False, ignore_update=False):
|
||||
"""Update the battery's state, if needed."""
|
||||
|
@ -264,7 +269,6 @@ class DeconzSensorStateTracker:
|
|||
self.gateway.hass,
|
||||
self.gateway.async_signal_new_device(NEW_SENSOR),
|
||||
[self.sensor],
|
||||
False,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Support for deCONZ switches."""
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.components.switch import DOMAIN, SwitchEntity
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
|
@ -15,9 +15,10 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up switches for deCONZ component.
|
||||
|
||||
Switches are based same device class as lights in deCONZ.
|
||||
Switches are based on the same device class as lights in deCONZ.
|
||||
"""
|
||||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
@callback
|
||||
def async_add_switch(lights):
|
||||
|
@ -26,10 +27,15 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
|
||||
for light in lights:
|
||||
|
||||
if light.type in POWER_PLUGS:
|
||||
if (
|
||||
light.type in POWER_PLUGS
|
||||
and light.uniqueid not in gateway.entities[DOMAIN]
|
||||
):
|
||||
entities.append(DeconzPowerPlug(light, gateway))
|
||||
|
||||
elif light.type in SIRENS:
|
||||
elif (
|
||||
light.type in SIRENS and light.uniqueid not in gateway.entities[DOMAIN]
|
||||
):
|
||||
entities.append(DeconzSiren(light, gateway))
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
@ -46,6 +52,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class DeconzPowerPlug(DeconzDevice, SwitchEntity):
|
||||
"""Representation of a deCONZ power plug."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if switch is on."""
|
||||
|
@ -65,6 +73,8 @@ class DeconzPowerPlug(DeconzDevice, SwitchEntity):
|
|||
class DeconzSiren(DeconzDevice, SwitchEntity):
|
||||
"""Representation of a deCONZ siren."""
|
||||
|
||||
TYPE = DOMAIN
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return true if switch is on."""
|
||||
|
|
|
@ -67,6 +67,7 @@ async def test_no_binary_sensors(hass):
|
|||
"""Test that no sensors in deconz results in no sensor entities."""
|
||||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 0
|
||||
assert len(hass.states.async_all()) == 0
|
||||
|
||||
|
||||
|
@ -80,6 +81,7 @@ async def test_binary_sensors(hass):
|
|||
assert "binary_sensor.clip_presence_sensor" not in gateway.deconz_ids
|
||||
assert "binary_sensor.vibration_sensor" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 3
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 2
|
||||
|
||||
presence_sensor = hass.states.get("binary_sensor.presence_sensor")
|
||||
assert presence_sensor.state == "off"
|
||||
|
@ -111,6 +113,7 @@ async def test_binary_sensors(hass):
|
|||
await gateway.async_reset()
|
||||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_allow_clip_sensor(hass):
|
||||
|
@ -127,6 +130,7 @@ async def test_allow_clip_sensor(hass):
|
|||
assert "binary_sensor.clip_presence_sensor" in gateway.deconz_ids
|
||||
assert "binary_sensor.vibration_sensor" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 4
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 3
|
||||
|
||||
presence_sensor = hass.states.get("binary_sensor.presence_sensor")
|
||||
assert presence_sensor.state == "off"
|
||||
|
@ -150,6 +154,7 @@ async def test_allow_clip_sensor(hass):
|
|||
assert "binary_sensor.clip_presence_sensor" not in gateway.deconz_ids
|
||||
assert "binary_sensor.vibration_sensor" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 3
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 2
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True}
|
||||
|
@ -161,12 +166,14 @@ async def test_allow_clip_sensor(hass):
|
|||
assert "binary_sensor.clip_presence_sensor" in gateway.deconz_ids
|
||||
assert "binary_sensor.vibration_sensor" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 4
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 3
|
||||
|
||||
|
||||
async def test_add_new_binary_sensor(hass):
|
||||
"""Test that adding a new binary sensor works."""
|
||||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 0
|
||||
|
||||
state_added_event = {
|
||||
"t": "event",
|
||||
|
@ -182,3 +189,4 @@ async def test_add_new_binary_sensor(hass):
|
|||
|
||||
presence_sensor = hass.states.get("binary_sensor.presence_sensor")
|
||||
assert presence_sensor.state == "off"
|
||||
assert len(gateway.entities[binary_sensor.DOMAIN]) == 1
|
||||
|
|
|
@ -59,6 +59,7 @@ async def test_no_sensors(hass):
|
|||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_climate_devices(hass):
|
||||
|
@ -72,6 +73,7 @@ async def test_climate_devices(hass):
|
|||
assert "climate.presence_sensor" not in gateway.deconz_ids
|
||||
assert "climate.clip_thermostat" not in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 3
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 1
|
||||
|
||||
thermostat = hass.states.get("climate.thermostat")
|
||||
assert thermostat.state == "auto"
|
||||
|
@ -181,6 +183,7 @@ async def test_climate_devices(hass):
|
|||
await gateway.async_reset()
|
||||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_clip_climate_device(hass):
|
||||
|
@ -198,6 +201,7 @@ async def test_clip_climate_device(hass):
|
|||
assert "climate.presence_sensor" not in gateway.deconz_ids
|
||||
assert "climate.clip_thermostat" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 4
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 2
|
||||
|
||||
thermostat = hass.states.get("climate.thermostat")
|
||||
assert thermostat.state == "auto"
|
||||
|
@ -225,6 +229,7 @@ async def test_clip_climate_device(hass):
|
|||
assert "climate.presence_sensor" not in gateway.deconz_ids
|
||||
assert "climate.clip_thermostat" not in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 3
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 1
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True}
|
||||
|
@ -237,6 +242,7 @@ async def test_clip_climate_device(hass):
|
|||
assert "climate.presence_sensor" not in gateway.deconz_ids
|
||||
assert "climate.clip_thermostat" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 4
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 2
|
||||
|
||||
|
||||
async def test_verify_state_update(hass):
|
||||
|
@ -268,6 +274,7 @@ async def test_add_new_climate_device(hass):
|
|||
"""Test that adding a new climate device works."""
|
||||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 0
|
||||
|
||||
state_added_event = {
|
||||
"t": "event",
|
||||
|
@ -283,3 +290,4 @@ async def test_add_new_climate_device(hass):
|
|||
|
||||
thermostat = hass.states.get("climate.thermostat")
|
||||
assert thermostat.state == "auto"
|
||||
assert len(gateway.entities[climate.DOMAIN]) == 1
|
||||
|
|
|
@ -67,6 +67,7 @@ async def test_no_covers(hass):
|
|||
"""Test that no cover entities are created."""
|
||||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(gateway.entities[cover.DOMAIN]) == 0
|
||||
assert len(hass.states.async_all()) == 0
|
||||
|
||||
|
||||
|
@ -81,6 +82,7 @@ async def test_cover(hass):
|
|||
assert "cover.deconz_old_brightness_cover" in gateway.deconz_ids
|
||||
assert "cover.window_covering_controller" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 5
|
||||
assert len(gateway.entities[cover.DOMAIN]) == 4
|
||||
|
||||
level_controllable_cover = hass.states.get("cover.level_controllable_cover")
|
||||
assert level_controllable_cover.state == "open"
|
||||
|
@ -158,3 +160,4 @@ async def test_cover(hass):
|
|||
await gateway.async_reset()
|
||||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[cover.DOMAIN]) == 0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Test deCONZ remote events."""
|
||||
from copy import deepcopy
|
||||
|
||||
from homeassistant.components.deconz.deconz_event import CONF_DECONZ_EVENT
|
||||
from homeassistant.components.deconz.deconz_event import CONF_DECONZ_EVENT, EVENT
|
||||
|
||||
from .test_gateway import DECONZ_WEB_REQUEST, setup_deconz_integration
|
||||
|
||||
|
@ -62,6 +62,7 @@ async def test_deconz_events(hass):
|
|||
assert "sensor.switch_2_battery_level" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 3
|
||||
assert len(gateway.events) == 5
|
||||
assert len(gateway.entities[EVENT]) == 5
|
||||
|
||||
switch_1 = hass.states.get("sensor.switch_1")
|
||||
assert switch_1 is None
|
||||
|
@ -127,3 +128,4 @@ async def test_deconz_events(hass):
|
|||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.events) == 0
|
||||
assert len(gateway.entities[EVENT]) == 0
|
||||
|
|
|
@ -95,6 +95,7 @@ async def test_no_lights_or_groups(hass):
|
|||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[light.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_lights_and_groups(hass):
|
||||
|
@ -111,6 +112,7 @@ async def test_lights_and_groups(hass):
|
|||
assert "light.on_off_light" in gateway.deconz_ids
|
||||
|
||||
assert len(hass.states.async_all()) == 6
|
||||
assert len(gateway.entities[light.DOMAIN]) == 5
|
||||
|
||||
rgb_light = hass.states.get("light.rgb_light")
|
||||
assert rgb_light.state == "on"
|
||||
|
@ -256,6 +258,7 @@ async def test_lights_and_groups(hass):
|
|||
await gateway.async_reset()
|
||||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[light.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_disable_light_groups(hass):
|
||||
|
@ -275,6 +278,7 @@ async def test_disable_light_groups(hass):
|
|||
assert "light.on_off_switch" not in gateway.deconz_ids
|
||||
# 3 entities
|
||||
assert len(hass.states.async_all()) == 5
|
||||
assert len(gateway.entities[light.DOMAIN]) == 4
|
||||
|
||||
rgb_light = hass.states.get("light.rgb_light")
|
||||
assert rgb_light is not None
|
||||
|
@ -300,6 +304,7 @@ async def test_disable_light_groups(hass):
|
|||
assert "light.on_off_switch" not in gateway.deconz_ids
|
||||
# 3 entities
|
||||
assert len(hass.states.async_all()) == 6
|
||||
assert len(gateway.entities[light.DOMAIN]) == 5
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
gateway.config_entry, options={deconz.gateway.CONF_ALLOW_DECONZ_GROUPS: False}
|
||||
|
@ -313,3 +318,4 @@ async def test_disable_light_groups(hass):
|
|||
assert "light.on_off_switch" not in gateway.deconz_ids
|
||||
# 3 entities
|
||||
assert len(hass.states.async_all()) == 5
|
||||
assert len(gateway.entities[light.DOMAIN]) == 4
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
from copy import deepcopy
|
||||
|
||||
from homeassistant.components import deconz
|
||||
from homeassistant.components.deconz.deconz_event import EVENT
|
||||
import homeassistant.components.sensor as sensor
|
||||
from homeassistant.const import (
|
||||
DEVICE_CLASS_BATTERY,
|
||||
|
@ -96,6 +97,7 @@ async def test_no_sensors(hass):
|
|||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_sensors(hass):
|
||||
|
@ -114,6 +116,7 @@ async def test_sensors(hass):
|
|||
assert "sensor.consumption_sensor" in gateway.deconz_ids
|
||||
assert "sensor.clip_light_level_sensor" not in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 5
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 5
|
||||
|
||||
light_level_sensor = hass.states.get("sensor.light_level_sensor")
|
||||
assert light_level_sensor.state == "999.8"
|
||||
|
@ -174,6 +177,8 @@ async def test_sensors(hass):
|
|||
await gateway.async_reset()
|
||||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
# Daylight sensor from deCONZ is added to set but is disabled by default
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 1
|
||||
|
||||
|
||||
async def test_allow_clip_sensors(hass):
|
||||
|
@ -196,6 +201,7 @@ async def test_allow_clip_sensors(hass):
|
|||
assert "sensor.consumption_sensor" in gateway.deconz_ids
|
||||
assert "sensor.clip_light_level_sensor" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 6
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 6
|
||||
|
||||
light_level_sensor = hass.states.get("sensor.light_level_sensor")
|
||||
assert light_level_sensor.state == "999.8"
|
||||
|
@ -243,6 +249,7 @@ async def test_allow_clip_sensors(hass):
|
|||
assert "sensor.consumption_sensor" in gateway.deconz_ids
|
||||
assert "sensor.clip_light_level_sensor" not in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 5
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 5
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True}
|
||||
|
@ -260,6 +267,7 @@ async def test_allow_clip_sensors(hass):
|
|||
assert "sensor.consumption_sensor" in gateway.deconz_ids
|
||||
assert "sensor.clip_light_level_sensor" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 6
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 6
|
||||
|
||||
|
||||
async def test_add_new_sensor(hass):
|
||||
|
@ -292,6 +300,8 @@ async def test_add_battery_later(hass):
|
|||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(gateway.events) == 1
|
||||
assert len(remote._callbacks) == 2
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 0
|
||||
assert len(gateway.entities[EVENT]) == 1
|
||||
|
||||
remote.update({"config": {"battery": 50}})
|
||||
await hass.async_block_till_done()
|
||||
|
@ -302,3 +312,5 @@ async def test_add_battery_later(hass):
|
|||
|
||||
battery_sensor = hass.states.get("sensor.switch_1_battery_level")
|
||||
assert battery_sensor is not None
|
||||
assert len(gateway.entities[sensor.DOMAIN]) == 1
|
||||
assert len(gateway.entities[EVENT]) == 1
|
||||
|
|
|
@ -64,6 +64,7 @@ async def test_no_switches(hass):
|
|||
gateway = await setup_deconz_integration(hass)
|
||||
assert len(gateway.deconz_ids) == 0
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[switch.DOMAIN]) == 0
|
||||
|
||||
|
||||
async def test_switches(hass):
|
||||
|
@ -77,6 +78,7 @@ async def test_switches(hass):
|
|||
assert "switch.unsupported_switch" not in gateway.deconz_ids
|
||||
assert "switch.on_off_relay" in gateway.deconz_ids
|
||||
assert len(hass.states.async_all()) == 5
|
||||
assert len(gateway.entities[switch.DOMAIN]) == 4
|
||||
|
||||
on_off_switch = hass.states.get("switch.on_off_switch")
|
||||
assert on_off_switch.state == "on"
|
||||
|
@ -173,3 +175,4 @@ async def test_switches(hass):
|
|||
await gateway.async_reset()
|
||||
|
||||
assert len(hass.states.async_all()) == 0
|
||||
assert len(gateway.entities[switch.DOMAIN]) == 0
|
||||
|
|
Loading…
Add table
Reference in a new issue