Tado X Offset in Home Assistant

Introduction

Tado X radiator thermostats measure the temperature directly at the radiator, often leading to inaccurate readings. With this solution, you can automatically adjust the temperature offset by using external room thermostats as a reference.

This guide shows you how to set the offset via Home Assistant by regularly generating a new access token and calculating the temperature difference between the room thermostat and the radiator thermostat.

Requirements

  • Home Assistant (HA)
  • Tado X radiator thermostats
  • A separate room thermostat for more accurate measurements
  • Developer tools in Firefox or Chrome to retrieve the refresh token

Step 1: Retrieve the Refresh Token

  1. Open the developer tab (before logging in!):
  • Open app.tado.com, but do not log in yet!
  • Open the developer tools with F12 and go to the Network tab → XHR.
  • Now log in.
  • Click on the first POST result. There, you will find the refresh token and client ID in the response, which you will need later in the configuration.yaml.
  1. Create a JSON file in Home Assistant Open the File Editor or the Studio Code Server and create the following file /config/tado_rooms_devices.json and /config/tado_response.json with the following content:
{"refresh_token":"YOUR_REFRESH_TOKEN"}

Step 2: Add Shell Commands to configuration.yaml

Open your configuration.yaml and add the following Shell Commands: ADD YOUR CLIENT ID

shell_command:
  get_tado_token: >-
    curl -s -X POST "https://login.tado.com/oauth2/token"
    -d "client_id=>>>>>>>>>>>>>>>>CLIENT_ID_HERE<<<<<<<<<<<<<<<<<<"
    -d "grant_type=refresh_token"
    -d "refresh_token=$(jq -r '.refresh_token' /config/tado_response.json)"
    > /config/tado_response.json

  set_temperature_offset: >-
    curl "https://hops.tado.com/homes/1763547/roomsAndDevices/devices/{{ device }}?ngsw-bypass=true" 
    -X PATCH 
    -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0" 
    -H "Accept: application/json, text/plain, */*" 
    -H "Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3" 
    -H "Accept-Encoding: gzip, deflate, br, zstd" 
    -H "Content-Type: application/json" 
    -H "Referer: https://app.tado.com/" 
    -H "X-Amzn-Trace-Id: tado=webapp-2025.3.6.10.51-release/v3676" 
    -H "Origin: https://app.tado.com" 
    -H "Sec-Fetch-Dest: empty" 
    -H "Sec-Fetch-Mode: cors" 
    -H "Sec-Fetch-Site: same-site" 
    -H "Authorization: Bearer {{ access_token }}" 
    -H "Connection: keep-alive" 
    -H "Priority: u=0" 
    -H "TE: trailers" 
    --data-raw '{"temperatureOffset":{{ offset }}}'

  get_tado_access_token: "jq -r '.access_token' /config/tado_response.json"

  get_tado_rooms_devices_json: "jq -r '.' /config/tado_rooms_devices.json"

  get_tado_temperature_as_measured: >-
    jq -r '.rooms[].devices[] | select(.serialNumber=="{{ device }}") | .temperatureAsMeasured' /config/tado_rooms_devices.json

  get_tado_rooms_devices: >-
    curl -s "https://hops.tado.com/homes/1763547/roomsAndDevices?ngsw-bypass=true" 
    -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0" 
    -H "Accept: application/json, text/plain, */*" 
    -H "Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3" 
    -H "Accept-Encoding: gzip, deflate, br, zstd" 
    -H "Referer: https://app.tado.com/" 
    -H "X-Amzn-Trace-Id: tado=webapp-2025.3.7.9.55-release/v3677" 
    -H "Origin: https://app.tado.com" 
    -H "Sec-Fetch-Dest: empty" 
    -H "Sec-Fetch-Mode: cors" 
    -H "Sec-Fetch-Site: same-site" 
    -H "Authorization: Bearer $(jq -r '.access_token' /config/tado_response.json)" 
    -H "Connection: keep-alive" 
    -H "TE: trailers" 
    > /config/tado_rooms_devices.json

Save and restart Home Assistant!

Step 3: Automation to Refresh the Access Token

Since the Access Token expires every 10 minutes, a new one must be generated regularly. Create a new automation with the following YAML code:

alias: Tado Load New Access Token Every 9 Minutes
description: ""
trigger:
  - platform: time_pattern
    minutes: "/9"
action:
  - service: shell_command.get_tado_token
mode: single

Step 4: Automation to Calculate the Offset

Each time the temperature from the room thermostat or the Tado radiator valve changes, the offset is calculated and set:

alias: Offset berechnen
description: ""
triggers:
  - trigger: state
    entity_id:
      - sensor.ROOMTermostat
  - trigger: state
    entity_id:
      - sensor.Tado_Radiator_Termostat
conditions: []
actions:
  - action: shell_command.get_tado_rooms_devices
    metadata: {}
    data: {}
  - action: shell_command.get_tado_temperature_as_measured
    metadata: {}
    data:
      device: VAxxxxxxxxxx 
    response_variable: temperature_as_measured
  - action: shell_command.get_tado_access_token
    data: {}
    response_variable: bearer
  - action: shell_command.set_temperature_offset
    data:
      device: VAxxxxxxxxxx
      offset: >-
        {{ ((states('sensor.ROOMTermostat') | float(0)) -
        (temperature_as_measured.stdout | float(0))) | round(1) }}
      access_token: "{{bearer.stdout}}"
  - delay:
      hours: 0
      minutes: 0
      seconds: 30
      milliseconds: 0
    enabled: true
mode: single

Explanations:

  • INSERT_YOUR_DEVICE_SERIAL_NUMBER_HERE: Replace VAxxxxxxxxxx with the serial number of your Tado radiator thermostat.
  • sensor.ROOMTermostat = Room thermostat for accurate measurement.
  • sensor.Tado_Radiator_Termostat = Tado radiator thermostat.

Step 5: Testing & Activation

  1. Generate the Access Token: Go to Developer Tools → Actions and start shell_command.get_tado_token.
  2. Check the file: Open /config/tado_response.json and ensure that the access_token is stored.
  3. Start the automation:
  • Activate the 9-minute token renewal.
  • Activate the offset calculation automation.
  • Check the temperature values and offset values in Home Assistant.
  • Ensure that the offset is applied in the Tado app.

Is this needed when integrated via Matter ?

over matter you can only set the Heat mode and the setpoint. nothing else.
in the `tado_rooms_devices.json you have also other informations like the percent of heating of eatch valve ect.