You provideNotes**AK (Access Key)**Get one from the Ecovacs Open Platform “Service Overview” (Mainland China: https://open.ecovacs.cn/, non-China regions: https://open.ecovacs.com/) and put it in your env or pass to set-ak. Do not hand the skill a username/password to log in on your behalf.Device nickname fragmentUsed to fuzzy-match nick or name returned by the device list.
export ECOVACS_AK=... or python3 scripts/ecovacs.py set-ak <ak>)python3 scripts/ecovacs.py devicesPOST /robot/skill/pet/cmd or the script's cmd / display subcommands; cmd must be in the gateway allowlist, otherwise the gateway returns command not enabled.Run from the repository root: python3 scripts/ecovacs.py .... You may set ECOVACS_PORTAL_URL to a custom gateway base URL; when unset, the default is the Mainland China Open Platform domain.
cmd (string) + data (object); invalid parameters surface as cloud error messages.command not enabled, that cmd is outside the deployment's supported set — use only commands listed below or ask a maintainer.set* inputs#See references/schema.md.
DescriptioncmdPet state / emotion / persona / gender / location & weather / initializationgetPetState, getEmotion, getPerson, getPetGender, getLocationInfo, getInitiateStateMicrophone / camera / volume / eye brightness / language / wake idle timeoutgetMicro, getCamera, getVolume, getEyesLight, getLanguage, getWakeTimeoutLatest diary entrygetLatestDiary
DescriptioncmdMicrophone / camera / volume / wake idle timeout / wake word / gendersetMicro, setCamera, setVolume, setWakeTimeout, setNickname, setPetGender
DescriptioncmdDisplay / motion sequencesdisplayPlay sound ( category or file + optional count / moveTimeMs)playSound
Sound routing (conversation → payload) — see phoenix-single-action.md §2.2:
User intentSend“Bark happily” / vague mood sound{"category":"happy","count":1} — gateway picks a random clip in that category“Bark loudly / big happy bark”{"file":"happy-h-<1-5>","count":1} — pick one happy-h-1… happy-h-5“Soft / quiet bark”{"file":"happy-l-<1-5>","count":1}Other moodscategory = calm / attached / curious / angry / sad / scared, or pick file with matching {mood}-{l|m|h}-{n}
For action_sequence rows, each play_sound step needs an explicit file (choose using the table above before building JSON).
Dance — single preset in references/dance-routines.md ( showcase_custom / 定制秀舞):
User intentCLIDance / short dance / any legacy mood namedisplay <nick> dance
Fixed script ~45s; length is ignored. Aliases ( cheerful, 点头舞, etc.) all map to the same dance.
Persona / mood (read-only): getPerson, getPetState, getEmotion.
Sleep: display <nick> sleep.
Motion protocols — two paths; do not mix fields between them:
PathWhenDocplay_actionOne step: display … action, bare playSoundphoenix-single-action.mdaction_sequenceMulti-step, dance, playSound + actions, timedphoenix-action-control.md + action-sequence.md
Critical — pick one protocol and its field names only:
Topicplay_action (single)action_sequence (composite)Head angle×100 on wire ( 30° → "3000"); script accepts degrees in CLI JSONDegrees as-is ( "-14", "44"); must stay in rangeHead rangesScript converts degrees; still respect device limits when choosing valuesnod_head −14~+22 · shake_head −60~+60 · cock_head −20~+20Tail speedWire field angle = speed×100; CLI may use percent / angle 0–100Field percent 0–100 only — not angleSoundWire field angle = filename; CLI file or category via playSoundField file — not angle``moveTimeMs``-1 allowed (default speed / continuous tail)Must be >0; -1 is replaced by script defaultsTimingNo delayEvery row needs delay (ms)
Common mistakes: copying a single-action JSON into actions[] (×100 angles, -1 times); using percent in display action wag_tail without letting the script convert (OK in CLI, wrong on raw wire); using angle: "3000" in a dance step (device expects "30").
UtilityScriptEnter sleepdisplay <nick> sleepStop motion / cancel device-side scheduled routinesdisplay <nick> reset
Before sending any display motion/persona action through scripts/ecovacs.py display ..., the script checks getCamera. If enable != 1, it wakes the pet through the skill gateway with setCamera {"enable":1}, waits until getCamera.enable=1, switches work mode back to standard with setWorkMode {"mode":"standard"}, and only then sends the action. Set ECOVACS_SKIP_WAKE_CHECK=1 only for debugging when you intentionally want to bypass this guard.
Dance / timed barks / multi-step shows: one action_sequence per show. Dance: build_dance_sequence() → showcase_custom — see references/dance-routines.md.
Default timing limits (hand-built JSON only; preset dance is exempt — see below):
ScopeDefault capOverrideSingle step ( play_action or one actions[] row)delay + duration ≤ 10s"user_timing": true on the JSON objectHand-built action_sequence (non-scheduled)end time ≤ ~20ssame flag, or conditions.scheduled / repeatPreset dance ( display … dance → showcase_custom)~45s fixed scriptScript sets user_timing: true automatically — do not trim steps to fit 20sDebugskip all checksECOVACS_SKIP_TIMING_LIMIT=1
user_timing is stripped before the gateway sees the payload.
bash
SCRIPT="./scripts/ecovacs.py"
python3 "$SCRIPT" cmd <nickname-fragment> getPetState '{}'
python3 "$SCRIPT" cmd <nickname-fragment> getCamera '{}'
python3 "$SCRIPT" cmd <nickname-fragment> setWakeTimeout '{"timeout":180}'
python3 "$SCRIPT" cmd <nickname-fragment> getPerson '{}'
python3 "$SCRIPT" display <nickname-fragment> dance
python3 "$SCRIPT" display <nickname-fragment> dance showcase_custom
python3 "$SCRIPT" cmd <nickname-fragment> playSound '{"category":"happy","count":1}'
python3 "$SCRIPT" cmd <nickname-fragment> playSound '{"file":"happy-h-3","count":1}'
python3 "$SCRIPT" display <nickname-fragment> sleep
python3 "$SCRIPT" display <nickname-fragment> reset
python3 "$SCRIPT" display <nickname-fragment> action shake_head '{"angle":"30","moveTimeMs":"-1","count":"3"}'
python3 "$SCRIPT" display <nickname-fragment> action wag_tail '{"percent":30,"moveTimeMs":"-1"}'
python3 "$SCRIPT" cmd <nickname-fragment> playSound '{"file":"happy-h-1","count":1,"conditions":{"scheduled":"0","repeat_type":"1","repeat_count":"10"}}'
Default gateways: Mainland China https://open.ecovacs.cn, non-China regions https://open.ecovacs.com (override with ECOVACS_PORTAL_URL if needed).
Device list
bash
curl -sS "${BASE_URL}/robot/skill/deviceList?ak=YOUR_AK"
Pet control
bash
curl -sS -X POST "${BASE_URL}/robot/skill/pet/cmd" -H 'Content-Type: application/json' \
-d "{\"ak\":\"${AK}\",\"nickName\":\"nickname-fragment\",\"cmd\":\"getPetState\",\"data\":{}}"
The field name must be nickName exactly as above (uppercase N).
Compatibility path: POST /robot/skill/ctl + ctl is still accepted for pet devices and is also subject to the cmd allowlist.
Use the script and HTTP examples earlier in this document ( get* first, then set* / display) to confirm nickName resolution and allowlist behavior before relying on higher-risk writes.
CaseWhat to doOuter code != 0Read msg (invalid AK, device not found, not FAMIBOT, command not enabled)command not enabledUse only commands listed in Supported commands above; ask a maintainer if the user needs something elsesetCamera / setWorkMode blocked before a display actionAutomatic wake-up could not complete; wake the pet in the app and retryToken errors like 4504Check / rotate the AK3003Verify nickname matches the right device and that the model supports the capability
More detailed troubleshooting (including "why was this judged not-pet") lives in references/troubleshooting.md.
FileAudienceContentThis SKILL.mdAgent / userAK, device list, pet/cmd usage, public capability name-level notesreferences/api.mdUserGateway URLs and request body fieldsreferences/schema.mdUserCommon response fields, set* input names and compatibility rulesreferences/troubleshooting.mdUserCommon error branches and resolution pathsreferences/phoenix-single-action.mdAgent单步 play_action 字段references/phoenix-action-control.mdAgent编排 action_sequence 字段表references/action-sequence.mdAgentdelay / conditions、helper、场景(无重复字段表)references/dance-routines.mdAgent / user唯一预设 showcase_custom(定制秀舞)结构与 CLI
Supported commands are listed in this SKILL.md; protocol docs describe only those motion paths. Legacy multi-routine names ( cheerful_motion, party, 点头舞, …) are aliases to showcase_custom only.