diff --git a/homeassistant/components/fritzbox/binary_sensor.py b/homeassistant/components/fritzbox/binary_sensor.py index b7e78ceaf47..25831da957c 100644 --- a/homeassistant/components/fritzbox/binary_sensor.py +++ b/homeassistant/components/fritzbox/binary_sensor.py @@ -1,17 +1,49 @@ """Support for Fritzbox binary sensors.""" from __future__ import annotations +from dataclasses import dataclass +from typing import Callable, Final + from pyfritzhome.fritzhomedevice import FritzhomeDevice -from homeassistant.components.binary_sensor import BinarySensorEntity -from homeassistant.components.fritzbox.model import FritzBinarySensorEntityDescription +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_WINDOW, + BinarySensorEntity, + BinarySensorEntityDescription, +) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from . import FritzBoxEntity -from .const import BINARY_SENSOR_TYPES, CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN +from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN +from .model import FritzEntityDescriptionMixinBase + + +@dataclass +class FritzEntityDescriptionMixinBinarySensor(FritzEntityDescriptionMixinBase): + """BinarySensor description mixin for Fritz!Smarthome entities.""" + + is_on: Callable[[FritzhomeDevice], bool | None] + + +@dataclass +class FritzBinarySensorEntityDescription( + BinarySensorEntityDescription, FritzEntityDescriptionMixinBinarySensor +): + """Description for Fritz!Smarthome binary sensor entities.""" + + +BINARY_SENSOR_TYPES: Final[tuple[FritzBinarySensorEntityDescription, ...]] = ( + FritzBinarySensorEntityDescription( + key="alarm", + name="Alarm", + device_class=DEVICE_CLASS_WINDOW, + suitable=lambda device: device.has_alarm, # type: ignore[no-any-return] + is_on=lambda device: device.alert_state, # type: ignore[no-any-return] + ), +) async def async_setup_entry( diff --git a/homeassistant/components/fritzbox/const.py b/homeassistant/components/fritzbox/const.py index 79123abbda7..6af75449a29 100644 --- a/homeassistant/components/fritzbox/const.py +++ b/homeassistant/components/fritzbox/const.py @@ -4,26 +4,6 @@ from __future__ import annotations import logging from typing import Final -from homeassistant.components.binary_sensor import DEVICE_CLASS_WINDOW -from homeassistant.components.fritzbox.model import ( - FritzBinarySensorEntityDescription, - FritzSensorEntityDescription, -) -from homeassistant.components.sensor import ( - STATE_CLASS_MEASUREMENT, - STATE_CLASS_TOTAL_INCREASING, -) -from homeassistant.const import ( - DEVICE_CLASS_BATTERY, - DEVICE_CLASS_ENERGY, - DEVICE_CLASS_POWER, - DEVICE_CLASS_TEMPERATURE, - ENERGY_KILO_WATT_HOUR, - PERCENTAGE, - POWER_WATT, - TEMP_CELSIUS, -) - ATTR_STATE_BATTERY_LOW: Final = "battery_low" ATTR_STATE_DEVICE_LOCKED: Final = "device_locked" ATTR_STATE_HOLIDAY_MODE: Final = "holiday_mode" @@ -44,53 +24,3 @@ DOMAIN: Final = "fritzbox" LOGGER: Final[logging.Logger] = logging.getLogger(__package__) PLATFORMS: Final[list[str]] = ["binary_sensor", "climate", "switch", "sensor"] - -BINARY_SENSOR_TYPES: Final[tuple[FritzBinarySensorEntityDescription, ...]] = ( - FritzBinarySensorEntityDescription( - key="alarm", - name="Alarm", - device_class=DEVICE_CLASS_WINDOW, - suitable=lambda device: device.has_alarm, # type: ignore[no-any-return] - is_on=lambda device: device.alert_state, # type: ignore[no-any-return] - ), -) - -SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = ( - FritzSensorEntityDescription( - key="temperature", - name="Temperature", - native_unit_of_measurement=TEMP_CELSIUS, - device_class=DEVICE_CLASS_TEMPERATURE, - state_class=STATE_CLASS_MEASUREMENT, - suitable=lambda device: ( - device.has_temperature_sensor and not device.has_thermostat - ), - native_value=lambda device: device.temperature, # type: ignore[no-any-return] - ), - FritzSensorEntityDescription( - key="battery", - name="Battery", - native_unit_of_measurement=PERCENTAGE, - device_class=DEVICE_CLASS_BATTERY, - suitable=lambda device: device.battery_level is not None, - native_value=lambda device: device.battery_level, # type: ignore[no-any-return] - ), - FritzSensorEntityDescription( - key="power_consumption", - name="Power Consumption", - native_unit_of_measurement=POWER_WATT, - device_class=DEVICE_CLASS_POWER, - state_class=STATE_CLASS_MEASUREMENT, - suitable=lambda device: device.has_powermeter, # type: ignore[no-any-return] - native_value=lambda device: device.power / 1000 if device.power else 0.0, - ), - FritzSensorEntityDescription( - key="total_energy", - name="Total Energy", - native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, - device_class=DEVICE_CLASS_ENERGY, - state_class=STATE_CLASS_TOTAL_INCREASING, - suitable=lambda device: device.has_powermeter, # type: ignore[no-any-return] - native_value=lambda device: device.energy / 1000 if device.energy else 0.0, - ), -) diff --git a/homeassistant/components/fritzbox/model.py b/homeassistant/components/fritzbox/model.py index fb694a97012..69aefb8071c 100644 --- a/homeassistant/components/fritzbox/model.py +++ b/homeassistant/components/fritzbox/model.py @@ -6,9 +6,6 @@ from typing import Callable, TypedDict from pyfritzhome import FritzhomeDevice -from homeassistant.components.binary_sensor import BinarySensorEntityDescription -from homeassistant.components.sensor import SensorEntityDescription - class EntityInfo(TypedDict): """TypedDict for EntityInfo.""" @@ -53,31 +50,3 @@ class FritzEntityDescriptionMixinBase: """Bases description mixin for Fritz!Smarthome entities.""" suitable: Callable[[FritzhomeDevice], bool] - - -@dataclass -class FritzEntityDescriptionMixinSensor(FritzEntityDescriptionMixinBase): - """Sensor description mixin for Fritz!Smarthome entities.""" - - native_value: Callable[[FritzhomeDevice], float | int | None] - - -@dataclass -class FritzEntityDescriptionMixinBinarySensor(FritzEntityDescriptionMixinBase): - """BinarySensor description mixin for Fritz!Smarthome entities.""" - - is_on: Callable[[FritzhomeDevice], bool | None] - - -@dataclass -class FritzSensorEntityDescription( - SensorEntityDescription, FritzEntityDescriptionMixinSensor -): - """Description for Fritz!Smarthome sensor entities.""" - - -@dataclass -class FritzBinarySensorEntityDescription( - BinarySensorEntityDescription, FritzEntityDescriptionMixinBinarySensor -): - """Description for Fritz!Smarthome binary sensor entities.""" diff --git a/homeassistant/components/fritzbox/sensor.py b/homeassistant/components/fritzbox/sensor.py index 2150c2359b3..6f1cf49129d 100644 --- a/homeassistant/components/fritzbox/sensor.py +++ b/homeassistant/components/fritzbox/sensor.py @@ -1,14 +1,89 @@ """Support for AVM FRITZ!SmartHome temperature sensor only devices.""" from __future__ import annotations -from homeassistant.components.fritzbox.model import FritzSensorEntityDescription -from homeassistant.components.sensor import SensorEntity +from dataclasses import dataclass +from typing import Callable, Final + +from pyfritzhome.fritzhomedevice import FritzhomeDevice + +from homeassistant.components.sensor import ( + STATE_CLASS_MEASUREMENT, + STATE_CLASS_TOTAL_INCREASING, + SensorEntity, + SensorEntityDescription, +) from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ( + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_ENERGY, + DEVICE_CLASS_POWER, + DEVICE_CLASS_TEMPERATURE, + ENERGY_KILO_WATT_HOUR, + PERCENTAGE, + POWER_WATT, + TEMP_CELSIUS, +) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import FritzBoxEntity -from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN, SENSOR_TYPES +from .const import CONF_COORDINATOR, DOMAIN as FRITZBOX_DOMAIN +from .model import FritzEntityDescriptionMixinBase + + +@dataclass +class FritzEntityDescriptionMixinSensor(FritzEntityDescriptionMixinBase): + """Sensor description mixin for Fritz!Smarthome entities.""" + + native_value: Callable[[FritzhomeDevice], float | int | None] + + +@dataclass +class FritzSensorEntityDescription( + SensorEntityDescription, FritzEntityDescriptionMixinSensor +): + """Description for Fritz!Smarthome sensor entities.""" + + +SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = ( + FritzSensorEntityDescription( + key="temperature", + name="Temperature", + native_unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + suitable=lambda device: ( + device.has_temperature_sensor and not device.has_thermostat + ), + native_value=lambda device: device.temperature, # type: ignore[no-any-return] + ), + FritzSensorEntityDescription( + key="battery", + name="Battery", + native_unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_BATTERY, + suitable=lambda device: device.battery_level is not None, + native_value=lambda device: device.battery_level, # type: ignore[no-any-return] + ), + FritzSensorEntityDescription( + key="power_consumption", + name="Power Consumption", + native_unit_of_measurement=POWER_WATT, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + suitable=lambda device: device.has_powermeter, # type: ignore[no-any-return] + native_value=lambda device: device.power / 1000 if device.power else 0.0, + ), + FritzSensorEntityDescription( + key="total_energy", + name="Total Energy", + native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + suitable=lambda device: device.has_powermeter, # type: ignore[no-any-return] + native_value=lambda device: device.energy / 1000 if device.energy else 0.0, + ), +) async def async_setup_entry(