1 """Support for Tado sensors for each zone."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
13 SensorEntityDescription,
22 from .
import TadoConfigEntry
25 SENSOR_DATA_CATEGORY_GEOFENCE,
26 SENSOR_DATA_CATEGORY_WEATHER,
27 SIGNAL_TADO_UPDATE_RECEIVED,
28 TYPE_AIR_CONDITIONING,
32 from .entity
import TadoHomeEntity, TadoZoneEntity
33 from .tado_connector
import TadoConnector
35 _LOGGER = logging.getLogger(__name__)
38 @dataclass(frozen=True, kw_only=True)
40 """Describes Tado sensor entity."""
42 state_fn: Callable[[Any], StateType]
44 attributes_fn: Callable[[Any], dict[Any, StateType]] |
None =
None
45 data_category: str |
None =
None
49 """Return condition from dict CONDITIONS_MAP."""
50 for key, value
in CONDITIONS_MAP.items():
51 if condition
in value:
57 """Return Tado Mode based on Presence attribute."""
58 if "presence" in data:
59 return data[
"presence"]
64 """Return whether Automatic Geofencing is enabled based on Presence Locked attribute."""
65 if "presenceLocked" in data:
66 if data[
"presenceLocked"]:
73 """Return Geofencing Mode based on Presence and Presence Locked attributes."""
74 tado_mode = data.get(
"presence",
"unknown")
76 if "presenceLocked" in data:
77 if data[
"presenceLocked"]:
78 geofencing_switch_mode =
"manual"
80 geofencing_switch_mode =
"auto"
82 geofencing_switch_mode =
"manual"
84 return f
"{tado_mode.capitalize()} ({geofencing_switch_mode.capitalize()})"
89 key=
"outdoor temperature",
90 translation_key=
"outdoor_temperature",
91 state_fn=
lambda data: data[
"outsideTemperature"][
"celsius"],
92 attributes_fn=
lambda data: {
93 "time": data[
"outsideTemperature"][
"timestamp"],
95 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
96 device_class=SensorDeviceClass.TEMPERATURE,
97 state_class=SensorStateClass.MEASUREMENT,
98 data_category=SENSOR_DATA_CATEGORY_WEATHER,
101 key=
"solar percentage",
102 translation_key=
"solar_percentage",
103 state_fn=
lambda data: data[
"solarIntensity"][
"percentage"],
104 attributes_fn=
lambda data: {
105 "time": data[
"solarIntensity"][
"timestamp"],
107 native_unit_of_measurement=PERCENTAGE,
108 state_class=SensorStateClass.MEASUREMENT,
109 data_category=SENSOR_DATA_CATEGORY_WEATHER,
112 key=
"weather condition",
113 translation_key=
"weather_condition",
115 attributes_fn=
lambda data: {
"time": data[
"weatherState"][
"timestamp"]},
116 data_category=SENSOR_DATA_CATEGORY_WEATHER,
120 translation_key=
"tado_mode",
121 state_fn=get_tado_mode,
122 data_category=SENSOR_DATA_CATEGORY_GEOFENCE,
125 key=
"geofencing mode",
126 translation_key=
"geofencing_mode",
127 state_fn=get_geofencing_mode,
128 data_category=SENSOR_DATA_CATEGORY_GEOFENCE,
131 key=
"automatic geofencing",
132 translation_key=
"automatic_geofencing",
133 state_fn=get_automatic_geofencing,
134 data_category=SENSOR_DATA_CATEGORY_GEOFENCE,
140 state_fn=
lambda data: data.current_temp,
141 attributes_fn=
lambda data: {
142 "time": data.current_temp_timestamp,
145 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
146 device_class=SensorDeviceClass.TEMPERATURE,
147 state_class=SensorStateClass.MEASUREMENT,
151 state_fn=
lambda data: data.current_humidity,
152 attributes_fn=
lambda data: {
"time": data.current_humidity_timestamp},
153 native_unit_of_measurement=PERCENTAGE,
154 device_class=SensorDeviceClass.HUMIDITY,
155 state_class=SensorStateClass.MEASUREMENT,
159 translation_key=
"tado_mode",
160 state_fn=
lambda data: data.tado_mode,
164 translation_key=
"heating",
165 state_fn=
lambda data: data.heating_power_percentage,
166 attributes_fn=
lambda data: {
"time": data.heating_power_timestamp},
167 native_unit_of_measurement=PERCENTAGE,
168 state_class=SensorStateClass.MEASUREMENT,
172 translation_key=
"ac",
174 state_fn=
lambda data: data.ac_power,
175 attributes_fn=
lambda data: {
"time": data.ac_power_timestamp},
180 TEMPERATURE_ENTITY_DESCRIPTION,
181 HUMIDITY_ENTITY_DESCRIPTION,
182 TADO_MODE_ENTITY_DESCRIPTION,
183 HEATING_ENTITY_DESCRIPTION,
185 TYPE_AIR_CONDITIONING: [
186 TEMPERATURE_ENTITY_DESCRIPTION,
187 HUMIDITY_ENTITY_DESCRIPTION,
188 TADO_MODE_ENTITY_DESCRIPTION,
189 AC_ENTITY_DESCRIPTION,
191 TYPE_HOT_WATER: [TADO_MODE_ENTITY_DESCRIPTION],
196 hass: HomeAssistant, entry: TadoConfigEntry, async_add_entities: AddEntitiesCallback
198 """Set up the Tado sensor platform."""
200 tado = entry.runtime_data
202 entities: list[SensorEntity] = []
208 for entity_description
in HOME_SENSORS
214 zone_type = zone[
"type"]
215 if zone_type
not in ZONE_SENSORS:
216 _LOGGER.warning(
"Unknown zone type skipped: %s", zone_type)
221 TadoZoneSensor(tado, zone[
"name"], zone[
"id"], entity_description)
222 for entity_description
in ZONE_SENSORS[zone_type]
230 """Representation of a Tado Sensor."""
232 entity_description: TadoSensorEntityDescription
235 self, tado: TadoConnector, entity_description: TadoSensorEntityDescription
237 """Initialize of the Tado Sensor."""
245 """Register for sensor updates."""
250 SIGNAL_TADO_UPDATE_RECEIVED.format(self.
_tado_tado.home_id,
"home",
"data"),
258 """Update and write state."""
264 """Handle update callbacks."""
266 tado_weather_data = self.
_tado_tado.data[
"weather"]
267 tado_geofence_data = self.
_tado_tado.data[
"geofence"]
272 if self.
entity_descriptionentity_description.data_category == SENSOR_DATA_CATEGORY_WEATHER:
273 tado_sensor_data = tado_weather_data
275 tado_sensor_data = tado_geofence_data
284 """Representation of a tado Sensor."""
286 entity_description: TadoSensorEntityDescription
293 entity_description: TadoSensorEntityDescription,
295 """Initialize of the Tado Sensor."""
298 super().
__init__(zone_name, tado.home_id, zone_id)
300 self.
_attr_unique_id_attr_unique_id = f
"{entity_description.key} {zone_id} {tado.home_id}"
303 """Register for sensor updates."""
308 SIGNAL_TADO_UPDATE_RECEIVED.format(
318 """Update and write state."""
324 """Handle update callbacks."""
326 tado_zone_data = self.
_tado_tado.data[
"zone"][self.
zone_idzone_id]
None _async_update_home_data(self)
_attr_extra_state_attributes
None __init__(self, TadoConnector tado, TadoSensorEntityDescription entity_description)
None async_added_to_hass(self)
None _async_update_callback(self)
None async_added_to_hass(self)
_attr_extra_state_attributes
None _async_update_zone_data(self)
None __init__(self, TadoConnector tado, str zone_name, int zone_id, TadoSensorEntityDescription entity_description)
None _async_update_callback(self)
None async_write_ha_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
str get_geofencing_mode(dict[str, str] data)
str|None get_tado_mode(dict[str, str] data)
bool get_automatic_geofencing(dict[str, str] data)
None async_setup_entry(HomeAssistant hass, TadoConfigEntry entry, AddEntitiesCallback async_add_entities)
str format_condition(str condition)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)