Skip to content

Conversation

@erwindouna
Copy link
Contributor

@erwindouna erwindouna commented Sep 8, 2025

Breaking change

This PR is meant as a general refactor to make the API calls more efficient by utilizing the asynchronous principles. This means that there's a switch from PyTado to tadoasync. The is a work in progress PR. please treat it as such.

Main parts to benefit from this PR:

  • Asynchronous library, doing all the heavy-lifting to the Tado REST API.
  • Better session handler (next attempt to tackle the long awaited re-authentication issues users experience).
  • Efficient usage of the Tado's API (remove redundant calls, etc.)

Proposed change

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:
  • Link to developer documentation pull request:
  • Link to frontend pull request:

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

@MrEbbinghaus
Copy link
Contributor

@erwindouna Seeing that large of a refactor.
Have you looked at Home Assistant's built-in OAuth support?

https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2

@erwindouna
Copy link
Contributor Author

@erwindouna Seeing that large of a refactor.
Have you looked at Home Assistant's built-in OAuth support?

https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2

I did indeed. That particular parts of HA only supports client credentials, not the device authentication Tado has put on. That explains the extra work both in python-tado and the Tado integration I programmed. :)

@MrEbbinghaus
Copy link
Contributor

@erwindouna I see. I thought there might be a way to implement the device flow as a custom solution, but the API seems to be very focused on client credentials.

@erwindouna erwindouna marked this pull request as ready for review September 24, 2025 20:39
Copilot AI review requested due to automatic review settings September 24, 2025 20:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the Tado integration from the synchronous PyTado library to the asynchronous tadoasync library, aimed at improving efficiency and addressing authentication issues users experience with the current implementation.

Key changes:

  • Library Migration: Switches from python-tado (PyTado) to tadoasync for better async support
  • API Restructure: Updates data models and API calls to use the new library's structured data classes
  • Test Modernization: Refactors test files to use new mock structures and removes deprecated testing patterns

Reviewed Changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
homeassistant/components/tado/manifest.json Updates dependency from python-tado==0.18.15 to tadoasync==0.2.2
homeassistant/components/tado/coordinator.py Major refactor to use tadoasync models and async patterns instead of PyTado
homeassistant/components/tado/climate.py Updates to work with new data structures from tadoasync library
homeassistant/components/tado/config_flow.py Refactors authentication flow to use async device activation
tests/components/tado/conftest.py Updates test fixtures to mock the new tadoasync API
Various test files Modernizes test patterns and removes deprecated utility functions


if not zoneChildLockSupported:
for zone in tado.zones.values():
if not len(zone.devices) > 0 and zone.devices[0].child_lock_enabled is not None:
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic error in the condition. The current condition if not len(zone.devices) > 0 and zone.devices[0].child_lock_enabled is not None: will cause an IndexError when zone.devices is empty because it tries to access zone.devices[0] even when the list is empty. The condition should be if len(zone.devices) > 0 and zone.devices[0].child_lock_enabled is not None: (removing the not).

Suggested change
if not len(zone.devices) > 0 and zone.devices[0].child_lock_enabled is not None:
if len(zone.devices) == 0 or zone.devices[0].child_lock_enabled is None:

Copilot uses AI. Check for mistakes.
Comment on lines +6 to 7
from tadoasync import Tado

Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import. The Tado class is imported but not used in this test file. Consider removing this import to keep the code clean.

Suggested change
from tadoasync import Tado

Copilot uses AI. Check for mistakes.
Comment on lines +218 to 225
# This is on older interface style, where the temperatures are inside the HEATING data attribute
# TODO: see if this still relevant, whereas it will most likely always resolve in the second if-statement
# if capabilities.type == CONST_MODE_HEAT and capabilities[CONST_MODE_HEAT].get(
# "temperatures"
# ):
# heat_temperatures = capabilities[CONST_MODE_HEAT]["temperatures"]
# CHECK WITH A TADO DEV

Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large block of commented-out code with TODO comments should be resolved. Either implement the proper logic for handling older interface styles or remove the commented code if it's no longer needed. The comment 'CHECK WITH A TADO DEV' suggests this needs developer input before the refactor is complete.

Suggested change
# This is on older interface style, where the temperatures are inside the HEATING data attribute
# TODO: see if this still relevant, whereas it will most likely always resolve in the second if-statement
# if capabilities.type == CONST_MODE_HEAT and capabilities[CONST_MODE_HEAT].get(
# "temperatures"
# ):
# heat_temperatures = capabilities[CONST_MODE_HEAT]["temperatures"]
# CHECK WITH A TADO DEV

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +66
# if "presenceLocked" in data:
if data.presence_locked:
geofencing_switch_mode = "manual"
else:
geofencing_switch_mode = "auto"
# else:
# geofencing_switch_mode = "manual"
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code should be removed. The old dictionary-style access pattern is no longer needed since the function now receives a structured HomeState object. Clean up by removing the commented lines.

Copilot uses AI. Check for mistakes.
Copy link
Member

@frenck frenck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa @erwindouna 🤯

That is quite a large PR. I would strongly recommend into making smaller iterations.

That said, there are CI failure, so marking this PR a draft.

@frenck frenck marked this pull request as draft October 18, 2025 20:48
@erwindouna
Copy link
Contributor Author

erwindouna commented Oct 19, 2025

Fair point, @frenck - quite a lot of work went into this and it’s still in progress. The challenge is that this PR both switches from PyTado to tadoasync and converts the integration from synchronous to asynchronous. I haven’t found a clean way to split that up without breaking the existing integration in between, since we can’t run both libraries side-by-side.

Do you have a suggestion on how you’d like this divided? I’d be happy to adjust the approach if there’s a preferred pattern for handling this kind of library migration. Once this migration is done, I intend to optimize the integration to handle the API interactions as efficient as possible. So it that sense I already intended to split up PR's. 🙈

@jwt99412
Copy link

Any update on this? Keen to test.

@ArtemKiyashko
Copy link

This I become critical since tado dramatically decreased limit rate on their API :)

@banter240
Copy link

Tbh I doubt that this will change anything. 100 API calls is good for nothing.

I build a "companion" for HomeKit and in the future for matter, to add the missing pieces like battery entities, home/away toggle, schedule toggle etc. Feel free to ask for even more. With it you can also see the current API Quota.

https://github.com/banter240/tado_hijack/

@ArtemKiyashko
Copy link

@frenck hey, could you respond to @erwindouna ?

without that change tado integration completely useless.
@erwindouna what if introduce separate integration temporary for beta testing? Name it like „Tado async” and push separately. For example. Then current integration become „stable” for safety and give you space for bugfixes of beta-integration.

Thanks, gents. We really waiting that :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants