New pages (sourced from actual codebase): - Security: command approval, DM pairing, container isolation, production checklist - Session Management: resume, export, prune, search, per-platform tracking - Context Files: AGENTS.md project context, discovery, size limits, security - Personality: SOUL.md, 14 built-in personalities, custom definitions - Browser Automation: Browserbase setup, 10 browser tools, stealth mode - Image Generation: FLUX 2 Pro via FAL, aspect ratios, auto-upscaling - Provider Routing: OpenRouter sort/only/ignore/order config - Honcho: AI-native memory integration, setup, peer config - Home Assistant: HASS setup, 4 HA tools, WebSocket gateway - Batch Processing: trajectory generation, dataset format, checkpointing - RL Training: Atropos/Tinker integration, environments, workflow Expanded pages: - code-execution: 51 → 195 lines (examples, limits, security, comparison table) - delegation: 60 → 216 lines (context tips, batch mode, model override) - cron: 88 → 273 lines (real-world examples, delivery options, expression cheat sheet) - memory: 98 → 249 lines (best practices, capacity management, examples)
239 lines
7.7 KiB
Markdown
239 lines
7.7 KiB
Markdown
---
|
|
title: Home Assistant
|
|
description: Control your smart home with Hermes Agent via Home Assistant integration.
|
|
sidebar_label: Home Assistant
|
|
sidebar_position: 5
|
|
---
|
|
|
|
# Home Assistant Integration
|
|
|
|
Hermes Agent integrates with [Home Assistant](https://www.home-assistant.io/) in two ways:
|
|
|
|
1. **Gateway platform** — subscribes to real-time state changes via WebSocket and responds to events
|
|
2. **Smart home tools** — four LLM-callable tools for querying and controlling devices via the REST API
|
|
|
|
## Setup
|
|
|
|
### 1. Create a Long-Lived Access Token
|
|
|
|
1. Open your Home Assistant instance
|
|
2. Go to your **Profile** (click your name in the sidebar)
|
|
3. Scroll to **Long-Lived Access Tokens**
|
|
4. Click **Create Token**, give it a name like "Hermes Agent"
|
|
5. Copy the token
|
|
|
|
### 2. Configure Environment Variables
|
|
|
|
```bash
|
|
# 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
|
|
The `homeassistant` toolset is automatically enabled when `HASS_TOKEN` is set. Both the gateway platform and the device control tools activate from this single token.
|
|
:::
|
|
|
|
### 3. Start the Gateway
|
|
|
|
```bash
|
|
hermes gateway
|
|
```
|
|
|
|
Home Assistant will appear as a connected platform alongside any other messaging platforms (Telegram, Discord, etc.).
|
|
|
|
## Available Tools
|
|
|
|
Hermes Agent registers four tools for smart home control:
|
|
|
|
### `ha_list_entities`
|
|
|
|
List Home Assistant entities, optionally filtered by domain or area.
|
|
|
|
**Parameters:**
|
|
- `domain` *(optional)* — Filter by entity domain: `light`, `switch`, `climate`, `sensor`, `binary_sensor`, `cover`, `fan`, `media_player`, etc.
|
|
- `area` *(optional)* — Filter by area/room name (matches against friendly names): `living room`, `kitchen`, `bedroom`, etc.
|
|
|
|
**Example:**
|
|
```
|
|
List all lights in the living room
|
|
```
|
|
|
|
Returns entity IDs, states, and friendly names.
|
|
|
|
### `ha_get_state`
|
|
|
|
Get detailed state of a single entity, including all attributes (brightness, color, temperature setpoint, sensor readings, etc.).
|
|
|
|
**Parameters:**
|
|
- `entity_id` *(required)* — The entity to query, e.g., `light.living_room`, `climate.thermostat`, `sensor.temperature`
|
|
|
|
**Example:**
|
|
```
|
|
What's the current state of climate.thermostat?
|
|
```
|
|
|
|
Returns: state, all attributes, last changed/updated timestamps.
|
|
|
|
### `ha_list_services`
|
|
|
|
List available services (actions) for device control. Shows what actions can be performed on each device type and what parameters they accept.
|
|
|
|
**Parameters:**
|
|
- `domain` *(optional)* — Filter by domain, e.g., `light`, `climate`, `switch`
|
|
|
|
**Example:**
|
|
```
|
|
What services are available for climate devices?
|
|
```
|
|
|
|
### `ha_call_service`
|
|
|
|
Call a Home Assistant service to control a device.
|
|
|
|
**Parameters:**
|
|
- `domain` *(required)* — Service domain: `light`, `switch`, `climate`, `cover`, `media_player`, `fan`, `scene`, `script`
|
|
- `service` *(required)* — Service name: `turn_on`, `turn_off`, `toggle`, `set_temperature`, `set_hvac_mode`, `open_cover`, `close_cover`, `set_volume_level`
|
|
- `entity_id` *(optional)* — Target entity, e.g., `light.living_room`
|
|
- `data` *(optional)* — Additional parameters as a JSON object
|
|
|
|
**Examples:**
|
|
|
|
```
|
|
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"})
|
|
```
|
|
|
|
## Gateway Platform: Real-Time Events
|
|
|
|
The Home Assistant gateway adapter connects via WebSocket and subscribes to `state_changed` events. When a device state changes, it's forwarded to the agent as a message.
|
|
|
|
### Event Filtering
|
|
|
|
Configure which events the agent sees via platform config in the gateway:
|
|
|
|
```python
|
|
# In platform extra config
|
|
{
|
|
"watch_domains": ["climate", "binary_sensor", "alarm_control_panel"],
|
|
"watch_entities": ["sensor.front_door"],
|
|
"ignore_entities": ["sensor.uptime", "sensor.cpu_usage"],
|
|
"cooldown_seconds": 30
|
|
}
|
|
```
|
|
|
|
| Setting | Default | Description |
|
|
|---------|---------|-------------|
|
|
| `watch_domains` | *(all)* | Only watch these entity domains |
|
|
| `watch_entities` | *(all)* | Only watch these specific entities |
|
|
| `ignore_entities` | *(none)* | Always ignore these entities |
|
|
| `cooldown_seconds` | `30` | Minimum seconds between events for the same entity |
|
|
|
|
:::tip
|
|
Without any filters, the agent receives **all** state changes, which can be noisy. For practical use, set `watch_domains` to the domains you care about (e.g., `climate`, `binary_sensor`, `alarm_control_panel`).
|
|
:::
|
|
|
|
### Event Formatting
|
|
|
|
State changes are formatted as human-readable messages based on domain:
|
|
|
|
| Domain | Format |
|
|
|--------|--------|
|
|
| `climate` | "HVAC mode changed from 'off' to 'heat' (current: 21, target: 23)" |
|
|
| `sensor` | "changed from 21°C to 22°C" |
|
|
| `binary_sensor` | "triggered" / "cleared" |
|
|
| `light`, `switch`, `fan` | "turned on" / "turned off" |
|
|
| `alarm_control_panel` | "alarm state changed from 'armed_away' to 'triggered'" |
|
|
| *(other)* | "changed from 'old' to 'new'" |
|
|
|
|
### Agent Responses
|
|
|
|
Outbound messages from the agent are delivered as **Home Assistant persistent notifications** (via `persistent_notification.create`). These appear in the HA notification panel with the title "Hermes Agent".
|
|
|
|
### Connection Management
|
|
|
|
- **WebSocket** with 30-second heartbeat for real-time events
|
|
- **Automatic reconnection** with backoff: 5s → 10s → 30s → 60s
|
|
- **REST API** for outbound notifications (separate session to avoid WebSocket conflicts)
|
|
- **Authorization** — HA events are always authorized (no user allowlist needed, since the `HASS_TOKEN` authenticates the connection)
|
|
|
|
## Security
|
|
|
|
The Home Assistant tools enforce security restrictions:
|
|
|
|
:::warning Blocked Domains
|
|
The following service domains are **blocked** to prevent arbitrary code execution on the HA host:
|
|
|
|
- `shell_command` — arbitrary shell commands
|
|
- `command_line` — sensors/switches that execute commands
|
|
- `python_script` — scripted Python execution
|
|
- `pyscript` — broader scripting integration
|
|
- `hassio` — addon control, host shutdown/reboot
|
|
- `rest_command` — HTTP requests from HA server (SSRF vector)
|
|
|
|
Attempting to call services in these domains returns an error.
|
|
:::
|
|
|
|
Entity IDs are validated against the pattern `^[a-z_][a-z0-9_]*\.[a-z0-9_]+$` to prevent injection attacks.
|
|
|
|
## Example Automations
|
|
|
|
### Morning Routine
|
|
|
|
```
|
|
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")
|
|
```
|
|
|
|
### Security Check
|
|
|
|
```
|
|
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."
|
|
```
|
|
|
|
### Reactive Automation (via Gateway Events)
|
|
|
|
When connected as a gateway platform, the agent can react to events:
|
|
|
|
```
|
|
[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."
|
|
```
|