米家体脂秤接入 Home Assistant
这事一开始挺拧巴的。
我的米家体脂秤其实已经进了 Home Assistant。设备页里能看到,米家集成也在,甚至还有几个看起来和称重有关的事件实体。按理说,既然 HA 都已经“认识”这台秤了,我上去称一次,体重、BMI、体脂率这些数据就应该跟着出来。
但实际不是这样。
HA 知道这台秤存在,却没有把我真正想要的身体数据同步出来。设备在那里,事件也在那里,可我准备拿来做记录的体重、体脂率、肌肉量这些值,还是不会自己更新。
我当时的感觉就是:门已经开了,但东西没进屋。
一开始我走了最省脑子的办法:让 SmartScaleConnect 定时跑。它本来就能从小米账号里拉体脂秤数据,再通过 webhook 发给 Home Assistant。我把它放在 FNOS 的 Docker 里跑,不想把这些东西都塞进 HA 虚拟机里。最开始设的是 5 分钟轮询,容器启动后每隔 5 分钟拉一次。
这个办法是能用的。日志里能看到同步成功,HA 里的 helper 也能被写进去。
但用起来总觉得不对。
我不是想要一个“每隔几分钟查一次有没有新数据”的东西。我想要的是很自然的那种体验:刚称完,过一小会儿,HA 里的身体数据自己变了。5 分钟轮询虽然解决了“迟早会同步”,但它不是我想要的“测完触发”。而且没新数据的时候也一直请求,多少有点笨。
后来真正让我停下来重新想的,是 HA 里那个很长的事件实体。
它大概长这样:
event.yunmai_cn_blt_3_1nmqkef804g01_ms103_customized_event_1_e_11_1022
名字也很长,大意是米家体脂秤 S400 的离线称重网关上报事件。每次我测量的时候,这个实体的状态都会更新。
我一开始看到它的时候,第一反应还是老路子:这是不是就是体脂秤的原始数据?能不能把里面的体重、阻抗、心率解出来?尤其是它还有一个类似“复合字段”的东西,看起来像是藏着什么。
但越看越别扭。
有些字段像是解析不出来,有些值看起来又不完整。继续往下搞,可能就要研究米家的 BLE 包、设备模型、字段含义,甚至还得考虑不同固件和区域差异。那条路当然也能研究,但它已经偏离了我最初的目的。
我不是想写一个米家体脂秤协议解析器。
我只是想在自己称完之后,让 HA 更新一下身体数据。
想明白这一点以后,事情就简单了很多:这个事件本身不需要被解析。它只要出现变化,就已经告诉我一件事:我刚刚测量了。
也就是说,它不用负责提供数据,只负责敲门。
真正的数据,还是交给 SmartScaleConnect 去小米云端拉。这样职责一下子清楚了:HA 里的米家事件告诉我“该同步了”,FNOS 上的 watcher 负责听这个事件,SmartScaleConnect 负责拿最新数据,最后 HA 通过 webhook 接收结果。
所以最后我在 FNOS 上多放了一个很小的 watcher 容器。它什么复杂逻辑都不做,只连到 Home Assistant,盯着那个事件实体。一旦事件状态变化,它不马上动手,而是先等 20 秒。这个等待很重要,因为事件到了不代表小米云端的数据已经完全落好了,太着急去拉,偶尔会拿到旧值。
20 秒之后,watcher 通过 Docker socket 临时启动一次 SmartScaleConnect,让它用同一个 scaleconnect.yaml 跑一遍同步。同步完,临时容器清掉。HA 那边的 webhook 收到 JSON,再把体重、BMI、体脂率、水分、肌肉量这些字段写进我准备好的 helper。
整个流程变成了这样:
```mermaidflowchart LR A[称一次体脂秤] --> B[HA 里的米家事件变了] B --> C[FNOS watcher 发现变化] C --> D[等 20 秒] D --> E[跑一次 SmartScaleConnect] E --> F[webhook 写回 HA]```
这套东西跑起来之后,体验就顺多了。不是我去等轮询,而是称重这件事本身把同步带起来。
我也没有把原来的定时同步完全删掉,只是把 5 分钟改成了 24 小时。平时靠事件触发,主容器每天跑一次当兜底。万一 watcher 重启、HA 漏了事件,或者小米云有点抽风,至少不会一直停在那里。
最后 HA 里展示的部分,我没有直接依赖米家集成暴露出来的那些实体,而是自己建了一组 helper。体重、BMI、体脂率、体水分、肌肉量、骨量、内脏脂肪、基础代谢、心率,还有上次同步时间,都放进一个“身体数据”分组里。这样后面我要做仪表盘、历史趋势,或者接到自己的生活管理系统里,数据入口都是稳定的。
回头看,这次折腾最容易走偏的地方,其实就是那个“解析不出来的数据”。
刚看到它的时候,很容易觉得问题就在这里:只要把它解析出来,一切就好了。但对我的需求来说,它根本不需要被解析。它的意义只是证明“测量发生了”。拿它做触发器,比硬啃原始包更稳,也更省事。
现在这套链路基本就是:
我上秤HA 的米家事件更新FNOS 触发一次同步HA 的身体数据更新
它不花哨,但正好够用。
对我这个项目来说,这种自动化才是我想要的:不用每天想着去同步,也不用把 HA 弄得很重。称完之后,数据自己进来,后面才能拿它去做真正有用的东西,比如趋势、提醒,或者日常状态建议。
