diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index 0d090751edd..814dec443e0 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -24,7 +24,6 @@ from homeassistant.components.binary_sensor import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.helpers.entity_registry as er @@ -215,9 +214,6 @@ async def async_setup_entry( """Add sensor from deCONZ.""" sensor = gateway.api.sensors[sensor_id] - if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): - return - for description in ( ENTITY_DESCRIPTIONS.get(type(sensor), []) + BINARY_SENSOR_DESCRIPTIONS ): @@ -236,21 +232,6 @@ async def async_setup_entry( gateway.api.sensors, ) - @callback - def async_reload_clip_sensors() -> None: - """Load clip sensor sensors from deCONZ.""" - for sensor_id, sensor in gateway.api.sensors.items(): - if sensor.type.startswith("CLIP"): - async_add_sensor(EventType.ADDED, sensor_id) - - config_entry.async_on_unload( - async_dispatcher_connect( - hass, - gateway.signal_reload_clip_sensors, - async_reload_clip_sensors, - ) - ) - class DeconzBinarySensor(DeconzDevice, BinarySensorEntity): """Representation of a deCONZ binary sensor.""" diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index 880e11f080b..75b37db2c13 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -28,7 +28,6 @@ from homeassistant.components.climate.const import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import ATTR_LOCKED, ATTR_OFFSET, ATTR_VALVE @@ -85,8 +84,6 @@ async def async_setup_entry( def async_add_climate(_: EventType, climate_id: str) -> None: """Add climate from deCONZ.""" climate = gateway.api.sensors.thermostat[climate_id] - if not gateway.option_allow_clip_sensor and climate.type.startswith("CLIP"): - return async_add_entities([DeconzThermostat(climate, gateway)]) gateway.register_platform_add_device_callback( @@ -94,21 +91,6 @@ async def async_setup_entry( gateway.api.sensors.thermostat, ) - @callback - def async_reload_clip_sensors() -> None: - """Load clip sensors from deCONZ.""" - for climate_id, climate in gateway.api.sensors.thermostat.items(): - if climate.type.startswith("CLIP"): - async_add_climate(EventType.ADDED, climate_id) - - config_entry.async_on_unload( - async_dispatcher_connect( - hass, - gateway.signal_reload_clip_sensors, - async_reload_clip_sensors, - ) - ) - class DeconzThermostat(DeconzDevice, ClimateEntity): """Representation of a deCONZ thermostat.""" diff --git a/homeassistant/components/deconz/deconz_event.py b/homeassistant/components/deconz/deconz_event.py index 270e66bf91d..6f7b6f9038a 100644 --- a/homeassistant/components/deconz/deconz_event.py +++ b/homeassistant/components/deconz/deconz_event.py @@ -46,9 +46,6 @@ async def async_setup_events(gateway: DeconzGateway) -> None: new_event: DeconzAlarmEvent | DeconzEvent sensor = gateway.api.sensors[sensor_id] - if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): - return None - if isinstance(sensor, Switch): new_event = DeconzEvent(sensor, gateway) diff --git a/homeassistant/components/deconz/gateway.py b/homeassistant/components/deconz/gateway.py index 25471d1448a..0ee967f88d9 100644 --- a/homeassistant/components/deconz/gateway.py +++ b/homeassistant/components/deconz/gateway.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, cast import async_timeout from pydeconz import DeconzSession, errors +from pydeconz.interfaces import sensors from pydeconz.interfaces.api import APIItems, GroupedAPIItems from pydeconz.interfaces.groups import Groups from pydeconz.models.event import EventType @@ -42,6 +43,35 @@ from .errors import AuthenticationRequired, CannotConnect if TYPE_CHECKING: from .deconz_event import DeconzAlarmEvent, DeconzEvent +SENSORS = ( + sensors.SensorResourceManager, + sensors.AirPurifierHandler, + sensors.AirQualityHandler, + sensors.AlarmHandler, + sensors.AncillaryControlHandler, + sensors.BatteryHandler, + sensors.CarbonMonoxideHandler, + sensors.ConsumptionHandler, + sensors.DaylightHandler, + sensors.DoorLockHandler, + sensors.FireHandler, + sensors.GenericFlagHandler, + sensors.GenericStatusHandler, + sensors.HumidityHandler, + sensors.LightLevelHandler, + sensors.OpenCloseHandler, + sensors.PowerHandler, + sensors.PresenceHandler, + sensors.PressureHandler, + sensors.RelativeRotaryHandler, + sensors.SwitchHandler, + sensors.TemperatureHandler, + sensors.ThermostatHandler, + sensors.TimeHandler, + sensors.VibrationHandler, + sensors.WaterHandler, +) + class DeconzGateway: """Manages a single deCONZ gateway.""" @@ -60,14 +90,17 @@ class DeconzGateway: self.ignore_state_updates = False self.signal_reachable = f"deconz-reachable-{config_entry.entry_id}" - self.signal_reload_clip_sensors = f"deconz_reload_clip_{config_entry.entry_id}" self.deconz_ids: dict[str, str] = {} self.entities: dict[str, set[str]] = {} self.events: list[DeconzAlarmEvent | DeconzEvent] = [] - self.ignored_devices: set[tuple[Callable[[EventType, str], None], str]] = set() + self.clip_sensors: set[tuple[Callable[[EventType, str], None], str]] = set() self.deconz_groups: set[tuple[Callable[[EventType, str], None], str]] = set() + self.ignored_devices: set[tuple[Callable[[EventType, str], None], str]] = set() + self.option_allow_clip_sensor = self.config_entry.options.get( + CONF_ALLOW_CLIP_SENSOR, DEFAULT_ALLOW_CLIP_SENSOR + ) self.option_allow_deconz_groups = config_entry.options.get( CONF_ALLOW_DECONZ_GROUPS, DEFAULT_ALLOW_DECONZ_GROUPS ) @@ -90,20 +123,12 @@ class DeconzGateway: """Gateway which is used with deCONZ services without defining id.""" return cast(bool, self.config_entry.options[CONF_MASTER_GATEWAY]) - # Options - - @property - def option_allow_clip_sensor(self) -> bool: - """Allow loading clip sensor from gateway.""" - return self.config_entry.options.get( - CONF_ALLOW_CLIP_SENSOR, DEFAULT_ALLOW_CLIP_SENSOR - ) - @callback def register_platform_add_device_callback( self, add_device_callback: Callable[[EventType, str], None], deconz_device_interface: APIItems | GroupedAPIItems, + always_ignore_clip_sensors: bool = False, ) -> None: """Wrap add_device_callback to check allow_new_devices option.""" @@ -128,6 +153,13 @@ class DeconzGateway: if not self.option_allow_deconz_groups: return + if isinstance(deconz_device_interface, SENSORS): + device = deconz_device_interface[device_id] + if device.type.startswith("CLIP") and not always_ignore_clip_sensors: + self.clip_sensors.add((async_add_device, device_id)) + if not self.option_allow_clip_sensor: + return + add_device_callback(EventType.ADDED, device_id) self.config_entry.async_on_unload( @@ -212,15 +244,20 @@ class DeconzGateway: # Allow CLIP sensors - if self.option_allow_clip_sensor: - async_dispatcher_send(self.hass, self.signal_reload_clip_sensors) - - else: - deconz_ids += [ - sensor.deconz_id - for sensor in self.api.sensors.values() - if sensor.type.startswith("CLIP") - ] + option_allow_clip_sensor = self.config_entry.options.get( + CONF_ALLOW_CLIP_SENSOR, DEFAULT_ALLOW_CLIP_SENSOR + ) + if option_allow_clip_sensor != self.option_allow_clip_sensor: + self.option_allow_clip_sensor = option_allow_clip_sensor + if option_allow_clip_sensor: + for add_device, device_id in self.clip_sensors: + add_device(EventType.ADDED, device_id) + else: + deconz_ids += [ + sensor.deconz_id + for sensor in self.api.sensors.values() + if sensor.type.startswith("CLIP") + ] # Allow Groups diff --git a/homeassistant/components/deconz/lock.py b/homeassistant/components/deconz/lock.py index cf4bd7f14f5..d6f9d670c01 100644 --- a/homeassistant/components/deconz/lock.py +++ b/homeassistant/components/deconz/lock.py @@ -46,6 +46,7 @@ async def async_setup_entry( gateway.register_platform_add_device_callback( async_add_lock_from_sensor, gateway.api.sensors.door_lock, + always_ignore_clip_sensors=True, ) diff --git a/homeassistant/components/deconz/number.py b/homeassistant/components/deconz/number.py index 81f3e434007..acd890d9c90 100644 --- a/homeassistant/components/deconz/number.py +++ b/homeassistant/components/deconz/number.py @@ -65,8 +65,7 @@ async def async_setup_entry( def async_add_sensor(_: EventType, sensor_id: str) -> None: """Add sensor from deCONZ.""" sensor = gateway.api.sensors.presence[sensor_id] - if sensor.type.startswith("CLIP"): - return + for description in ENTITY_DESCRIPTIONS.get(type(sensor), []): if ( not hasattr(sensor, description.key) @@ -78,6 +77,7 @@ async def async_setup_entry( gateway.register_platform_add_device_callback( async_add_sensor, gateway.api.sensors.presence, + always_ignore_clip_sensors=True, ) diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index 2aff2b12448..15af1b3dd8f 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -39,7 +39,6 @@ from homeassistant.const import ( TEMP_CELSIUS, ) from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType @@ -248,9 +247,6 @@ async def async_setup_entry( sensor = gateway.api.sensors[sensor_id] entities: list[DeconzSensor] = [] - if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): - return - if sensor.battery is None and not sensor.type.startswith("CLIP"): DeconzBatteryTracker(sensor_id, gateway, async_add_entities) @@ -276,21 +272,6 @@ async def async_setup_entry( gateway.api.sensors, ) - @callback - def async_reload_clip_sensors() -> None: - """Load clip sensor sensors from deCONZ.""" - for sensor_id, sensor in gateway.api.sensors.items(): - if sensor.type.startswith("CLIP"): - async_add_sensor(EventType.ADDED, sensor_id) - - config_entry.async_on_unload( - async_dispatcher_connect( - hass, - gateway.signal_reload_clip_sensors, - async_reload_clip_sensors, - ) - ) - class DeconzSensor(DeconzDevice, SensorEntity): """Representation of a deCONZ sensor."""