Skip to main content

Home Assistant 集成

Hermes Agent 通过两种方式与 Home Assistant 集成:

  1. 网关平台 —— 通过 WebSocket 订阅实时状态变化,并响应事件
  2. 智能家居工具 —— 四个可通过大语言模型调用的工具,通过 REST API 查询和控制设备

设置步骤

1. 创建长期访问令牌

  1. 打开您的 Home Assistant 实例
  2. 进入您的 个人资料(点击侧边栏中的用户名)
  3. 滚动至 长期访问令牌
  4. 点击 创建令牌,为其命名如 "Hermes Agent"
  5. 复制生成的令牌

2. 配置环境变量

# Add to ~/.hermes/.env

# Required: your Long-Lived Access Token
HASS_TOKEN=your-long-lived-access-token

# Optional: HA URL (default: http://homeassistant.local:8123)
HASS_URL=http://192.168.1.100:8123
info

当设置 HASS_TOKEN 时,homeassistant 工具集会自动启用。该单一令牌同时激活网关平台和设备控制工具。

3. 启动网关

hermes gateway

启动后,Home Assistant 将作为已连接的平台之一,与其他消息平台(如 Telegram、Discord 等)并列显示。

可用工具

Hermes Agent 注册了四个用于智能家居控制的工具:

ha_list_entities

列出 Home Assistant 中的所有实体,可按领域或区域进行筛选。

参数:

  • domain (可选) —— 按实体领域过滤:lightswitchclimatesensorbinary_sensorcoverfanmedia_player
  • area (可选) —— 按区域/房间名称过滤(匹配友好名称):living roomkitchenbedroom

示例:

List all lights in the living room

返回实体 ID、状态及友好名称。

ha_get_state

获取单个实体的详细状态,包括所有属性(亮度、颜色、温度设定点、传感器读数等)。

参数:

  • entity_id (必填) —— 要查询的实体,例如 light.living_roomclimate.thermostatsensor.temperature

示例:

What's the current state of climate.thermostat?

返回:状态、所有属性、最后更改/更新时间戳。

ha_list_services

列出可用的服务(操作),展示每种设备类型可执行的动作及其接受的参数。

参数:

  • domain (可选) —— 按领域过滤,例如 lightclimateswitch

示例:

What services are available for climate devices?

ha_call_service

调用 Home Assistant 的服务以控制设备。

参数:

  • domain (必填) —— 服务领域:lightswitchclimatecovermedia_playerfanscenescript
  • service (必填) —— 服务名称:turn_onturn_offtoggleset_temperatureset_hvac_modeopen_coverclose_coverset_volume_level
  • entity_id (可选) —— 目标实体,例如 light.living_room
  • data (可选) —— 额外参数,以 JSON 对象形式提供

示例:

Turn on the living room lights
→ ha_call_service(domain="light", service="turn_on", entity_id="light.living_room")
Set the thermostat to 22 degrees in heat mode
→ ha_call_service(domain="climate", service="set_temperature",
entity_id="climate.thermostat", data={"temperature": 22, "hvac_mode": "heat"})
Set living room lights to blue at 50% brightness
→ ha_call_service(domain="light", service="turn_on",
entity_id="light.living_room", data={"brightness": 128, "color_name": "blue"})

网关平台:实时事件

Home Assistant 网关适配器通过 WebSocket 连接,并订阅 state_changed 事件。当设备状态发生变化且符合您的过滤条件时,该事件将被转发给代理作为消息。

事件过滤

必需配置

默认情况下,不会转发任何事件。您必须至少配置 watch_domainswatch_entitieswatch_all 之一才能接收事件。若未设置过滤器,启动时将记录警告信息,所有状态变更将被静默丢弃。

~/.hermes/config.yaml 中配置代理可见的事件,位于 Home Assistant 平台的 extra 部分:

platforms:
homeassistant:
enabled: true
extra:
watch_domains:
- climate
- binary_sensor
- alarm_control_panel
- light
watch_entities:
- sensor.front_door_battery
ignore_entities:
- sensor.uptime
- sensor.cpu_usage
- sensor.memory_usage
cooldown_seconds: 30
设置项默认值说明
watch_domains(无)仅监控这些实体领域(如 climatelightbinary_sensor
watch_entities(无)仅监控这些特定实体 ID
watch_allfalse设为 true 以接收 全部 状态变更(不推荐大多数场景)
ignore_entities(无)始终忽略这些实体(在领域/实体过滤前应用)
cooldown_seconds30同一实体事件之间的最小间隔秒数
tip

建议从少量核心领域开始——climatebinary_sensoralarm_control_panel 覆盖了最常用的自动化场景。根据需要逐步添加更多。使用 ignore_entities 来屏蔽噪声较大的传感器(如 CPU 温度或运行时间计数器)。

事件格式化

状态变更将以人类可读的消息格式呈现,具体取决于领域:

领域格式
climate“HVAC 模式从 'off' 变更为 'heat'(当前:21,目标:23)”
sensor“从 21°C 变更为 22°C”
binary_sensor“触发” / “清除”
lightswitchfan“开启” / “关闭”
alarm_control_panel“报警状态从 'armed_away' 变更为 'triggered'”
(其他)“从 '旧值' 变更为 '新值'”

代理响应

代理发出的出站消息将以 Home Assistant 持久通知 形式发送(通过 persistent_notification.create)。这些通知将在 HA 通知面板中显示,标题为“Hermes Agent”。

连接管理

  • WebSocket,30 秒心跳维持实时事件连接
  • 自动重连,采用退避机制:5s → 10s → 30s → 60s
  • REST API 用于出站通知(独立会话,避免与 WebSocket 冲突)
  • 授权机制 —— HA 事件始终受授权保护(无需用户白名单,因 HASS_TOKEN 已验证连接身份)

安全性

Home Assistant 工具强制实施安全限制:

被阻止的领域

以下服务领域被 禁止,以防止在 HA 主机上执行任意代码:

  • shell_command —— 任意 shell 命令执行
  • command_line —— 执行命令的传感器/开关
  • python_script —— 脚本化 Python 执行
  • pyscript —— 更广泛的脚本集成
  • hassio —— 插件控制、主机关机/重启
  • rest_command —— 由 HA 服务器发起的 HTTP 请求(存在 SSRF 风险)

尝试调用这些领域的服务将返回错误。

实体 ID 会根据模式 ^[a-z_][a-z0-9_]*\.[a-z0-9_]+$ 进行验证,以防止注入攻击。

示例自动化

早晨例行程序

User: Start my morning routine

Agent:
1. ha_call_service(domain="light", service="turn_on",
entity_id="light.bedroom", data={"brightness": 128})
2. ha_call_service(domain="climate", service="set_temperature",
entity_id="climate.thermostat", data={"temperature": 22})
3. ha_call_service(domain="media_player", service="turn_on",
entity_id="media_player.kitchen_speaker")

安全检查

User: Is the house secure?

Agent:
1. ha_list_entities(domain="binary_sensor")
→ checks door/window sensors
2. ha_get_state(entity_id="alarm_control_panel.home")
→ checks alarm status
3. ha_list_entities(domain="lock")
→ checks lock states
4. Reports: "All doors closed, alarm is armed_away, all locks engaged."

反应式自动化(通过网关事件实现)

当作为网关平台连接时,代理可对事件做出反应:

[Home Assistant] Front Door: triggered (was cleared)

Agent automatically:
1. ha_get_state(entity_id="binary_sensor.front_door")
2. ha_call_service(domain="light", service="turn_on",
entity_id="light.hallway")
3. Sends notification: "Front door opened. Hallway lights turned on."