触发器全家桶:时间、状态、事件、区域
触发器是自动化的发动机
上一篇讲了四要素的骨架,本篇把「触发」这一格彻底填满。HA 的触发器平台有十几种,但底层逻辑只有三类:时间到了、状态变了、事件发生了。区域类触发其实就是「设备状态变化」的一种特殊形态,webhook 和 mqtt 则是「事件」的外部来源。理解这个分类,看到一个新平台也能马上猜到它的脾气。
先给一张总览表,后面逐类展开:
| 分类 | 触发平台 | 一句话说明 |
|---|---|---|
| 时间 | time、sun、template(时间型) | 到点、日出日落、算时间 |
| 状态 | state、numeric_state | 开关变化、数值跨线 |
| 事件 | event、webhook、mqtt、template(事件型) | 总线事件、外部推送 |
| 位置 | zone | 手机进出围栏 |
| 设备 | device | 绑定具体设备的按钮等 |
注意最后一行的 device 触发器:它面向「某个具体设备」而非实体,常见于「无线按钮被按下」这类集成事件,优点是在编辑器里选设备就行,缺点是换设备后要重选。它本质仍是事件,只是被包装得更易用。
时间类:最朴素也最多坑
time 触发器最直观:每天某个时刻执行。它支持指定时间点、星期几,甚至可以配合一个 input_datetime 实体实现「闹钟联动」——改 helper 的时间,自动化跟着变,不用重载配置。典型写法:
trigger:
- platform: time
at: "07:00:00"
- platform: time
at: input_alarm_time
第二个触发器引用了一个 helper 实体,它的时间被改了,触发点也立刻跟着变——这就是「可调闹钟」的标准做法。
sun 触发器跟日照走:event: sunrise 或 sunset,还能加偏移量(offset)。黎明前 30 分钟开窗帘、日落后 10 分钟开灯,都是它的典型用法。不过要记住:偏移是相对天文事件的,跟实际天黑程度略有出入,可以再叠一个光照传感器条件校准。
template 触发器里面有一种时间型用法:写一段模板判断「现在该不该执行」,HA 每秒评估一次,返回值从假变真时触发。适合「每月最后一个周五」「只在电价谷段」这类规则型时间。

时间类触发最常见的坑是时区与夏令时。HA 以实例时区为准,容器部署如果时区没设对,所有定时任务会整体偏移。另外时间触发每天只在精确到秒的那一刻发一次,如果当时 HA 恰好重启错过了,这一天就没了——关键任务建议加一个补救逻辑(比如开机时检查并补执行)。
状态类:变化即触发
state 触发器监听某个实体从一种状态变到另一种状态。门窗传感器从关到开、插座从关到开、设备从家到不在家,都吃这一套。写法关心三样:entity_id、to、from,三者可省略可组合,省略 to 表示「变成任何状态都算」。
numeric_state 是数值版本:above、below 画两条线,数值跨过去就触发。两个高频配件:for 表示「持续多久才算数」,用来过滤传感器抖动;value_template 表示先算出一个数再比较,灵活度很高的同时也提醒你——模板里取值要是数字类型。
一个经典组合:温度高于 28 度且持续 5 分钟 → 打开空调。少了 for,传感器在 27.9 和 28.1 之间抖两下就会触发三四次,配合 restart 模式还能自我叠加。状态触发 + for 参数 + restart 模式,是温控类自动化的稳定三件套。
写出来大概是这样:
trigger:
- platform: numeric_state
entity_id: sensor.living_temp
above: 28
for: "00:05:00"
action:
- service: climate.set_temperature
target:
entity_id: climate.ac
data:
temperature: 26
mode: restart
for 的值是「持续时间」,格式为 时:分:秒。注意它只在「持续满足」后才发触发,期间数值回落会重新计时,天然过滤毛刺。
事件类:直通事件总线
event 触发器直接监听事件总线上的具名事件,比如 homeassistant_start(系统启动完成)、zha_event(Zigbee 设备事件)、call_service(任意服务被调用)。它的参数只有 event_type 和可选的 event_data 过滤条件,但能力是最强的——因为 HA 内部一切显著动作都会发事件。
一个实用的例子:监听开关被外部物理按下的事件:
trigger:
- platform: event
event_type: zha_event
event_data:
command: "on"
事件触发器拿到的数据可以在动作里通过 trigger.event.data 访问,相当于把「谁、按了什么」一路传到执行端。调试事件最好的工具是「开发者工具 → 事件」里的监听功能:开着监听然后物理操作设备,总线上流过的事件会实时打印出来,照着抄参数最靠谱。
webhook 触发器把一个 URL 变成触发器:任何能发 HTTP 请求的东西(路由器、群晖、第三方服务)都能通过回调 URL 点火。安全做法是开启本地模式或加强鉴权,别把裸 URL 暴露在公网。webhook 触发后用 trigger.webhook.body 取请求体,配合模板解析 JSON。
mqtt 触发器监听某个主题的消息,适合已有 MQTT 基础设施的玩家:传感器上报、自定义固件、Homebridge 桥接都能走这条路。消息体可以是 JSON,触发后用模板解析字段。如果你还没有代理,在 NAS 上跑一个容器即可,具体做法可参考 《群晖 DSM 指南》 的容器章节。

区域类:回家与离家
zone 触发器依赖 device tracker 实体和地理围栏区域:手机进入或离开 zone.home(或你自建的办公楼围栏)时触发。它的精度取决于定位来源——手机 App 的集成定位精度不错,纯路由器判定则取决于路由器的在线检测快慢。
区域触发的一个典型搭配是多设备共识:家里两个人,只有「所有人都离开」才算离家。实现思路是写条件判断所有 tracker 的状态,或干脆维护一个「家里有几个人」的传感器。第 3 章「回家与离家」一篇会给出完整方案。
区域触发的写法同样简洁,进和出是两个独立事件:
trigger:
- platform: zone
entity_id: device_tracker.my_phone
zone: zone.home
event: enter
开发时善用「开发者工具 → 状态」页面观察 tracker 的状态值,不同集成返回的字符串可能是 home/not_home 或具体围栏名,条件判断别写错。
选择触发器的三条原则
- 优先选窄的:能用 numeric_state 就别用 template,能用 state 就别监听总事件——越精确的触发器,误触发越少。
- 事件只在状态不够用时上:状态类天然带「变化」语义,事件类需要你自己描述「发生了什么」。
- 外部来源优先走官方集成:设备厂商有的集成先走集成,集成不支持再考虑 webhook、mqtt 这类通用通道。
再加一条经验之谈:一条自动化可以有多个触发器。触发器之间是 OR 关系,任何一个发生都会启动流水线。所以「按键按下」和「定时到点」可以共存于一条自动化,再用条件区分是谁触发的(通过 trigger.platform 或 trigger.entity_id 判断),逻辑紧凑又好维护。
最后提醒:触发器选好后,一定到「开发者工具 → 状态」里核对实体真实的状态值与精度。很多「不触发」的问题,根源只是实体返回的是字符串而不是数字,或者状态拼写与预期不符。先把数据看清楚,触发器才写得明白。
延伸阅读
- 存在检测与 device tracker 的完整方案,见本系列「回家与离家:存在检测实战」。
- MQTT 基础设施搭建可参考 《OpenWrt 入门》 中的服务章节,或直接在 NAS 上用 《群晖 DSM 指南》 的容器套件部署代理。
