aqara-agent is an official Aqara Home AI Agent skill. It supports natural-language home and space management, device inquiry, device control, ambience_create...
---
name: aqara-agent
description: "aqara-agent is an official Aqara Home AI Agent skill. It supports natural-language home and space management, device inquiry, device control, ambience_create (氛围创建: apply or compose a named mood in a room or whole home via scene match then lights + optional music), ambience / mood orchestration reference, lighting effect inquiry and control (named lighting presets), device configuration (firmware/OTA upgrade only - not supported: rename devices, move devices between rooms or positions, or other device record edits outside firmware), device logs, scene management (query, execute, create, snapshot, and logs), automation management (create, query, detail, toggle, and logs), and energy / electricity-cost statistics (by device, room, or home). Examples: \"How many lights are at home?\", \"Switch to my other home.\", \"Turn off the living room AC.\", \"What are the temperature and humidity in the bedroom?\", \"氛围创建\", \"卧室营造温馨居家氛围.\", \"Whole home sunset vibe.\", \"What lighting effects or scene modes are available at home?\", \"Set the bedroom lights to the reading lighting effect.\", \"Upgrade the bedroom camera firmware.\", \"Upgrade firmware for the hub.\", \"Show device logs for this device.\", \"Run the Movie scene.\", \"Recommend a bedtime setup for the bedroom.\", \"Create a good-night scene in the bedroom.\", \"Capture a scene snapshot of how things are now.\", \"Which scenes use the kitchen lights?\", \"When it is sunset in Haidian District, Beijing, turn off the security alarm.\", \"Create an automation to turn off the bedroom lights every day at 10:30pm.\", \"Five minutes after the living room motion sensor detects someone, turn on the hallway lights.\", \"At 7am on weekdays, run the Good Morning scene.\", \"If outdoor temperature drops below 5 degrees C, send me a notification.\", \"What automations do I have?\", \"Turn off the morning routine automation.\", \"What triggers the Leave Home automation?\", \"What was last month's electricity bill at home?\", \"How much power did the bedroom use this week?\", \"Check automation execution in the bedroom for the last three days.\", \"Show scene run history for the Movie scene.\""
---
# Aqara Smart Home AI Agent Skill
## Basics
### `aqara_open_api.py` CLI
- **Invocation:** `python3 scripts/aqara_open_api.py <method_name> [json_body]`.
- **Must:** first argument equals the **exact** public method name on `AqaraOpenAPI` (see bash examples in `references/*.md`). **Forbidden:** aliases or shortened names unless a reference documents an equivalent.
- **Dispatch:** `get_*` -> no JSON body; `post_*` -> JSON object (optional, default `{}`).
- **Energy:** `post_energy_consumption_statistic` - route from **`device_ids` only** (non-empty -> device API; else position). Fields and NL mapping: `references/energy-statistic.md`.
- **Methods (ground list):** `get_homes`, `get_rooms`, `get_home_devices`, `get_home_scenes`, `get_home_automations`, `get_home_lighting_effects_query`, `post_current_outdoor_weather`, `post_device_base_info`, `post_device_status`, `post_device_control`, `post_device_lighting_effect_query`, `post_lighting_effect_control`, `post_device_firmware_query`, `post_device_firmware_upgrade`, `post_device_log`, `post_execute_scene`, `post_scene_detail_query`, `post_create_scene`, `post_scene_snapshot`, `post_scene_execution_log`, `post_device_related_automation_query`, `post_automation_execution_log`, `post_automation_switch`, `post_create_automation`, `post_energy_consumption_statistic`. **Forbidden** call names not present on `AqaraOpenAPI` unless a reference adds them.
- **`post_create_automation` and `raw_config` (non-negotiable):** **Every** call **Must** send **non-empty** `raw_config` in the HTTP body ([automation-create.md](references/automation-create.md#post-create-raw-config-always)). **Forbidden** to send only `auxiliary_config` or only root-level supplemental `conditions` / `actions` without **non-empty** `raw_config`.
- **`post_create_automation` first round vs follow-up:** **First** call: **non-empty** `raw_config` only; **`auxiliary_config` Must be empty** (omit the argument or pass `{}`). If the response needs config-list matching, use **`LLMConfigReference`** as the **only** source for Step 03 -> **`auxiliary_config`** ([step-03-parse-config-prompt.md](references/automation-create-workflow/step-03-parse-config-prompt.md)). **Second and later** calls: **Must** resend the same **non-empty** `raw_config` **and** attach **`auxiliary_config`** ([Step 3 supplement](references/automation-create.md#step-3b-auxiliary-config)). `scripts/aqara_open_api.py` **shallow-merges** `raw_config` and `auxiliary_config` into one JSON when both are passed.
- **Optional env:** `AQARA_OPEN_HTTP_TIMEOUT` (default 60), `AQARA_OPEN_API_URL` (overrides disk). **Optional disk:** `assets/user_account.json` keys `aqara_open_api_url` or `open_api_url` (full base, no trailing slash required) when env is unset — requests use `{base}/{path}` (e.g. `homes/query`).
## Skill Package Layout
Relative to the **skill root** directory (Cursor project: **`.cursor/skills/aqara-agent/`**; other layouts: **`skills/aqara-agent/`**). **Normative:** this file + `references/*.md` (including **`references/ambience.md`** for **`ambience_create`(氛围创建)**, mood orchestration, and lighting-preset paths) + `references/scene-workflow/*.md` where scene applies + `references/automation-workflow/*.md` where automation applies (**includes** `recommend.md` for **recommend-style automation -> example NL -> create**) + `references/automation-create-workflow/*` for **`post_create_automation`** (see `references/automation-create.md`). Optional **`README.md`** (human index only) when present in a pack; **Forbidden** treat it as overriding `SKILL.md`.
| Path | Purpose |
|------|---------|
| `SKILL.md` | This document. |
| `README.md` | Optional human index in some packs; **Forbidden** treat as overriding `SKILL.md`. |
| `assets/login_reply_prompt.json` | Locales, `official_open_login_url`, `login_url_policy`. |
| `assets/user_account.example.json` | Template shape. |
| `assets/user_account.json` | Live session (sensitive). |
| `assets/device_control_action_table.csv` | Normative `attribute` / `action` / `value` mapping for control and scene slots (`devices-control.md`, scene workflows). |
| `references/*.md` | Per-domain procedures (account, home-space, devices inquiry/control/config, **[ambience.md](references/ambience.md)** — **`ambience_create`(氛围创建)** + inquiry / thin preset, scenes index, automations, energy, weather). |
| `references/scene-workflow/*.md` | Scene sub-workflows; enter via `references/scene-manage.md`. **Files (scan):** `list.md` (catalog `#catalog-list` + `#scenes-by-device`), `execute.md`, `recommend.md`, `create.md`, `snapshot.md`, `execution-log.md`, `failure-response.md`, `appendices.md`. |
| `references/automation-workflow/*.md` | Automation sub-workflows; enter via `references/automation-manage.md`. **Files (scan):** `list.md` (catalog `#catalog-list` + by-device `#by-device`), `toggle.md`, `execution-log.md`, `failure-response.md`, **`recommend.md`** (recommend-style automation -> example NL -> create; **Forbidden** `post_automation_recommend_query`). |
| `references/automation-create-workflow/` | NL -> `raw_config` -> create; **Files (scan):** `manifest.json`, `step-01-conditions-actions-extract.md`, `step-02-cell-info-fill.md`, `step-03-parse-config-prompt.md`. |
| `scripts/aqara_open_api.py` | CLI + HTTP client. |
| `scripts/save_user_account.py` | Writes `aqara_api_key`. |
| `scripts/runtime_utils.py` | Shared helpers. |
| `scripts/requirements.txt` | Dependencies. |
## Core Workflow
**deps -> sign-in -> pick home -> intent -> `references/*.md` -> summarize**
## Ground Truth (Binding)
**Forbidden** stating or implying as factual: homes, rooms, devices, capabilities, attributes, counts, logs, or control outcomes, except from **executed** skill scripts + real API responses or skill-accepted user input (e.g. pasted `aqara_api_key`). If that flow **has not** succeeded, **Forbidden** any factual claim about those entities.
**Forbidden** demo-style lists, guessed layouts, synthetic values, fake success after errors/timeouts/missing auth, or prose/JSON mimicking API output without a real response.
**Must** state missing data and cause (e.g. not signed in, API error), then auth/retry/`references/`. **Forbidden** imagined padding.
---
Execute in order:
### 1. Environment
```bash
export AQARA_OPEN_HOST=agent.aqara.com
```
```bash
cd .cursor/skills/aqara-agent # Cursor project layout (repo root)
# cd skills/aqara-agent # upstream pack layout
pip install -r scripts/requirements.txt
```
### 2. Auth
- **Must** confirm `user_account.json` readable/writable before features; host/project rules may require reading it first.
- **Must** follow `references/aqara-account-manage.md` (switch-home vs re-login, token save, Step 1 login copy).
- **Must** read `assets/login_reply_prompt.json` on every login guidance turn. **Must** set the user-facing login link to the **exact** `official_open_login_url` string (`login_url_policy`). **Forbidden** invent Open Platform / `sns-auth` / `client_id` / `redirect_uri` URLs from memory.
- Locale from JSON for the user's language; unknown -> `en` (`fallback_locale` / `default_locale`). **Must** deliver the **single-line** login URL per `references/aqara-account-manage.md`.
`user_account.json`:
```json
{
"aqara_api_key": "",
"updated_at": "",
"home_id": "",
"home_name": ""
}
```
### 3. Home Management
- **Must** after saving `aqara_api_key` run `references/home-space-manage.md` step **0** immediately (fetch homes; one home -> write; many -> **show the complete home list** + remind user to **choose one**, then user picks). **Forbidden** reply only "send home name" without running fetch or without listing all homes when many.
- **Must** run `save_user_account.py` and `aqara_open_api.py get_homes` as **two separate** invocations. **Forbidden** `&&` on one shell line (`aqara-account-manage.md` step 2, `home-space-manage.md` step 0).
- **Switch home:** **Must** re-fetch homes, show the **complete** list, remind user to **pick one**, then persist (`home-space-manage.md`). **Forbidden** default to re-login. **Must** use `aqara-account-manage.md` login only if the user demands re-login/token rotation or the API signals expired/unauthorized.
### 4. Intent
Categories: space, device query, device control, **`ambience_create`(氛围创建)**, ambience inquiry / thin lighting preset, device configuration, scene, automation, energy. **Multiple intents:** **Must** query before control or configuration, in utterance order.
| Intent | `AqaraOpenAPI` methods (details in reference) | Reference |
|--------|-----------------------------------------------|-----------|
| Space | `get_homes`, `get_rooms` | `references/home-space-manage.md` |
| Device query | `get_home_devices`, `post_device_status`; optional `post_device_base_info`, `post_device_log`, `post_device_firmware_query` (firmware version read) | `references/devices-inquiry.md` (incl. **User-facing wording**: say **device**, not **endpoint**; **`endpoint_id` / `device_ids`** vs. multi-channel hardware) |
| Device control | `post_device_control` - **immediate only** (generic attributes; **not** named lighting presets) | `references/devices-control.md` + `assets/device_control_action_table.csv` — **`ambience_create` / 氛围创建** → **Ambience create** row + [ambience.md](references/ambience.md); thin lamp preset only → **Fast path** in [ambience.md](references/ambience.md#fast-path-lighting-preset-inquiry-only). If NL is **scheduled / delayed device control** (not immediate), use **create automation** - see **Automation** row. |
| **Ambience create** (`ambience_create` / **氛围创建**) | User **applies or creates** a named mood for a room or whole home (**Must** [Workflow](references/ambience.md#ambience-workflow) + [LightingEffectAgent](references/ambience.md#lighting-effect-agent) in [ambience.md](references/ambience.md)): **`get_home_scenes`** (+ **`post_scene_detail_query`**) → scene match (default **≥0.85**) → **`post_execute_scene`** **or** composite **`MOOD_PRESETS`** → **`fuzzy_device_batch_control`** (Sec. **4b** only: lights **off** in Sec. 1 **`position_id`(s)**) → **`mood_device_batch_control`** ∥ **`music_on_demand`** (Sec. **4c**–**4d**) → **`get_home_lighting_effects_query`** → **`post_lighting_effect_control`** (Sec. **4e**). **Logical:** `scene_base_inquiry`, `music_on_demand`. **Persist save:** [ambience.md — Save scene payload](references/ambience.md#save-scene-payload) → **`post_create_scene`** only; **Forbidden** route through [scene-workflow/create.md](references/scene-workflow/create.md) (保存见 ambience.md,勿路由到 create.md). NL e.g. 氛围创建、营造/来个××氛围、全屋落日感. | [ambience.md](references/ambience.md) |
| **Ambience inquiry & lighting presets** | **Not** `ambience_create`: list lamp presets (`get_home_lighting_effects_query`, `post_device_lighting_effect_query`); **Fast path** thin **`post_lighting_effect_control`** only — [ambience.md#fast-path-lighting-preset-inquiry-only](references/ambience.md#fast-path-lighting-preset-inquiry-only). | [ambience.md](references/ambience.md) |
| Device configuration | `post_device_firmware_upgrade` - **Firmware/OTA only** - [Firmware-only scope](references/devices-config.md#firmware-only-scope) | `references/devices-config.md` |
| Scene | `get_home_scenes`, `post_execute_scene`, `post_create_scene`, `post_scene_snapshot`, `post_scene_detail_query`, `post_scene_execution_log`; **`post_current_outdoor_weather`** - **only** [Scene recommend workflow](references/scene-workflow/recommend.md) step 7 **Leaving home** before control (`references/weather-forecast.md`); **Forbidden** elsewhere. Recommend path uses `post_device_control` unless **Create scene** applies. Catalog list + `post_scene_detail_query`: [list.md](references/scene-workflow/list.md) (`#catalog-list`, `#scenes-by-device`) | `references/scene-manage.md` (index); `references/weather-forecast.md`; other steps in `references/scene-workflow/*.md`. If NL is **scheduled / delayed catalog scene control** (not immediate catalog scene run), use **create automation** - see **Automation** row. |
| Automation | `get_home_automations`, `post_device_related_automation_query`, `post_automation_switch`, `post_automation_execution_log`, **`post_create_automation`** | [automation-manage.md](references/automation-manage.md) (list / toggle / logs / **direct** create when the user already has an executable rule). **Recommend automation** (situational help, example sentences, then create): [automation-workflow/recommend.md](references/automation-workflow/recommend.md) only; **Forbidden** `post_automation_recommend_query`. **Create automation** (including NL classified as scheduled / delayed **device** control or scheduled / delayed **catalog scene** control, not immediate `post_device_control` / `post_execute_scene`): [automation-create.md](references/automation-create.md) + [automation-create-workflow/](references/automation-create-workflow/). Catalog and by-device: [list.md](references/automation-workflow/list.md); toggle and logs: same as first column. |
| Energy | `post_energy_consumption_statistic` | `references/energy-statistic.md` |
- **Composite `device_type`:** `get_home_devices` rows (and `device_types` filters on batch calls such as `post_device_status`) may use **comma-separated** `device_type` strings (e.g. `Switch,Button,Light`). **Must** classify and count by **token presence**: **`Light`** in the composite string means the **listed device** is still a **light-class** device for listings and counts (wall switches that control lighting included). **Must** apply the **same rule** to **air conditioners**, **curtains** (`WindowCovering`), **fans** (e.g. `IRDevice,Fan`), and other families — if the category token appears in the composite type, treat the **listed device** under that category for inquiry, filters, and summaries. User-facing list/count nouns: [devices-inquiry.md](references/devices-inquiry.md#user-facing-device-wording).
**Recommend automation (automation path):** If the user wants **situational ideas** and has **not** given one create-ready rule sentence, **Must** run [automation-workflow/recommend.md](references/automation-workflow/recommend.md) steps **0-5** (scope gate in **§0**: if neither position nor device, **`get_rooms`** + position list only — **no** examples same turn; else **`get_rooms`**, scoped **`get_home_devices`**, **`get_home_scenes`**, mandatory **`post_device_status`**, optional **`post_device_base_info`**, optional **`get_home_automations`**). **Forbidden** `post_automation_recommend_query` and platform "template name" strings as data. **User-facing reply:** success vs error format and id redaction -> that doc **§5** (§5.2: localized lead-in line matching the user's input language + numbered lines `1.` through `10.` (digit + ASCII period only) on success; on error, detail only, **no** home/device/position/scene/automation **ids**). After the user **selects or rewrites** one example line, **Must** continue with [automation-create.md](references/automation-create.md) and **`post_create_automation`** (non-empty `raw_config` on every call; `LLMConfigReference` handling per that doc and step-03).
### 5. Route and Summarize
**Must** open the matching `references/` doc, run scripts, summarize from **actual** output only. **Forbidden** fabricate success or any home/room/device/state not in script/API output (**Ground truth**).
### Illustrative CLI JSON (Agents Only)
**Forbidden** paste these raw blocks to end users.
REST shape (skeleton):
```json
{
"code": 0,
"message": "",
"data": {}
}
```
### Error Handling
| Situation | Action |
|-----------|--------|
| Device not found | **Must** state no match; **allowed:** short candidate list. |
| Capability unsupported | **Must** state unsupported; **Forbidden** imply success. |
| Home/room not found | **Must** state no hit; **Must** direct next step via `references/` (re-fetch or verify home). |
| Multiple device matches | **Must** list matches; **Must** one disambiguation question (room or full name). |
| Not signed in / empty `aqara_api_key` | **Must** login + save per `references/aqara-account-manage.md`, then homes. `MissingAqaraApiKeyError` -> same. |
| No home selected | **Must** `references/home-space-manage.md`. No `home_id` -> `homes/query`; one home -> auto-write; many -> show **full** home list + **choose one** prompt, then `home_selection_required`. |
| Bad token / auth | **Must** re-login / refresh (no secret leak). **Forbidden** treat **home switch** as auth failure unless home-list returns auth error. `unauthorized or insufficient permissions` (or equivalent) -> **Must** re-login per `references/aqara-account-manage.md`; **Forbidden** fake success. |
| Control path blocked | **Must** say device found, command not sent. |
| Firmware / configuration path blocked | **Must** say device found, upgrade or config action not sent; **Must** `references/devices-config.md`. |
| Other | **Must** short summary + retry/`references/`; **Forbidden** internal URLs or full headers. |
| Indeterminate | **Must** use `references/` + script output; confirmed bug -> **Must** file skill issue. |
| Empty API data | **Forbidden** invent entities/readings; **Must** re-run or report failure (**Ground truth**). |
| HTTP / network | **Forbidden** treat as success; **Must** retry or brief explanation; **Forbidden** raw stacks. |
## Notes
1. **Forbidden** raw IDs in user text (device, position, `home_id`, ...). **Exception:** `automation_id` **allowed** if server desensitized virtual ID.
2. After layout changes, if match fails: **Must** re-fetch space + devices (`references/home-space-manage.md`, `references/devices-inquiry.md`), retry.
3. User replies: **Must** conclusion first, then detail; **Must** <= one clarification question.
4. **Session gate:** unsigned -> **Must** end on setup; **Forbidden** imply control ran.
5. **Must** run `scripts/*.py` automatically when required (stricter host policy wins).
6. Account/home change: **Must** update `user_account.json` and re-run [`references/aqara-account-manage.md`](references/aqara-account-manage.md).
7. **Forbidden** echo tokens/headers; **Must** treat `user_account.json` and caches as sensitive.
8. Multiple fuzzy name hits: **Must** user confirm.
9. User-visible: **Forbidden** shell, paths, raw stdout, debug JSON, `references/` filenames; **Must** plain summary.
10. Control OK: **Must** brief close; **Forbidden** preemptive hedging; fix only after user reports failure.
## Out of Scope
**Fully unsupported** (no API in this skill; point users to **Aqara Home app** when relevant):
- **Cameras** - live view / playback.
- **Locks** - unlock / lock-unlock.
- **Shortcuts** (e.g. Siri lists) - **Must** point to **Aqara Home app**.
- **Weather** - general forecasts and Q&A; **exception:** `post_current_outdoor_weather` **only** in [recommend.md](references/scene-workflow/recommend.md) step 7 **Leaving home** before control - see [weather-forecast.md](references/weather-forecast.md); **Forbidden** for Create scene, snapshot, run catalog scene, logs, or any other flow.
- **Entertainment** - beyond [devices-control.md](references/devices-control.md); **exception:** mood **music** only as **`music_on_demand`** inside [ambience.md](references/ambience.md) composite **Sec. 4** when the product implements it.
**Limited to documented workflows** (no app-only or undocumented features):
- **`ambience_create`(氛围创建)** - **only** [ambience.md](references/ambience.md) full workflow (ordered Sec. 1–4 + Result); **Ambience inquiry & thin preset** - **only** [ambience.md](references/ambience.md) fast path + listed APIs.
- **Scenes** - **only** procedures in [scene-manage.md](references/scene-manage.md) and `references/scene-workflow/*.md` (e.g. `list.md`, `execute.md`, `recommend.md`, `create.md`, `snapshot.md`, `execution-log.md`, `failure-response.md`, `appendices.md`).
- **Automations** - **only** procedures in [automation-manage.md](references/automation-manage.md) and `references/automation-workflow/*.md` (`list.md`, `toggle.md`, `execution-log.md`, `failure-response.md`, `recommend.md` for recommend-then-create, plus [automation-create.md](references/automation-create.md) and `references/automation-create-workflow/*` for **`post_create_automation`**).
**When** the user asks outside the above: **Must** say unsupported (or not yet); **Must** direct to **Aqara Home app** if the app covers it.
don't have the plugin yet? install it then click "run inline in claude" again.