The Tado API v2

Posted in Posted on 2017-01-07 15:00

I’ve been poking around in the Tado smart thermostat API again as the web application now uses v2. Here are the API calls I have found, including how to manually adjust the heating temperature. Tado haven’t published their API so this could change and break at any time.

In the descriptions below I list the API call then an example curl command to make the call, followed by an example response. I have replaced some parts of the response with “xxx” (for strings) or “123” (for numbers) so as not to reveal my personal data.

Authentication

To make any of the calls work, you first have to authenticate yourself (log in). It seems that you can just put your username and password as parameters for any call (this is what the Android mobile app does). For earlier versions of the API you could just log in and store a cookie but for v2 if you do not want to use your password every time you need to authenticate using OAuth (OAuth2 actually).

Username and Password

This is the simplest form of authentication. For any of the calls listed below you just need to specify your username and password as parameters. The examples below all assume you are using OAuth2 but you can easily adjust. For instance, replace:

$ curl "https://my.tado.com/api/v2/me" -H "Authorization: Bearer `cat /tmp/tadotoken`"

with

$ curl "https://my.tado.com/api/v2/me" -d username=[email protected] -d password=yourPassword

OAuth2

OAuth2 is primarily intended for authorisation but here we are basically using it for authentication. Hopefully Tado will add in API methods to allow us to add or remove devices and other clients. Right now we have to pretend to be the already-authorised existing web application client.

To use OAuth you have to send over your username and password and you get a token back plus an expiry time (currently 10 minutes) and a special token you could use to refresh the first one without sending the password again. To get all this you use the following call:

$ curl -s "https://my.tado.com/oauth/token" -d client_id=tado-webapp -d grant_type=password -d scope=home.user -d username=[email protected] -d password=yourPasssword

That returns some JSON data:

{
  "access_token": "eyJraW...somethingReallyQuiteLong...0UQ",
  "token_type": "bearer",
  "refresh_token": "xxx",
  "expires_in": 599,
  "scope": "home.user"
}

If you don’t have curl installed then just do sudo apt-get install curl first (similarly for perl below). Obviously, you need to replace yourPassword with your password and [email protected] with your email address that you use to log in to your Tado account. The information is sent over HTTPS so it is encrypted and no-one can see the password.

To execute any other commands we need to get hold of just the access_token and save it. The following command does just that by running the output through a Perl regular expression and then saving it in /tmp/tadotoken:

$ curl -s "https://my.tado.com/oauth/token" -d client_id=tado-webapp -d grant_type=password -d password=yourPasssword -d scope=home.user -d username=[email protected] | perl -pe 's/^.*"access_token"\s*:\s*"([^"]*).*/$1/' > /tmp/tadotoken

Alternatively, you could install jq (with sudo apt-get install jq) which is a command line JSON processor and do the job slightly more intuitively:

$ curl -s "https://my.tado.com/oauth/token" -d client_id=tado-webapp -d grant_type=password -d password=yourPasssword -d scope=home.user -d username=[email protected]  | jq -r '.access_token' > /tmp/tadotoken

The -r flag is needed because otherwise jq puts quotes around the value of the access token.

Once the token expires it’s probably easiest just to get a new one from scratch using the same command, but you can use the refresh token as follows:

$ curl -X POST -s "https://my.tado.com/oauth/token" -d client_id=tado-webapp -d grant_type=refresh_token -d refresh_token=REFRESH_TOKEN -d scope=home.user

That returns the same JSON as the first command with the password in so you can process it in the same way to extract a new access token.

To use some of the API you need to know your home’s ID number. You can get this using the /api/v2/me call. I have replaced my home ID with “<homeID>” in the following documentation: you should insert yours (without any brackets) instead.

Tado mobile API v1.6

We have a special mention here for a method in v1.6 of the mobile API (as used by the Android app). The method lets you access the graph data that you can see plotted in the mobile app (but for some reason, not in the webapp).

/mobile/1.6/getTemperaturePlotData

$ curl -X POST -s "https://my.tado.com/mobile/1.6/getTemperaturePlotData" -d fromDate=2017-02-04T23:42:00.012Z -d toDate=2017-02-06T00:17:59.047Z -d zoneId=1  -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "success": true,
  "minInsideTemperature": 17.695,
  "maxInsideTemperature": 22.695,
  "plotdata": [
    {
      "timestamp": "2017-02-04T23:42:00.012Z",
      "rxControlPhase": "COOLDOWN",
      "heatingOn": null,
      "insideTemperature": 20.67,
      "virtSolarIntensity": null,
      "thermostatOperation": "HOME",
      "setPointTemperature": 10,
      "hotWaterProduction": null
    },
    ... one entry approximately every 3 minutes ...
  ],
  "dayStatistics": {
    "2017-02-04": {
      "day": 1486166400000,
      "SLEEP": 0,
      "HOME": 86400000,
      "AWAY": 0,
      "MANUAL": 0,
      "NO_FREEZE": 0,
      "UNDEFINED": 0,
      "NO_INTERNET": 0
    },
    "2017-02-05": {
      "day": 1486252800000,
      "SLEEP": 0,
      "HOME": 86400000,
      "AWAY": 0,
      "MANUAL": 0,
      "NO_FREEZE": 0,
      "UNDEFINED": 0,
      "NO_INTERNET": 0
    },
    "2017-02-06": {
      "day": 1486339200000,
      "SLEEP": 0,
      "HOME": 75052283,
      "AWAY": 0,
      "MANUAL": 0,
      "NO_FREEZE": 0,
      "UNDEFINED": 0,
      "NO_INTERNET": 0
    }
  },
  "noConnection": [],
  "privacy": []
}

If you wanted to extract all the insideTemperature values from that mass of data you could pipe it through the excellent jq and do:

$ curl -X POST -s "https://my.tado.com/mobile/1.6/getTemperaturePlotData" -d fromDate=2017-02-04T23:42:00.012Z -d toDate=2017-02-06T00:17:59.047Z -d zoneId=1  -H "Authorization: Bearer `cat /tmp/tadotoken`" | jq '.plotdata | .[].insideTemperature'

For the POST parameters, you need to supply the fromDate and toDate in the full ISO 8601 format (not forgetting the “Z” on the end). I expect that for most installations the zoneId will be 1, but see the /api/v2/homes/<homeID>/zones method further down to find out what your zones are.

Tado API v2

/api/v2/me

A GET on this endpoint provides information about the authenticated user, the home(s) and mobile devices.

$ curl "https://my.tado.com/api/v2/me" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "name": "xxx",
  "email": "xxx",
  "username": "xxx",
  "homes": [
    {
      "id": <homeID>,
      "name": "xxx"
    }
  ],
  "locale": "en_GB",
  "mobileDevices": [
    {
      "name": "xxx",
      "id": 12345,
      "settings": {
        "geoTrackingEnabled": true
      },
      "location": {
        "stale": true,
        "atHome": true,
        "bearingFromHome": {
          "degrees": 152.29927711986,
          "radians": 2.6581238341488
        },
        "relativeDistanceFromHomeFence": 0
      },
      "deviceMetadata": {
        "platform": "Android",
        "osVersion": "1.2.3",
        "model": "xxx",
        "locale": "en"
      }
    },
    etc
  ]
}

/api/v2/homes/<homeID>

Once you have your home ID, you can use a GET here to find all sorts of information about the home.

$ curl "https://my.tado.com/api/v2/homes/<homeID>" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "id": <homeID>,
  "name": "Phillips",
  "dateTimeZone": "Europe\/London",
  "temperatureUnit": "CELSIUS",
  "installationCompleted": true,
  "partner": null,
  "simpleSmartScheduleEnabled": true,
  "contactDetails": {
    "name": "Stephen C Phillips",
    "email": "xxx",
    "phone": "+4412345678901"
  },
  "address": {
    "addressLine1": "xxx",
    "addressLine2": null,
    "zipCode": "xxx",
    "city": "Southampton",
    "state": null,
    "country": "GBR"
  },
  "geolocation": {
    "latitude": 50.1234567,
    "longitude": -1.1234567
  }
}

/api/v2/homes/<homeID>/weather

A GET on this endpoint returns the weather at the home’s location. The solar intensity is used by Tado to help determine the likely rate of heat loss from the home and therefore how much heating will be required. I guess the charts in the Tado app shows the sun as shining if the intensity was over some threshold.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/weather" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "solarIntensity": {
    "type": "PERCENTAGE",
    "percentage": 15.06,
    "timestamp": "2017-01-07T14:36:43.507Z"
  },
  "outsideTemperature": {
    "celsius": 10.25,
    "fahrenheit": 50.45,
    "timestamp": "2017-01-07T14:36:43.507Z",
    "type": "TEMPERATURE",
    "precision": {
      "celsius": 0.01,
      "fahrenheit": 0.01
    }
  },
  "weatherState": {
    "type": "WEATHER_STATE",
    "value": "SCATTERED_RAIN",
    "timestamp": "2017-01-07T14:36:43.507Z"
  }
}

So to get the outside temperature you could do the following:

$ curl -s "https://my.tado.com/api/v2/homes/<homeID>/weather" -H "Authorization: Bearer `cat /tmp/tadotok en`" | jq '.outsideTemperature.celsius'

The -s flag for curl stops it reporting the progress statistics about the data transfer so that all you see is the actual temperature data.

For the weatherState I have observed SCATTERED_RAIN, FOGGY and NIGHT_CLOUDY so far.

/api/v2/homes/<homeID>/devices

A GET on /devices returns lots of information about the Tado hardware installed in your home. In the example below I think “BU01” is the boiler controller, “GW02” is the gateway unit which plugs into my ethernet and provides the gateway between the wireless network Tado uses and the internet, and “RU01” is the remote thermostat.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/devices" -H "Authorization: Bearer `cat /tmp/tadotoken`"
[
  {
    "deviceType": "BU01",
    "serialNo": "BUxxx",
    "shortSerialNo": "BUx",
    "currentFwVersion": "12.34",
    "connectionState": {
      "value": true,
      "timestamp": "2017-01-07T14:28:41.122Z"
    },
    "characteristics": {
      "capabilities": [
        "IDENTIFY"
      ]
    }
  },
  {
    "deviceType": "GW02",
    "serialNo": "GWxxx",
    "shortSerialNo": "GWx",
    "currentFwVersion": "12.3",
    "connectionState": {
      "value": true,
      "timestamp": "2017-01-07T14:41:07.547Z"
    },
    "characteristics": {
      "capabilities": [

      ]
    },
    "gatewayOperation": "NORMAL"
  },
  {
    "deviceType": "RU01",
    "serialNo": "RUxxx",
    "shortSerialNo": "RUx",
    "currentFwVersion": "12.34",
    "connectionState": {
      "value": true,
      "timestamp": "2017-01-07T14:25:04.634Z"
    },
    "characteristics": {
      "capabilities": [
        "INSIDE_TEMPERATURE_MEASUREMENT",
        "IDENTIFY"
      ]
    }
  }
]

/api/v2/homes/<homeID>/installations

A GET here returns more info on the Tado hardware in the home.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/installations" -H "Authorization: Bearer `cat /tmp/tadotoken`"
[
  {
    "id": 0,
    "type": "SALE_FITTING_ST_G1",
    "revision": 1,
    "state": "COMPLETED",
    "devices": [
      {
        "deviceType": "BU01",
        "serialNo": "BUxxx",
        "shortSerialNo": "BUx",
        "currentFwVersion": "12.34",
        "connectionState": {
          "value": true,
          "timestamp": "2017-01-07T14:28:41.122Z"
        },
        "characteristics": {
          "capabilities": [
            "IDENTIFY"
          ]
        }
      },
      {
        "deviceType": "RU01",
        "serialNo": "RUxxx",
        "shortSerialNo": "RUx",
        "currentFwVersion": "12.34",
        "connectionState": {
          "value": true,
          "timestamp": "2017-01-07T14:25:04.634Z"
        },
        "characteristics": {
          "capabilities": [
            "INSIDE_TEMPERATURE_MEASUREMENT",
            "IDENTIFY"
          ]
        }
      }
    ]
  }
]

/api/v2/homes/<homeID>/users

A GET on this endpoint provides a combination of the users and their mobile devices.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/users" -H "Authorization: Bearer `cat /tmp/tadotoken`"
[
  {
    "name": "xxx",
    "email": "[email protected]",
    "username": "[email protected]",
    "homes": [
      {
        "id": <homeID>,
        "name": "xxx"
      }
    ],
    "locale": "en_GB",
    "mobileDevices": [
      {
        "name": "xxxPhone",
        "id": 123456,
        "settings": {
          "geoTrackingEnabled": true
        },
        "location": {
          "stale": false,
          "atHome": true,
          "bearingFromHome": {
            "degrees": 57.29429990161771,
            "radians": 0.9999741759082923
          },
          "relativeDistanceFromHomeFence": 0
        },
        "deviceMetadata": {
          "platform": "Android",
          "osVersion": "1.2.3",
          "model": "xxx",
          "locale": "en"
        }
      },
      etc
    ]
  },
  etc
]

/api/v2/homes/<homeID>/mobileDevices

A GET on mobileDevices gives some potentially useful information: a list of all mobile devices that are linked to your home vua the Tado app, including their bearing from the home to help provide the small radar view of device locations.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/mobileDevices" -H "Authorization: Bearer `cat /tmp/tadotoken`"
[
  {
    "name": "xxx",
    "id": 12345,
    "settings": {
      "geoTrackingEnabled": true
    },
    "location": {
      "stale": true,
      "atHome": true,
      "bearingFromHome": {
        "degrees": 152.29927711986,
        "radians": 2.6581238341488
      },
      "relativeDistanceFromHomeFence": 0
    },
    "deviceMetadata": {
      "platform": "Android",
      "osVersion": "1.2.3",
      "model": "xxx",
      "locale": "en"
    }
  },
  etc
]

/api/v2/homes/<homeID>/mobileDevices/<deviceID>

I expected that you’d be able to do a GET on e.g. https://my.tado.com/api/v2/homes/<homeID>/mobileDevices/12345 where 12345 is the ID of one of the devices to get the subset of information about a specific device but this call returns a 404.

However, what you can do is delete a device. Attached to my Tado at the moment are 4 mobile phones but two of them are zombies: they were registered via the app but then after an app upgrade we had to log in again and the two phones appeared for a second time. You can remove a device through the web app but also through an HTTP DELETE command:

curl -X DELETE "https://my.tado.com/api/v2/homes/<homeID>/mobileDevices/deviceID" -H "Authorization: Bearer `cat /tmp/tadotoken`"

/api/v2/homes/<homeID>/mobileDevices/<deviceID>/settings

A GET on this endpoint gives you just the geoTrackingEnabled status. Using a PUT can change that setting:

curl "https://my.tado.com/api/v2/homes/<homeID>/mobileDevices/<deviceID>/settings" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "geoTrackingEnabled": true
}

When doing a PUT you need to additionally provide the new data in JSON form and set the character set being used. Be very careful of the different quotes as well: the JSON needs double quotes round the string literals and the whole of the JSON can be enclosed by single quotes.

$ curl -X PUT "https://my.tado.com/api/v2/homes/<homeID>/mobileDevices/<deviceID>/settings" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '{"geoTrackingEnabled":false}'
{
  "geoTrackingEnabled": false
}

/api/v2/homes/<homeID>/zones

This call tells you about the different “zones” in your system. For several other calls you need to know which is your heating zone (mine is “1”) and which is your hot water zone (mine is “0”). This call gives you that information. You may of course have more than one heating zone. In some of the subsequent documentation I have written <zoneID> which you need to replace with the appropriate number.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones" -H "Authorization: Bearer `cat /tmp/tadotoken`"
[
  {
    "id": 1,
    "name": "Heating",
    "type": "HEATING",
    "deviceTypes": [
      "BU01",
      "RU01"
    ],
    "devices": [
      {
        "deviceType": "BU01",
        "serialNo": "BUxxx",
        "shortSerialNo": "BUx",
        "currentFwVersion": "12.34",
        "connectionState": {
          "value": true,
          "timestamp": "2017-01-07T14:28:41.122Z"
        },
        "characteristics": {
          "capabilities": [
            "IDENTIFY"
          ]
        },
        "duties": [
          "CIRCUIT_DRIVER"
        ]
      },
      {
        "deviceType": "RU01",
        "serialNo": "RUxxx",
        "shortSerialNo": "RUx",
        "currentFwVersion": "12.34",
        "connectionState": {
          "value": true,
          "timestamp": "2017-01-07T14:25:04.634Z"
        },
        "characteristics": {
          "capabilities": [
            "INSIDE_TEMPERATURE_MEASUREMENT",
            "IDENTIFY"
          ]
        },
        "duties": [
          "ZONE_UI",
          "ZONE_LEADER"
        ]
      }
    ],
    "reportAvailable": true,
    "supportsDazzle": true,
    "dazzleEnabled": true
  },
  {
    "id": 0,
    "name": "Hot Water",
    "type": "HOT_WATER",
    "deviceTypes": [
      "BU01",
      "RU01"
    ],
    "devices": [
      {
        "deviceType": "BU01",
        "serialNo": "BUxxx",
        "shortSerialNo": "BUx",
        "currentFwVersion": "12.34",
        "connectionState": {
          "value": true,
          "timestamp": "2017-01-07T14:28:41.122Z"
        },
        "characteristics": {
          "capabilities": [
            "IDENTIFY"
          ]
        },
        "duties": [
          "ZONE_DRIVER"
        ]
      },
      {
        "deviceType": "RU01",
        "serialNo": "RUxxx",
        "shortSerialNo": "RUx",
        "currentFwVersion": "12.34",
        "connectionState": {
          "value": true,
          "timestamp": "2017-01-07T14:25:04.634Z"
        },
        "characteristics": {
          "capabilities": [
            "INSIDE_TEMPERATURE_MEASUREMENT",
            "IDENTIFY"
          ]
        },
        "duties": [
          "ZONE_UI",
          "ZONE_LEADER"
        ]
      }
    ],
    "reportAvailable": false,
    "supportsDazzle": false,
    "dazzleEnabled": true
  }
]

/api/v2/homes/<homeID>/zones/<zoneID>/state

Here’s where we get some key information. The “state” of a HOT_WATER zone might tell us if the hot water heating is on or off. It looks as though it is possible to obtain the temperature of the domestic hot water as well - perhaps I am missing a sensor?

For my hot water zone I get:

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/0/state" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "tadoMode": "HOME",
  "geolocationOverride": true,
  "geolocationOverrideDisableTime": "2017-01-07T18:00:00Z",
  "preparation": null,
  "setting": {
    "type": "HOT_WATER",
    "power": "OFF",
    "temperature": null
  },
  "overlayType": null,
  "overlay": null,
  "link": {
    "state": "ONLINE"
  },
  "activityDataPoints": {

  },
  "sensorDataPoints": {

  }
}

A GET on the state for the central heating zone tells us the target and actual temperature and the humidity. Also the heatingPower, but I don’t know what that is.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/1/state" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "tadoMode": "HOME",
  "geolocationOverride": false,
  "geolocationOverrideDisableTime": null,
  "preparation": null,
  "setting": {
    "type": "HEATING",
    "power": "ON",
    "temperature": {
      "celsius": 19.5,
      "fahrenheit": 67.1
    }
  },
  "overlayType": null,
  "overlay": null,
  "link": {
    "state": "ONLINE"
  },
  "activityDataPoints": {
    "heatingPower": {
      "type": "PERCENTAGE",
      "percentage": 20,
      "timestamp": "2017-01-07T14:30:59.439Z"
    }
  },
  "sensorDataPoints": {
    "insideTemperature": {
      "celsius": 19.37,
      "fahrenheit": 66.87,
      "timestamp": "2017-01-07T14:24:48.623Z",
      "type": "TEMPERATURE",
      "precision": {
        "celsius": 0.1,
        "fahrenheit": 0.1
      }
    },
    "humidity": {
      "type": "PERCENTAGE",
      "percentage": 58.7,
      "timestamp": "2017-01-07T14:24:48.623Z"
    }
  }
}

To extract the key pieces of information you could do the following:

$ curl -s "https://my.tado.com/api/v2/homes/<homeID>/zones/1/state" -H "Authorization: Bearer `cat /tmp/tadotoken`" | jq '.setting.power .setting.temperature.celsius, .sensorDataPoints.insideTemperature.celsius, .sensorDataPoints.humidity.percentage'

That would return something like:

"ON"
19.5
19.69
60.5

/api/v2/homes/<homeID>/zones/<zoneID>/capabilities

For my hot water zone:

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/0/capabilities" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "type": "HOT_WATER",
  "canSetTemperature": false
}

For my heating zone:

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/1/capabilities" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "type": "HEATING",
  "temperatures": {
    "celsius": {
      "min": 5,
      "max": 25,
      "step": 0.1
    },
    "fahrenheit": {
      "min": 41,
      "max": 77,
      "step": 0.1
    }
  }
}

/api/v2/homes/<homeID>/zones/<zoneID>/earlyStart

This call controls whether the Tado makes sure a set temperature is reached at the start of a block.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/earlyStart" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "enabled": true
}

Using a PUT lets us change the setting:

$ curl -X PUT "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/earlyStart" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '{"enabled":false}'
{
  "enabled": false
}

/api/v2/homes/<homeID>/zones/<zoneID>/overlay

Using a PUT on this endpoint for a heating zone we can manually set the heating temperature (an “overlay”) and query the manual setting. So to set the temperature to 21°C for example:

$ curl -X PUT "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/overlay" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '{"setting":{"type":"HEATING","power":"ON","temperature":{"celsius":21}},"termination":{"type":"MANUAL"}}'

The request payload is defined in the --data-binary argument and you must also define the content-type of the request data with the additional Content-Type header. Alternative termination types are TADO_MODE for stopping manual control when the next Tado mode change occurs or “TIMER” in which case you must also define how many seconds you want the manual mode to persist for. The request payload for that would be something like:

{
  "setting": {
    "type": "HEATING",
    "power": "ON",
    "temperature": {
      "celsius": 21
    }
  },
  "termination": {
    "type": "TIMER",
    "durationInSeconds": 900
  }
}

The response confirms the setting:

{
  "type": "MANUAL",
  "setting": {
    "type": "HEATING",
    "power": "ON",
    "temperature": {
      "celsius": 21,
      "fahrenheit": 69.8
    }
  },
  "termination": {
    "type": "TIMER",
    "durationInSeconds": 900,
    "expiry": "2017-01-08T13:31:36Z",
    "remainingTimeInSeconds": 763,
    "projectedExpiry": "2017-01-08T13:31:36Z"
  }
}

A GET on the endpoint will also return the JSON response above if an overlay is defined.

To remove manual control, you just do an HTTP DELETE on the same resource:

$ curl -X DELETE "https://my.tado.com/api/v2/homes/<homeID>/zones/1/overlay" -H "Authorization: Bearer `cat /tmp/tadotoken`"

/api/v2/homes/<homeID>/zones/<zoneID>/schedule/activeTimetable

A GET here will return the type of schedule you have configured: I have the same programme for Mon-Fri and different ones on Sat and Sun (hence THREE_DAY).

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/schedule/activeTimetable" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "id": 1,
  "type": "THREE_DAY"
}

You can do a PUT on this endpoint with a payload of e.g. {"id":0} for instance to switch to a Mon-Sun schedule. To do this you have to add the data and its content type:

$ curl -X PUT "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/schedule/activeTimetable" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '{"id":0}'

/api/v2/homes/<homeID>/zones/<zoneID>/schedule/awayConfiguration

Using a GET this will return the settings to use if everyone is out of the house.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/0/schedule/awayConfiguration" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "type": "HOT_WATER",
  "setting": {
    "type": "HOT_WATER",
    "power": "OFF",
    "temperature": null
  }
}
$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/1/schedule/awayConfiguration" -H "Authorization: Bearer `cat /tmp/tadotoken`"
{
  "type": "HEATING",
  "setting": null,
  "autoAdjust": true,
  "comfortLevel": 0
}

Using a PUT you can configure the settings. For instance, to adjust the “comfort level”:

$ curl -X PUT "https://my.tado.com/api/v2/homes/<homeID>/zones/1/schedule/awayConfiguration" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '{"type":"HEATING","autoAdjust":true,"comfortLevel":50,"setting":{"type":"HEATING","power":"OFF"}}'
{
  "type": "HEATING",
  "setting": null,
  "autoAdjust": true,
  "comfortLevel": 0
}

The mobile app allows you to set comfortLevel to 0, 50 or 100 for “Eco”, “Balance” and “Comfort”

If you want to set a specific temperature for the house to use while you are away then PUT data such as this:

{
  "type": "HEATING",
  "autoAdjust": false,
  "setting": {
    "type": "HEATING",
    "power": "ON",
    "temperature": {
      "celsius": 16,
      "fahrenheit": 60.8
    }
  }
}

/api/v2/homes/<homeID>/zones/<zoneID>/schedule/timetables/1/blocks

This call gets the schedule for your heating. My heating zoneID is “1”: I don’t know if the “1” in /1/blocks is a repeat of the zone.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/1/schedule/timetables/1/blocks" -H "Authorization: Bearer `cat /tmp/tadotoken`"
[
  {
    "dayType": "MONDAY_TO_FRIDAY",
    "start": "00:00",
    "end": "07:30",
    "geolocationOverride": false,
    "modeId": 12418936,
    "setting": {
      "type": "HEATING",
      "power": "ON",
      "temperature": {
        "celsius": 10,
        "fahrenheit": 50
      }
    }
  },
  {
    "dayType": "MONDAY_TO_FRIDAY",
    "start": "07:30",
    "end": "10:00",
    "geolocationOverride": false,
    "modeId": 12418937,
    "setting": {
      "type": "HEATING",
      "power": "ON",
      "temperature": {
        "celsius": 20,
        "fahrenheit": 68
      }
    }
  },
  etc
]

/api/v2/homes/<homeID>/zones/<zoneID>/schedule/timetables/1/blocks/<day>

To just get the schedule blocks for a particular day or period you can use this call. What values of <day> are valid depends on what schedule type you are using. If you are using the THREE_DAY timetable then you can use MONDAY_TO_FRIDAY, SATURDAY and SUNDAY.

$ curl "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/schedule/timetables/1/blocks/MONDAY_TO_FRIDAY" -H "Authorization: Bearer `cat /tmp/tadotoken`"

The response is the appropriate subset of the response from the previous call.

You can also use this call to set the schedule for a day or timetable period. You have to take exactly the same data format as the GET returns, modify it as you please, and pass it back using a PUT:

$ curl -X PUT "https://my.tado.com/api/v2/homes/<homeID>/zones/<zoneID>/schedule/timetables/1/blocks/MONDAY_TO_FRIDAY" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '[...]'

The response is the same data back again to confirm.

/api/v2/devices/<deviceID>/identify

If you get the short serial number of your Tado hardware device(s) using the /api/v2/homes/<homeID>/devices call then you can use this call to make the thermostat display “HI!” on its screen.

Get the short serial numbers using:

$ curl "https://my.tado.com/api/v2/homes/<homeID>/devices" -H "Authorization: Bearer `cat /tmp/tadotoken`" -s |jq '.[].shortSerialNo'

The one starting with “RU” is the thermostat. This call makes it say “HI!”:

$ curl -X POST "https://my.tado.com/api/v2/devices/<deviceID>/identify" -H "Authorization: Bearer `cat /tmp/tadotoken`"

/api/v2/users/name%40example.com/language

There is at least one method in this namespace, acting on a “user” resource (using the URL-endcoded email address as the identifier). Here you can do a PUT to change the language setting for a user, e.g.:

$ curl -X PUT "https://my.tado.com/api/v2/users/user%40example.com/language" -H "Authorization: Bearer `cat /tmp/tadotoken`" -H "Content-Type:application/json;charset=UTF-8" --data-binary '{"language":"en"}'

Any more?

Is there anything specific anyone wants to do with the API that I could try to document the method for?

Changelog

  • 2017-02-07: added instructions on using username/password authentication; added /mobile/1.6/getTemperaturePlotData call.
  • 2017-03-13: added /mobileDevices/<deviceID>/settings call (thanks to Jacques Mulders in the comments).
  • 2017-03-18: added
    • /api/v2/devices/<deviceID>/identify
    • /api/v2/homes/<homeID>/zones/<zoneID>/earlyStart
    • /api/v2/homes/<homeID>/zones/<zoneID>/schedule/awayConfiguration
    • /api/v2/homes/<homeID>/zones/<zoneID>/schedule/timetables/1/blocks
    • /api/v2/homes/<homeID>/zones/<zoneID>/schedule/timetables/1/blocks/<day>

Comments

Comments powered by Disqus