智能家居搭好之后,大多数人只关心一件事:能不能跑通。跑通了就转头去折腾下一个设备,至于自动化多久查一次传感器、多久给设备发一次请求,很少有人再回头看。等到设备越接越多,这些后台动作才开始显形。我最近重新翻了一遍自己的配置,砍掉不必要的轮询,对自动化什么时候触发、Home Assistant 记录什么变得更挑剔,系统跑起来温度更低,响应也更快了。
自动化在反复检查根本没变的东西
基于时间的触发器是让自动化跑起来最省事的办法,问题在于它会一直按表执行,哪怕什么都没发生。房间可能空了好几个小时,自动化照样一遍遍确认有没有人在。
单次读取一个传感器的当前值本身不费什么算力。麻烦出在这些检查还会顺带刷新设备、计算复杂模板,或者反复发送同一条命令。灯已经关了,就没有任何理由因为房间还是空的,每隔几分钟再告诉它关一次。
Home Assistant 支持基于状态的触发器,可以让自动化在事情真正发生变化时才运行。比如不必每隔几分钟查一次房间是否为空,而是让占用传感器检测到两分钟没人时触发自动化。用温度控制风扇也是同理,可以让它在温度越过某个阈值时触发,而不是一直盯着读数。
我审查自动化通常就从这里开始:看每条自动化在检查什么,能不能改成由状态变化直接触发。定时检查当然还有用武之地,尤其是周期性更新或者补漏的时候。
离线设备不需要被反复关照
有些设备可能一关就是几个小时,或者干脆断连。麻烦在于自动化仍然不停尝试和它们通信。每隔几秒发一条同样的命令什么也做不成,反复失败还会把日志塞满。
Home Assistant 允许在执行动作前先检查实体是否可用。设备不可用或状态未知时,自动化可以跳过发给它的命令。这在涉及多个设备的例程里特别有用:一台设备离线,整个例程不必失败,也不必一直去够它,其他设备照常干活。
还有一层值得看:Home Assistant 到底多久轮询这些设备一次。给自动化加可用性检查,并不会改变集成联系设备的频率。对支持关闭自动轮询的集成,可以关掉它,改用 homeassistant.update_entity 按合理的间隔请求更新。比如一个传感器每 15 分钟读一次就够,那就没什么理由每几秒刷新一次。
恢复这块要小心。有些集成依赖轮询来发现设备重新上线,如果彻底停掉轮询,Home Assistant 可能永远不知道设备又回来了。我的做法是保留一个更慢的周期检查,或者用别的触发方式请求更新,比如智能插座重新通电。设备一旦可用,自动化再去判断还需不需要做点什么。
不是每次更新都值得响应
用 Home Assistant 久了会明白另一件事:不是东西一变,你就希望自动化立刻反应。传感器并不完美,读数会上下浮动。存在传感器可能在你明明坐着的时候,短暂报告房间没人。自动化要是立刻响应,灯就会莫名其妙地关掉。上报功耗的电器也一样,运行过程中读数会来回跳。
简单的处理办法是要求某个条件持续成立一段时间再触发动作。以洗衣机为例,可以设置成功率降到某个阈值以下时通知你。但洗衣机在阶段之间会短暂停止大功率取电,你不希望每次出现这种情况都收到通知。可以让功耗在该阈值以下持续三到五分钟,Home Assistant 才认为这一轮洗完了。
同理,我宁愿让存在传感器多花两分钟确认房间确实空了,再关灯。这是有意加的一点延迟,换来的是自动化可靠得多。我也开始更留意 Home Assistant 数据库里存了什么。很多传感器更新频繁,我想在面板上看到当前读数,但不一定需要它把每一次变化都记进历史。
Recorder 里有个 commit_interval 设置,可以控制 Home Assistant 向数据库提交变更的频率。调大这个间隔能把更多写入合并,减少磁盘 I/O,代价是一旦在提交前崩溃,可能丢掉更多最近的更新。
Home Assistant 本身已经相当高效,但随着智能家居规模变大,不必要的后台活动会累积起来。回头翻翻旧自动化、减少轮询、清理数据库记录,差别是能感觉到的。如果你已经用了一段时间,值得看看自己的自动化到底在忙些什么。
热门跟贴