Home Assistant Agent (Secure)
Control smart home devices by sending natural language to Home Assistant's Conversation (Assist) API.
Security model: This skill uses ONLY the /api/conversation/process endpoint. Do NOT use the token to call any other HA API endpoint. The token should belong to a restricted, non-admin Home Assistant user with access limited to specific areas and entities.
Important Security Rules
- - ONLY call
/api/conversation/process — never call /api/states, /api/services, /api/config, or any other endpoint - NEVER output or echo the token value
- NEVER use the token for any purpose other than the Assist API call below
- NEVER attempt to log in to Home Assistant via the browser or web UI — always use the API token
- If a user request cannot be handled by Assist, say so — do not fall back to other API calls
Important: Disable Trusted Networks Login Bypass
If your Home Assistant instance uses the trusted_networks auth provider with allow_bypass_login: true, any agent or user on the local network can log in as any HA user (including administrators) without a password. This completely bypasses the restricted-user security model of this skill.
To fix: In your HA configuration.yaml, set allow_bypass_login: false under the trusted_networks auth provider, or remove the trusted_networks provider entirely. Restart HA after making the change.
Setup
1. Create a Restricted Home Assistant User
- 1. In Home Assistant go to Settings → People → Add Person
- Create a new user (e.g.
openclaw-bot) - Do NOT make it an administrator
- Under Settings → Areas & Zones, assign only the areas this user should control
- Optionally restrict entity access using a custom group or dashboard-only permissions
2. Generate a Long-Lived Access Token
- 1. Log in to Home Assistant as the restricted user (
openclaw-bot) - Go to Profile (bottom-left)
- Scroll to Long-Lived Access Tokens
- Click Create Token, name it (e.g.
openclaw) - Copy the token immediately — it is shown only once
3. Configure OpenClaw
Set HOME_ASSISTANT_URL and HOME_ASSISTANT_TOKEN using any of the methods below. OpenClaw applies them in this precedence order (highest first): process environment → .env file → openclaw.json config. A value set by a higher-priority source is never overridden by a lower one.
Option A: .env file (recommended)
Add to ~/.openclaw/.env:
CODEBLOCK0
The URL can be a hostname (e.g. https://homeassistant.local) or an IP address (e.g. https://192.168.1.50:8123).
Option B: Config file
Add to ~/.openclaw/openclaw.json under skills.entries:
CODEBLOCK1
The apiKey field automatically maps to HOME_ASSISTANT_TOKEN via the skill's primaryEnv declaration.
Option C: Shell environment variables
Export in your shell profile (e.g. ~/.bashrc, ~/.zshrc):
CODEBLOCK2
Usage
Send any smart home command in natural language. The skill passes it directly to HA Assist:
CODEBLOCK3
The -k flag allows connections to HA instances using self-signed certificates. If your HA uses a trusted certificate (e.g. Let's Encrypt), you can remove it.
Set the language field based on the detected language of the user's input (e.g. "pl" for Polish, "en" for English, "de" for German, etc.).
Examples
- - "Turn on the living room lights" (English)
- "Włącz światło w salonie" (Polish)
- "Schalte das Licht im Wohnzimmer ein" (German)
- "Jaka jest temperatura w kuchni?" (Polish)
- "Turn off all lights in the bedroom" (English)
Inflected Language Handling (Nominative Retry)
Many languages use grammatical cases or word inflection, causing entity names to change form in natural speech. Home Assistant entity names are typically in their base/dictionary form (nominative), but users naturally use other grammatical forms in commands.
This affects languages including (but not limited to):
- - Polish — 7 cases (e.g. drukarkę → drukarka, lampę → lampa)
- Czech — 7 cases (e.g. tiskárnu → tiskárna, lampu → lampa)
- German — 4 cases + articles (e.g. den Drucker → Drucker, die Lampe → Lampe)
- Finnish — 15 cases (e.g. tulostinta → tulostin, lamppua → lamppu)
- Hungarian — 18 cases (e.g. nyomtatót → nyomtató, lámpát → lámpa)
- Russian — 6 cases (e.g. принтеру → принтер, лампу → лампа)
- Croatian/Serbian — 7 cases, similar patterns to Polish and Czech
Example: A user says "włącz drukarkę 3d" (Polish accusative), but the entity is named "drukarka 3d" (nominative). HA Assist won't find it.
Retry strategy: If HA responds with an error (no_valid_targets, no_intent_match, or a message indicating the entity was not found), and the user's input is in an inflected language:
- 1. Identify the entity name within the command
- Convert inflected words to their base/dictionary/nominative form
- Retry the API call with the corrected form
- If the retry also fails, report the error to the user
Important: Only retry once. Do not loop. If the nominative retry also fails, inform the user that the entity was not found.
Handling Responses
The response is in response.speech.plain.speech. Relay it directly to the user:
- -
"Turned on the light" → success - INLINECODE38 → Assist couldn't parse the request
- INLINECODE39 → ambiguous entity name
On errors (response_type: "error")
| Error | What to tell the user |
|---|
| INLINECODE41 | Try nominative retry (if inflected language). If still fails: "Home Assistant didn't recognize that command." |
| INLINECODE42 |
Try nominative retry (if inflected language). If still fails: "Entity not found — check the device name or add an alias in HA." |
| Multiple matches | "Multiple devices share that name — consider adding unique aliases in HA." |
Troubleshooting
- - 401 Unauthorized: Token is invalid or expired. Generate a new one from the restricted user's profile.
- Connection refused: Check that
HOME_ASSISTANT_URL is correct and HA is reachable. - Command not understood: Rephrase the request or check that the entity is exposed to the restricted user.
- Entity not found: The restricted user may not have access to that area/entity. Update permissions in HA.
API Reference
Endpoint
CODEBLOCK4
Note: Use /api/conversation/process, NOT /api/services/conversation/process.
Request Body
CODEBLOCK5
Polish example:
CODEBLOCK6
Success Response
CODEBLOCK7
Home Assistant Agent (Secure)
通过向 Home Assistant 的对话(Assist)API 发送自然语言来控制智能家居设备。
安全模型: 此技能仅使用 /api/conversation/process 端点。请勿使用该令牌调用任何其他 HA API 端点。该令牌应属于一个受限的、非管理员 Home Assistant 用户,其访问权限仅限于特定的区域和实体。
重要安全规则
- - 仅调用 /api/conversation/process — 切勿调用 /api/states、/api/services、/api/config 或任何其他端点
- 切勿输出或回显令牌值
- 切勿将令牌用于除下方 Assist API 调用之外的任何目的
- 切勿尝试通过浏览器或 Web UI 登录 Home Assistant — 始终使用 API 令牌
- 如果 Assist 无法处理用户请求,请如实告知 — 不要回退到其他 API 调用
重要提示:禁用受信任网络登录绕过
如果您的 Home Assistant 实例使用 trustednetworks 认证提供程序并设置了 allowbypass_login: true,则本地网络上的任何代理或用户都可以在无需密码的情况下以任何 HA 用户(包括管理员)的身份登录。这将完全绕过此技能的受限用户安全模型。
解决方法: 在您的 HA configuration.yaml 文件中,在 trustednetworks 认证提供程序下设置 allowbypasslogin: false,或者完全移除 trustednetworks 提供程序。更改后重启 HA。
设置
1. 创建受限 Home Assistant 用户
- 1. 在 Home Assistant 中,前往 设置 → 人员 → 添加人员
- 创建一个新用户(例如 openclaw-bot)
- 不要将其设为管理员
- 在 设置 → 区域与区域 下,仅分配此用户应控制的区域
- 可选:使用自定义组或仅仪表板权限限制实体访问
2. 生成长期访问令牌
- 1. 以受限用户身份(openclaw-bot)登录 Home Assistant
- 前往 个人资料(左下角)
- 滚动到 长期访问令牌
- 点击 创建令牌,为其命名(例如 openclaw)
- 立即复制令牌 — 它只会显示一次
3. 配置 OpenClaw
使用以下任一方法设置 HOMEASSISTANTURL 和 HOMEASSISTANTTOKEN。OpenClaw 按以下优先级顺序应用它们(最高优先):进程环境 → .env 文件 → openclaw.json 配置。由较高优先级源设置的值永远不会被较低优先级源覆盖。
选项 A:.env 文件(推荐)
添加到 ~/.openclaw/.env:
bash
HOMEASSISTANTURL=https://your-ha-instance.local
HOMEASSISTANTTOKEN=your-restricted-user-token-here
URL 可以是主机名(例如 https://homeassistant.local)或 IP 地址(例如 https://192.168.1.50:8123)。
选项 B:配置文件
添加到 ~/.openclaw/openclaw.json 的 skills.entries 下:
json
{
skills: {
entries: {
home-assistant-agent-secure: {
apiKey: your-restricted-user-token-here,
env: {
HOMEASSISTANTURL: https://your-ha-instance.local
}
}
}
}
}
apiKey 字段通过技能的 primaryEnv 声明自动映射到 HOMEASSISTANTTOKEN。
选项 C:Shell 环境变量
在您的 shell 配置文件(例如 ~/.bashrc、~/.zshrc)中导出:
bash
export HOMEASSISTANTURL=https://your-ha-instance.local
export HOMEASSISTANTTOKEN=your-restricted-user-token-here
使用方法
以自然语言发送任何智能家居命令。该技能将其直接传递给 HA Assist:
bash
curl -sk -X POST $HOMEASSISTANTURL/api/conversation/process \
-H Authorization: Bearer $HOMEASSISTANTTOKEN \
-H Content-Type: application/json \
-d {text: 用户请求内容, language: 检测到的语言代码}
-k 标志允许连接到使用自签名证书的 HA 实例。如果您的 HA 使用受信任的证书(例如 Lets Encrypt),您可以移除它。
根据检测到的用户输入语言设置 language 字段(例如波兰语为 pl,英语为 en,德语为 de 等)。
示例
- - 打开客厅的灯(英语)
- Włącz światło w salonie(波兰语)
- Schalte das Licht im Wohnzimmer ein(德语)
- Jaka jest temperatura w kuchni?(波兰语)
- 关闭卧室所有灯(英语)
屈折语言处理(主格重试)
许多语言使用语法格或词形变化,导致实体名称在自然语言中改变形式。Home Assistant 实体名称通常采用其基本/词典形式(主格),但用户在命令中自然使用其他语法形式。
这影响的语言包括(但不限于):
- - 波兰语 — 7 个格(例如 drukarkę → drukarka,lampę → lampa)
- 捷克语 — 7 个格(例如 tiskárnu → tiskárna,lampu → lampa)
- 德语 — 4 个格 + 冠词(例如 den Drucker → Drucker,die Lampe → Lampe)
- 芬兰语 — 15 个格(例如 tulostinta → tulostin,lamppua → lamppu)
- 匈牙利语 — 18 个格(例如 nyomtatót → nyomtató,lámpát → lámpa)
- 俄语 — 6 个格(例如 принтеру → принтер,лампу → лампа)
- 克罗地亚语/塞尔维亚语 — 7 个格,模式与波兰语和捷克语相似
示例: 用户说 włącz drukarkę 3d(波兰语宾格),但实体名为 drukarka 3d(主格)。HA Assist 将无法找到它。
重试策略: 如果 HA 返回错误(novalidtargets、nointentmatch 或指示未找到实体的消息),并且用户输入使用的是屈折语言:
- 1. 识别命令中的实体名称
- 将屈折词转换为其基本/词典/主格形式
- 使用修正后的形式重试 API 调用
- 如果重试也失败,向用户报告错误
重要提示: 仅重试一次。不要循环。如果主格重试也失败,请告知用户未找到该实体。
处理响应
响应位于 response.speech.plain.speech 中。将其直接转达给用户:
- - 已打开灯 → 成功
- 抱歉,我无法理解 → Assist 无法解析请求
- 抱歉,有多个名为 X 的设备 → 实体名称不明确
错误时(response_type: error)
| 错误 | 告知用户的内容 |
|---|
| nointentmatch | 尝试主格重试(如果是屈折语言)。如果仍然失败:Home Assistant 未识别该命令。 |
| novalidtargets |
尝试主格重试(如果是屈折语言)。如果仍然失败:未找到实体 — 请检查设备名称或在 HA 中添加别名。 |
| 多个匹配 | 多个设备共享该名称 — 考虑在 HA 中添加唯一别名。 |
故障排除
- - 401 未授权:令牌无效或已过期。从受限用户的个人资料生成新令牌。
- 连接被拒绝:检查 HOMEASSISTANTURL 是否正确且 HA 可访问。
- 命令无法理解:重新表述请求,或检查实体是否已暴露给受限用户。
- 未找到实体:受限用户可能无权访问该区域/实体。在 HA 中更新权限。
API 参考
端点
POST /api/conversation/process
注意: 使用 /api/conversation/process,而不是 /api/services/conversation/process。
请求体
json
{
text: 打开厨房灯,
language: zh