我在本地的服务器上跑 Home Assistant 已经两年多了,最初那几十条自动化用自带的 YAML 拖拖拽拽也完全够用,但是规则一旦超过三十条,整个人就开始难受:一个传感器状态变化可能同时触发四五条自动化,改 A 的时候总会莫名其妙牵连出 B 的问题,想排查“哪条规则把灯关了”都要在日志里翻半天。后来我把自动化引擎逐步迁移到 AppDaemon,用纯 Python 重写核心逻辑和状态机,才真正觉得自动化这条路走通了。
这篇文章从零开始,记录我如何在本地部署 AppDaemon、把它和 Home Assistant 接入,写出一批实用的自动化应用,最后再把整个 HA 系统安全地发布到外网访问。适合已经跑通 HA 基础功能、想进一步提升自动化能力和远程访问体验的朋友参考。
1. 为什么我弃了 YAML 自动化:从第 30 条规则开始失控
1.1 单一职责的自动化在变多之后会怎样
Home Assistant 自身的自动化并不差,它把触发条件、执行动作拆得明明白白,对入门非常友好。但它的表达上限停留在“条件 + 动作”这个模式上,而现实中的家庭自动化场景根本不是这个形态,更多是带时序、带分支、带状态记录的东西。
举个例子:我走廊的灯需要“有人在且照度低于某个值才开,并且 5 分钟后自动关,如果这期间人一直在动就不断往后延时”。用 YAML 写的话,trigger 里面要同时监听人体传感器和照度传感器,condition 要判断时间区间,动作里还要依靠 delay_on 或者再定义一条“重置倒计时”的自动化来配合。这套逻辑用 YAML 表达勉强能用,但可读性已经非常差了,之后想再加一个“晚上 11 点后降低亮度”的分支,整个自动化就得推翻重写。
当自动化数量超过 30 条之后,另一个问题开始放大:自动化之间相互影响。比如“离家模式”把所有灯关了,但“观影模式”可能同时在执行开灯动作,两个自动化抢同一个实体状态,最后结果取决于谁后执行。这类问题在 YAML 里极难排查,因为自动化是扁平结构,没有任何图层和优先级的概念。
1.2 AppDaemon 在自动化体系里的真实定位
AppDaemon 是一个独立运行的 Python 自动化引擎,它通过 WebSocket 长连接实时监听 Home Assistant 的事件和状态变化。你可以理解成:HA 负责设备接入和数据采集,AppDaemon 负责“思考”和决策,两者各管一摊。
AppDaemon 和 HA 自带自动化的本质区别在于,它给你的是一个完整的 Python 运行时。你可以定义类、写循环、用第三方库,甚至在自己的 App 里维护一份长期状态。原本 YAML 里绕来绕去的东西,在 Python 里就是几行代码的事。
比如刚才说的走廊灯逻辑,AppDaemon 里可以这样写:
python复制import appdaemon.plugins.hass.hassapi as hass
class MotionLight(hass.Hass):
def initialize(self):
self.sensor = self.args.get("sensor")
self.light = self.args.get("light")
self.delay = self.args.get("delay", 300)
self.timer = None
self.listen_state(self.on_motion, self.sensor, new="on")
def on_motion(self, entity, attribute, old, new, kwargs):
if self.timer:
self.cancel_timer(self.timer)
self.turn_on(self.light)
self.timer = self.run_in(self.turn_off_light, self.delay)
def turn_off_light(self, kwargs):
self.turn_off(self.light)
self.timer = None
每次检测到“有人”事件就把旧的定时器取消,再开灯并重新设定时器。这个重试逻辑在 YAML 里可以实现,但绝对没有这么直白。而且这里的 timer 是保留在 App 对象里的,你完全清楚当前这个流程走到了哪一步,不会出现改了一条规则还要全局搜索引用的情况。
1.3 什么情况下不建议上 AppDaemon
虽然我推荐 AppDaemon,但它不是银弹。如果你的自动化只有十来条,用 HA 自带的可视化编辑就够,硬要上 AppDaemon 只会增加维护成本。另外,对编程完全没有概念的朋友也不要强行引入,因为 AppDaemon 的应用文件本质上就是 Python 代码,涉及类、回调、参数注入这些概念,出问题的时候需要点编程功底来 debug。
还有一个容易被忽视的点:AppDaemon 是独立进程,相当于给整个智能家居系统多了一个故障节点。如果你家里的网络环境极不稳定,或者你希望整个系统越简单越好,那就要认真评估一下这些高级自动化是不是可以继续用 HA 自带的。就我个人经验来说,自动化规则超过 30 条、里面又带状态延时的,闭眼入 AppDaemon 不亏。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 部署前必须想清楚的目录结构与容器编排
2.1 两种部署方式对比:Docker 与裸机 pip
AppDaemon 官方支持 pip 安装,也支持 Docker 镜像。我强烈建议用 Docker,原因有三点:一是环境隔离,不会因为系统里的 Python 版本或者某个依赖库冲突搞坏整个自动化系统;二是升级和回滚异常方便,镜像标签切回去就还原了;三是容器可以通过 restart: unless-stopped 实现开机自启和崩溃自愈,这条对长期放在家里运行的设备来说太重要了。
如果你用的是 Home Assistant OS 或者 Supervised 安装方式,可以直接通过 Add-on 商店装社区版 AppDaemon Add-on。但我本地的 HA 是 Docker 部署的,所以这篇顺着 Docker Compose 的路线写。
2.2 我采用的目录布局和各文件职责
我所有智能家居相关服务都放在一个根目录下统一管理,这样备份和迁移都很方便。目录结构如下:
text复制/srv/smarthome/
├── docker-compose.yml
├── ha_config/ # Home Assist
