跳转到内容

热加载

改完配置敲一条命令就生效,不用重启进程:

Terminal window
rha reload

等价写法有两个:给进程发 SIGHUP,或者 systemd 部署下 systemctl reload rha (packaging/rha.service 里的 ExecReload 走的就是这条)。

最要紧的一条性质:不存在把系统搞挂的路径

Section titled “最要紧的一条性质:不存在把系统搞挂的路径”

reload 是 check-then-swap:新配置完整校验通过才切换,任何一条错都整份拒绝, 旧配置继续原样跑。

所以敲 rha reload 最坏的结果是「它拒绝了,并告诉你哪里写错了」,不会出现「一半新配置 一半旧配置」的中间状态。这个性质是刻意保出来的,代价是 reload 的实现里有一条铁律: 校验全部通过之后才允许动任何现役状态。

想在改之前先确认,用离线校验(它不碰网络、不连设备):

Terminal window
rha check
改了什么 要不要重启
automations/*.toml(规则与命名动作) 不用
devices.toml(加 / 删 / 改设备) 不用
bridges.toml 要重启
rha.toml 的 [api] / [storage] / [llm] / [notify] 要重启
spec.d/*.toml(miot 型号表) 要重启

设备增删改:只动该动的那几台

Section titled “设备增删改:只动该动的那几台”

加一台温湿度计不会重启整个 daemon。既有设备的连接、会话、轮询节奏都不受影响, 只有新那台会起来。

这一点值得强调,因为它决定了运维体感。「加个设备要重启」意味着 HomeKit 桥断开重连、 BLE 重新扫描、所有小米设备重新握手、面板会话全掉——而真正变的只有一台设备。

三类改动分别怎么处理:

  • 加:起一个新的设备任务,注册它的实体。
  • 删:停掉那台的任务,摘掉它的实体。
  • 改(比如 IP 变了):停旧的、用新参数起一个——等价于只重启这一台。

判断“变没变”看的是 devices.toml 里那一条的原文,不只是连接参数。所以只改 label(显示名)也会重起那台设备。这是刻意的:不这样的话改显示名会 reload 报成功, 而北向协议里显示的还是旧名字。代价只是一次重连。

删设备时,规则还引用着它怎么办

Section titled “删设备时,规则还引用着它怎么办”

整份配置会被拒绝,并点名是哪条规则、哪个实体挡着:

automations (卧室太热开风扇): trigger entity "thermo.temperature" does not exist

这不需要单独实现——被删设备的实体在新配置里已经不存在,而「规则引用不存在的实体」本来 就是加载期错误。与 nginx 拒绝加载坏配置是同一个语义:先把规则改了,再删设备。

不是没做,是这几样在启动时就固化进了运行中的组件,热切换会留下比重启更糟的状态:

  • [llm] / [notify]:启动时已经固化进动作执行器。不拦的话,改了配置会看着 reload 成功,实际运行时静默沿用旧设置——那是最难查的一类不一致。
  • spec.d/(miot 型号表):校验用的是启动时读进来的那一份,而不是重新读一遍。 否则「加一个型号文件 + 一台用它的设备」会通过校验,但跑着的 adapter 手里没有那个型号, 于是它一遍遍启动失败,而 reload 报的是成功。
  • [api]:监听地址与 token 换了要重建监听器与认证状态。
  • [storage]:后端连接与历史记录订阅在启动时建立。
  • bridges.toml:桥的配对状态、端口、广播都是启动时建立的。

改了它们敲 reload 会被明确拒绝(而不是接受了却不生效):

[api]/[storage]/[llm]/[notify]/bridges.toml changes require restart
(only rules/actions/devices are hot-reloadable)

一次成功的 reload 里,这些会自动跟上,不用你操心:

  • 轮询分层。哪些实体值得每轮都问一遍(fast)是从规则集推导的,加一条用到某实体 的规则,它自动变 fast。定义是「被规则引用 ∪ 被任一桥导出」——「我把它导出到 HomeKit」 等价于「有人会实时看它、点它」,语义上就是 hot。
  • /api/devices 的设备清单(人话名字、厂商、型号)。
  • /metrics 里的设备数与实体数(下一次抓取就是新的)。

MCP 的 upsert_rule / delete_rule 与 rha reload 共用同一把锁和同一套 校验。模型起草的规则会被完整校验,通过才原子生效,失败则把诊断返回给它自己修—— 写错的规则进不了运行时。

reload 成功时日志里有一行,写明这次动了哪几台设备:

INFO rha_daemon::reload: device set reloaded without restarting the daemon
added=["thermo_desk"] removed=[] changed=[]

三个都是空的说明这次只换了规则,没碰设备。

reload 之后规则的行为不符合预期,用 rha trace <规则名> 看它的评估记录——那里有触发内容、 每个条件的实际值与判定、以及动作结果。