dsh-iot-studio
English | 简体中文
IoT studio plugin for DeepSeek Harness: one generic, brand-neutral tool layer for the agent to discover, inspect, and control smart-home devices. Not tied to any single vendor — a new IoT device is usable immediately once paired in its brand app, and a new brand attaches by registering one IotBrandProvider. Ships with xiaomi / mijia built-in.
Open-source attribution. The built-in xiaomi provider's cloud protocol (login, RC4/SHA1 request signing, device listing, MIoT spec lookup) is adapted for TypeScript from hass-xiaomi-miot by al-one, licensed under Apache License 2.0 — the same license as this repository. See NOTICE and THIRD_PARTY_NOTICES.md for the file-by-file provenance and changes. This plugin is an independent derivative work and is not affiliated with, endorsed by, or sponsored by Xiaomi Inc. or the Home Assistant project.
What it gives the agent
Five brand-neutral tools; every call takes an optional brand key:
| Tool | Purpose |
|---|---|
iot_list_devices |
All devices on the account: did, name, model urn, online, home/room |
iot_get_spec |
Friendly MIoT spec of one device: services, properties (access/format/range/enum), actions (in/out) |
iot_get_props |
Read specific properties, or a whole-device snapshot (≤ 60 readable props) |
iot_set_prop |
Write one property: power, brightness, target temperature, mode… |
iot_call_action |
Run one action with positional in-arguments |
Plus a bundled skill (iot-studio) that teaches the agent the safe loop:
list → spec → read → act → verify, with explicit confirmation before touching
locks, cameras, power strips, heaters, and vacuums.
New devices: zero setup
Devices are discovered from the brand cloud account at call time. A sensor, lamp, or plug you paired yesterday in the brand app already works:
> 新买的加湿器能用吗? → iot_list_devices finds it → iot_get_spec → control it
No per-device configuration, no plugin restart, no code change.
New brands: one provider to register
A brand is one folder under src/brands/<name>/ implementing IotBrandProvider
(list devices, get spec, read/write properties, call actions) plus one
register() line in src/brands/registry.ts. Tool signatures, config shape,
auth-cache layout, and the skill contract stay identical, so agent behavior
transfers unchanged. A second brand's cloud settings will get their own
<brand>: config block beside xiaomi:.
Install
dsh plugin --profile web add https://github.com/CarryChang/dsh-iot-studio
Configure credentials (built-in brand: xiaomi)
Option A — environment (recommended, keeps secrets out of files):
XIAOMI_USERNAME=<phone/email/user id>
XIAOMI_PASSWORD=<password>
Option B — the plugin config block in your profile's cordis.yml:
- id: iot-studio
name: dsh-iot-studio
config:
defaultBrand: xiaomi
xiaomi:
username: 'you@example.com'
password: '...' # or leave empty and use XIAOMI_PASSWORD
serverCountry: cn # cn, de, ru, ...
stateDir: '' # token cache dir; default ~/.dsh-iot-studio
httpTimeoutSec: 15
On first use the plugin logs in and caches the service token under
stateDir (0600 permissions, never committed, never printed). With only a
valid cache and no password it keeps working until the token expires.
Try it
> 帮我看下家里现在有哪些米家设备在线?
> 把卧室台灯调到 40% 亮度
> 扫地机开始清扫客厅
Architecture (for brand contributors)
src/
index.ts plugin entry: Config + skill + 5 tools
skill.ts embedded IoT-control methodology
brands/
types.ts IotBrandProvider seam (brand-neutral DTOs)
registry.ts brand key -> provider factory
xiaomi/
crypto.ts RC4-skip-1024, nonce, HMAC-SHA1, SHA1 sign
cloud.ts login step1/2/3, signed api.io.mi.com requests
spec.ts miot-spec.org instance fetch + summary
provider.ts IotBrandProvider implementation
A new brand is one folder under src/brands/<name>/ plus one register() line;
tool signatures, config shape, and the skill contract stay identical. The tools
only ever see the IotBrandProvider interface.
Limitations (v0.1)
- Built-in providers: xiaomi only so far; the seam is generic and more brands land on request.
- Captcha / SMS / email verification during login is not interactive: the tool returns an actionable message asking you to sign in once at account.xiaomi.com or in the Mi Home app.
- Legacy miio-only devices (model is not a
urn:miot-spec-v2:...) are not supported; MIoT-spec devices only. - Cloud control only; no LAN/local token path yet.
- Mainland China and overseas Xiaomi server sites are supported via
serverCountry.
Development
pnpm install # needs access to the @deepseek-ai registry packages
pnpm run build # tsc -> lib/
pnpm run check # build + offline deterministic smoke
License
Apache License 2.0 (same as the upstream hass-xiaomi-miot). Third-party notices: NOTICE, THIRD_PARTY_NOTICES.md.
No comments yet. Be the first to write one.