Skip to content

dsh-smarthome

Verified

dsh-smarthome · v1.4.0 · MIT · Web UI

Home Assistant control for DeepSeek Harness agents — read entity states, query history, and call services behind an approval gate.

Install

dsh plugin add dsh-smarthome

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Published to npm without a public repository. Inspect the package contents before installing.

Tags

Readme

dsh-smarthome

DeepSeek Harness agent 的 Home Assistant 控制插件。
读取实体状态 · 查询历史 · 调用服务——所有改变状态的调用都经过人工审批闸门。

English · dsh-plugin · MIT · CI

除 harness 本身外零运行时依赖。使用 Home Assistant 内置 REST API——不需要 MQTT、WebSocket 或额外守护进程。


✨ 效果预览

点击图片可打开在线演示 —— docs/demo.html 会模拟完整的 DSH 对话,右侧实时控制台直连自带的 HA 模拟器(不需要真实 Home Assistant)。

① 提问 ② 审批闸门 ③ 完成——状态真的变了
开始 审批 完成
agent 用 ha_list_entities 列出你的灯。 ha_call_service 暂停,弹出人工审批框。 批准后 ha_get_state 确认灯已打开。

还有 Web UI 仪表盘卡片 —— 调用 ha_dashboard,全屋状态直接渲染在对话里:

家庭仪表盘

它接入的就是这样的 Home Assistant(典型智能家居仪表盘,示意图):

Home Assistant 仪表盘示意图

🎯 能做什么?

像跟管家说话一样指挥你的家——所有写操作都先经过人工审批。

你说 会发生什么
「检查一下全屋,哪些设备还开着?」 agent 用 ha_list_entities / ha_get_state 扫描并汇总
「给我看看家庭仪表盘。」 ha_dashboard 在对话里渲染实时仪表盘卡片——设备、场景、最近变化一览无余
「等洗衣机洗完,然后推送到我手机。」 ha_wait_for_state 轮询到完成 → ha_notify 推送到 HA
「明天天气怎么样,要带伞吗?」 ha_weather 返回结构化预报
「把卧室灯调到 200 亮度。」 ha_call_service审批弹窗 → 执行 → 状态即时更新
「关掉客厅里所有的灯。」 区域定位——一次调用控制整间房
「开启电影模式。」 场景联动:灯调暗、电视打开——一条命令多设备联动(ha_events 实时显示每个变化)
「过去一小时家里发生了什么变化?」 WebSocket 实时事件流
「客厅温度够吗?和卧室比一下。」 ha_get_state / ha_render_template 查传感器、算模板
「我要出门了,把一切都关掉。」 一个场景(scene.away)或批量实体调用

💡 为什么好用?

  • 一行安装dsh plugin --profile web add dsh-smarthome,装完直接说话
  • 安全默认:所有改变状态的调用都停在人工审批前;allowedDomains 域白名单是第二道保险——agent 不经你同意永远碰不了你的家
  • 自然语言控制:不用翻 App、不用记 API,一句「把灯调暗」就搞定
  • 状态永远新鲜:WebSocket 实时推送,agent 不会"以为"灯还开着
  • 轻量:零运行时依赖——纯 REST + Node 内置 WebSocket,没有 MQTT、没有额外守护进程
  • 没有 Home Assistant 也能玩:自带演示模拟器 + 交互演示页,5 分钟完整感受
  • 工程化而非拼凑:36 个测试(含完整真实 agent-loop 端到端)、严格 TypeScript、CI

💻 你的电脑就是控制中心

dsh-smarthome 就装在跑 dsh 的这台电脑上——不用手机 App、不用额外网关、不用切换上下文:

  • 👀 边工作边监控 —— ha_dashboard 仪表盘卡片 + ha_events 实时事件,全屋状态一直显示在编辑器旁边:什么开着、刚发生了什么,一目了然
  • 🎙️ 语音控制 —— 再给 dsh 接一个社区语音插件(在 dsh-plugin topic 里搜 voice;如 dsh-voice 零 key 语音输入+朗读、dsh-voice-chat 实时语音对话),直接开口说话:「把卧室灯调到 200」→ 审批 → 完成——打字的同时动动嘴就控制全家
  • 🖥️ 一个窗口全搞定 —— 写代码、看家、控设备,全程不离开 dsh。所有改变状态的调用依然要你批准

🛠 功能

工具 说明 审批
ha_health 验证连接;返回实例名、版本、时区、WebSocket 状态 只读
ha_list_entities 列出实体,按 domain(lightswitchsensor…)和文本过滤 只读
ha_list_areas 通过 WebSocket 列出房间(区域),如 living_room 只读
ha_list_devices 通过 WebSocket 设备注册表列出物理设备 只读
ha_get_state 单个实体的完整状态与属性 只读
ha_history 一段时间内的状态变化时间线 只读
ha_events WebSocket 缓冲的最近实时状态变化 只读
ha_list_scenes 列出一键场景(cinemagoodnightaway…) 只读
ha_dashboard 全屋快照,在 Web UI 里渲染为仪表盘卡片 只读
ha_wait_for_state 轮询等待实体达到/离开某状态(等洗衣机停、等温度到位…) 只读
ha_notify 通过 Home Assistant 发通知(持久通知 / 手机 / 音箱) 不设闸
ha_weather 天气实体 + 结构化预报 只读
ha_call_service 调用任意服务——按实体、按区域(整间房)、按设备、按场景 需批准
ha_render_template 服务端渲染 Jinja2 模板 需批准

示例提示词:

「检查 Home Assistant 是否在线,然后列出客厅的灯。」

「把客厅灯调到 60% 亮度。」(会触发审批请求)

「给我看过去 24 小时锅炉开关的历史记录。」

「关掉卧室里所有的灯。」(区域定位——一次调用,整间房)

「开启电影模式。」(场景联动——灯调暗、电视打开)

「过去一小时家里发生了什么变化?」(实时 ha_events

📦 安装

需要 dsh ≥ 0.1.0-rc.6(当前 npm latest)。

# 从 npm 安装(推荐,预构建产物):
dsh plugin --profile web add dsh-smarthome

# 或从 GitHub 安装(源码安装,pnpm 会在安装时自动构建):
# dsh plugin --profile web add github:YLifeOnlyOnce/dsh-smarthome
# 如果 pnpm 拒绝运行 git 依赖的 prepare 构建脚本,需要放行一次:
#   在 <profile>/pnpm-workspace.yaml 里加上,然后重新执行 add:
#     allowBuilds:
#       dsh-smarthome: true

安装后重启 dsh --profile web。可在 Settings → Plugins 管理。

🧪 没有 Home Assistant?先玩演示模式

仓库自带一个假的 HA 模拟器:一个会"动"的演示小家——调用服务真的会改变实体状态,适合在接真实硬件之前完整体验插件。

git clone https://github.com/YLifeOnlyOnce/dsh-smarthome
cd dsh-smarthome
pnpm install
pnpm demo:ha          # 在 http://127.0.0.1:8124 起一个假的 Home Assistant

另开一个终端,在 profile 的 cordis.patch.yml 里配置插件:

- id: smarthome
  config:
    baseUrl: http://127.0.0.1:8124
    tokenEnv: HOME_ASSISTANT_TOKEN

然后启动 dsh 试试:

HOME_ASSISTANT_TOKEN=demo-token dsh --profile web

「检查 Home Assistant 是否在线,然后列出所有灯。」

「把卧室灯调到 200 亮度。」——会弹出审批请求;批准后 ha_get_state 会显示灯确实是 on,且 brightness: 200

「关掉客厅里所有的灯。」——通过 WebSocket 区域注册表做区域定位。

「过去一分钟发生了什么变化?」——WebSocket 实时 state_changed 事件。

模拟器里的温度传感器每几秒漂移一次,所以 ha_historyha_events 永远有新数据。任意 Bearer token 都行,demo-token 只是约定俗成。

想完全不启动 dsh 就先看效果? 用浏览器打开 docs/demo.html:它会回放一段模拟的 DSH 对话(工具卡片 + 审批弹窗),模拟器运行时右侧实时控制台还会直连它做真实调用。

可直接粘贴的配置(演示模式 / 真实 HA / 关闭审批)见 examples/cordis.patch.yml

⚙️ 配置

在 Home Assistant 中创建长期访问令牌:个人资料 → 安全 → 长期访问令牌

在 profile 的 cordis.patch.yml 中覆盖插件配置(后层覆盖前层):

- id: smarthome
  config:
    baseUrl: http://192.168.1.10:8123   # 你的 Home Assistant 实例
    token: ''                           # 建议用 tokenEnv,不要把令牌写进配置
    tokenEnv: HOME_ASSISTANT_TOKEN      # 存放令牌的环境变量名
    timeoutMs: 15000
    requireApproval: true               # 改变状态的调用需要人工批准
    allowedDomains: []                  # 例如 ["light", "switch"];留空 = 允许所有 domain
    maxHistoryEvents: 200
    wsEnabled: true                     # 实时事件 + 区域注册表(WebSocket)
    eventBufferSize: 50                 # ha_events 滚动缓冲大小

然后带上环境变量启动:

HOME_ASSISTANT_TOKEN=<token> dsh --profile web

baseUrl 默认为 http://homeassistant.local:8123(Home Assistant 标准 mDNS 地址)。未配置令牌时插件仍会加载——每次调用都会给出清晰的「未配置」错误,而不是让 harness 崩溃。

令牌如何解析

tokenEnv 是一个凭证引用,通过 harness 的凭证接缝解析:存在 credentials 服务时,从分层来源读取(进程环境 → <cwd>/.env$DSH_HOME/.env),否则直接回退到 process.env。令牌每次请求 / 每次连接都会重新解析,轮换凭证无需重启立即生效。

🔒 安全说明

  • Home Assistant 令牌可以控制实例里的一切——没有按实体授权的粒度。因此 requireApproval 默认为 trueha_call_service / ha_render_template 永远走 harness 的审批接缝。
  • allowedDomains 是第二道保险:设置后,其他 domain 的服务调用会被直接拒绝。
  • 优先用 tokenEnv 而不是 token,避免密钥进 Git 提交。

🛠 开发

pnpm install
pnpm typecheck   # 针对已发布的 @deepseek-ai/* 类型做严格 TS 检查
pnpm build       # 打包 lib/(ESM + d.ts)
pnpm test        # 24 个测试:客户端 + 真实 ToolRuntime 集成 + 完整 agent-loop 端到端
node scripts/capture-demo.mjs   # 重新生成 README 截图

📋 兼容性

真实 Home Assistant 兼容性

  • 使用 v1 REST API/api/states/api/services/…/api/history/…/api/template/api/config)和 WebSocket API/api/websocket:认证、subscribe_eventsconfig/area_registry/listconfig/device_registry/list)——与官方 HA 前端同协议。
  • 需要长期访问令牌(个人资料 → 安全 → 长期访问令牌)。
  • 注意事项:不支持自签名 HTTPS 证书(请用 http:// 或有效证书);受限制的令牌(无法调用服务)会导致 ha_call_service 失败。

DeepSeek Harness 处于 developer preview,迭代很快。本插件已针对 npm 发布的 @deepseek-ai/[email protected] 验证;如果 harness 更新导致不兼容,请提 issue。

📄 许可证

MIT