From 6917223cb35e29563abb488bbd3eee4b4ab651d2 Mon Sep 17 00:00:00 2001 From: Erwin Douna Date: Fri, 5 Jun 2026 12:39:43 +0200 Subject: [PATCH] Tado refactor to utilize get_zone_states (#173075) --- homeassistant/components/tado/coordinator.py | 30 +++++++++++++----- .../components/tado/fixtures/zone_states.json | 31 ++++++++++++++----- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/homeassistant/components/tado/coordinator.py b/homeassistant/components/tado/coordinator.py index a9ded1bcd25c..6ee33f39cb39 100644 --- a/homeassistant/components/tado/coordinator.py +++ b/homeassistant/components/tado/coordinator.py @@ -6,6 +6,7 @@ from typing import Any from zoneinfo import ZoneInfo from PyTado.interface import Tado +from PyTado.zone import TadoZone from requests import RequestException from homeassistant.components.climate import PRESET_AWAY, PRESET_HOME @@ -248,7 +249,7 @@ class TadoDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): return mapped_devices - async def _async_update_zones(self) -> dict[int, dict]: + async def _async_update_zones(self) -> dict[int, TadoZone]: """Update the zone data from Tado.""" try: @@ -260,16 +261,31 @@ class TadoDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): _LOGGER.error("Error updating Tado zones: %s", err) raise UpdateFailed(f"Error updating Tado zones: {err}") from err - mapped_zones: dict[int, dict] = {} - for zone in zone_states: - mapped_zones[int(zone)] = await self._update_zone(int(zone)) + mapped_zones: dict[int, TadoZone] = {} + for zone_id_str, raw_state in zone_states.items(): + zone_id = int(zone_id_str) + mapped_zones[zone_id] = await self._build_zone(zone_id, raw_state) return mapped_zones - async def _update_zone(self, zone_id: int) -> dict[str, str]: - """Update the internal data of a zone.""" - + async def _build_zone(self, zone_id: int, raw_state: dict[str, Any]) -> TadoZone: + """Fetch defaultOverlay for a zone and construct a TadoZone.""" _LOGGER.debug("Updating zone %s", zone_id) + try: + overlay_default = await self.hass.async_add_executor_job( + self._tado.get_zone_overlay_default, zone_id + ) + except RequestException as err: + _LOGGER.error("Error updating Tado zone %s: %s", zone_id, err) + raise UpdateFailed(f"Error updating Tado zone {zone_id}: {err}") from err + + data = TadoZone.from_data(zone_id, {**raw_state, **overlay_default}) + _LOGGER.debug("Zone %s updated, with data: %s", zone_id, data) + return data + + async def _update_zone(self, zone_id: int) -> TadoZone: + """Fetch the latest state for a single zone (used after overlay changes).""" + _LOGGER.debug("Refreshing zone %s after overlay change", zone_id) try: data = await self.hass.async_add_executor_job( self._tado.get_zone_state, zone_id diff --git a/tests/components/tado/fixtures/zone_states.json b/tests/components/tado/fixtures/zone_states.json index df1a99a80f38..fa5b28849a6c 100644 --- a/tests/components/tado/fixtures/zone_states.json +++ b/tests/components/tado/fixtures/zone_states.json @@ -295,14 +295,29 @@ "preparation": null, "setting": { "type": "AIR_CONDITIONING", - "power": "OFF" + "power": "ON", + "mode": "HEAT", + "temperature": { + "celsius": 25.0, + "fahrenheit": 77.0 + }, + "fanLevel": "LEVEL3", + "verticalSwing": "ON", + "horizontalSwing": "ON" }, "overlayType": "MANUAL", "overlay": { "type": "MANUAL", "setting": { "type": "AIR_CONDITIONING", - "power": "OFF" + "power": "ON", + "mode": "HEAT", + "temperature": { + "celsius": 25.0, + "fahrenheit": 77.0 + }, + "fanLevel": "LEVEL3", + "verticalSwing": "ON" }, "termination": { "type": "MANUAL", @@ -337,14 +352,14 @@ "acPower": { "timestamp": "2022-07-13T18: 06: 58.183Z", "type": "POWER", - "value": "OFF" + "value": "ON" } }, "sensorDataPoints": { "insideTemperature": { - "celsius": 24.21, - "fahrenheit": 75.58, - "timestamp": "2024-06-28T21: 43: 51.067Z", + "celsius": 24.3, + "fahrenheit": 75.74, + "timestamp": "2024-06-28T22: 23: 15.679Z", "type": "TEMPERATURE", "precision": { "celsius": 0.1, @@ -353,8 +368,8 @@ }, "humidity": { "type": "PERCENTAGE", - "percentage": 71.4, - "timestamp": "2024-06-28T21: 43: 51.067Z" + "percentage": 70.9, + "timestamp": "2024-06-28T22: 23: 15.679Z" } }, "terminationCondition": {