MQTT(Home Assistant 自动发现)
把 rha 的实体发布出去。主要用途是 Home Assistant:桥会发一份符合 HA 自动发现约定的 配置,HA 那边零手工配置就能认出全屋设备。任何订阅得了 MQTT 的东西(Node-RED、Grafana、 自己写的脚本)同样能直接用。
[[bridge]]name = "ha"type = "mqtt"broker = "192.168.52.10:1883"password = "${MQTT_PASSWORD}"
export = ["plug_desk.*", "thermo_desk.*"]exclude = ["*.indicator"]name / export / exclude / enabled 是所有 bridge 共有的字段,说明在
bridges.toml;本页只讲 type = "mqtt" 的私有参数。
最小配置只要 broker 一行,其余全有缺省。
rha/<设备>/<能力>/state 实体当前值rha/<设备>/<能力>/set 往这里发就是下命令(仅可写实体)rha/<设备>/<能力>/availability 这个实体可不可用rha/status 桥自己在不在前缀 rha 由 base_topic 决定。
一个实体一条主题,不是一台设备一条 JSON。 三条理由,按重要性:
- rha 的状态单位就是实体。一台设备一条 JSON 意味着任何一个字段变化都要把整台设备的当前 值拼一遍发出去——而其中一部分可能是快照恢复的旧值、甚至根本 还没有值。发出去就等于替设备编了一份它没说过的完整状态。
- HA 的自动发现里每个实体各有自己的
state_topic。一条 JSON 就得给每条配置带value_template,而模板写错是静默的(HA 那边只表现为值永远 unknown)。 - 一个实体的读 / 写 / 可用性共用同一个前缀,broker 侧做 ACL 时一台设备一条规则就够。
桥自身的可用性是两段(rha/status)、实体主题是四段,撞不上——哪怕真有一台设备叫
status,它的实体主题也是 rha/status/<能力>/state。这个形状照抄 HA 自己的
homeassistant/status。
discovery = true(缺省)时,桥会往
homeassistant/<组件>/<base_topic>/<设备>_<能力>/config 发一份 retained 的配置。组件类型
由实体的语义类推出来——温度是 sensor、插座是 switch、
档位是 number、门铃是 event。
device 块用的是 devices.toml 里的 label / manufacturer / model,所以在 HA 里
看到的是「书桌插座 / Xiaomi / cuco.plug.v3」而不是一串 id。
单位取的是语义类的规范单位而不是 adapter 的方言:miot 报的 celsius 到 HA 那边是
°C。
改过 HA 的发现前缀才需要动 discovery_prefix。不想让 HA 掺和(只想拿数据喂 Grafana)
就 discovery = false,状态照发。
留存与遗嘱:断电之后还说得清
Section titled “留存与遗嘱:断电之后还说得清”发现配置和实体状态都是 retained(broker 替你记着最后一条)。不这样的话 HA 一重启就 把全屋 rha 实体丢了,要等每个实体各自下一次状态变化才逐个回来——温度计可能几分钟,门磁 可能几天。
瞬时事件(门铃按下这类)刻意不留存:它是「刚刚发生了一件事」,留存意味着任何新连上来 的客户端都会收到一次,等于门铃自己响了。
桥还挂了一条遗嘱(last will):连接非正常断开时由 broker 代发 rha/status = offline。
没有它,rha 被 kill -9 或者断网时 HA 那边会显示一切正常,实际早就没人在发数据了。优雅
关停时桥会自己先发一条 offline——正常断开会让 broker 丢掉遗嘱,那条必须自己补。
撤回:从 export 里去掉之后
Section titled “撤回:从 export 里去掉之后”发现配置 retained 意味着 broker 会永远替你记着。把一个实体从 export 里去掉之后,
那条配置还在,HA 每次重启都会重建一个再也收不到值的幽灵实体。
所以桥在自己的状态目录(<配置目录>/bridges/<name>/)里记了一份「上次宣告过哪些主题」,
下次启动往消失的那些发一条空 payload 把配置撤回。删掉那个文件不会出错,只是那一批旧配置
从此没人撤得掉,得自己去 broker 上清。
两类实体导不出去
Section titled “两类实体导不出去”都会在 rha check 阶段点名报出来,不会静默丢:
- 字符串档位(空调伴侣的
"small_fan"/"large_fan"这种)。HA 的select需要一份 选项列表,而 rha 的取值域目前只装得下整数。 - 没有取值范围的数值档位。HA 的
number必须带min/max,硬给一个 0–100 是撒谎 ——一台 1–4 档的风扇会画出一根拖到 57 就失败的滑条。
用 exclude 排掉它们即可。
和南向的 mqtt adapter 共用连接
Section titled “和南向的 mqtt adapter 共用连接”如果你同时用了 mqtt adapter 读设备,两边连的是同一个中枢。
不过桥有自己的 client id(缺省 <base_topic>-bridge),所以在 broker 上是一条独立连接
——它必须独立,遗嘱是逐连接的属性。
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
base_topic | string | 可省略 | 所有主题的前缀, 缺省 只能是一段, 且只能用 |
broker* | string | — | broker 地址, 不要带 |
client_id | string | 可省略 | 本桥的 MQTT client id, 缺省 桥必须有一个与南向设备不同的 client id: 遗嘱(last will)是连接级属性,
而 同一个局域网里跑两套 rha 指向同一个 broker 时必须给它们不同的值(或者不同的
|
discovery | boolean | 可省略 | 要不要发自动发现配置, 缺省开。 关掉之后状态照发, 只是 HA 不会自动认出实体(得自己写 YAML)。给的是 「只想喂 Node-RED / Grafana, 别往 HA 里塞东西」这种场景。 |
discovery_prefix | string | 可省略 | Home Assistant 的自动发现前缀, 缺省 |
keep_alive_secs | integer | 可省略 | 心跳间隔秒数, 默认 60。 |
password | string | 可省略 | broker 密码。建议写成 敏感值。建议写成 ${ENV} 由环境变量插值, 不要把明文提交进配置文件。该值绝不进日志与 trace。 |
username | string | 可省略 | broker 账号。broker 开了匿名就不用写。 |