Tado Integration - Put Offset

Apologies if this is in the wrong place, as it’s a feature request for the existing Tado integration.

The Tado integration is useful, but doesn’t include the functionality to change the thermostat offset, although it is available via the Tado API. The advantage of doing this is that it allows a separate (DIY / cheap) room thermostat to be used away from, and unaffected by, the direct heat from the radiator.

There would need to be 2 additions - an extra ‘sensor’ that contained the current offset for a device, and a service that would put the offset to a device.

If it helps the explanation, at present I’m doing it in a very clunky way using cURL in a command line sensor to both get the existing offset, and put the desired one.

Below is how I’ve bodged it in my config - sadly I have no knowledge of Python (yet…). The sensor “sensor.front_bedroom_temperature_display” is my separate MQTT sensor.

I use some automations to call the service that updates sensor.tado_front_bedroom_put_offset
whenever ‘sensor.front_bedroom_offset_difference’ is out by enough to warrant sending, rather than just on a timed basis.

# Tado login, retrieve token - as attribute, due to length. Scope used as value arbitrarily
  - platform: command_line
    name: Tado Auth
    scan_interval: 500
    json_attributes:
      - access_token
      - token_type
      - refresh_token
      - expires_in
      - scope
      - jti
      
    command: 'curl -s "https://auth.tado.com/oauth/token" -d client_id=tado-web-app -d grant_type=password -d scope=home.user -d username="********" -d password="*******" -d client_secret=*******************'
    value_template: '{{ value_json.scope }}'

############################ Front Bedroom #####################################
# Get Temperature Offset from Tado
  - platform: command_line
    name: Tado_Front_Bedroom_Offset
    scan_interval: 120
    unit_of_measurement: '°C'
    json_attributes:
      - celsius
      - fahrenheit
      
    command: 'curl -s "https://my.tado.com/api/v2/devices/VA*******/temperatureOffset" -H "Authorization: Bearer {{ state_attr(''sensor.tado_auth'', ''access_token'') }}"'
    value_template: '{{ value_json.celsius }}'


# Calculate radiator temperature
  - platform: template
    sensors:
      front_bedroom_radiator:
        friendly_name: "Tado Front Bedroom Radiator Sensor"
        unit_of_measurement: '°C'
        value_template: "{{ ((states('sensor.front_bedroom_temperature_2')|float ) - (state_attr('sensor.tado_front_bedroom_offset','celsius')|float))|round(2)}}"

# Calculate radiator offset required
  - platform: template
    sensors:
      front_bedroom_calculated_offset:
        friendly_name: "Front Bedroom Calculated Offset"
        unit_of_measurement: '°C'
        value_template: "{% if (states('sensor.front_bedroom_temperature_display')|float ) > 0 -%} {{((states('sensor.front_bedroom_temperature_display')|float ) - (states('sensor.front_bedroom_radiator')|float))| round(2)}} {%- else -%} 0 {%- endif %}"

# Calculate offset difference
  - platform: template
    sensors:
      front_bedroom_offset_difference:
        friendly_name: "Front Bedroom Offset Difference"
        unit_of_measurement: '°C'
        value_template: "{{ ((states('sensor.front_bedroom_calculated_offset')|float ) - (states('sensor.tado_front_bedroom_put_offset')|float))| round(2)}}"

# Put Offset to Tado
  - platform: command_line
    name: Tado_Front_Bedroom_Put_Offset
    scan_interval: 300000
    unit_of_measurement: '°C'
    json_attributes:
      - celsius
      - fahrenheit
      
    command: 'curl -X PUT "https://my.tado.com/api/v2/devices/VA******/temperatureOffset" -H "Authorization: Bearer {{ state_attr(''sensor.tado_auth'', ''access_token'') }}" -H "Content-Type: text/plain" --data-raw "{celsius: {{ ((states(''sensor.front_bedroom_calculated_offset'')|float))| round(2)}} }" '
    value_template: '{{ value_json.celsius }}'


Useful sources of info: -


In case it proves to be of any help I also wrote this for the ESP32, that calls the API directly, rather than using HA: -

Jonathan

Edited 17/7/2020 to remove backslashes (for escaping) before quotes in command line sensors, due to change in HA

That would be very useful

Thanks, missed that, voted on it

I’ve implemented something similar to the above, here is the text that differs -

# Get Temperature Offset from Tado
  - platform: command_line
    name: tado_kitchen_current_offset
    scan_interval: 120
    unit_of_measurement: '°C'
    json_attributes:
      - celsius
      - fahrenheit
    command: 'curl -s \"https://my.tado.com/api/v2/devices/VAxxxx/temperatureOffset\" -H \"Authorization: Bearer {{ state_attr(''sensor.tado_auth'', ''access_token'') }}\"'
    value_template: '{{ value_json.celsius }}'

# Calculate temperature of radiator temperature sensor, i.e. reported temp - offset
  - platform: template
    sensors:
      kitchen_radiator_internal_temp:
        friendly_name: "Tado Kitchen Radiator Sensor Temp"
        unit_of_measurement: '°C'
        value_template: "{{ ((states('sensor.kitchen_temp_tado')|float ) - (state_attr('sensor.tado_kitchen_current_offset','celsius')|float))|round(1)}}"

# Calculate radiator offset required: aqara temp - internal radiator temp
  - platform: template
    sensors:
      kitchen_required_offset:
        friendly_name: "Kitchen Required Offset"
        unit_of_measurement: '°C'
        value_template: "{{((states('sensor.kitchen_temp_aqara')|float ) - (states('sensor.kitchen_radiator_internal_temp')|float))| round(1)}}"

# Put Offset to Tado
  - platform: command_line
    name: tado_kitchen_put_offset
    scan_interval: 600
    unit_of_measurement: '°C'
    json_attributes:
      - celsius
      - fahrenheit
    command: 'curl -X PUT \"https://my.tado.com/api/v2/devices/VAxxxxx/temperatureOffset\" -H \"Authorization: Bearer {{ state_attr(''sensor.tado_auth'', ''access_token'') }}\" -H \"Content-Type: text/plain\" --data-raw \"{celsius: {{ ((states(''sensor.kitchen_required_offset'')|float))| round(1)}} }\" '
    value_template: '{{ value_json.celsius }}'

I’ve been experimenting with how frequently you can push updates to Tado. If you push the updates too often, then the reported temperature from the TRV doesn’t have time to update to reflect the new offset (can take up to 10 minutes), and you get into a cycle of pushing ever more extreme offsets.

@jon_r - how frequent do you push updates? why round to two decimal places when the offset is only stored by tado at least online as whole numbers?

1 Like

@hamoph I originally had the problem you describe, but then changed my code to what it is now.
By querying the existing offset I avoid the loop that leads to ever higher offsets. I haven’t fully looked at what yours is doing, but some how you’ve got the original problem I had.

The other thing is my ‘PUTing’ the offset is conditional, and I increase it quicker than I lower it, as when the radiator is on it increases quickly, but drops slowly when off.

My automation looks like this: -

- id: 'xxxxxxxxxx'
  alias: Put Tado Offset Front Bedroom
  description: ''
  trigger:
  - above: '0.3'
    entity_id: sensor.front_bedroom_offset_difference
    for: 00:10:00
    platform: numeric_state
    value_template: '{{ states(''sensor.front_bedroom_offset_difference'') }}'
  - below: '-0.3'
    entity_id: sensor.front_bedroom_offset_difference
    for: 00:05:00
    platform: numeric_state
    value_template: '{{ states(''sensor.front_bedroom_offset_difference'') }}'
  condition: []
  action:
  - entity_id: sensor.tado_front_bedroom_put_offset
    service: homeassistant.update_entity

Hope it helps

Jon

ps the two decimal place thing isn’t really logical, I know. The API accepts it though, and it does respond with the 2 dp value when queried

1 Like

amazing, thanks - presumably you then set the scan_interval for sensor.tado_front_bedroom_put_offset to be very high, so that it only runs very infrequently by itself?

Yes, sorry forgot to mention

While I remember, for anyone looking, it seems to be that the valve motor operates every time an offset is put. Using the conditions to only put an offset when it’s actually required to change reduces this, reducing battery consumption of the valve. Without it the valve seems to eat batteries, as the motor is in use every few minutes.

Is there a way to get battery level?

1 Like

Like jon_r said, the valve motor operates every time an offset is put. This opens the radiator full blast. Even though it’s only for a second, it can significantly increase the temperature of the room. Assuming this feature sets the offset periodically, the resultant inscrease to the room temperature renders this feature counter productive at best (or at least for me it does). If anyone would like Tado to stop the operating of the motor upon setting the offset, you can vote for it here: https://community.tado.com/en-gb/discussion/4325/disable-trv-calibration-when-offset-is-changed-required-for-using-external-sensor

What I meant to say was please vote so we can take proper advantage of the offset feature: https://community.tado.com/en-gb/discussion/4325/disable-trv-calibration-when-offset-is-changed-required-for-using-external-sensor. Pretty please with sugar on top

As you’ve likely already gathered, only the following endpoint gives battery level data but it’s not a percentage. Just “NORMAL”, etc
https://my.tado.com/api/v2/homes/MyHomeID/zones?username=MyUserName&password=MyPassWord

I’ve tried this out for a while, but the re-calibration on every offset update is a real pain - noise wise.

Has anyone tried using the tado API and a template switch to create a switch that turns the radiator on and off (e.g. set to off or heat (with high temp) and then use the temperature sensor and this template switch to create a generic thermostat?

I’m interested in a solution to this. I find the separate TRVs really useful, but you can never rely on the offset. I’d love to be able to use my Xiaomi sensors in the same room to be able to configure the offset.

Hi,

Am I the only one who started having trouble with this model of getting and putting the offset?
Don’t know exactly when it started failing since it’s summer and warm, but probably a couple of months ago.

The logs say:

Command failed: curl -s \"https://my.tado.com/api/v2/devices/VAxxxxxxxx/temperatureOffset\" -H \"Authorization: Bearer eyXXyyZZxxYYZZxxNiI.......KnKG8ng\"

Also the following error at the same amount and time:

Empty reply found when expecting JSON data
1 Like

There was a change to HA to fix removal of " from command line sensors. Unfortunately it was a breaking change, but no one noticed until after. (I updated the blog, but you might not have seen it or realised the implications)
Anyway, remove the backslashes in front of each of the quotes and it works again

1 Like

I hadn’t noticed that at all. Thank you so much!

Btw, which blog are you referring to? The first post in this thread still has the backslashes.

The HA upgrade blog one that included the announcement of the fix to command line sensors.
Can’t remember which version it was now
(It’s editable via a GitHub PR)
I’ll see if I can edit my post above

1 Like