Back to skills
SkillHub ClubShip Full StackFull Stack

tado

Interact with Tado smart thermostat. Use for reading temperature, setting heating with auto-revert, viewing energy usage, and controlling zones.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,084
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
A92.4

Install command

npx @skill-hub/cli install openclaw-skills-tado-thermostat

Repository

openclaw/skills

Skill path: skills/davek-dev/tado-thermostat

Interact with Tado smart thermostat. Use for reading temperature, setting heating with auto-revert, viewing energy usage, and controlling zones.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install tado into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding tado to shared team environments
  • Use tado for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: tado
description: Interact with Tado smart thermostat. Use for reading temperature, setting heating with auto-revert, viewing energy usage, and controlling zones.
---

# Tado Skill

Use the Tado API to control your smart thermostat.

## Authentication

Tado uses OAuth2 device code flow. You'll need:

- **Client ID:** `1bb50063-6b0c-4d11-bd99-387f4a91cc46`
- **Token endpoint:** `https://login.tado.com/oauth2/token`

### Step 1: Get Device Code

```bash
curl -s -X POST "https://login.tado.com/oauth2/device_authorize" \
  -d "client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46" \
  -d "scope=offline_access"
```

Response:
```json
{
  "device_code": "XXX_code_XXX",
  "expires_in": 300,
  "interval": 5,
  "user_code": "7BQ5ZQ",
  "verification_uri_complete": "https://login.tado.com/oauth2/device?user_code=7BQ5ZQ"
}
```

### Step 2: User Authenticates

Visit the `verification_uri_complete` URL and enter the user code. The user must log into their Tado account.

### Step 3: Poll for Token

```bash
curl -s -X POST "https://login.tado.com/oauth2/token" \
  -d "client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46" \
  -d "device_code=YOUR_DEVICE_CODE" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code"
```

Response:
```json
{
  "access_token": "...",
  "refresh_token": "...",
  "expires_in": 600,
  "token_type": "Bearer"
}
```

### Step 4: Refresh Token

Access tokens expire in ~10 minutes. Use the refresh token to get a new one:

```bash
curl -s -X POST "https://login.tado.com/oauth2/token" \
  -d "client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=YOUR_REFRESH_TOKEN"
```

## Environment Variables

Store these securely (not in the skill):
```bash
export TADO_TOKEN="your-access-token"
export TADO_REFRESH_TOKEN="your-refresh-token"
export TADO_HOME_ID="your-home-id"
```

## Get Home ID

```bash
curl -s "https://my.tado.com/api/v2/me" -H "Authorization: Bearer $TADO_TOKEN"
```

Returns: `{"homes":[{"id":123456,...}]}`

## List Zones

```bash
curl -s "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/zones" -H "Authorization: Bearer $TADO_TOKEN"
```

## Get Zone State

```bash
curl -s "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/zones/$ZONE_ID/state" -H "Authorization: Bearer $TADO_TOKEN"
```

## Get All Zones Summary

This script gets the current temperature, target temperature, and heating % for all zones:

```python
#!/usr/bin/env python3
import os
import requests

TOKEN = os.environ.get("TADO_TOKEN")
HOME_ID = os.environ.get("TADO_HOME_ID")

headers = {"Authorization": f"Bearer {TOKEN}"}

# Get zones
zones = requests.get(f"https://my.tado.com/api/v2/homes/{HOME_ID}/zones", headers=headers).json()

print("Zone           | Current | Target | Heating")
print("---------------|---------|--------|-------")

for zone in zones:
    zid = zone["id"]
    name = zone["name"]
    state = requests.get(f"https://my.tado.com/api/v2/homes/{HOME_ID}/zones/{zid}/state", headers=headers).json()
    
    # Current temperature from sensorDataPoints
    current = state.get("sensorDataPoints", {}).get("insideTemperature", {}).get("celsius")
    # Target temperature from setting
    target = state.get("setting", {}).get("temperature", {}).get("celsius")
    # Actual heating % from activityDataPoints (not from setting!)
    heating = state.get("activityDataPoints", {}).get("heatingPower", {}).get("percentage", 0)
    
    c = f"{current:.1f}°C" if current else "N/A"
    t = f"{target:.0f}°C" if target else "-"
    h = f"{heating:.0f}%" if heating else "OFF"
    
    print(f"{name:14} | {c:7} | {t:6} | {h:>6}")
```

Example output:
```
Zone           | Current | Target | Heating
---------------|---------|--------|-------
Kitchen        | 18.2°C  | 18°C   | 45%
Living Room    | 16.8°C  | 17°C   | 0%
Downstairs Off | 15.2°C  | 14°C   | 78%
Master Bedroom | 17.1°C  | 14°C   | 0%
Cora's Room    | 17.7°C  | 16°C   | 23%
Upstairs Office| 19.1°C  | 19°C   | OFF
Spare Bedroom  | 19.6°C  | -      | OFF
```

**Note:** Use `activityDataPoints.heatingPower.percentage` to get actual heating status, not `setting.power` which only shows the target.

## Set Temperature

**Until next schedule change:**
```bash
curl -s -X PUT "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/zones/$ZONE_ID/overlay" \
  -H "Authorization: Bearer $TADO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"setting":{"type":"HEATING","power":"ON","temperature":{"celsius":21}},"termination":{"type":"UNTIL_NEXT_TIME_BLOCK"}}'
```

**With timer (e.g., 2 hours):**
```bash
curl -s -X PUT "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/zones/$ZONE_ID/overlay" \
  -H "Authorization: Bearer $TADO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"setting":{"type":"HEATING","power":"ON","temperature":{"celsius":22}},"termination":{"type":"TIMER","durationInSeconds":7200}}'
```

**Permanent:**
```bash
curl -s -X PUT "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/zones/$ZONE_ID/overlay" \
  -H "Authorization: Bearer $TADO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"setting":{"type":"HEATING","power":"ON","temperature":{"celsius":20}},"termination":{"type":"MANUAL"}}'
```

## Clear Override

```bash
curl -s -X DELETE "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/zones/$ZONE_ID/overlay" \
  -H "Authorization: Bearer $TADO_TOKEN"
```

## Get Energy Usage

```bash
curl -s "https://my.tado.com/api/v2/homes/$TADO_HOME_ID/energyUsage" -H "Authorization: Bearer $TADO_TOKEN"
```

## Termination Types

| Type | Description |
|------|-------------|
| `UNTIL_NEXT_TIME_BLOCK` | Reverts at next scheduled change |
| `TIMER` | Temporary (max 12 hours / 43200 seconds) |
| `MANUAL` | Permanent until cancelled |


---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "davek-dev",
  "slug": "tado-thermostat",
  "displayName": "tado-thermostat",
  "latest": {
    "version": "1.2.3",
    "publishedAt": 1772192171202,
    "commit": "https://github.com/openclaw/skills/commit/0129cfe4e34078397ceaf5239a8eb02e36598e39"
  },
  "history": []
}

```

tado | SkillHub