Skip to main content

PyTado -- Pythonize your central heating

Linting and testing Build and deploy to pypi PyPI version codecov Open in Dev Containers

PyTado is a Python module implementing an interface to the Tado web API. It allows a user to interact with their Tado heating system for the purposes of monitoring or controlling their heating system, beyond what Tado themselves currently offer.

It is hoped that this module might be used by those who wish to tweak their Tado systems, and further optimize their heating setups.


Original author: Chris Jewell chrism0dwk@gmail.com

License: GPL v3

Copyright: Chris Jewell 2016-2018

Disclaimer

Besides owning a Tado system, I have no connection with the Tado company themselves. PyTado was created for my own use, and for others who may wish to experiment with personal Internet of Things systems. I receive no help (financial or otherwise) from Tado, and have no business interest with them. This software is provided without warranty, according to the GNU Public License version 3, and should therefore not be used where it may endanger life, financial stakes, or cause discomfort and inconvenience to others.

Usage

As of the 15th of March 2025, Tado has updated their OAuth2 authentication flow. It will now use the device flow, instead of a username/password flow. This means that the user will have to authenticate the device using a browser, and then enter the code that is displayed on the browser into the terminal.

PyTado handles this as following:

  1. The _login_device_flow() will be invoked at the initialization of a PyTado object. This will start the device flow and will return a URL and a code that the user will have to enter in the browser. The URL can be obtained via the method device_verification_url(). Or, when in debug mode, the URL will be printed. Alternatively, you can use the device_activation_status() method to check if the device has been activated. It returns three statuses: NOT_STARTED, PENDING, and COMPLETED. Wait to invoke the device_activation() method until the status is PENDING.

  2. Once the URL is obtained, the user will have to enter the code that is displayed on the browser into the terminal. By default, the URL has the user_code attached, for the ease of going trough the flow. At this point, run the method device_activation(). It will poll every five seconds to see if the flow has been completed. If the flow has been completed, the method will return a token that will be used for all further requests. It will timeout after five minutes.

  3. Once the token has been obtained, the user can use the PyTado object to interact with the Tado API. The token will be stored in the Tado object, and will be used for all further requests. The token will be refreshed automatically when it expires. The device_verification_url() will be reset to None and the device_activation_status() will return COMPLETED.

Screenshots of the device flow

Tado device flow: invoking Tado device flow: browser Tado device flow: complete

How to not authenticate the device again

It is possible to save the refresh token and reuse to skip the next login.

The following code will use the refresh_token file to save the refresh-token after login, and load the refresh-token if you create the Tado interface class again.

If the file doesn't exists, the web browser is started and the device authentication url is automatically opened. You can activate the device in the browser. When you restart the program, the refresh-token is reused and no web browser will be opened.

import webbrowser   # only needed for direct web browser access

from PyTado.interface.interface import Tado

tado = Tado(token_file_path="/var/tado/refresh_token")

status = tado.device_activation_status()

if status == "PENDING":
    url = tado.device_verification_url()

    webbrowser.open_new_tab(url)

    tado.device_activation()

    status = tado.device_activation_status()

if status == "COMPLETED":
    print("Login successful")
else:
    print(f"Login status is {status}")

Example code

"""Example client for PyTado"""

from PyTado.interface.interface import Tado


def main() -> None:
    """Retrieve all zones, once successfully logged in"""
    tado = Tado()

    print("Device activation status: ", tado.device_activation_status())
    print("Device verification URL: ", tado.device_verification_url())

    print("Starting device activation")
    tado.device_activation()

    print("Device activation status: ", tado.device_activation_status())

    zones = tado.get_zones()
    print(zones)


if __name__ == "__main__":
    main()

Note: For developers, there is an example.py script in examples/ which is configured to fetch data from your account. You can then invoke python examples/example.py.

Contributing

We are very open to the community's contributions - be it a quick fix of a typo, or a completely new feature!

You don't need to be a Python expert to provide meaningful improvements. To learn how to get started, check out our Contributor Guidelines first, and ask for help in GitHub Discussions if you have questions.

Development

We welcome external contributions, even though the project was initially intended for personal use. If you think some parts could be exposed with a more generic interface, please open a GitHub issue to discuss your suggestion.

Setting up a devcontainer

The easiest way to start, is by opening a CodeSpace here on GitHub, or by using the Dev Container feature of Visual Studio Code.

Open in Dev Containers

Dev Environment

To contribute to this repository, you should first clone your fork and then setup your development environment. Clone your repository as follows (replace yourusername with your GitHub account name):

git clone https://github.com/yourusername/PyTado.git
cd PyTado

Then, to create your development environment and install the project with its dependencies, execute the ./scripts/bootstrap script.

Coding Guidelines

To maintain a consistent codebase, we utilize black. Consistency is crucial as it helps readability, reduces errors, and facilitates collaboration among developers.

To ensure that every commit adheres to our coding standards, we've integrated pre-commit hooks. These hooks automatically run black before each commit, ensuring that all code changes are automatically checked and formatted.

For details on how to set up your development environment to make use of these hooks, please refer to the Development section of our documentation.

Testing

Ensuring the robustness and reliability of our code is paramount. Therefore, all contributions must include at least one test to verify the intended behavior.

To run tests locally, execute the test suite using pytest with the following command:

pytest tests/ --cov --cov-branch -vv

A message from the original author:

This software is at a purely experimental stage. If you're interested and can write Python, clone the Github repo, drop me a line, and get involved!

Best wishes and a warm winter to all!

Chris Jewell

Metadata

Release files for python-tado 0.19.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-tado 0.19.4
File Size Uploaded Provenance Actions
python_tado-0.19.4.tar.gz 50.8 kB With provenance Details for python_tado-0.19.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for python-tado 0.19.4
File Interpreter ABI Platform Actions
python_tado-0.19.4-py3-none-any.whl Python 3 none any Details for python_tado-0.19.4-py3-none-any.whl

Total release size: 117.8 kB

Release files / python_tado-0.19.4.tar.gz

Download URL python_tado-0.19.4.tar.gz
Size 50.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c77f62dde7e93b01a60013efedd3b006c5622dde7d88fadb130bb9776a68219f
BLAKE2b-256 checksum
How to use checksums
30f2c802830c262b9303a27fd6110e00de4e460954ea2d6f848bdd98a0661879
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / python_tado-0.19.4-py3-none-any.whl

Download URL python_tado-0.19.4-py3-none-any.whl
Size 67.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28ddd4532f105687851b7b3e57c70d3a068c0a9a48f6ce68e80632219ced0dcc
BLAKE2b-256 checksum
How to use checksums
e8a2bae61fec01127675c9f1e1c0a33c8713b03a54f2cc7d735dd121adc61f64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Security for python-tado 0.19.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for python_tado-0.19.4.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.19.4 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page