diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index c8917934dd7..eefd66778ad 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -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.""" diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index 424693505ca..10ea7173f8a 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -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.""" diff --git a/homeassistant/components/deconz/cover.py b/homeassistant/components/deconz/cover.py index 996727d366b..7bcd821a344 100644 --- a/homeassistant/components/deconz/cover.py +++ b/homeassistant/components/deconz/cover.py @@ -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) diff --git a/homeassistant/components/deconz/deconz_device.py b/homeassistant/components/deconz/deconz_device.py index b77014cc34b..56dc00dab58 100644 --- a/homeassistant/components/deconz/deconz_device.py +++ b/homeassistant/components/deconz/deconz_device.py @@ -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): diff --git a/homeassistant/components/deconz/deconz_event.py b/homeassistant/components/deconz/deconz_event.py index bde2db90663..4b7027b8b36 100644 --- a/homeassistant/components/deconz/deconz_event.py +++ b/homeassistant/components/deconz/deconz_event.py @@ -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): diff --git a/homeassistant/components/deconz/gateway.py b/homeassistant/components/deconz/gateway.py index d3a781302e5..ceed473a383 100644 --- a/homeassistant/components/deconz/gateway.py +++ b/homeassistant/components/deconz/gateway.py @@ -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 diff --git a/homeassistant/components/deconz/light.py b/homeassistant/components/deconz/light.py index fc0c01b30df..135a01cd0df 100644 --- a/homeassistant/components/deconz/light.py +++ b/homeassistant/components/deconz/light.py @@ -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.""" diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index 72465282421..d7d7b777b41 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -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, ) diff --git a/homeassistant/components/deconz/switch.py b/homeassistant/components/deconz/switch.py index d7b6b55fbb8..dacae4d4a56 100644 --- a/homeassistant/components/deconz/switch.py +++ b/homeassistant/components/deconz/switch.py @@ -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.""" diff --git a/tests/components/deconz/test_binary_sensor.py b/tests/components/deconz/test_binary_sensor.py index 30f7251e067..1ced3b8ed2d 100644 --- a/tests/components/deconz/test_binary_sensor.py +++ b/tests/components/deconz/test_binary_sensor.py @@ -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 diff --git a/tests/components/deconz/test_climate.py b/tests/components/deconz/test_climate.py index ddc89295cba..361e182fe98 100644 --- a/tests/components/deconz/test_climate.py +++ b/tests/components/deconz/test_climate.py @@ -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 diff --git a/tests/components/deconz/test_cover.py b/tests/components/deconz/test_cover.py index 095ae7e4bc5..28a6f150fc4 100644 --- a/tests/components/deconz/test_cover.py +++ b/tests/components/deconz/test_cover.py @@ -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 diff --git a/tests/components/deconz/test_deconz_event.py b/tests/components/deconz/test_deconz_event.py index 525821e389f..717c783d0ed 100644 --- a/tests/components/deconz/test_deconz_event.py +++ b/tests/components/deconz/test_deconz_event.py @@ -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 diff --git a/tests/components/deconz/test_light.py b/tests/components/deconz/test_light.py index 4e9f6b3d512..dac1b071e93 100644 --- a/tests/components/deconz/test_light.py +++ b/tests/components/deconz/test_light.py @@ -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 diff --git a/tests/components/deconz/test_sensor.py b/tests/components/deconz/test_sensor.py index 9d87c7b91cb..8c7829586e4 100644 --- a/tests/components/deconz/test_sensor.py +++ b/tests/components/deconz/test_sensor.py @@ -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 diff --git a/tests/components/deconz/test_switch.py b/tests/components/deconz/test_switch.py index b441868859b..7b1e0e6121c 100644 --- a/tests/components/deconz/test_switch.py +++ b/tests/components/deconz/test_switch.py @@ -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