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). 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). Second and later calls: Must resend the same non-empty raw_config and attach auxiliary_config (Step 3 supplement). 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 — 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
export AQARA_OPEN_HOST=agent.aqara.com
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:
{
"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; thin lamp preset only → Fast path in ambience.md. 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 + LightingEffectAgent in 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 → post_create_scene only; Forbidden route through scene-workflow/create.md (保存见 ambience.md,勿路由到 create.md). NL e.g. 氛围创建、营造/来个××氛围、全屋落日感. |
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. |
ambience.md |
| Device configuration |
post_device_firmware_upgrade - Firmware/OTA only - 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 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 (#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 (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 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 + automation-create-workflow/. Catalog and by-device: 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.
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 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 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):
{
"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
- Forbidden raw IDs in user text (device, position,
home_id, ...). Exception: automation_id allowed if server desensitized virtual ID.
- After layout changes, if match fails: Must re-fetch space + devices (
references/home-space-manage.md, references/devices-inquiry.md), retry.
- User replies: Must conclusion first, then detail; Must <= one clarification question.
- Session gate: unsigned -> Must end on setup; Forbidden imply control ran.
- Must run
scripts/*.py automatically when required (stricter host policy wins).
- Account/home change: Must update
user_account.json and re-run references/aqara-account-manage.md.
- Forbidden echo tokens/headers; Must treat
user_account.json and caches as sensitive.
- Multiple fuzzy name hits: Must user confirm.
- User-visible: Forbidden shell, paths, raw stdout, debug JSON,
references/ filenames; Must plain summary.
- 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 step 7 Leaving home before control - see weather-forecast.md; Forbidden for Create scene, snapshot, run catalog scene, logs, or any other flow.
- Entertainment - beyond devices-control.md; exception: mood music only as
music_on_demand inside 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 full workflow (ordered Sec. 1–4 + Result); Ambience inquiry & thin preset - only ambience.md fast path + listed APIs.
- Scenes - only procedures in 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 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 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.
1---2name: aqara-agent3description: 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?", "Se4---5
6# Aqara Smart Home AI Agent Skill
7
8## Basics
9
10### `aqara_open_api.py` CLI
11
12- **Invocation:** `python3 scripts/aqara_open_api.py <method_name> [json_body]`.
13- **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.
14- **Dispatch:** `get_*` -> no JSON body; `post_*` -> JSON object (optional, default `{}`).
15- **Energy:** `post_energy_consumption_statistic` - route from **`device_ids` only** (non-empty -> device API; else position). Fields and NL mapping: `references/energy-statistic.md`.
16- **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.
17- **`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`.
18- **`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.
19- **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`).
20
21## Skill Package Layout
22
23Relative 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`.
24
25| Path | Purpose |
26|------|---------|
27| `SKILL.md` | This document. |
28| `README.md` | Optional human index in some packs; **Forbidden** treat as overriding `SKILL.md`. |
29| `assets/login_reply_prompt.json` | Locales, `official_open_login_url`, `login_url_policy`. |
30| `assets/user_account.example.json` | Template shape. |
31| `assets/user_account.json` | Live session (sensitive). |
32| `assets/device_control_action_table.csv` | Normative `attribute` / `action` / `value` mapping for control and scene slots (`devices-control.md`, scene workflows). |
33| `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). |
34| `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`. |
35| `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`). |
36| `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`. |
37| `scripts/aqara_open_api.py` | CLI + HTTP client. |
38| `scripts/save_user_account.py` | Writes `aqara_api_key`. |
39| `scripts/runtime_utils.py` | Shared helpers. |
40| `scripts/requirements.txt` | Dependencies. |
41
42## Core Workflow
43
44**deps -> sign-in -> pick home -> intent -> `references/*.md` -> summarize**
45
46## Ground Truth (Binding)
47
48**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.
49
50**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.
51
52**Must** state missing data and cause (e.g. not signed in, API error), then auth/retry/`references/`. **Forbidden** imagined padding.
53
54---
55
56Execute in order:
57
58### 1. Environment
59```bash
60export AQARA_OPEN_HOST=agent.aqara.com
61```
62
63```bash
64cd .cursor/skills/aqara-agent # Cursor project layout (repo root)
65# cd skills/aqara-agent # upstream pack layout
66pip install -r scripts/requirements.txt
67```
68
69### 2. Auth
70
71- **Must** confirm `user_account.json` readable/writable before features; host/project rules may require reading it first.
72- **Must** follow `references/aqara-account-manage.md` (switch-home vs re-login, token save, Step 1 login copy).
73- **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.
74- 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`.
75
76`user_account.json`:
77
78```json
79{
80 "aqara_api_key": "",
81 "updated_at": "",
82 "home_id": "",
83 "home_name": ""
84}
85```
86
87### 3. Home Management
88
89- **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.
90- **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).
91- **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.
92
93### 4. Intent
94
95Categories: 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.
96
97| Intent | `AqaraOpenAPI` methods (details in reference) | Reference |
98|--------|-----------------------------------------------|-----------|
99| Space | `get_homes`, `get_rooms` | `references/home-space-manage.md` |
100| 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) |
101| 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. |
102| **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) |
103| **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) |
104| Device configuration | `post_device_firmware_upgrade` - **Firmware/OTA only** - [Firmware-only scope](references/devices-config.md#firmware-only-scope) | `references/devices-config.md` |
105| 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. |
106| 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. |
107| Energy | `post_energy_consumption_statistic` | `references/energy-statistic.md` |
108
109- **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).
110
111**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).
112
113### 5. Route and Summarize
114
115**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**).
116
117### Illustrative CLI JSON (Agents Only)
118
119**Forbidden** paste these raw blocks to end users.
120
121REST shape (skeleton):
122
123```json
124{
125 "code": 0,
126 "message": "",
127 "data": {}
128}
129```
130
131### Error Handling
132
133| Situation | Action |
134|-----------|--------|
135| Device not found | **Must** state no match; **allowed:** short candidate list. |
136| Capability unsupported | **Must** state unsupported; **Forbidden** imply success. |
137| Home/room not found | **Must** state no hit; **Must** direct next step via `references/` (re-fetch or verify home). |
138| Multiple device matches | **Must** list matches; **Must** one disambiguation question (room or full name). |
139| Not signed in / empty `aqara_api_key` | **Must** login + save per `references/aqara-account-manage.md`, then homes. `MissingAqaraApiKeyError` -> same. |
140| 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`. |
141| 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. |
142| Control path blocked | **Must** say device found, command not sent. |
143| Firmware / configuration path blocked | **Must** say device found, upgrade or config action not sent; **Must** `references/devices-config.md`. |
144| Other | **Must** short summary + retry/`references/`; **Forbidden** internal URLs or full headers. |
145| Indeterminate | **Must** use `references/` + script output; confirmed bug -> **Must** file skill issue. |
146| Empty API data | **Forbidden** invent entities/readings; **Must** re-run or report failure (**Ground truth**). |
147| HTTP / network | **Forbidden** treat as success; **Must** retry or brief explanation; **Forbidden** raw stacks. |
148
149## Notes
150
1511. **Forbidden** raw IDs in user text (device, position, `home_id`, ...). **Exception:** `automation_id` **allowed** if server desensitized virtual ID.
1522. After layout changes, if match fails: **Must** re-fetch space + devices (`references/home-space-manage.md`, `references/devices-inquiry.md`), retry.
1533. User replies: **Must** conclusion first, then detail; **Must** <= one clarification question.
1544. **Session gate:** unsigned -> **Must** end on setup; **Forbidden** imply control ran.
1555. **Must** run `scripts/*.py` automatically when required (stricter host policy wins).
1566. Account/home change: **Must** update `user_account.json` and re-run [`references/aqara-account-manage.md`](references/aqara-account-manage.md).
1577. **Forbidden** echo tokens/headers; **Must** treat `user_account.json` and caches as sensitive.
1588. Multiple fuzzy name hits: **Must** user confirm.
1599. User-visible: **Forbidden** shell, paths, raw stdout, debug JSON, `references/` filenames; **Must** plain summary.
16010. Control OK: **Must** brief close; **Forbidden** preemptive hedging; fix only after user reports failure.
161
162## Out of Scope
163
164**Fully unsupported** (no API in this skill; point users to **Aqara Home app** when relevant):
165
166- **Cameras** - live view / playback.
167- **Locks** - unlock / lock-unlock.
168- **Shortcuts** (e.g. Siri lists) - **Must** point to **Aqara Home app**.
169- **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.
170- **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.
171
172**Limited to documented workflows** (no app-only or undocumented features):
173
174- **`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.
175- **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`).
176- **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`**).
177
178**When** the user asks outside the above: **Must** say unsupported (or not yet); **Must** direct to **Aqara Home app** if the app covers it.