Gadget Tuya Cloud Devices logo

Gadget Tuya Cloud Devices

Organization
tuya
gadget-tuya-cloud-devices

Read status and control the user's Tuya app devices through Tuya's cloud end-user API with a user-supplied API key: homes and rooms, device detail, thing-model property control, rename, weather, hourly statistics, self-send notifications, IPC cloud snapshots and real-time event subscription. Cloud only; prefer a device-specific or local-TCP skill when one matches.

Overview

Publishertuya
Repositorytuya-openclaw-skills
Skill namegadget-tuya-cloud-devices
Stars
482
Forks
37
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by tuya on GitHub. Read the source before you install it.

Installation

Install the Gadget Tuya Cloud Devices AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/tuya/tuya-openclaw-skills/tree/master/platforms/muse
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/tuya/tuya-openclaw-skills.git /tmp/tuya-openclaw-skills
mkdir -p .claude/skills
cp -r /tmp/tuya-openclaw-skills/platforms/muse .claude/skills/gadget-tuya-cloud-devices
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Gadget Tuya Cloud Devices in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Gadget Tuya Cloud Devices on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Gadget Tuya Cloud Devices is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Tuya Cloud Devices: End-User API Control

Use this skill when the user supplies a Tuya end-user API key (sk-...) and asks to control or query devices from their Tuya app account. Devices are reached in the cloud, so no local keys or model-specific datapoint maps are needed. For direct local-TCP control with a confirmed key and datapoint schema, prefer Tuya Wi-Fi devices.

Prerequisites

Read and follow the Home Link networking and safety rules in ~/docs/devices/home_link.md.

Workflow

  1. List homes with GET /v1.0/end-user/homes/all, and rooms with GET /v1.0/end-user/homes/{home_id}/rooms when the user names one.
  2. Locate the device: GET /v1.0/end-user/devices/all, or scope to .../homes/{home_id}/devices or .../homes/room/{room_id}/devices. Each entry in result.devices[] carries device_id, name, category, category_name, online and, under a home scope, room_id. Match the user's words against category_name first, then fuzzy-match name. With multiple matches, list the candidates with their rooms and ask.
  3. Read GET /v1.0/end-user/devices/{device_id}/detail. A null result means the device does not exist or the key has no access — stop. online: false means report the device as offline and command nothing. result.properties maps each property code to its current value.
  4. Read the thing model GET /v1.0/end-user/devices/{device_id}/model. Its result.model field is a JSON string that needs a second parse. services[].properties[] then defines each property's code, accessMode (ro properties are read-only — say so) and typeSpec:
    • value: min, max, step and scale — the real-world value is the raw number divided by 10^scale.
    • enum: the issued value must be one of range.
    • bool / string: true/false, and maxlen respectively. Common codes are switch_led/switch (bool power), bright_value/temp_value (0–1000), temp_set (16–30) and mode (enum) — the model response is always authoritative.
  5. Issue POST /v1.0/end-user/devices/{device_id}/shadow/properties/issue with a body whose properties value is a JSON string, not an object — it is double-serialized: {"properties": "{\"switch_led\":true}"}. An empty result object means the command was accepted, not that it took effect. For relative asks ("a bit brighter"), adjust the current value by 10% of the typeSpec range for vague amounts or by the stated amount exactly, clamp to [min, max], honor scale and round to step.
  6. Wait 1–2 seconds, re-read the detail and compare the mapped value before reporting success.

Also Available

  • Rename: POST /v1.0/end-user/devices/{device_id}/attribute with {"name": "..."}, max 50 characters.
  • Weather: GET /v1.0/end-user/services/weather/recent with lat, lon and codes — a URL-encoded JSON array of attribute codes such as w.temp, w.humidity, w.condition, w.conditionNum, w.pressure, w.realFeel, w.uvi, w.windDir, w.windLevel, w.windSpeed, plus w.hour.N to set the forecast horizon to the next N hours. Response keys are {code}.{index} with index 0 meaning now. Home coordinates are shaped {"Value": "30.3"} — read the inner Value; ask the user for their city if the home has none set.
  • Hourly statistics: confirm capability with GET /v1.0/end-user/statistics/hour/config (items carry dev_id, dp_code, statistic_type of SUM/COUNT/MAX/MIN), then GET .../hour/data?dev_id=..&dp_code=..&statistic_type=..&start_time=..&end_time=... Times are yyyyMMddHH and one request spans at most 24 hours; page longer ranges and aggregate. Values return as an array of {time: value} pairs with string values.
  • Notifications are self-send only — they reach the key's own user, nobody else. SMS and voice take {"message": "..."}; mail and push take {"subject": "...", "content": "..."}. Rate and duplicate limits apply (per contact: 15–30 per day, identical content more than twice within 50 seconds is refused).
  • IPC cloud snapshots (cameras): POST /v1.0/end-user/ipc/{device_id}/capture/allocate with body {"capture_json": "<json string>"} — double-serialized like property issue. The string carries device_id, capture_type (PIC or VIDEO), optionally pic_count (clamped to 1–5), video_duration_seconds (1–60, default 10) and home_id. Allocate only reserves an upload slot: result.status is ACCEPTED or REJECTED and result carries bucket and the object key(s) (image_object_key, and for VIDEO also video_object_key / cover_image_object_key) — never a media URL; the device still has to capture and upload. Then poll POST .../capture/resolve with a resolve_json string echoing device_id, capture_type, bucket and the object key(s) from allocate, and pass user_privacy_consent_accepted: true. Resolve returns the link to hand the user: the image/video cloud storage URL in decrypt_image_url / decrypt_video_url. status: NOT_READY means keep polling — for PIC sleep 2 s, then resolve every 2 s up to 30 s, then retry up to 3 times 3 s apart; for VIDEO sleep max(5, video_duration_seconds_effective) + 2 s using the clamped duration from the allocate response, then resolve every 2 s up to 120 s, then retry up to 3 times 5 s apart. With pic_count above 1, allocate returns per-snapshot coordinates in pic_slots[] — resolve each slot's key separately. A video's cover image can lag the video itself — check message_for_user.

Real-Time Subscription

Property changes and online/offline transitions are also pushed over WebSocket. This is a long-lived process for an always-on host (a Linux gadget), not a one-shot query. Write a short Python script using the websockets package:

  • URI by key prefix (same mapping as the REST table): AZ wss://wsmsgs.iot-wus.com, EU wss://wsmsgs.iot-eu.com, IN wss://wsmsgs.iot-ap.com, UE wss://wsmsgs.iot-eus.com, WE wss://wsmsgs.iot-weu.com, SG wss://wsmsgs.iot-sea.com.
  • Auth: an Authorization: <key> header on the handshake — the same key as REST but without the Bearer prefix.
  • Frames are JSON with two top-level fields, eventType and data. A devicePropertyChange carries data.devId and data.status[], each with code, value and time (ms); an onlineStatusChange carries data.devId, data.status ("online"/"offline") and data.time.
  • Codes match thing-model codes. Look their meanings up via the model endpoint instead of guessing from the code string.
  • Reconnect with backoff on transient drops. Treat close codes 1002, 1003, 1008 and 1011 as fatal, and any frame containing error, a failing errorCode, or "success": false as a server error.
  • For event-driven automation, on a matching trigger issue properties to the action device as in Workflow step 5, and confirm the trigger→action mapping with the user before running it.

Limits

  • Control only basic property types (bool, enum, integer, string). Never write raw, bitmap, struct or array properties, or anything absent from the thing model.
  • No lock/unlock, live video streaming, firmware updates, pairing or device removal — say so and point to the Tuya app.
  • Device listing takes one scope at a time (all, home or room). Rate-limit batch writes with a short delay between commands.
  • Notifications triggered by device events must cool down at least 30 minutes — property events fire frequently.
  • These are the user's own account devices behind an end-user key; never attempt another user's devices.

Sources

Frequently asked questions

What does the Gadget Tuya Cloud Devices AI skill do?

Read status and control the user's Tuya app devices through Tuya's cloud end-user API with a user-supplied API key: homes and rooms, device detail, thing-model property control, rename, weather, hourly statistics, self-send notifications, IPC cloud snapshots and real-time event subscription. Cloud only; prefer a device-specific or local-TCP skill when one matches.

Why use Gadget Tuya Cloud Devices on TypingMind?

Because you install it once and use it with any model. Gadget Tuya Cloud Devices is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Gadget Tuya Cloud Devices in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/tuya/tuya-openclaw-skills/tree/master/platforms/muse. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Gadget Tuya Cloud Devices?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Gadget Tuya Cloud Devices?

As many as you like. As long as a model supports skills, you can use Gadget Tuya Cloud Devices with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Gadget Tuya Cloud Devices AI skill free?

Yes. It is published on GitHub by tuya under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇