Tado Smart Thermostat Skill
Control your Tado smart thermostat from OpenClaw.
Features
- 📊 Status: Get current temperature, humidity, heating status per zone
- 🌡️ Temperature Control: Set target temperature with optional timer
- 🏠 Presence: Check who is home (geolocation)
- 🔄 Modes: Home, Away, Auto (schedule-based)
- ⚙️ Zone Management: Support for multi-zone setups
- 📋 JSON Output: Machine-readable format for scripting
Installation
1. Install Dependencies
cd ~/clawd/skills/tado
pip3 install libtado --break-system-packages
Minimum version: libtado 4.1.1+ (OAuth2 support required)
2. OAuth2 Authentication (One-Time Setup)
⚠️ Important: libtado 4.1.1+ requires OAuth2. Username/password authentication is no longer supported.
First-time setup:
# Run the libtado CLI to authenticate via browser
python3 -m libtado -f ~/.tado_auth.json zones
What happens:
- libtado generates a Tado login URL
- Your browser opens (or you paste the URL manually)
- Log in with your Tado credentials
- libtado saves OAuth2 tokens to
~/.tado_auth.json - You'll see your zones listed (confirming success)
After setup:
- The skill will automatically use
~/.tado_auth.json - No further browser login needed
- Tokens refresh automatically
Security Note: The token file should be readable only by you:
chmod 600 ~/.tado_auth.json
3. Test Connection
cd ~/clawd/skills/tado
./scripts/tado.py zones
You should see a list of your configured zones.
If authentication fails:
# Re-authenticate (regenerates tokens)
python3 -m libtado -f ~/.tado_auth.json zones
Authentication
OAuth2 Flow (Required)
As of libtado 4.1.1+, OAuth2 is the only supported authentication method.
Token file location: ~/.tado_auth.json
How it works:
- First run: Browser login via
python3 -m libtado -f ~/.tado_auth.json zones - libtado saves access token + refresh token
- Skill uses
token_file_pathparameter:Tado(token_file_path='~/.tado_auth.json') - libtado automatically refreshes expired tokens
Token structure (managed by libtado):
{
"access_token": "...",
"refresh_token": "...",
"expires_at": 1234567890
}
Do NOT manually edit this file! Let libtado manage it.
Migration from Username/Password
Old authentication (no longer works):
Tado(username='email', password='pass') # ❌ Not supported
New authentication (required):
Tado(token_file_path='~/.tado_auth.json') # ✅ Works
Migration steps:
- Delete old
~/.tado_credentials.json(no longer used) - Run
python3 -m libtado -f ~/.tado_auth.json zones - Follow browser login flow
- Done! Skill will work automatically
No backward compatibility: Once you upgrade to libtado 4.1.1+, you MUST use OAuth2.
Usage
Status Commands
Get status of all zones:
./scripts/tado.py status
Output:
🏠 Woonkamer (Zone 1)
Current: 20.5°C (55% humidity)
Target: 21.0°C
Heating: ON (45%)
Mode: Auto (following schedule)
🏠 Slaapkamer (Zone 2)
Current: 18.2°C (58% humidity)
Target: 18.0°C
Heating: OFF (0%)
Mode: Auto (following schedule)
Get status of specific zone:
./scripts/tado.py status --zone 1
./scripts/tado.py status --zone "Woonkamer"
JSON output (for scripting):
./scripts/tado.py status --json
Temperature Control
Set temperature (permanent until next schedule change):
./scripts/tado.py set --zone 1 --temperature 21
./scripts/tado.py set --zone "Woonkamer" --temperature 21.5
Set temperature with timer (temporary override):
# Set 22°C for 60 minutes, then return to schedule
./scripts/tado.py set --zone 1 --temperature 22 --duration 60
# Short form
./scripts/tado.py set --zone 1 -t 22 -d 60
Reset to automatic schedule:
./scripts/tado.py reset --zone 1
./scripts/tado.py reset --zone "Woonkamer"
Home/Away Modes
Set home mode (all zones follow schedule):
./scripts/tado.py mode home
Set away mode (energy-saving temperatures):
./scripts/tado.py mode away
Set auto mode (geolocation-based):
./scripts/tado.py mode auto
When in auto mode, Tado automatically switches between home/away based on your phone's location.
Presence Detection
Check who is home:
./scripts/tado.py presence
Output:
👥 Presence
Anyone home: Yes
- Sander's iPhone: 🏠 Home
- Partner's iPhone: 🚶 Away
Zone Management
List all zones:
./scripts/tado.py zones
Output:
📍 Available Zones:
1: Woonkamer (HEATING)
2: Slaapkamer (HEATING)
3: Badkamer (HOT_WATER)
Zone Identification
Zones can be referenced by ID or name:
# By ID (faster)
./scripts/tado.py status --zone 1
# By name (case-insensitive)
./scripts/tado.py status --zone "Woonkamer"
./scripts/tado.py status --zone "woonkamer"
JSON Output for Scripting
All commands support --json flag for machine-readable output:
./scripts/tado.py status --zone 1 --json
Example output:
{
"zone_id": 1,
"zone_name": "Woonkamer",
"current_temp": 20.5,
"current_humidity": 55,
"target_temp": 21.0,
"heating": true,
"heating_power": 45,
"mode": "MANUAL",
"overlay": true
}
Use in scripts:
# Get current temperature as number
TEMP=$(./scripts/tado.py status --zone 1 --json | jq -r '.current_temp')
# Check if heating is on
HEATING=$(./scripts/tado.py status --zone 1 --json | jq -r '.heating')
# Get all zones data
./scripts/tado.py status --json | jq '.zones[] | {name: .zone_name, temp: .current_temp}'
OpenClaw Integration
From OpenClaw chat:
@jarvis What's the temperature in the living room?
→ Uses: ./scripts/tado.py status --zone "Woonkamer"
@jarvis Set living room to 22 degrees for 1 hour
→ Uses: ./scripts/tado.py set --zone "Woonkamer" -t 22 -d 60
@jarvis Is anyone home?
→ Uses: ./scripts/tado.py presence
@jarvis Turn on away mode
→ Uses: ./scripts/tado.py mode away
Troubleshooting
Authentication Errors
Error: Tado OAuth2 token not found!
Solution: Run the one-time authentication flow:
python3 -m libtado -f ~/.tado_auth.json zones
Then follow the browser login prompt.
Error: Failed to connect to Tado: 401 Unauthorized
Possible causes:
- Expired or invalid OAuth2 token
- Token file corrupted
- Tado service outage
Solutions:
- Re-authenticate:
python3 -m libtado -f ~/.tado_auth.json zones - Check token file exists:
ls -la ~/.tado_auth.json - Verify token file permissions:
chmod 600 ~/.tado_auth.json - Check Tado service status at https://status.tado.com
API Errors
Error: Failed to get status: HTTP 500
Solution: Tado API may be temporarily down. Check https://status.tado.com
Error: Zone 'X' not found
Solution:
- List available zones:
./scripts/tado.py zones - Use exact zone ID or name from the list
Connection Issues
Error: Failed to connect to Tado: Network unreachable
Solution:
- Check internet connection
- Verify DNS is working:
ping my.tado.com - Check firewall settings
Library Errors
Error: ModuleNotFoundError: No module named 'PyTado'
Solution:
pip3 install libtado --break-system-packages
Error: AttributeError: 'Tado' object has no attribute 'setAutoMode'
Possible cause: Outdated libtado version
Solution:
pip3 install --upgrade libtado
API Rate Limits
Tado API has rate limits (exact numbers not publicly documented):
Best practices:
- Don't poll status more than once per minute
- Use
--jsonoutput and cache results when possible - Batch multiple zones in one
statuscall instead of separate calls
If rate limited:
- Wait 1-2 minutes before retrying
- Reduce polling frequency
Data Privacy
Local data:
- Credentials stored in
~/.tado_credentials.json(mode 600 recommended) - No usage tracking or telemetry
- All API calls go directly to Tado servers
Never exposed:
- Your credentials are never sent anywhere except Tado API
- Zone names, temperatures, and presence data stay local
- No third-party analytics
Advanced Usage
Temperature Scheduling
Create a simple heating schedule script:
#!/bin/bash
# morning-heat.sh - Warm up before wake-up
# Set living room to 21°C at 6:30 AM
./scripts/tado.py set --zone "Woonkamer" -t 21 -d 120
# Reset to schedule after 2 hours
sleep 7200
./scripts/tado.py reset --zone "Woonkamer"
Run with cron:
30 6 * * * /path/to/morning-heat.sh
Smart Away Detection
#!/bin/bash
# smart-away.sh - Set away mode if nobody home
ANYONE_HOME=$(./scripts/tado.py presence --json | jq -r '.anyone_home')
if [ "$ANYONE_HOME" = "false" ]; then
./scripts/tado.py mode away
echo "Nobody home - enabled away mode"
fi
Energy Monitoring
#!/bin/bash
# energy-log.sh - Log heating activity
DATE=$(date +%Y-%m-%d_%H:%M)
./scripts/tado.py status --json > ~/logs/tado-$DATE.json
# Analyze with jq
jq '.zones[] | select(.heating == true) | {zone: .zone_name, power: .heating_power}' \
~/logs/tado-$DATE.json
Known Limitations
- Hot Water Control: Basic support only (ON/OFF), no temperature setting
- Weather Data: Not yet implemented (available in Tado API)
- Energy IQ: Statistics not yet exposed (available in Tado API)
- Multi-Home: Only one Tado home supported per token file
Future Enhancements
- OAuth2 authentication (✅ Implemented in v1.1.0)
- Weather data integration
- Energy IQ statistics
- Multi-home support
- Web dashboard (optional)
- Push notifications for temperature alerts
Resources
- libtado Documentation: https://libtado.readthedocs.io/
- libtado GitHub: https://github.com/germainlefebvre4/libtado
- Tado API (unofficial): https://blog.scphillips.com/posts/2017/01/the-tado-api-v2/
- Tado Service Status: https://status.tado.com
Support
For skill issues:
- Check this SKILL.md
- Read error messages carefully (they include hints)
- Try
--jsonoutput for debugging
For Tado API/account issues:
- Check Tado app first (does it work?)
- Visit https://my.tado.com
- Contact Tado support
Changelog
v1.1.0 (2026-02-03)
- ✅ OAuth2 authentication (libtado 4.1.1+)
- ⚠️ BREAKING: Username/password auth removed (no longer supported by libtado)
- One-time browser login flow via
python3 -m libtado - Automatic token refresh
- Updated all documentation for OAuth2
v0.1.0 (2026-01-29)
- Initial release
- Status, temperature control, modes, presence
- JSON output support
- Zone management (ID and name-based)
- Error handling and troubleshooting