Initial commit with translated description

This commit is contained in:
2026-03-29 09:46:25 +08:00
commit bdfce0a24a
4 changed files with 528 additions and 0 deletions

175
SKILL.md Normal file
View File

@@ -0,0 +1,175 @@
---
name: home-assistant
description: "控制Home Assistant智能家居设备、运行自动化和接收Webhook事件。"
metadata: {"clawdbot":{"emoji":"🏠","requires":{"bins":["jq","curl"]}}}
---
# Home Assistant
Control your smart home via Home Assistant's REST API and webhooks.
## Setup
### Option 1: Config File (Recommended)
Create `~/.config/home-assistant/config.json`:
```json
{
"url": "https://your-ha-instance.duckdns.org",
"token": "your-long-lived-access-token"
}
```
### Option 2: Environment Variables
```bash
export HA_URL="http://homeassistant.local:8123"
export HA_TOKEN="your-long-lived-access-token"
```
### Getting a Long-Lived Access Token
1. Open Home Assistant → Profile (bottom left)
2. Scroll to "Long-Lived Access Tokens"
3. Click "Create Token", name it (e.g., "Clawdbot")
4. Copy the token immediately (shown only once)
## Quick Reference
### List Entities
```bash
curl -s -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/states" | jq '.[].entity_id'
```
### Get Entity State
```bash
curl -s -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/states/light.living_room"
```
### Control Devices
```bash
# Turn on
curl -X POST -H "Authorization: Bearer $HA_TOKEN" -H "Content-Type: application/json" \
"$HA_URL/api/services/light/turn_on" -d '{"entity_id": "light.living_room"}'
# Turn off
curl -X POST -H "Authorization: Bearer $HA_TOKEN" -H "Content-Type: application/json" \
"$HA_URL/api/services/light/turn_off" -d '{"entity_id": "light.living_room"}'
# Set brightness (0-255)
curl -X POST -H "Authorization: Bearer $HA_TOKEN" -H "Content-Type: application/json" \
"$HA_URL/api/services/light/turn_on" -d '{"entity_id": "light.living_room", "brightness": 128}'
```
### Run Scripts & Automations
```bash
# Trigger script
curl -X POST -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/services/script/turn_on" \
-H "Content-Type: application/json" -d '{"entity_id": "script.goodnight"}'
# Trigger automation
curl -X POST -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/services/automation/trigger" \
-H "Content-Type: application/json" -d '{"entity_id": "automation.motion_lights"}'
```
### Activate Scenes
```bash
curl -X POST -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/services/scene/turn_on" \
-H "Content-Type: application/json" -d '{"entity_id": "scene.movie_night"}'
```
## Common Services
| Domain | Service | Example entity_id |
|--------|---------|-------------------|
| `light` | `turn_on`, `turn_off`, `toggle` | `light.kitchen` |
| `switch` | `turn_on`, `turn_off`, `toggle` | `switch.fan` |
| `climate` | `set_temperature`, `set_hvac_mode` | `climate.thermostat` |
| `cover` | `open_cover`, `close_cover`, `stop_cover` | `cover.garage` |
| `media_player` | `play_media`, `media_pause`, `volume_set` | `media_player.tv` |
| `scene` | `turn_on` | `scene.relax` |
| `script` | `turn_on` | `script.welcome_home` |
| `automation` | `trigger`, `turn_on`, `turn_off` | `automation.sunrise` |
## Inbound Webhooks (HA → Clawdbot)
To receive events from Home Assistant automations:
### 1. Create HA Automation with Webhook Action
```yaml
# In HA automation
action:
- service: rest_command.notify_clawdbot
data:
event: motion_detected
area: living_room
```
### 2. Define REST Command in HA
```yaml
# configuration.yaml
rest_command:
notify_clawdbot:
url: "https://your-clawdbot-url/webhook/home-assistant"
method: POST
headers:
Authorization: "Bearer {{ webhook_secret }}"
Content-Type: "application/json"
payload: '{"event": "{{ event }}", "area": "{{ area }}"}'
```
### 3. Handle in Clawdbot
Clawdbot receives the webhook and can notify you or take action based on the event.
## CLI Wrapper
The `scripts/ha.sh` CLI provides easy access to all HA functions:
```bash
# Test connection
ha.sh info
# List entities
ha.sh list all # all entities
ha.sh list lights # just lights
ha.sh list switch # just switches
# Search entities
ha.sh search kitchen # find entities by name
# Get/set state
ha.sh state light.living_room
ha.sh states light.living_room # full details with attributes
ha.sh on light.living_room
ha.sh on light.living_room 200 # with brightness (0-255)
ha.sh off light.living_room
ha.sh toggle switch.fan
# Scenes & scripts
ha.sh scene movie_night
ha.sh script goodnight
# Climate
ha.sh climate climate.thermostat 22
# Call any service
ha.sh call light turn_on '{"entity_id":"light.room","brightness":200}'
```
## Troubleshooting
- **401 Unauthorized**: Token expired or invalid. Generate a new one.
- **Connection refused**: Check HA_URL, ensure HA is running and accessible.
- **Entity not found**: List entities to find the correct entity_id.
## API Reference
For advanced usage, see [references/api.md](references/api.md).

6
_meta.json Normal file
View File

@@ -0,0 +1,6 @@
{
"ownerId": "kn739j7n05ptqcedg52zgnhrfh7zx24g",
"slug": "home-assistant",
"version": "1.0.0",
"publishedAt": 1769638965135
}

175
references/api.md Normal file
View File

@@ -0,0 +1,175 @@
# Home Assistant REST API Reference
## Authentication
All requests require the `Authorization` header:
```
Authorization: Bearer <long-lived-access-token>
```
## Base Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/` | GET | API status and HA version |
| `/api/config` | GET | Current configuration |
| `/api/states` | GET | All entity states |
| `/api/states/<entity_id>` | GET | Single entity state |
| `/api/states/<entity_id>` | POST | Set entity state |
| `/api/services` | GET | Available services |
| `/api/services/<domain>/<service>` | POST | Call a service |
| `/api/events` | GET | Available events |
| `/api/events/<event_type>` | POST | Fire an event |
| `/api/history/period/<timestamp>` | GET | State history |
| `/api/logbook/<timestamp>` | GET | Logbook entries |
## Common Services
### Lights
```bash
# Turn on with options
POST /api/services/light/turn_on
{
"entity_id": "light.living_room",
"brightness": 255, # 0-255
"color_temp": 370, # Mireds (153-500 typically)
"rgb_color": [255, 0, 0], # RGB array
"transition": 2 # Seconds
}
# Turn off
POST /api/services/light/turn_off
{"entity_id": "light.living_room"}
```
### Climate
```bash
# Set temperature
POST /api/services/climate/set_temperature
{
"entity_id": "climate.thermostat",
"temperature": 22,
"hvac_mode": "heat" # heat, cool, auto, off
}
# Set preset
POST /api/services/climate/set_preset_mode
{
"entity_id": "climate.thermostat",
"preset_mode": "away"
}
```
### Media Player
```bash
# Play/pause
POST /api/services/media_player/media_play_pause
{"entity_id": "media_player.tv"}
# Set volume (0.0-1.0)
POST /api/services/media_player/volume_set
{"entity_id": "media_player.tv", "volume_level": 0.5}
# Play media
POST /api/services/media_player/play_media
{
"entity_id": "media_player.tv",
"media_content_type": "music",
"media_content_id": "spotify:playlist:xyz"
}
```
### Cover (Blinds/Garage)
```bash
POST /api/services/cover/open_cover
{"entity_id": "cover.garage"}
POST /api/services/cover/close_cover
{"entity_id": "cover.garage"}
POST /api/services/cover/set_cover_position
{"entity_id": "cover.blinds", "position": 50} # 0=closed, 100=open
```
### Notifications
```bash
POST /api/services/notify/mobile_app_phone
{
"message": "Motion detected!",
"title": "Security Alert",
"data": {
"image": "/local/camera_snapshot.jpg"
}
}
```
## Entity State Object
```json
{
"entity_id": "light.living_room",
"state": "on",
"attributes": {
"brightness": 255,
"color_temp": 370,
"friendly_name": "Living Room Light",
"supported_features": 63
},
"last_changed": "2024-01-15T10:30:00+00:00",
"last_updated": "2024-01-15T10:30:00+00:00"
}
```
## Webhooks (Inbound to HA)
Trigger automations via webhook:
```bash
POST /api/webhook/<webhook_id>
{"custom": "data"}
```
Create webhook trigger in automation:
```yaml
automation:
trigger:
- platform: webhook
webhook_id: my_webhook_id
allowed_methods:
- POST
```
## WebSocket API
For real-time updates, use the WebSocket API at `ws://ha-url/api/websocket`.
Connection flow:
1. Connect to WebSocket
2. Receive `auth_required`
3. Send `{"type": "auth", "access_token": "TOKEN"}`
4. Receive `auth_ok`
5. Subscribe to events: `{"id": 1, "type": "subscribe_events", "event_type": "state_changed"}`
## Error Responses
| Code | Meaning |
|------|---------|
| 400 | Bad request (invalid JSON or missing fields) |
| 401 | Unauthorized (invalid/missing token) |
| 404 | Entity or service not found |
| 405 | Method not allowed |
## Rate Limits
Home Assistant doesn't enforce strict rate limits, but avoid:
- Polling faster than every 1 second
- Bulk updates without batching
Use WebSocket for real-time state tracking instead of polling.

172
scripts/ha.sh Normal file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env bash
# Home Assistant CLI wrapper
# Usage: ha.sh <command> [args...]
set -euo pipefail
CONFIG_FILE="${HA_CONFIG:-$HOME/.config/home-assistant/config.json}"
# Load config
if [[ -f "$CONFIG_FILE" ]]; then
HA_URL="${HA_URL:-$(jq -r '.url // empty' "$CONFIG_FILE")}"
HA_TOKEN="${HA_TOKEN:-$(jq -r '.token // empty' "$CONFIG_FILE")}"
fi
: "${HA_URL:?Set HA_URL or configure $CONFIG_FILE}"
: "${HA_TOKEN:?Set HA_TOKEN or configure $CONFIG_FILE}"
cmd="${1:-help}"
shift || true
api() {
curl -s -H "Authorization: Bearer $HA_TOKEN" -H "Content-Type: application/json" "$@"
}
case "$cmd" in
state|get)
# Get entity state: ha.sh state light.living_room
entity="${1:?Usage: ha.sh state <entity_id>}"
api "$HA_URL/api/states/$entity" | jq -r '.state // "unknown"'
;;
states)
# Get full entity state with attributes
entity="${1:?Usage: ha.sh states <entity_id>}"
api "$HA_URL/api/states/$entity" | jq
;;
on|turn_on)
# Turn on entity: ha.sh on light.living_room [brightness]
entity="${1:?Usage: ha.sh on <entity_id> [brightness]}"
domain="${entity%%.*}"
brightness="${2:-}"
if [[ -n "$brightness" ]]; then
api -X POST "$HA_URL/api/services/$domain/turn_on" \
-d "{\"entity_id\": \"$entity\", \"brightness\": $brightness}"
else
api -X POST "$HA_URL/api/services/$domain/turn_on" \
-d "{\"entity_id\": \"$entity\"}"
fi
echo "$entity turned on"
;;
off|turn_off)
# Turn off entity: ha.sh off light.living_room
entity="${1:?Usage: ha.sh off <entity_id>}"
domain="${entity%%.*}"
api -X POST "$HA_URL/api/services/$domain/turn_off" \
-d "{\"entity_id\": \"$entity\"}" >/dev/null
echo "$entity turned off"
;;
toggle)
# Toggle entity: ha.sh toggle switch.fan
entity="${1:?Usage: ha.sh toggle <entity_id>}"
domain="${entity%%.*}"
api -X POST "$HA_URL/api/services/$domain/toggle" \
-d "{\"entity_id\": \"$entity\"}" >/dev/null
echo "$entity toggled"
;;
scene)
# Activate scene: ha.sh scene movie_night
scene="${1:?Usage: ha.sh scene <scene_name>}"
[[ "$scene" == scene.* ]] || scene="scene.$scene"
api -X POST "$HA_URL/api/services/scene/turn_on" \
-d "{\"entity_id\": \"$scene\"}" >/dev/null
echo "✓ Scene $scene activated"
;;
script)
# Run script: ha.sh script goodnight
script="${1:?Usage: ha.sh script <script_name>}"
[[ "$script" == script.* ]] || script="script.$script"
api -X POST "$HA_URL/api/services/script/turn_on" \
-d "{\"entity_id\": \"$script\"}" >/dev/null
echo "✓ Script $script executed"
;;
automation|trigger)
# Trigger automation: ha.sh automation motion_lights
auto="${1:?Usage: ha.sh automation <automation_name>}"
[[ "$auto" == automation.* ]] || auto="automation.$auto"
api -X POST "$HA_URL/api/services/automation/trigger" \
-d "{\"entity_id\": \"$auto\"}" >/dev/null
echo "✓ Automation $auto triggered"
;;
climate|temp)
# Set temperature: ha.sh climate climate.thermostat 22
entity="${1:?Usage: ha.sh climate <entity_id> <temperature>}"
temp="${2:?Usage: ha.sh climate <entity_id> <temperature>}"
api -X POST "$HA_URL/api/services/climate/set_temperature" \
-d "{\"entity_id\": \"$entity\", \"temperature\": $temp}" >/dev/null
echo "$entity set to ${temp}°"
;;
list)
# List entities by domain: ha.sh list lights / ha.sh list all
filter="${1:-all}"
if [[ "$filter" == "all" ]]; then
api "$HA_URL/api/states" | jq -r '.[].entity_id' | sort
else
# Normalize: "lights" -> "light", "switches" -> "switch"
filter="${filter%s}"
api "$HA_URL/api/states" | jq -r --arg d "$filter" \
'.[] | select(.entity_id | startswith($d + ".")) | .entity_id' | sort
fi
;;
search)
# Search entities: ha.sh search kitchen
pattern="${1:?Usage: ha.sh search <pattern>}"
api "$HA_URL/api/states" | jq -r --arg p "$pattern" \
'.[] | select(.entity_id | test($p; "i")) | "\(.entity_id): \(.state)"'
;;
call)
# Call any service: ha.sh call light turn_on '{"entity_id":"light.room","brightness":200}'
domain="${1:?Usage: ha.sh call <domain> <service> [json_data]}"
service="${2:?Usage: ha.sh call <domain> <service> [json_data]}"
data="${3:-{}}"
api -X POST "$HA_URL/api/services/$domain/$service" -d "$data"
;;
info)
# Get HA instance info
api "$HA_URL/api/" | jq
;;
help|*)
cat <<EOF
Home Assistant CLI
Usage: ha.sh <command> [args...]
Commands:
state <entity> Get entity state
states <entity> Get full entity state with attributes
on <entity> [brightness] Turn on (optional brightness 0-255)
off <entity> Turn off
toggle <entity> Toggle on/off
scene <name> Activate scene
script <name> Run script
automation <name> Trigger automation
climate <entity> <temp> Set temperature
list [domain] List entities (lights, switches, all)
search <pattern> Search entities by name
call <domain> <svc> [json] Call any service
info Get HA instance info
Environment:
HA_URL Home Assistant URL (required)
HA_TOKEN Long-lived access token (required)
Examples:
ha.sh on light.living_room 200
ha.sh scene movie_night
ha.sh list lights
ha.sh search kitchen
EOF
;;
esac