home-assistant-best-practices
git clone https://github.com/homeassistant-ai/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/homeassistant-ai/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/home-assistant-best-practices" ~/.claude/skills/homeassistant-ai-skills-home-assistant-best-practices && rm -rf "$T"
skills/home-assistant-best-practices/SKILL.mdHome Assistant Best Practices
Core principle: Use native Home Assistant constructs wherever possible. Templates bypass validation, fail silently at runtime, and make debugging opaque.
Decision Workflow
Follow this sequence when creating any automation:
0. Gate: modifying existing config?
If your change affects entity IDs or cross-component references — renaming entities, replacing template sensors with helpers, converting device triggers, or restructuring automations — read
references/safe-refactoring.md first. That reference covers impact analysis, device-sibling discovery, and post-change verification. Complete its workflow before proceeding.
Steps 1-5 below apply to new config or pattern evaluation.
1. Check for native condition/trigger
Before writing any template, check
references/automation-patterns.md for native alternatives.
Common substitutions:
→{{ states('x') | float > 25 }}
condition withnumeric_stateabove: 25
→{{ is_state('x', 'on') and is_state('y', 'on') }}
with state conditionscondition: and
→{{ now().hour >= 9 }}
withcondition: timeafter: "09:00:00"
→wait_template: "{{ is_state(...) }}"
with state trigger (caveat: different behavior when state is already true — seewait_for_trigger
)references/safe-refactoring.md#trigger-restructuring
2. Check for built-in helper or Template Helper
Before creating a template sensor, check
references/helper-selection.md.
Common substitutions:
- Sum/average multiple sensors →
integrationmin_max - Binary any-on/all-on logic →
helpergroup - Rate of change →
integrationderivative - Cross threshold detection →
integrationthreshold - Consumption tracking →
helperutility_meter
If no built-in helper fits, use a Template Helper — not YAML. Create it via the HA config flow (MCP tool or API) or via the UI: Settings → Devices & Services → Helpers → Create Helper → Template. Only write
template: YAML if explicitly requested or if neither path is available.
3. Select correct automation mode
Default
single mode is often wrong. See references/automation-patterns.md#automation-modes.
| Scenario | Mode |
|---|---|
| Motion light with timeout | |
| Sequential processing (door locks) | |
| Independent per-entity actions | |
| One-shot notifications | |
4. Use entity_id over device_id
device_id breaks when devices are re-added. See references/device-control.md.
Exception: Zigbee2MQTT autodiscovered device triggers are acceptable.
5. For Zigbee buttons/remotes
- ZHA: Use
trigger withevent
(persistent)device_ieee - Z2M: Use
trigger (autodiscovered) ordevice
triggermqtt
See
references/device-control.md#zigbee-buttonremote-patterns.
Critical Anti-Patterns
| Anti-pattern | Use instead | Why | Reference |
|---|---|---|---|
with | | Validated at load, not runtime | |
| with state trigger | Event-driven, not polling; waits for change (see for semantic differences) | |
in triggers | (or for ZHA) | device_id breaks on re-add | |
for motion lights | | Re-triggers must reset the timer | |
as a top-level key in | (temporary) or entity registry disable (permanent) | Not a valid top-level key — rejected during schema validation; automation loads as | |
| Template sensor for sum/mean | helper | Declarative, handles unavailable states | |
| Template binary sensor with threshold | helper | Built-in hysteresis support | |
| Renaming entity IDs without impact analysis | Follow workflow | Renames break dashboards, scripts, scenes, Config-Entry data, and storage dashboards silently | |
| Renaming members of Config-Entry-based groups (UI groups) without updating membership | Update group membership via Options Flow after the registry rename | The entity registry rename does not update in the Config Entry — group silently breaks | |
| Renaming entities used by Config-Entry integrations (Better/Generic Thermostat, Min/Max, Threshold) without patching Config-Entry data | Scan and patch + fields | These integrations store entity_ids in Config Entry — not updated by entity registry renames | |
sensor/binary sensor in YAML | Template Helper (UI or config flow API) | Requires file edit and config reload; harder to manage | |
Editing files or other HA internal state directly | Use the HA REST/WebSocket API to manage state and config entries | files are HA's internal state database; direct edits bypass validation, risk corruption, and can be silently overwritten by HA | — |
Writing raw YAML to by hand for YAML-only integrations | Use managed YAML config editing with backup and validation | Unmanaged writes risk syntax errors, have no backup, and skip — managed editing provides all three | |
| Generating YAML snippets for automations/scripts/scenes | Use the HA config API to create automations/scripts programmatically | API calls validate config, avoid syntax errors, and don't require manual file edits or restarts | , |
Telling user to edit for integrations | Direct user to Settings > Devices & Services in the HA UI | Most integrations are UI-configured; YAML integration config is rare and integration-specific | — |
| Referring to HA "add-ons" | Use the term "Apps" | HA renamed add-ons to Apps in 2026.2 — "Apps are standalone applications that run alongside Home Assistant" | — |
with vendor room IDs | with HA (if segments are mapped) | Uses native HA areas, works across integrations — but requires segment-to-area mapping in entity settings first | |
Using (mireds) in light service calls | Use | The parameter was removed in 2026.3; only Kelvin is supported | |
Reference Files
Read these when you need detailed information:
| File | When to read | Key sections |
|---|---|---|
| Renaming entities, replacing helpers, restructuring automations, or any modification to existing config | , , , , , |
| Writing triggers, conditions, waits, or choosing automation modes; disabling automations | , , , , , , , , |
| Deciding whether to use a built-in helper vs template sensor | , , , , , , |
| Confirming templates ARE appropriate for a use case | , , , , |
| Creating or editing YAML-only integrations that have no config flow (e.g. , platform-based , ) | , |
| Writing service calls, Zigbee button automations, or using target: | , , , |
| Designing or modifying Lovelace dashboards — layout, view types, sections, custom cards, CSS styling, HACS | , , , , , , |
| Looking up available card types or fetching card-specific documentation | — |
| Looking up integration or domain documentation for service calls, entity attributes, or configuration | — |
| Need compound examples combining multiple best practices | — |