autojanet/skills/home-assistant-automation/SKILL.md
Zoë cc74ad0bd0
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: use library/ Harbor project, add skills, fix pipeline secrets
- .woodpecker.yaml: image paths -> library/autojanet-{agent,dispatcher}
- .woodpecker.yaml: secret names RS_HARBOR_USER / RS_HARBOR_PASS (global)
- container/Dockerfile: restore COPY skills/, skills/ populated from opencode config
- skills/: 84 opencode skills bundled into image
- k8s/manifests: update image refs to library/
2026-05-30 15:43:14 -07:00

3.8 KiB

name description
home-assistant-automation 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.
# 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:

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

# 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

# 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