---
name: home-assistant-automation
description: Use when writing, editing, or debugging Home Assistant automations or scripts for Zoe's HA instance at 10.0.2.6:8123. Covers entity discovery, modern YAML syntax, automation/script patterns, and live MCP testing.
---

# Home Assistant Automation

## Overview

Write automations and scripts for Zoe's HA instance. You have live MCP access — use it. **Never guess entity IDs.** Always discover them first.

## HARD REQUIREMENT: Discover Entities Before Writing YAML

```
GetLiveContext BEFORE any YAML. No exceptions.
```

```python
# By domain
GetLiveContext(domain="light")
GetLiveContext(domain="media_player")
GetLiveContext(domain="siren")

# By area
GetLiveContext(area="living room")
GetLiveContext(area="office")

# By name (specific)
GetLiveContext(name="doorbell")
GetLiveContext(name="chime")
```

Entity IDs drift and vary. If you write YAML without checking, it will break.

## Known Devices (verify with GetLiveContext before use)

| Device | Domain hint | Notes |
|--------|------------|-------|
| Amcrest AD410 doorbell | `binary_sensor` | Button press trigger |
| Living room chime | `siren.living_room_chime_play_tone` | Use `siren.turn_on` |
| Office chime | `siren.office_chime_play_tone` | Use `siren.turn_on` |
| Side door lock | `select` | Lock timing entity |
| Apple TV | `media_player` | Used for kiosk display dimming |
| Raspberry Pi kiosk | family room dashboard | |
| Season sensor | `sensor.season` | |

## Modern YAML Syntax (2024.x+)

Use **plural keys** for all top-level blocks:

```yaml
alias: "Descriptive name"
description: "What this does"
triggers:          # NOT trigger:
  - ...
conditions:        # NOT condition:
  - ...
actions:           # NOT action:
  - action: ...    # service calls inside actions use "action:" key, NOT "service:"
mode: single
```

## Common Trigger Patterns

```yaml
# State change with debounce
- trigger: state
  entity_id: binary_sensor.doorbell_button
  to: "on"
  for: "00:00:02"

# Time
- trigger: time
  at: "07:00:00"

# Sun offset
- trigger: sun
  event: sunset
  offset: "+00:30:00"

# Template
- trigger: template
  value_template: "{{ states('sensor.season') == 'winter' }}"
```

## Common Action Patterns

```yaml
# Light with brightness/color temp
- action: light.turn_on
  target:
    entity_id: light.living_room
  data:
    brightness_pct: 80
    color_temp_kelvin: 3000

# Play chime (siren domain, turn_on action)
- action: siren.turn_on
  target:
    entity_id: siren.living_room_chime_play_tone

# Conditional branch
- choose:
    - conditions:
        - condition: state
          entity_id: sun.sun
          state: above_horizon
      sequence:
        - action: light.turn_on
          target:
            area_id: living_room
  default:
    - action: light.turn_off
      target:
        area_id: living_room

# Delay
- delay: "00:05:00"

# Notify
- action: notify.notify
  data:
    message: "Someone at the door"
```

## Automation vs Script

- **Automation:** triggered by events/state/time — reactive behavior
- **Script:** called manually or from other automations — reusable action sequences

## Testing

1. **Verify entity exists:** `GetLiveContext(name="whatever")` — confirm state and ID
2. **Quick device test:** Use MCP action tools directly before writing YAML
   - `HassTurnOn`, `HassLightSet`, `HassSetVolume`, etc.
3. **Test automation:** Paste YAML in HA UI → Settings → Automations → + → Edit in YAML → Run

## Gotchas

- Entity IDs are case-sensitive, use underscores
- `area_id` in `target:` works for lights; not reliable for all domains
- Chimes use `siren` domain — action is `siren.turn_on`, not `siren.play_tone`
- `mode: single` blocks re-entry; use `restart` if you want it to restart mid-run
- Apple TV dimming: check `media_player` state before acting on it
- Template syntax: `{{ states('sensor.foo') }}` — never `states.sensor.foo`
