ha-ultimate

TotalClaw 作者 totalclaw

AI 代理的权威家庭助理技能。通过 REST API 控制 25 个以上实体域 具有安全执行、网络钩子、库存生成和完整的 CLI 包装器。 灯光、气候、门锁、状态、天气、日历、通知、TTS、脚本、 自动化等等。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~titunito-ha-ultimate
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~titunito-ha-ultimate/file -o titunito-ha-ultimate.md
## 概述(中文)

AI 代理的权威家庭助理技能。通过 REST API 控制 25 个以上实体域
具有安全执行、网络钩子、库存生成和完整的 CLI 包装器。
灯光、气候、门锁、状态、天气、日历、通知、TTS、脚本、
自动化等等。

## 原文

# ha-ultimate — Definitive Home Assistant Skill

Control your smart home via the Home Assistant REST API with safety enforcement, inventory
awareness, and full domain coverage.

## Setup

### 1. Environment Variables

```bash
export HA_URL="http://your-ha-instance:8123"
export HA_TOKEN="your-long-lived-access-token"
```

Or create a `.env` file in the skill directory (auto-loaded by ha.sh):

```env
HA_URL=http://192.168.1.100:8123
HA_TOKEN=eyJ...your-token...
```

The CLI wrapper also checks `$HOME/.config/homeassistant/config.json` as a fallback
(JSON with `url` and `token` keys). Protect this file with restrictive permissions
(`chmod 600`) since it may contain your token.

### 2. 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., "OpenClaw")
4. Copy the token immediately (shown only once)

### 3. Test Connection

```bash
curl -s -H "Authorization: Bearer $HA_TOKEN" "$HA_URL/api/" | jq
```

Or with the CLI wrapper:

```bash
scripts/ha.sh info
```

### 4. Generate Entity Inventory (Recommended, requires Node.js)

**Note:** Node.js is an **optional** dependency, only needed for `inventory.js`.
If Node.js is not available, `ha.sh inventory` falls back to a curl+jq listing.

```bash
node scripts/inventory.js
```

This generates `ENTITIES.md` with all entities organized by domain, including name, area,
and current state. **Read ENTITIES.md before acting on devices** to know what is available.

### 5. Docker / Container Networking

If running inside Docker:
- **Use IP address** (recommended): `http://192.168.1.100:8123`
- **Tailscale**: `http://homeassistant.ts.net:8123`
- **Avoid mDNS** in Docker: `homeassistant.local` often doesn't resolve
- **Nabu Casa**: `https://xxxxx.ui.nabu.casa` (requires subscription)

---

## Safety Rules

This skill implements a **layered safety system** to prevent accidental actions on
security-critical devices.

### Layer 1: Mandatory Confirmation (Agent Behavior)

**Always confirm with the user before performing these actions:**
- **Locks** — locking or unlocking any lock
- **Alarm panels** — arming or disarming
- **Garage doors** — opening or closing (`cover.*` with `device_class: garage`)
- **Security automations** — disabling automations related to security or safety
- **Covers** — opening or closing covers that control physical access (gates, barriers)

Never act on security-sensitive devices without explicit user confirmation.

### Layer 2: Critical Action Workflow

For critical domains (locks, alarm panels, garage doors, covers controlling physical
access), follow this workflow **before executing any command**:

1. **Identify the action as critical** — check if the entity domain is lock, alarm_control_panel, or cover with device_class garage/gate
2. **Inform the user and ask for confirmation** — "⚠️ Opening the garage door is a critical action. Do you want to proceed?"
3. **Wait for explicit confirmation** — "Yes", "OK", "Sure", "Do it", or any affirmative response
4. **Only then execute the command** — never execute first

**Important:** The agent (not the script) is responsible for enforcing this confirmation
flow. The CLI wrapper (`scripts/ha.sh`) checks `blocked_entities.json` as a hard block,
but interactive confirmation must be handled at the agent conversation level before
invoking any command on critical domains.

### Layer 3: Blocked Entities (Optional Configuration)

Users can permanently block entities by listing them in a `blocked_entities.json` file:

```json
{
  "blocked": ["switch.main_breaker", "lock.front_door"],
  "notes": "Main breaker should never be automated. Front door is manual-only."
}
```

**Blocked entities cannot be controlled under any circumstance**, even with user confirmation.
Check this file before executing any action if it exists.

---

## CLI Wrapper

The `scripts/ha.sh` CLI provides easy access to all HA functions:

```bash
# Test connection
scripts/ha.sh info

# List entities
scripts/ha.sh list all          # all entities
scripts/ha.sh list light        # just lights
scripts/ha.sh list switch       # just switches

# Search entities
scripts/ha.sh search kitchen    # find entities by name

# Get/set state
scripts/ha.sh state light.living_room
scripts/ha.sh full light.living_room    # full details with attributes
scripts/ha.sh on light.living_room
scripts/ha.sh on light.living_room 200  # with brightness (0-255)
scripts/ha.sh off light.living_room
scripts/ha.sh toggle switch.fan

# Scenes & scripts
scripts/ha.sh scene movie_night
scripts/ha.sh script goodnight

# Climate
scripts/ha.sh climate climate.thermostat 22

# Dashboard (quick status of everything)
scripts/ha.sh dashboard

# Call any service
scripts/ha.sh call light turn_on '{"entity_id":"light.room","brightness":200}'

# Areas
scripts/ha.sh areas
```

---

## Entity Discovery

### List all entities

```bash
curl -s "$HA_URL/api/states" -H "Authorization: Bearer $HA_TOKEN" \
  | jq -r '.[].entity_id' | sort
```

### List entities by domain

```bash
# Lights
curl -s "$HA_URL/api/states" -H "Authorization: Bearer $HA_TOKEN" \
  | jq -r '.[] | select(.entity_id | startswith("light.")) | "\(.entity_id): \(.state)"'

# Sensors (with units)
curl -s "$HA_URL/api/states" -H "Authorization: Bearer $HA_TOKEN" \
  | jq -r '.[] | select(.entity_id | startswith("sensor.")) | "\(.entity_id): \(.state) \(.attributes.unit_of_measurement // "")"'
```

Replace the domain prefix (`switch.`, `light.`, `sensor.`, etc.) to discover entities
in any domain.

### Get single entity state

```bash
curl -s "$HA_URL/api/states/ENTITY_ID" -H "Authorization: Bearer $HA_TOKEN"
```

### Area & Floor Discovery

Use the template API to query areas, floors, and labels.

```bash
# List all areas
curl -s -X POST "$HA_URL/api/template" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"template": "{{ areas() }}"}'

# Entities in a specific area
curl -s -X POST "$HA_URL/api/template" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"template": "{{ area_entities(\"kitchen\") }}"}'

# Find which area an entity belongs to
curl -s -X POST "$HA_URL/api/template" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"template": "{{ area_name(\"light.kitchen\") }}"}'

# List all floors and their areas
curl -s -X POST "$HA_URL/api/template" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"template": "{% for floor in floors() %}{{ floor }}: {{ floor_areas(floor) }}\n{% endfor %}"}'
```

---

## Switches

```bash
# Turn on
curl -s -X POST "$HA_URL/api/services/switch/turn_on" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "switch.office_lamp"}'

# Turn off
curl -s -X POST "$HA_URL/api/services/switch/turn_off" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "switch.office_lamp"}'

# Toggle
curl -s -X POST "$HA_URL/api/services/switch/toggle" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "switch.office_lamp"}'
```

## Lights

```bash
# Turn on with brightness (percentage)
curl -s -X POST "$HA_URL/api/services/light/turn_on" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "light.living_room", "brightness_pct": 80}'

# Turn on with color (RGB)
curl -s -X POST "$HA_URL/api/services/light/turn_on" \
  -H "Authorization: Bearer $HA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "light.living_room", "rgb_color": [255, 150, 50]}'

# Turn on with color temperature (mireds, 153-500)
curl -s -X POST "$HA_URL/api/services/light/turn_on" \
  -H "Authorization