1 """Support for AVM FRITZ!SmartHome temperature sensor only devices."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from datetime
import datetime
8 from typing
import Final
10 from pyfritzhome.fritzhomedevice
import FritzhomeDevice
16 SensorEntityDescription,
22 UnitOfElectricCurrent,
23 UnitOfElectricPotential,
33 from .coordinator
import FritzboxConfigEntry
34 from .entity
import FritzBoxDeviceEntity
35 from .model
import FritzEntityDescriptionMixinBase
38 @dataclass(frozen=True)
40 """Sensor description mixin for Fritz!Smarthome entities."""
42 native_value: Callable[[FritzhomeDevice], StateType | datetime]
45 @dataclass(frozen=True)
47 SensorEntityDescription, FritzEntityDescriptionMixinSensor
49 """Description for Fritz!Smarthome sensor entities."""
51 entity_category_fn: Callable[[FritzhomeDevice], EntityCategory |
None] |
None =
None
55 """Check suitablity for eco temperature sensor."""
56 return device.has_thermostat
and device.eco_temperature
is not None
60 """Check suitablity for comfort temperature sensor."""
61 return device.has_thermostat
and device.comfort_temperature
is not None
65 """Check suitablity for next scheduled temperature sensor."""
66 return device.has_thermostat
and device.nextchange_temperature
is not None
70 """Check suitablity for next scheduled changed time sensor."""
71 return device.has_thermostat
and device.nextchange_endperiod
is not None
75 """Check suitablity for temperature sensor."""
76 return device.has_temperature_sensor
and not device.has_thermostat
80 """Determine proper entity category for temperature sensor."""
81 if device.has_switch
or device.has_lightbulb:
82 return EntityCategory.DIAGNOSTIC
87 """Return native value for next scheduled preset sensor."""
88 if not device.nextchange_endperiod:
90 if device.nextchange_temperature == device.eco_temperature:
96 """Return native value for current scheduled preset sensor."""
97 if not device.nextchange_endperiod:
99 if device.nextchange_temperature == device.eco_temperature:
100 return PRESET_COMFORT
105 """Return native value for next scheduled temperature time sensor."""
106 if device.nextchange_endperiod
and isinstance(device.nextchange_temperature, float):
107 return device.nextchange_temperature
112 """Return native value for next scheduled changed time sensor."""
113 if device.nextchange_endperiod:
118 SENSOR_TYPES: Final[tuple[FritzSensorEntityDescription, ...]] = (
121 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
122 device_class=SensorDeviceClass.TEMPERATURE,
123 state_class=SensorStateClass.MEASUREMENT,
124 entity_category_fn=entity_category_temperature,
125 suitable=suitable_temperature,
126 native_value=
lambda device: device.temperature,
130 native_unit_of_measurement=PERCENTAGE,
131 device_class=SensorDeviceClass.HUMIDITY,
132 state_class=SensorStateClass.MEASUREMENT,
133 suitable=
lambda device: device.rel_humidity
is not None,
134 native_value=
lambda device: device.rel_humidity,
138 native_unit_of_measurement=PERCENTAGE,
139 device_class=SensorDeviceClass.BATTERY,
140 entity_category=EntityCategory.DIAGNOSTIC,
141 suitable=
lambda device: device.battery_level
is not None,
142 native_value=
lambda device: device.battery_level,
145 key=
"power_consumption",
146 native_unit_of_measurement=UnitOfPower.WATT,
147 device_class=SensorDeviceClass.POWER,
148 state_class=SensorStateClass.MEASUREMENT,
149 suitable=
lambda device: device.has_powermeter,
150 native_value=
lambda device: round((device.power
or 0.0) / 1000, 3),
154 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
155 device_class=SensorDeviceClass.VOLTAGE,
156 state_class=SensorStateClass.MEASUREMENT,
157 suitable=
lambda device: device.has_powermeter,
158 native_value=
lambda device: round((device.voltage
or 0.0) / 1000, 2),
161 key=
"electric_current",
162 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
163 device_class=SensorDeviceClass.CURRENT,
164 state_class=SensorStateClass.MEASUREMENT,
165 suitable=
lambda device: device.has_powermeter,
166 native_value=
lambda device: round((device.current
or 0.0) / 1000, 3),
170 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
171 device_class=SensorDeviceClass.ENERGY,
172 state_class=SensorStateClass.TOTAL_INCREASING,
173 suitable=
lambda device: device.has_powermeter,
174 native_value=
lambda device: (device.energy
or 0.0) / 1000,
178 key=
"comfort_temperature",
179 translation_key=
"comfort_temperature",
180 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
181 device_class=SensorDeviceClass.TEMPERATURE,
182 entity_category=EntityCategory.DIAGNOSTIC,
183 suitable=suitable_comfort_temperature,
184 native_value=
lambda device: device.comfort_temperature,
187 key=
"eco_temperature",
188 translation_key=
"eco_temperature",
189 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
190 device_class=SensorDeviceClass.TEMPERATURE,
191 entity_category=EntityCategory.DIAGNOSTIC,
192 suitable=suitable_eco_temperature,
193 native_value=
lambda device: device.eco_temperature,
196 key=
"nextchange_temperature",
197 translation_key=
"nextchange_temperature",
198 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
199 device_class=SensorDeviceClass.TEMPERATURE,
200 entity_category=EntityCategory.DIAGNOSTIC,
201 suitable=suitable_nextchange_temperature,
202 native_value=value_nextchange_temperature,
205 key=
"nextchange_time",
206 translation_key=
"nextchange_time",
207 device_class=SensorDeviceClass.TIMESTAMP,
208 entity_category=EntityCategory.DIAGNOSTIC,
209 suitable=suitable_nextchange_time,
210 native_value=value_nextchange_time,
213 key=
"nextchange_preset",
214 translation_key=
"nextchange_preset",
215 entity_category=EntityCategory.DIAGNOSTIC,
216 suitable=suitable_nextchange_temperature,
217 native_value=value_nextchange_preset,
220 key=
"scheduled_preset",
221 translation_key=
"scheduled_preset",
222 entity_category=EntityCategory.DIAGNOSTIC,
223 suitable=suitable_nextchange_temperature,
224 native_value=value_scheduled_preset,
231 entry: FritzboxConfigEntry,
232 async_add_entities: AddEntitiesCallback,
234 """Set up the FRITZ!SmartHome sensor from ConfigEntry."""
235 coordinator = entry.runtime_data
238 def _add_entities(devices: set[str] |
None =
None) ->
None:
241 devices = coordinator.new_devices
247 for description
in SENSOR_TYPES
248 if description.suitable(coordinator.data.devices[ain])
251 entry.async_on_unload(coordinator.async_add_listener(_add_entities))
253 _add_entities(set(coordinator.data.devices))
257 """The entity class for FRITZ!SmartHome sensors."""
259 entity_description: FritzSensorEntityDescription
263 """Return the state of the sensor."""
268 """Return the category of the entity, if any."""
271 return super().entity_category
FritzhomeDevice data(self)
FritzhomeEntityBase data(self)
StateType|datetime native_value(self)
bool suitable_nextchange_temperature(FritzhomeDevice device)
bool suitable_nextchange_time(FritzhomeDevice device)
float|None value_nextchange_temperature(FritzhomeDevice device)
bool suitable_comfort_temperature(FritzhomeDevice device)
bool suitable_temperature(FritzhomeDevice device)
str|None value_scheduled_preset(FritzhomeDevice device)
None async_setup_entry(HomeAssistant hass, FritzboxConfigEntry entry, AddEntitiesCallback async_add_entities)
str|None value_nextchange_preset(FritzhomeDevice device)
EntityCategory|None entity_category_temperature(FritzhomeDevice device)
bool suitable_eco_temperature(FritzhomeDevice device)
datetime|None value_nextchange_time(FritzhomeDevice device)