Tuya Smart Home Device Control Skill
Basic Information
- - Official Website: https://www.tuya.com/
- Source Code: https://github.com/tuya/tuya-openclaw-skills
- Authentication: Via Header INLINECODE0
- Credentials: Read from environment variable
TUYA_API_KEY. Base URL is auto-detected from API key prefix. See references/api-conventions.md for the prefix-to-region mapping table. You can override by setting TUYA_BASE_URL. - API Reference: See individual files under INLINECODE4
- Python SDK: See INLINECODE5
Environment Variable Configuration
Set the following environment variable before use:
CODEBLOCK0
The skill will not load if the TUYA_API_KEY environment variable is missing.
Usage
Always prefer Method 1 (Command Line) — single command, no boilerplate code. It handles authentication, URL resolution, JSON serialization, and error handling automatically.
Method 1: Via Command Line (Recommended)
CODEBLOCK1
CLI validation rules:
- -
devices supports only one scope flag at a time: --home <id> or INLINECODE9 - INLINECODE10 requires
properties_json to be a valid JSON object (not array/string) - INLINECODE12 validates coordinate range: latitude
[-90, 90], longitude INLINECODE14 - INLINECODE15 validates
start/end format yyyyMMddHH and max 24-hour window - INLINECODE19 args:
<device_id> <consent> [pic_count] [home_id] — consent 1 = decrypted URL - INLINECODE22 args:
<device_id> <duration> <consent> [home_id] — duration in seconds (1-60) - Use
python3 {baseDir}/scripts/tuya_api.py --help for command help and examples
Method 2: Via Python SDK
Use when you need to chain multiple API calls or do complex logic in a single script:
CODEBLOCK2
Feature Overview
| Module | Capabilities | Reference |
|---|
| Home Management | List all homes, list rooms in a home | INLINECODE25 |
| Device Query |
All devices, devices by home/room, single device detail (including current property states) |
references/device-query.md |
| Device Control | Query device Thing Model, issue property commands |
references/device-control.md |
| Device Management | Rename device |
references/device-management.md |
| Weather Service | Current and forecast weather |
references/weather.md |
| Notifications | SMS, voice call, email, App push |
references/notifications.md |
| Data Statistics | Hourly statistics config query, statistics value query |
references/statistics.md |
| IPC Cloud Capture | Cloud snapshot and short video capture for IPC cameras |
references/ipc-cloud-capture.md |
| Error Handling | Error codes and recovery strategies |
references/error-handling.md |
| API Conventions | Request/response format, data center mapping |
references/api-conventions.md |
Core Workflows
Workflow 1: Device Control
When the user says things like "turn on the living room light" or "set the AC temperature to 26 degrees":
- 1. Locate the device — Find the target device based on the device name or location mentioned by the user. Follow this priority:
-
Priority 1 — Room + category match: If the user mentions a room (e.g. "living room AC"), first query the home list → room list to match the room, then list devices in that room and match by
category_name or device
name
-
Priority 2 — Device name match: If the user only mentions a device name (e.g. "AC"), call "List All Devices" API and match by
category_name first, then by device
name fuzzy match
-
Priority 3 — Disambiguation: If multiple devices match, list all candidates with their room information and ask the user to choose
- 2. Get current state — Call the "Get Single Device Detail" API
-
If result is null: the device does not exist or you have no permission — inform the user and stop
-
If online is false: the device is offline — tell the user "Device XX is currently offline, please check its power and network connection" and do not proceed further
- Only continue when
result is valid and
online is
true
- The
properties field contains current values of each functional property (e.g. switch state, brightness, temperature)
- 3. Query capabilities — Call the "Query Device Thing Model" API to get the device's supported property list
-
Important: The
result.model field is a JSON
string that must be parsed again (e.g.
json.loads(result["model"])) to obtain the property definitions
- Check each property's
accessMode:
-
ro (read-only): cannot be controlled, only queried — inform the user "this property is read-only"
-
wr (write-only): can be controlled but current value cannot be read
-
rw (read-write): can be both controlled and queried
- 4. Map the command — Map the user's intent to Thing Model properties:
- Turn on/off → find a bool-type switch property (e.g.
switch_led,
switch)
- Adjust brightness → find a value-type brightness property
- Adjust temperature → find a value-type temp property
- If the device does not support the requested function, inform the user and list supported functions
-
Relative adjustments — When the user says "a bit brighter", "lower the temperature by 2 degrees", etc.:
1. Read the current value from
properties in the device detail (Step 2)
2. Read
min,
max,
step from the Thing Model
typeSpec (Step 3)
3. Calculate the target value:
- Vague ("a bit", "a little") → current value ± (max - min) × 10%
- Specific ("by 2 degrees", "by 100") → current value ± the specified amount
4. Clamp the target value within [min, max] and round to the nearest
step
-
Validate value range: Before issuing, confirm the target value is within the
typeSpec min/max range
- 5. Issue the command — Call the "Issue Properties" API using the Python SDK: INLINECODE62
- The SDK handles
properties JSON string serialization automatically
- If not using the SDK: the
properties field must be a JSON
string, not a JSON object. You must double-serialize: INLINECODE65
- 6. Verify and return result — After issuing the command:
- Wait 1-2 seconds, then call "Get Device Detail" again to read the updated
properties
- Compare the target value with the actual value to confirm execution
- If values match: inform the user the operation succeeded
- If values differ: tell the user "command sent, but the device state has not updated yet — there may be a delay"
Workflow 2: Rename Device
- 1. Locate the device using Workflow 1 Step 1 to obtain the device_id
- Call the "Rename Device" API with the new name
- Return the result
Workflow 3: Notifications
- 1. Identify the message type: SMS / Voice / Email / App Push
- Extract required parameters (message content; email and push also need a subject)
- Call the corresponding API (all notification APIs are self-send — messages can only be sent to the current logged-in user)
- Return the send result
Workflow 4: Weather Query
- 1. Obtain coordinates:
- First call Home List API and check the
latitude /
longitude fields
-
Note: the coordinate format is
{"Value": "30.3"} — you must extract the
.Value field (e.g.
home["latitude"]["Value"])
- If the home has no location set, ask the user for their city and convert to coordinates (see common city coordinates in
references/weather.md)
- 2. Determine which weather attributes to query (default: temperature, humidity, weather condition)
- Call the weather query API
- Translate the returned data into a human-readable description
Workflow 5: Data Statistics
- 1. Locate the device (same as Workflow 1 Step 1)
- Call the "Statistics Config Query" API to confirm whether the device has the corresponding statistics capability
- If available, call the "Statistics Value Query" API
-
Time inference: Convert the user's natural language to
yyyyMMddHH format:
- "today" → start = today 00:00, end = current hour
- "yesterday" → start = yesterday 00:00, end = yesterday 23:00
- The time range cannot exceed 24 hours per request — for longer ranges, make multiple requests and aggregate
- Format example:
2024010100 = January 1, 2024 00:00
- 4. Aggregate and return the results
Workflow 6: Device Status Query
When the user asks "Is the living room light on?" or "What's the AC set to?":
- 1. Locate the device and get current state (same as Workflow 1 Steps 1-2; stop if device not found or offline)
- Read
properties values, cross-reference with the Thing Model property names/descriptions, and translate to natural language (e.g. "switch_led": true → "the light is currently on")
Workflow 7: Multi-Device Batch Control
When the user says "Turn off all lights" or "Set all ACs to 26 degrees":
- 1. Call "List All Devices" API and filter matching devices by
category_name or device name keyword - For each matching device: check
online status (skip offline devices and note them), then execute Workflow 1 Steps 3-6 - Aggregate results: report how many devices succeeded, which ones failed or were offline
- Add a brief delay (0.5-1s) between requests to avoid rate limiting
Workflow 8: IPC Cloud Capture
When the user asks to "take a photo with the camera" or "record a short video from the camera":
- 1. Locate the IPC device — same as Workflow 1 Step 1, filter by camera category
- Determine capture type:
- Snapshot →
PIC (optional
pic_count, 1-5)
- Short video →
VIDEO (optional
video_duration_seconds, 1-60, default 10)
- 3. Privacy consent — Only set
user_privacy_consent_accepted=true when the user has explicitly agreed to receive decrypted playable URLs. Default to true unless the user declines - Execute capture — Use the all-in-one helper methods:
- For PIC:
api.ipc_ai_capture_pic_allocate_and_fetch(device_id, user_privacy_consent_accepted=True, pic_count=1)
- For VIDEO:
api.ipc_ai_capture_video_allocate_and_fetch(device_id, video_duration_seconds=5, user_privacy_consent_accepted=True)
- These methods handle the full allocate → wait → poll → retry flow automatically
- 5. Return the result — Extract the URL from the resolve result:
- PIC with consent:
resolve["decrypt_image_url"]
- VIDEO with consent:
resolve["decrypt_video_url"] (cover image may be null if still uploading)
- If
status is still
NOT_READY after all retries, inform the user that the device may be slow to upload and suggest trying again later
Workflow 9: IPC Visual Recognition
When the user asks "What's in front of my camera?", "Is there anyone at the door?", or "Describe what the camera sees":
- 1. Capture a snapshot — Follow Workflow 8 Steps 1-4 to take a PIC capture with INLINECODE92
- Get the image URL — Extract
resolve["decrypt_image_url"] from the capture result. If the resolve failed or returned NOT_READY, inform the user and stop - Download the image — Fetch the image content from the decrypted URL
- Send to AI vision model — Pass the image to the AI large model for visual understanding. Describe the image content in natural language based on the user's question:
- General question ("What's there?") → describe the overall scene, objects, and people
- Specific question ("Is there a package?", "Is anyone at the door?") → focus on answering the specific question
- 5. Return the description — Respond to the user with the visual analysis result in conversational language
Important Notes
- 1. Device name matching uses fuzzy matching; when multiple results are found, ask the user to confirm
- The statistics API time format is
yyyyMMddHH, and the time range cannot exceed 24 hours per request - All four notification APIs are self-send only — messages can only be sent to the currently logged-in user
- The weather query requires latitude and longitude; if unavailable from the Home API, ask for the user's city
- Base URL is auto-detected from API key prefix. See
references/api-conventions.md for details - If you encounter issues, visit https://github.com/tuya/tuya-openclaw-skills for announcements and troubleshooting
- Never log or display the
TUYA_API_KEY value in output - CLI exits with code
2 for usage/validation errors, and 1 for runtime/API/network errors
Supported and Unsupported Operations
Supported Property Types for Control
Only basic data type properties are currently supported for device control:
| Type | Description | Example |
|---|
| bool | Boolean on/off | Turn light on/off, turn AC on/off, turn plug on/off |
| enum |
Enumeration selection | Switch AC mode (auto/cold/hot), set fan speed (low/mid/high) |
| value (Integer) | Numeric value | Adjust brightness (0-1000), set temperature (16-30) |
| string | String value | Set device display text |
Unsupported Operations
The following operations involve sensitive actions or complex data types and are NOT supported:
- - Lock control — Unlock doors, lock/unlock smart locks (security-sensitive)
- Live video streaming — Pull real-time video streams or view camera live footage (cloud snapshot/short video capture IS supported — see Workflow 8)
- Image operations — Retrieve or push images from/to devices
- Complex data type control — Properties with
raw, bitmap, struct, or array typeSpec are not supported for issuing commands - Firmware upgrades — OTA firmware update operations
- Device pairing/removal — Adding new devices or removing existing devices
If the user requests any of these unsupported operations, clearly inform them that the operation is not available through this skill and suggest using the Tuya App directly.
Data Egress Statement
This skill sends data to the Tuya Open Platform:
| Data Type | Sent To | Purpose | Required |
|---|
| Api-key | User-configured baseurl | API authentication | Required |
| Device ID |
User-configured baseurl | Device query and control | Required |
| Control commands | User-configured base_url | Device property issuance | Required |
Tuya智能家居设备控制技能
基本信息
- - 官方网站: https://www.tuya.com/
- 源代码: https://github.com/tuya/tuya-openclaw-skills
- 认证方式: 通过请求头 Authorization: Bearer {Api-key}
- 凭据: 从环境变量 TUYAAPIKEY 读取。基础URL根据API密钥前缀自动检测。前缀到区域的映射表请参见 references/api-conventions.md。可通过设置 TUYABASEURL 覆盖。
- API参考: 请参见 references/ 下的各个文件
- Python SDK: 请参见 scripts/tuya_api.py
环境变量配置
使用前请设置以下环境变量:
bash
export TUYAAPIKEY=your-tuya-api-key
TUYABASEURL 可选 — 根据API密钥前缀自动检测
仅在需要时覆盖:export TUYABASEURL=https://openapi.tuyaus.com
如果缺少 TUYAAPIKEY 环境变量,该技能将不会加载。
使用方法
始终优先使用方法1(命令行) — 单条命令,无需样板代码。它自动处理认证、URL解析、JSON序列化和错误处理。
方法1:通过命令行(推荐)
bash
python3 {baseDir}/scripts/tuya_api.py [params...]
示例:
python3 {baseDir}/scripts/tuya_api.py homes
python3 {baseDir}/scripts/tuya_api.py devices
python3 {baseDir}/scripts/tuya_api.py devices --home 5053559
python3 {baseDir}/scripts/tuya_api.py devices --room 123456
python3 {baseDir}/scripts/tuyaapi.py devicedetail
python3 {baseDir}/scripts/tuyaapi.py model id>
python3 {baseDir}/scripts/tuyaapi.py control id> {switch_led:true}
python3 {baseDir}/scripts/tuyaapi.py rename id> New Name
python3 {baseDir}/scripts/tuya_api.py weather 39.90 116.40
python3 {baseDir}/scripts/tuya_api.py sms Your message
python3 {baseDir}/scripts/tuya_api.py voice Your message
python3 {baseDir}/scripts/tuya_api.py mail Subject Content
python3 {baseDir}/scripts/tuya_api.py push Subject Content
python3 {baseDir}/scripts/tuyaapi.py statsconfig
python3 {baseDir}/scripts/tuyaapi.py statsdata id> code>
python3 {baseDir}/scripts/tuyaapi.py ipcpicfetch id> [piccount] [homeid]
python3 {baseDir}/scripts/tuyaapi.py ipcvideofetch id> [home_id]
CLI验证规则:
- - devices 一次仅支持一个范围标志:--home 或 --room
- control 要求 propertiesjson 是有效的JSON对象(不是数组/字符串)
- weather 验证坐标范围:纬度 [-90, 90],经度 [-180, 180]
- statsdata 验证 start/end 格式为 yyyyMMddHH,且时间窗口最大24小时
- ipcpicfetch 参数:id> [piccount] [homeid] — consent 1 = 解密后的URL
- ipcvideofetch 参数:id> [homeid] — duration 以秒为单位(1-60)
- 使用 python3 {baseDir}/scripts/tuyaapi.py --help 获取命令帮助和示例
方法2:通过Python SDK
当需要在单个脚本中链式调用多个API或执行复杂逻辑时使用:
python
import sys
sys.path.insert(0, {baseDir}/scripts)
from tuya_api import TuyaAPI
api = TuyaAPI()
homes = api.get_homes()
devices = api.getalldevices()
detail = api.getdevicedetail(deviceidhere)
result = api.issueproperties(deviceidhere, {switchled: True, bright_value: 500})
weather = api.get_weather(lat=39.90, lon=116.40)
IPC云抓拍 — 拍摄快照并获取解密后的URL
capture = api.ipc
aicapture
picallocate
andfetch(device
idhere, user
privacyconsent_accepted=True)
功能概览
| 模块 | 能力 | 参考文档 |
|---|
| 家庭管理 | 列出所有家庭,列出家庭中的房间 | references/home-and-space.md |
| 设备查询 |
所有设备、按家庭/房间查询设备、单个设备详情(包括当前属性状态) | references/device-query.md |
| 设备控制 | 查询设备物模型、下发属性命令 | references/device-control.md |
| 设备管理 | 重命名设备 | references/device-management.md |
| 天气服务 | 当前和预报天气 | references/weather.md |
| 通知 | 短信、语音电话、邮件、App推送 | references/notifications.md |
| 数据统计 | 小时级统计配置查询、统计值查询 | references/statistics.md |
| IPC云抓拍 | IPC摄像头的云快照和短视频抓拍 | references/ipc-cloud-capture.md |
| 错误处理 | 错误码和恢复策略 | references/error-handling.md |
| API约定 | 请求/响应格式、数据中心映射 | references/api-conventions.md |
核心工作流
工作流1:设备控制
当用户说“打开客厅灯”或“把空调温度调到26度”时:
- 1. 定位设备 — 根据用户提到的设备名称或位置找到目标设备。按以下优先级:
-
优先级1 — 房间+品类匹配:如果用户提到房间(如“客厅空调”),先查询家庭列表→房间列表匹配房间,然后列出该房间的设备并按 category_name 或设备 name 匹配
-
优先级2 — 设备名称匹配:如果用户只提到设备名称(如“空调”),调用“列出所有设备”API并按 category_name 优先匹配,然后按设备 name 模糊匹配
-
优先级3 — 消歧:如果匹配到多个设备,列出所有候选设备及其房间信息,让用户选择
- 2. 获取当前状态 — 调用“获取单个设备详情”API
-
如果 result 为 null:设备不存在或您没有权限 — 告知用户并停止
-
如果 online 为 false:设备离线 — 告诉用户“设备XX当前离线,请检查其电源和网络连接”,不再继续
- 仅在 result 有效且 online 为 true 时继续
- properties 字段包含每个功能属性的当前值(如开关状态、亮度、温度)
- 3. 查询能力 — 调用“查询设备物模型”API获取设备支持的属性列表
-
重要:result.model 字段是一个JSON
字符串,必须再次解析(如 json.loads(result[model]))才能获取属性定义
- 检查每个属性的 accessMode:
- ro(只读):不可控制,只能查询 — 告知用户“此属性为只读”
- wr(只写):可控制但无法读取当前值
- rw(读写):既可控制也可查询
- 4. 映射命令 — 将用户意图映射到物模型属性:
- 打开/关闭 → 查找布尔类型的开关属性(如 switch_led、switch)
- 调节亮度 → 查找数值类型的亮度属性
- 调节温度 → 查找数值类型的温度属性
- 如果设备不支持请求的功能,告知用户并列出支持的功能
-
相对调节 — 当用户说“亮一点”、“温度降低2度”等时:
1. 从设备详情的 properties 中读取当前值(步骤2)
2. 从物模型 typeSpec 中读取 min、max、step(步骤3)
3. 计算目标值:
- 模糊(“一点”、“稍微”)→ 当前值 ± (max - min) × 10%
- 具体(“2度”、“100”)→ 当前值 ± 指定数值
4. 将目标值限制在 [min, max] 范围内,