mcpField
H
home-assistant-best-practices

home-assistant-best-practices

github.com/homeassistant-ai其他9228.7k 次安装今天更新
代码仓库

关于 home-assistant-best-practices

home-assistant-best-practices 是指导 Agent 创建和修改 Home Assistant 配置的技能。它优先采用原生构件,并强调按版本选择功能、查阅对应参考资料,以及安全处理现有配置。

主要功能

  1. 01优先使用原生触发器、条件和辅助工具
  2. 02按 Home Assistant 版本选择功能
  3. 03查阅与任务对应的参考文件
  4. 04按安全流程修改配置
  5. 05规避常见自动化与 YAML 陷阱

适用场景

  1. 01设计新的 Home Assistant 自动化
  2. 02为传感器计算选择辅助工具
  3. 03检查影响后重构实体 ID
  4. 04无法使用 API 时编辑配置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/homeassistant-ai/skills --skill home-assistant-best-practices

安装后在 Claude Code 中输入/home-assistant-best-practices确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
appdaemon.md
automation-actions.md
backups.md
blueprint-guide.md
dashboard-cards.md
dashboard-guide.md
device-control.md
domain-docs.md
examples.yaml
helper-selection.md
safe-refactoring.md
scenes.md
template-guidelines.md
triggers-and-conditions.md
yaml-only-integrations.md

详细介绍

Home Assistant 最佳实践

核心原则: 尽可能使用 Home Assistant 原生构造。模板会绕过验证、在运行时静默失败,并使调试变得不透明。

没有工具能访问 HA API? 不要停下来请求访问权限。如果你能通过浏览器操作 HA 网页界面,就在那里进行更改,但先向用户展示确切的更改,并等用户同意后再保存:批准点击并不能让他们看到写入的内容。否则,提供用户可在界面中创建的完整配置(对于自动化,提供编辑器 Edit in YAML 模式所需的 YAML;对于辅助项,提供表单字段),并说明你假定的实体 ID。只能通过 YAML 写入的配置,应使用 File editor 应用编辑(Container 安装则在配置文件夹中编辑):先备份文件,再检查配置,并在 Tools 的 YAML 选项卡中执行相应的重新加载(2026.8 之前名为 Developer Tools;如果列表中没有该选项,则重启)。

标注了版本的功能(2026.5+)取决于实例的版本。 选择功能前先读取版本:通过 GET /api/config 中的 version,或在界面中查看 Settings → About。如果实例运行该版本或更新版本,请使用此功能,不要将旧方法作为同等选项提供。如果无法读取版本,则假定实例使用当前版本,并注明旧版备选方法所需的版本。

回答前阅读相应的参考资料。 本页仅概述了 Reference Files 中的文件;确切的键、字段和可用示例都在这些文件中。只阅读与任务匹配的文件,不要预先加载所有参考文件。

决策工作流

创建任何自动化时,请按以下顺序操作:

0. 前置检查:是否要修改现有配置?

如果更改会影响实体 ID、显示名称或跨组件引用——例如重命名实体或设备、用辅助项替换模板传感器、转换设备触发器或重构自动化——请先阅读 safe-refactoring。该参考资料涵盖影响分析、同设备关联项的发现、显示名称覆盖以及更改后的验证。继续操作前,请完成其中的工作流。

以下步骤 1–5 适用于新配置或模式评估。

1. 先检查特定用途的原生触发器/条件,再检查通用原生触发器/条件

自 2026.7 起,默认构建块是特定用途的触发器/条件——使用 <domain>.<name> 键(检测到移动、低电量、门打开),并支持区域/楼层/标签目标。先检查是否有符合意图的选项,然后检查通用原生触发器/条件,最后才考虑模板。编写触发器前,请阅读 triggers-and-conditions #purpose-specific-triggers--conditions-default-since-20267。

特定用途的触发器也可以在 target: 中使用 entity_id,因此,即使只知道一个传感器,也不构成退回使用 trigger: state 的理由。请使用特定用途的触发器编写自动化,不要只将其作为可选升级方案。

常见替换方式:

  • 对移动、占用或门的 binary_sensor 使用 trigger: state → 使用 motion.detected/motion.cleared、occupancy.detected/occupancy.cleared 或 door.opened/door.closed,并设置 target: {entity_id: ...};如果已知区域,则使用 area_id
  • 触发器中列出多个独立传感器实体 → 使用一个带区域/楼层/标签 target: 的特定用途触发器
  • 为实现“任何位置 N 分钟内都没有移动”,在 motion.detected 后使用 delay → 使用 motion.cleared 和 options: {behavior: all, for: ...},当所有目标传感器都持续无移动这么久时触发一次(unavailable 和 unknown 传感器不计入)
  • {{ states('x') | float > 25 }} → 使用带 above: 25 的 numeric_state 条件
  • {{ is_state('x', 'on') and is_state('y', 'on') }} → 使用包含状态条件的 condition: and
  • {{ now().hour >= 9 }} → 使用 after: "09:00:00" 的 condition: time
2. 检查是否有内置辅助工具或模板辅助工具

创建模板传感器之前,请阅读 helper-selection。

常见替代方案:

  • 对多个传感器求和/求平均 → min_max 集成
  • 二元任一开启/全部开启逻辑 → group 辅助工具
  • 变化率 → derivative 集成
  • 跨阈值检测 → threshold 集成
  • 用量跟踪 → utility_meter 辅助工具

如果没有合适的内置辅助工具,请使用模板辅助工具,而不是 YAML。 通过 HA 配置流程创建(以编程方式或在 UI 中操作: Settings → Devices & Services → Helpers → Create Helper → Template)。通过流程创建的辅助工具可在 UI 中编辑;template: YAML 条目则需要执行 template.reload,且无法在 UI 中编辑。

用户提出要求、两种方式都不可用,或配置需要流程中没有对应字段的键时,请编写 template: YAML——常见情况包括基于触发器的模板和 attributes:。然后使用受管理的 YAML 编辑方式(yaml-only-integrations),而不是手动编辑。

3. 选择正确的自动化模式

默认的 single 模式通常不合适。请参阅 automation-actions #automation-modes。

场景模式
带超时的运动感应灯restart
顺序处理(门锁)queued
对每个实体独立执行操作parallel
一次性通知single
4. 优先使用 entity_id,而不是 device_id

重新添加设备后,device_id 会失效。请参阅 device-control。

例外: Zigbee2MQTT 自动发现的设备触发器可以使用。

5. 对于按钮和遥控器
  • 任何会公开 event.* 实体的集成: 使用以该实体为目标的 event.received(参见下方的反模式行)
  • ZHA: 没有事件实体——使用包含 device_ieee 的 event 触发器(持久)
  • Z2M: 事件实体处于实验阶段,且默认关闭——使用 device 触发器(自动发现)或 mqtt 触发器

编写触发器之前,请阅读 device-control #buttonremote-patterns。


关键反模式

反模式改用原因参考
使用 condition: template 和 float > 25condition: numeric_state加载时会检查键和阈值;状态为 unavailable 或 unknown 时结果为 false,而不带默认值的 float 会引发错误triggers-and-conditions #native-conditions
对可能已经满足的条件,使用带状态触发器的 wait_for_triggerwait_template状态触发器只会在状态转换时触发,因此等待会持续到实体离开该状态并重新进入,或者在没有 timeout 的情况下永远等待(参见 safe-refactoring #trigger-restructuring)automation-actions #wait-actions
在触发器中使用 device_identity_id(ZHA 则使用 device_ieee)重新添加设备后,device_id 会失效device-control #entity-id-vs-device-id
对于具有 event.* 实体的按钮,使用集成总线事件(例如 hue_event)的 event 触发器使用 event.received 针对该实体,并从其 event_types 属性读取值如果集成保留稳定的唯一 ID,该实体可以重命名并在重新添加后继续使用;总线事件数据因集成而异device-control #buttonremote-patterns
未加保护的 numeric_state 触发器驱动高开销操作添加条件,在 trigger.from_state 中排除 unavailable/unknown重启或短暂故障会重新布防触发器,因此数值未变也会触发(此保护也会丢弃真实的越界触发)triggers-and-conditions #unavailable-arms-a-numeric-state-trigger
动态灯光使用 mode: singlemode: restart重新触发时必须重置计时器automation-actions #automation-modes
在 automations.yaml 中将 enabled: false 设为顶层键使用 automation.turn_off(临时停用)或在实体注册表中停用(永久停用)这不是有效的顶层键,会在架构验证期间被拒绝;自动化会加载为 unavailableautomation-actions #disabling-automations
用模板传感器计算总和/平均值min_max 辅助工具声明式配置,可处理不可用状态helper-selection #numeric-aggregation
使用带阈值的模板二进制传感器threshold 辅助工具内置迟滞支持helper-selection #threshold
未进行影响分析就重命名实体 ID按照 safe-refactoring 工作流操作重命名会悄无声息地破坏仪表盘、脚本、场景、Config Entry 数据和存储中的仪表盘safe-refactoring #entity-renames
重命名基于 Config Entry 的群组(UI 群组)成员,却不更新成员列表在注册表中重命名后,通过 Options Flow 更新群组成员列表实体注册表中的重命名不会更新 Config Entry 中的 options.entities,群组会悄无声息地失效safe-refactoring #config-entry-groups
重命名 Min/Max 辅助工具或自定义 Config Entry 集成(例如 Better Thermostat)使用的实体,却不检查其 Config Entry 数据扫描配置条目的 data+options;在 Min/Max Options Flow 中重新选择重命名后的实体。若集成将其保存在 data 中(Better Thermostat),则没有 API 修复方式:告知用户,并在重命名前进行完整备份它们会在 Config Entry 中存储 entity_id,而注册表中的重命名不会更新这些值;Threshold(自 2025.6 起)和 Generic Thermostat 等单一来源辅助工具会自行更新safe-refactoring #config-entry-data--blind-spots-for-entity-registry-renames
在 YAML 中使用 template: 传感器/二进制传感器通过配置流程创建 Template Helper流程辅助工具可原位重新加载,并且可在 UI 中编辑;template: 条目则需要重新加载配置,且不能在 UI 中编辑。确实存在例外:基于触发器的模板和 attributes: 没有对应的流程字段helper-selection #template-helpers
直接编辑 .storage/ 文件或其他 HA 内部状态使用 HA REST/WebSocket API 管理状态和配置条目.storage/ 文件是 HA 的内部状态数据库;直接编辑会绕过验证、有损坏风险,且 HA 可能会悄无声息地覆盖修改—
在 .storage/ 中查找自动化配置通过 HA 配置 API 读取和写入自动化。通过 UI 创建的自动化会保存到 automations.yaml在任何配置模式下,都没有 .storage/ 文件保存自动化配置。.storage/ 只保存自动化的实体注册表条目—
为仅支持 YAML 的集成手动将原始 YAML 写入 configuration.yaml使用带备份和验证的托管 YAML 配置编辑未托管的写入有语法错误风险、没有备份,还会跳过 check_config;托管编辑可提供这三项保障yaml-only-integrations
为自动化/脚本/场景生成 YAML 片段使用 HA 配置 API 以编程方式创建自动化/脚本;如果无法访问 API,则提供供 UI 编辑器使用的配置API 调用会验证配置,避免语法错误,而且无需手动编辑文件或重启triggers-and-conditions,automation-actions,examples.yaml
告诉用户通过编辑 configuration.yaml 配置集成引导用户前往 HA UI 中的“设置”>“设备与服务”大多数集成都通过 UI 配置;YAML 集成配置很少见,而且因集成而异—
将 HA 的“add-ons”称为插件使用“Apps”这一术语HA 在 2026.2 中将 add-ons 更名为 Apps——“Apps 是与 Home Assistant 同时运行的独立应用程序”—
使用带厂商房间 ID 的 vacuum.send_command使用 vacuum.clean_area,并在 cleaning_area_id 中填写 HA 区域 ID(如果已映射区段)使用 HA 原生区域,可跨集成工作,但必须先在实体设置中映射区段和区域device-control #vacuum-control
在灯光操作中使用 color_temp(mired)使用 color_temp_kelvin,并转换数值:开尔文 = 1,000,000 ÷ mired(500 mired = 2000 K)color_temp 参数已于 2026.3 移除;现在只支持开尔文。HA 会接受该参数的任何正数,因此直接复制 mired 数值会被当作开尔文读取(500 mired 会变成 500 K)device-control #lights
在 variables: 中保存状态或属性,或硬编码数值,以便在临时更改后恢复设备更改前使用 scene.create 和 snapshot_entities 创建快照,然后对该场景调用 scene.turn_on一次调用即可保存每个实体各自的状态,包括原本关闭的灯;变量需要为每个属性编写模板,并为每个实体添加恢复步骤scenes #snapshot--restore-scenecreate
使用 Person/Device Tracker 的 entered_home/left_home 设备触发器或 is_home/is_not_home 条件使用 to: home / to: not_home 的 state 触发器,或 state 条件这些功能已于 2026.5 移除;应改用状态触发器和条件triggers-and-conditions #presence-and-person-triggers-and-conditions-removed-in-20265
在触发器中使用实体列表,而区域/楼层/标签目标更合适使用带 target: {area_id: ...} 的专用触发器设备变更时,自动化会随区域成员关系更新,无需维护过时的实体列表triggers-and-conditions #purpose-specific-triggers--conditions-default-since-20267
使用旧的专用键(battery.low、vacuum.docked、timer.time_remaining 等),或触发器的 behavior: any/last使用 2026.7 重命名后的键(battery.became_low 等)和 behavior: each/all(于 2026.6 重命名)旧键不再加载;旧行为值会引发修复问题,并将被移除triggers-and-conditions #purpose-specific-triggers--conditions-default-since-20267
AppDaemon:在 __init__ 中注册回调、不取消 run_in 计时器、将状态保存在实例变量中、硬编码实体 ID在 initialize() 中注册,重新安排前先取消,通过 input_* 辅助工具持久化,并通过 self.args 传递 ID这些做法都会导致故障悄无声息地发生、重新加载时重置,或阻碍复用appdaemon #appdaemon-specific-anti-patterns
Blueprints:硬编码实体、应使用选择器的地方使用自由文本、在模板中使用 !input、遗漏 source_url使用带类型的 !input 选择器;在模板化输入前,将其绑定到 variables:;始终设置 source_url硬编码会破坏复用性,自由文本允许拼写错误,而 !input 是 YAML 标签,不是模板值blueprint-guide #common-pitfalls
备份:为撤销单个对象的编辑而执行完整恢复;在不可逆操作(删除注册表条目、移除集成、升级 Core/OS)前不做备份;称某个操作“可逆”却不说明其逆操作仅回滚该对象;在操作前进行备份;说明确切的逆操作,否则将其视为不可逆完整恢复会撤销此后所有无关更改并重启 HA;事后进行的备份会把损坏状态也保存进去backups #when-a-full-backup-earns-its-cost
未经用户明确确认就恢复备份、删除备份或升级 Core/OS每次都先询问,说明具体影响,并等待答复,无论是否已有备份完整恢复会丢弃归档后对所有已恢复部分所做的一切更改,并重启 HA;Supervisor 部分恢复只会覆盖所选的归档部分;删除操作会销毁一个恢复点;Core/OS 升级影响重大,且其恢复途径就是升级前的备份backups
在多个模板中重复使用同一段复杂 Jinja 表达式排除原生触发器/条件和内置辅助工具后,将其作为宏在 config/custom_templates/*.jinja 中定义一次并导入规则变更时只需修复一处,避免多个副本逐渐不一致template-guidelines #reusable-macros
在导入的宏中使用 trigger、this、value_json 或 {% set %} 变量将其作为参数传给宏导入不会携带调用方的上下文——因此变量在宏内未定义,会渲染为空,对其进行任何属性访问都会报错(HA 自带的 states 等函数属于全局变量,可以正常使用)template-guidelines #imports-do-not-carry-the-callers-context

参考文件

回答前,请阅读任务匹配的每个文件:

文件何时阅读
safe-refactoring重命名实体或其显示名称、替换辅助工具、重构自动化,或修改现有配置时
triggers-and-conditions编写自动化的触发器或条件时:特定用途和原生触发器/条件、for: 时长、触发器 ID
automation-actions编写自动化或脚本的操作,或选择其模式时:等待、变量、捕获操作响应、continue_on_error、脚本中的仅限管理员操作(Unauthorized)、停止序列、重复、if/then 与 choose、并行;记录/注释步骤;禁用自动化;通过 last_triggered 测量自动化之间的经过时间;Mobile App notify 操作与实体——将实体 ID 用作操作时出现 action not found;跟踪记录保留——频繁触发会将运行记录推入调试区,导致 5 条已存跟踪记录中有一条被挤出
helper-selection决定使用内置辅助工具还是模板传感器时——聚合、变化率、阈值、状态持续时间、计数/计时、调度、分组、概率推断、平滑、气候、域转换、决策矩阵
template-guidelines确认模板是否适用于某个用例;通过 custom_templates 宏在模板之间共享 Jinja 逻辑
yaml-only-integrations创建或编辑没有配置流程的纯 YAML 集成时(例如 command_line、基于平台的 mqtt、rest)
device-control编写操作、按钮/遥控器自动化,或使用 target: 时
scenes创建或启用场景;快照/恢复模式,包括在临时更改后将设备恢复原状;快照与脚本的区别
dashboard-guide设计或修改 Lovelace 仪表盘时——布局、视图类型、策略、分区、卡片、徽章、CSS 样式、HACS
dashboard-cards查找内置卡片类型(核心、能源、旧版),或了解卡片字段的文档位置;实体卡片的属性行——带有 attribute: 但没有 type: attribute 的行显示的是实体状态,而不是属性
domain-docs查找集成/域文档,或特定触发器、条件或操作的专属文档页面时
examples.yaml需要结合多项最佳实践的复合示例时
appdaemonAppDaemon 应用:何时选择它而非原生 HA、应用结构、操作、调度、错误处理、安全重构影响
blueprint-guide编写可复用蓝图:元数据与 source_url、输入与选择器、target 与 entity、默认值、输入分区、!input 模板、版本控制
backups判断操作是否需要先备份;在完整恢复、部分恢复和回滚单个对象之间进行选择;了解归档文件的实际内容;加密密钥和应急工具包;验证恢复;删除备份时 HA 会保护和不会保护的内容;git 配置仓库是否能替代完整备份

评论

支持 Markdown