diff --git a/homeassistant/components/deconz/alarm_control_panel.py b/homeassistant/components/deconz/alarm_control_panel.py index 823c9c67654..e16e4bcc327 100644 --- a/homeassistant/components/deconz/alarm_control_panel.py +++ b/homeassistant/components/deconz/alarm_control_panel.py @@ -1,6 +1,9 @@ """Support for deCONZ alarm control panel devices.""" from __future__ import annotations +from collections.abc import ValuesView + +from pydeconz.alarm_system import AlarmSystem from pydeconz.sensor import ( ANCILLARY_CONTROL_ARMED_AWAY, ANCILLARY_CONTROL_ARMED_NIGHT, @@ -23,6 +26,7 @@ from homeassistant.components.alarm_control_panel import ( SUPPORT_ALARM_ARM_NIGHT, AlarmControlPanelEntity, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -32,11 +36,12 @@ from homeassistant.const import ( STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, ) -from homeassistant.core import callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity_platform import AddEntitiesCallback from .deconz_device import DeconzDevice -from .gateway import get_gateway_from_config_entry +from .gateway import DeconzGateway, get_gateway_from_config_entry DECONZ_TO_ALARM_STATE = { ANCILLARY_CONTROL_ARMED_AWAY: STATE_ALARM_ARMED_AWAY, @@ -52,14 +57,21 @@ DECONZ_TO_ALARM_STATE = { } -def get_alarm_system_for_unique_id(gateway, unique_id: str): +def get_alarm_system_for_unique_id( + gateway: DeconzGateway, unique_id: str +) -> AlarmSystem | None: """Retrieve alarm system unique ID is registered to.""" for alarm_system in gateway.api.alarmsystems.values(): if unique_id in alarm_system.devices: return alarm_system + return None -async def async_setup_entry(hass, config_entry, async_add_entities) -> None: +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: """Set up the deCONZ alarm control panel devices. Alarm control panels are based on the same device class as sensors in deCONZ. @@ -68,7 +80,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None: gateway.entities[DOMAIN] = set() @callback - def async_add_alarm_control_panel(sensors=gateway.api.sensors.values()) -> None: + def async_add_alarm_control_panel( + sensors: list[AncillaryControl] + | ValuesView[AncillaryControl] = gateway.api.sensors.values(), + ) -> None: """Add alarm control panel devices from deCONZ.""" entities = [] @@ -77,10 +92,15 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None: if ( isinstance(sensor, AncillaryControl) and sensor.unique_id not in gateway.entities[DOMAIN] - and get_alarm_system_for_unique_id(gateway, sensor.unique_id) + and ( + alarm_system := get_alarm_system_for_unique_id( + gateway, sensor.unique_id + ) + ) + is not None ): - entities.append(DeconzAlarmControlPanel(sensor, gateway)) + entities.append(DeconzAlarmControlPanel(sensor, gateway, alarm_system)) if entities: async_add_entities(entities) @@ -100,16 +120,22 @@ class DeconzAlarmControlPanel(DeconzDevice, AlarmControlPanelEntity): """Representation of a deCONZ alarm control panel.""" TYPE = DOMAIN + _device: AncillaryControl _attr_code_format = FORMAT_NUMBER _attr_supported_features = ( SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_NIGHT ) - def __init__(self, device, gateway) -> None: + def __init__( + self, + device: AncillaryControl, + gateway: DeconzGateway, + alarm_system: AlarmSystem, + ) -> None: """Set up alarm control panel device.""" super().__init__(device, gateway) - self.alarm_system = get_alarm_system_for_unique_id(gateway, device.unique_id) + self.alarm_system = alarm_system @callback def async_update_callback(self) -> None: @@ -124,20 +150,20 @@ class DeconzAlarmControlPanel(DeconzDevice, AlarmControlPanelEntity): @property def state(self) -> str | None: """Return the state of the control panel.""" - return DECONZ_TO_ALARM_STATE.get(self._device.state) + return DECONZ_TO_ALARM_STATE.get(self._device.panel) - async def async_alarm_arm_away(self, code: None = None) -> None: + async def async_alarm_arm_away(self, code: str | None = None) -> None: """Send arm away command.""" await self.alarm_system.arm_away(code) - async def async_alarm_arm_home(self, code: None = None) -> None: + async def async_alarm_arm_home(self, code: str | None = None) -> None: """Send arm home command.""" await self.alarm_system.arm_stay(code) - async def async_alarm_arm_night(self, code: None = None) -> None: + async def async_alarm_arm_night(self, code: str | None = None) -> None: """Send arm night command.""" await self.alarm_system.arm_night(code) - async def async_alarm_disarm(self, code: None = None) -> None: + async def async_alarm_disarm(self, code: str | None = None) -> None: """Send disarm command.""" await self.alarm_system.disarm(code) diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index 7f77bbb8809..475c631bdf8 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -1,7 +1,13 @@ """Support for deCONZ binary sensors.""" +from __future__ import annotations + +from collections.abc import ValuesView + from pydeconz.sensor import ( Alarm, CarbonMonoxide, + DeconzBinarySensor as PydeconzBinarySensor, + DeconzSensor as PydeconzSensor, Fire, GenericFlag, OpenClose, @@ -22,13 +28,15 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, ENTITY_CATEGORY_DIAGNOSTIC -from homeassistant.core import callback +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_DARK, ATTR_ON from .deconz_device import DeconzDevice -from .gateway import get_gateway_from_config_entry +from .gateway import DeconzGateway, get_gateway_from_config_entry DECONZ_BINARY_SENSORS = ( Alarm, @@ -73,15 +81,22 @@ ENTITY_DESCRIPTIONS = { } -async def async_setup_entry(hass, config_entry, async_add_entities): +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: """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=gateway.api.sensors.values()): + def async_add_sensor( + sensors: list[PydeconzSensor] + | ValuesView[PydeconzSensor] = gateway.api.sensors.values(), + ) -> None: """Add binary sensor from deCONZ.""" - entities = [] + entities: list[DeconzBinarySensor | DeconzTampering] = [] for sensor in sensors: @@ -120,8 +135,9 @@ class DeconzBinarySensor(DeconzDevice, BinarySensorEntity): """Representation of a deCONZ binary sensor.""" TYPE = DOMAIN + _device: PydeconzBinarySensor - def __init__(self, device, gateway): + def __init__(self, device: PydeconzBinarySensor, gateway: DeconzGateway) -> None: """Initialize deCONZ binary sensor.""" super().__init__(device, gateway) @@ -129,21 +145,21 @@ class DeconzBinarySensor(DeconzDevice, BinarySensorEntity): self.entity_description = entity_description @callback - def async_update_callback(self): + def async_update_callback(self) -> None: """Update the sensor's state.""" keys = {"on", "reachable", "state"} if self._device.changed_keys.intersection(keys): super().async_update_callback() @property - def is_on(self): + def is_on(self) -> bool: """Return true if sensor is on.""" - return self._device.state + return self._device.state # type: ignore[no-any-return] @property - def extra_state_attributes(self): + def extra_state_attributes(self) -> dict[str, bool | float | int | list | None]: """Return the state attributes of the sensor.""" - attr = {} + attr: dict[str, bool | float | int | list | None] = {} if self._device.on is not None: attr[ATTR_ON] = self._device.on @@ -168,11 +184,12 @@ class DeconzTampering(DeconzDevice, BinarySensorEntity): """Representation of a deCONZ tampering sensor.""" TYPE = DOMAIN + _device: PydeconzSensor _attr_entity_category = ENTITY_CATEGORY_DIAGNOSTIC _attr_device_class = DEVICE_CLASS_TAMPER - def __init__(self, device, gateway): + def __init__(self, device: PydeconzSensor, gateway: DeconzGateway) -> None: """Initialize deCONZ binary sensor.""" super().__init__(device, gateway) @@ -193,4 +210,4 @@ class DeconzTampering(DeconzDevice, BinarySensorEntity): @property def is_on(self) -> bool: """Return the state of the sensor.""" - return self._device.tampered + return self._device.tampered # type: ignore[no-any-return]