diff --git a/homeassistant/components/deconz/alarm_control_panel.py b/homeassistant/components/deconz/alarm_control_panel.py index 00d21f8141e..73e85f13713 100644 --- a/homeassistant/components/deconz/alarm_control_panel.py +++ b/homeassistant/components/deconz/alarm_control_panel.py @@ -76,7 +76,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None: for sensor in sensors: if ( - sensor.type in AncillaryControl.ZHATYPE + isinstance(sensor, AncillaryControl) and sensor.unique_id not in gateway.entities[DOMAIN] and get_alarm_system_for_unique_id(gateway, sensor.unique_id) ): diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index 7dd569388e1..96de780c137 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -1,5 +1,15 @@ """Support for deCONZ binary sensors.""" -from pydeconz.sensor import CarbonMonoxide, Fire, OpenClose, Presence, Vibration, Water +from pydeconz.sensor import ( + Alarm, + CarbonMonoxide, + Fire, + GenericFlag, + GenericStatus, + OpenClose, + Presence, + Vibration, + Water, +) from homeassistant.components.binary_sensor import ( DEVICE_CLASS_GAS, @@ -21,6 +31,18 @@ from .const import ATTR_DARK, ATTR_ON, NEW_SENSOR from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry +DECONZ_BINARY_SENSORS = ( + Alarm, + CarbonMonoxide, + Fire, + GenericFlag, + GenericStatus, + OpenClose, + Presence, + Vibration, + Water, +) + ATTR_ORIENTATION = "orientation" ATTR_TILTANGLE = "tiltangle" ATTR_VIBRATIONSTRENGTH = "vibrationstrength" @@ -65,13 +87,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for sensor in sensors: + if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): + continue + if ( - sensor.BINARY + isinstance(sensor, DECONZ_BINARY_SENSORS) and sensor.unique_id not in gateway.entities[DOMAIN] - and ( - gateway.option_allow_clip_sensor - or not sensor.type.startswith("CLIP") - ) ): entities.append(DeconzBinarySensor(sensor, gateway)) diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index 307636480c9..86c19be3cd2 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -84,13 +84,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for sensor in sensors: + if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): + continue + if ( - sensor.type in Thermostat.ZHATYPE + isinstance(sensor, Thermostat) and sensor.unique_id not in gateway.entities[DOMAIN] - and ( - gateway.option_allow_clip_sensor - or not sensor.type.startswith("CLIP") - ) ): entities.append(DeconzThermostat(sensor, gateway)) diff --git a/homeassistant/components/deconz/const.py b/homeassistant/components/deconz/const.py index e961a62c7a0..67753aa0355 100644 --- a/homeassistant/components/deconz/const.py +++ b/homeassistant/components/deconz/const.py @@ -57,23 +57,6 @@ ATTR_OFFSET = "offset" ATTR_ON = "on" ATTR_VALVE = "valve" -# Covers -LEVEL_CONTROLLABLE_OUTPUT = "Level controllable output" -DAMPERS = [LEVEL_CONTROLLABLE_OUTPUT] -WINDOW_COVERING_CONTROLLER = "Window covering controller" -WINDOW_COVERING_DEVICE = "Window covering device" -WINDOW_COVERS = [WINDOW_COVERING_CONTROLLER, WINDOW_COVERING_DEVICE] -COVER_TYPES = DAMPERS + WINDOW_COVERS - -# Fans -FANS = ["Fan"] - -# Locks -LOCK_TYPES = ["Door Lock", "ZHADoorLock"] - -# Sirens -SIRENS = ["Warning device"] - # Switches POWER_PLUGS = ["On/Off light", "On/Off plug-in unit", "Smart plug"] diff --git a/homeassistant/components/deconz/cover.py b/homeassistant/components/deconz/cover.py index bc16b7881af..abf1fe4eea4 100644 --- a/homeassistant/components/deconz/cover.py +++ b/homeassistant/components/deconz/cover.py @@ -1,4 +1,7 @@ """Support for deCONZ covers.""" + +from pydeconz.light import Cover + from homeassistant.components.cover import ( ATTR_POSITION, ATTR_TILT_POSITION, @@ -18,20 +21,14 @@ from homeassistant.components.cover import ( from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from .const import ( - COVER_TYPES, - LEVEL_CONTROLLABLE_OUTPUT, - NEW_LIGHT, - WINDOW_COVERING_CONTROLLER, - WINDOW_COVERING_DEVICE, -) +from .const import NEW_LIGHT from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry DEVICE_CLASS = { - LEVEL_CONTROLLABLE_OUTPUT: DEVICE_CLASS_DAMPER, - WINDOW_COVERING_CONTROLLER: DEVICE_CLASS_SHADE, - WINDOW_COVERING_DEVICE: DEVICE_CLASS_SHADE, + "Level controllable output": DEVICE_CLASS_DAMPER, + "Window covering controller": DEVICE_CLASS_SHADE, + "Window covering device": DEVICE_CLASS_SHADE, } @@ -47,7 +44,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for light in lights: if ( - light.type in COVER_TYPES + isinstance(light, Cover) and light.unique_id not in gateway.entities[DOMAIN] ): entities.append(DeconzCover(light, gateway)) diff --git a/homeassistant/components/deconz/deconz_device.py b/homeassistant/components/deconz/deconz_device.py index 06b86ee214a..fe9eaa8ff60 100644 --- a/homeassistant/components/deconz/deconz_device.py +++ b/homeassistant/components/deconz/deconz_device.py @@ -1,4 +1,5 @@ """Base class for deCONZ devices.""" + from homeassistant.core import callback from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE from homeassistant.helpers.dispatcher import async_dispatcher_connect diff --git a/homeassistant/components/deconz/deconz_event.py b/homeassistant/components/deconz/deconz_event.py index ce67d2a4b29..2d9799c4d02 100644 --- a/homeassistant/components/deconz/deconz_event.py +++ b/homeassistant/components/deconz/deconz_event.py @@ -40,23 +40,24 @@ async def async_setup_events(gateway) -> None: @callback def async_add_sensor(sensors=gateway.api.sensors.values()): """Create DeconzEvent.""" + new_events = [] + known_events = {event.unique_id for event in gateway.events} + for sensor in sensors: if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): continue - if ( - sensor.type not in Switch.ZHATYPE + AncillaryControl.ZHATYPE - or sensor.unique_id in {event.unique_id for event in gateway.events} - ): + if sensor.unique_id in known_events: continue - if sensor.type in Switch.ZHATYPE: - new_event = DeconzEvent(sensor, gateway) + if isinstance(sensor, Switch): + new_events.append(DeconzEvent(sensor, gateway)) - elif sensor.type in AncillaryControl.ZHATYPE: - new_event = DeconzAlarmEvent(sensor, gateway) + elif isinstance(sensor, AncillaryControl): + new_events.append(DeconzAlarmEvent(sensor, gateway)) + for new_event in new_events: gateway.hass.async_create_task(new_event.async_update_device_registry()) gateway.events.append(new_event) diff --git a/homeassistant/components/deconz/fan.py b/homeassistant/components/deconz/fan.py index 8a94b78b85f..38fc087cdfd 100644 --- a/homeassistant/components/deconz/fan.py +++ b/homeassistant/components/deconz/fan.py @@ -1,6 +1,8 @@ """Support for deCONZ fans.""" from __future__ import annotations +from pydeconz.light import Fan + from homeassistant.components.fan import ( DOMAIN, SPEED_HIGH, @@ -17,7 +19,7 @@ from homeassistant.util.percentage import ( percentage_to_ordered_list_item, ) -from .const import FANS, NEW_LIGHT +from .const import NEW_LIGHT from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry @@ -39,7 +41,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None: for light in lights: - if light.type in FANS and light.unique_id not in gateway.entities[DOMAIN]: + if ( + isinstance(light, Fan) + and light.unique_id not in gateway.entities[DOMAIN] + ): entities.append(DeconzFan(light, gateway)) if entities: diff --git a/homeassistant/components/deconz/light.py b/homeassistant/components/deconz/light.py index 3c48fbc5177..2202bdbe58f 100644 --- a/homeassistant/components/deconz/light.py +++ b/homeassistant/components/deconz/light.py @@ -2,6 +2,8 @@ from __future__ import annotations +from pydeconz.light import Light + from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, @@ -28,25 +30,12 @@ from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.util.color import color_hs_to_xy -from .const import ( - COVER_TYPES, - DOMAIN as DECONZ_DOMAIN, - LOCK_TYPES, - NEW_GROUP, - NEW_LIGHT, - POWER_PLUGS, - SIRENS, -) +from .const import DOMAIN as DECONZ_DOMAIN, NEW_GROUP, NEW_LIGHT, POWER_PLUGS from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry -CONTROLLER = ["Configuration tool"] DECONZ_GROUP = "is_deconz_group" -OTHER_LIGHT_RESOURCE_TYPES = ( - CONTROLLER + COVER_TYPES + LOCK_TYPES + POWER_PLUGS + SIRENS -) - async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the deCONZ lights and groups from a config entry.""" @@ -60,7 +49,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for light in lights: if ( - light.type not in OTHER_LIGHT_RESOURCE_TYPES + isinstance(light, Light) + and light.type not in POWER_PLUGS and light.unique_id not in gateway.entities[DOMAIN] ): entities.append(DeconzLight(light, gateway)) diff --git a/homeassistant/components/deconz/lock.py b/homeassistant/components/deconz/lock.py index 19770734087..bb23ec4be7a 100644 --- a/homeassistant/components/deconz/lock.py +++ b/homeassistant/components/deconz/lock.py @@ -1,9 +1,13 @@ """Support for deCONZ locks.""" + +from pydeconz.light import Lock +from pydeconz.sensor import DoorLock + from homeassistant.components.lock import DOMAIN, LockEntity from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from .const import LOCK_TYPES, NEW_LIGHT, NEW_SENSOR +from .const import NEW_LIGHT, NEW_SENSOR from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry @@ -21,7 +25,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for light in lights: if ( - light.type in LOCK_TYPES + isinstance(light, Lock) and light.unique_id not in gateway.entities[DOMAIN] ): entities.append(DeconzLock(light, gateway)) @@ -43,7 +47,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): for sensor in sensors: if ( - sensor.type in LOCK_TYPES + isinstance(sensor, DoorLock) and sensor.unique_id not in gateway.entities[DOMAIN] ): entities.append(DeconzLock(sensor, gateway)) diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index 5c826e61516..e0e979ccf0b 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -1,10 +1,9 @@ """Support for deCONZ sensors.""" from pydeconz.sensor import ( - AncillaryControl, + AirQuality, Battery, Consumption, Daylight, - DoorLock, Humidity, LightLevel, Power, @@ -12,6 +11,7 @@ from pydeconz.sensor import ( Switch, Temperature, Thermostat, + Time, ) from homeassistant.components.sensor import ( @@ -48,6 +48,18 @@ from .const import ATTR_DARK, ATTR_ON, NEW_SENSOR from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry +DECONZ_SENSORS = ( + AirQuality, + Consumption, + Daylight, + Humidity, + LightLevel, + Power, + Pressure, + Temperature, + Time, +) + ATTR_CURRENT = "current" ATTR_POWER = "power" ATTR_DAYLIGHT = "daylight" @@ -136,13 +148,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): battery_handler.create_tracker(sensor) if ( - not sensor.BINARY - and sensor.type - not in AncillaryControl.ZHATYPE - + Battery.ZHATYPE - + DoorLock.ZHATYPE - + Switch.ZHATYPE - + Thermostat.ZHATYPE + isinstance(sensor, DECONZ_SENSORS) + and not isinstance(sensor, Thermostat) and sensor.unique_id not in gateway.entities[DOMAIN] ): entities.append(DeconzSensor(sensor, gateway)) @@ -301,7 +308,7 @@ class DeconzBattery(DeconzDevice, SensorEntity): """Return the state attributes of the battery.""" attr = {} - if self._device.type in Switch.ZHATYPE: + if isinstance(self._device, Switch): for event in self.gateway.events: if self._device == event.device: attr[ATTR_EVENT_ID] = event.event_id diff --git a/homeassistant/components/deconz/switch.py b/homeassistant/components/deconz/switch.py index 8f31af3a6cf..f7559e37838 100644 --- a/homeassistant/components/deconz/switch.py +++ b/homeassistant/components/deconz/switch.py @@ -1,9 +1,12 @@ """Support for deCONZ switches.""" + +from pydeconz.light import Siren + from homeassistant.components.switch import DOMAIN, SwitchEntity from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from .const import DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, POWER_PLUGS, SIRENS +from .const import DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, POWER_PLUGS from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry @@ -20,10 +23,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # Siren platform replacing sirens in switch platform added in 2021.10 for light in gateway.api.lights.values(): - if light.type not in SIRENS: - continue - if entity_id := entity_registry.async_get_entity_id( - DOMAIN, DECONZ_DOMAIN, light.unique_id + if isinstance(light, Siren) and ( + entity_id := entity_registry.async_get_entity_id( + DOMAIN, DECONZ_DOMAIN, light.unique_id + ) ): entity_registry.async_remove(entity_id) diff --git a/tests/components/deconz/test_sensor.py b/tests/components/deconz/test_sensor.py index 7f8bce24d80..33f9c8c6a2c 100644 --- a/tests/components/deconz/test_sensor.py +++ b/tests/components/deconz/test_sensor.py @@ -15,7 +15,6 @@ from homeassistant.const import ( DEVICE_CLASS_POWER, DEVICE_CLASS_TEMPERATURE, STATE_UNAVAILABLE, - STATE_UNKNOWN, ) from homeassistant.helpers import entity_registry as er from homeassistant.util import dt @@ -553,5 +552,4 @@ async def test_unsupported_sensor(hass, aioclient_mock): with patch.dict(DECONZ_WEB_REQUEST, data): await setup_deconz_integration(hass, aioclient_mock) - assert len(hass.states.async_all()) == 1 - assert hass.states.get("sensor.name").state == STATE_UNKNOWN + assert len(hass.states.async_all()) == 0