【免费下载链接】MenuBarMijia
Control Xiaomi Mijia from your Mac menu bar or Windows tray. Home Assistant supported on macOS.
MenuBarMijia 是一款 Mac 菜单栏 / Windows 托盘的小米米家控制工具,支持同时接入 Home Assistant 与米家云直连两条数据源。它的双源设备去重算法(Join Key 多级匹配 + 整卡级择优评分)让同一台物理设备只出现一张卡片,并在家网络断开时自动无缝回落到云端,无需手动切换。
🎯 这篇文章用尽量少的代码,把「键怎么设计、分数怎么打、赢了怎么路由」讲清楚。
一、为什么"两边都在线"会出重复设备?
MenuBarMijia 的两种连接方式各有优势:
| 数据源 | 优势 | 短板 |
|---|---|---|
| Home Assistant(局域网 WebSocket) | 低延迟、实体能力全(TTS、场景、传感器) | 必须部署、离开家庭网络即不可达 |
| 米家云端直连 | 手机扫码即用、外网可远程控制 | 新型号依赖 MIoT 云端能力,延迟略高 |
如果简单把两边设备列表相加,同一台空调会出现两张卡片;如果把两边字段硬拼进同一张卡片再混发指令,乐观锁、撤销快照和状态回读会在两个不同步的数据源之间产生竞态撕裂。
设计决策记录在 docs/adr/0008-dual-source-device-deduplication.md,核心结论是三个词:配对、整卡、路由——先判定"是不是同一台设备",再整卡选出唯一胜出的数据源,最后所有指令只从胜出方下发。
⚠️ 注意:跨源合并目前仅在 macOS 端执行。Windows 端支持 Home Assistant、米家云与演示模式三选一单源切换。
二、键设计:两级身份匹配(Join Key)
"两台设备是不是同一台"是整个算法的地基。MenuBarMijia 采用多级降级匹配,匹配逻辑在 Sources/MijiaCore/DeviceDeduplicator.swift。
2.1 一级:硬件标识精确匹配
解析 HA 设备注册表的identifiers与connections(含实体unique_id),用三种硬证据配对:
- 小米
did:官方xiaomi_home集成把标识符写成<server>_<did>(如cn_123456789),xiaomi_miot则直接用裸did。MenuBarMijia 的规范化器 DeviceSourceIdentity.swift 会把这些变体拆解、小写化后还原出did候选集合; - MAC 地址:去掉分隔符、转小写成 12 位十六进制后比对;
- 配对顺序上先跑
did轮、再跑 MAC 轮,避免共享网关 MAC 抢走子设备的精确did匹配。
只有恰好一对一命中才会配对;一台 HA 设备匹配到多台米家设备时直接放弃该轮,宁可慢也不错配。
2.2 二级:同房同款唯一兜底
很多 HA 集成并不写入硬件标识。此时退到启发式规则:归一化后的同一房间内,两边各仅有唯一一台相同型号(或相同归一化名称)且相同类别的设备,才自动归并为一台。
关键设计是拒绝猜测:同房间有两台同款"小米灯"时不合并,两张卡片会原样保留,留给人工判断。兜底键的构造见 DeviceDeduplicator.swift,格式为「前缀:房间|归一化值|类别」,同名多实例会被计数排除。
三、评分策略:整卡级择优,而不是拼字段
配对成功后,两张候选卡片必须选出一个"胜出方"。规则按优先级排列(实现见 preferredCandidate):
| 优先级 | 规则 | 用户价值 |
|---|---|---|
| ① 在线优先 | 一边在线一边离线,直接选在线方 | 在家走 HA 低延迟;出门 HA 断连,同一张卡自动切到米家云 |
| ② 能力评分 | 两边都在线时,按可控特性项数量打分,分高者胜 | 自动挑"能控得动更多东西"的那一端 |
| ③ 同分 HA 优先 | 分数相同时选局域网的 Home Assistant | 稳定偏向低延迟路径 |
能力评分(capabilityScore)怎么做?它对每种设备类别逐项累加"这张卡实际暴露的可控/可读特性",例如:
- 🎙️ 音箱:媒体播放 +1、TTS 播报 +2、文本指令 +2、静音/睡眠等实体各 +1;
- 💡 灯光:开关 +1、亮度 +1、色温 +1、灯效列表非空 +2;
- 🌬️ 空调:开关/温度/模式/风速/摆风/室温各 +1;
- 🔌 插座:开关 +1、功率 +1、电量统计 +1、童锁 +1。
评分是卡级的:不会把 HA 的亮度字段和米家云的 TTS 字段拼成一张"缝合卡"。这样HomeStore的 3 秒乐观锁、逆向指令撤销与批量操作语义完全不用重写。
胜出后还有两个贴心细节:
- 房间互补:胜出方没分配房间、另一方有明确房间时,自动借用对方的房间归属;
- 手动固定:卡片右键可把来源固定为 HA 或米家云;固定只有在该源在线时才生效,离线仍走自动回退。
四、Canonical ID:切换来源时设置不丢
设备源来回切换最怕的是"星标、排序、卡片大小、自定义分组全乱了"。MenuBarMijia 给配对成功的双源设备分配一个统一稳定主键(Canonical ID),注册表定义在 DeviceSourceIdentity.swift。
它的键集合同时包含pair:HA id|米家 id、ha:HA id、mi:米家 id、共享的did:与mac:前缀键——只要任意一个键能对上,卡片就复用历史主键。再配合偏好 ID 记忆(用户已在米家源下收藏过某设备时优先沿用米家 ID),两端互相回退时收藏、排序、重命名完全保留。
五、路由层:一张卡只认一个后端
合并不是终点。DualSourceHomeProvider.swift 持续监听两条数据流,任何一端快照或连接状态变化都会重跑去重合并,并为每张卡记录当前路由(后端 + 源端设备 ID):
- 控制指令只发给胜出方,撤销逆操作也由同一后端生成;
- 状态回读、传感器历史、摄像头取流全部按路由转发;
- 摄像头流遇到路由切换时先停旧流再开新流,不会两条流叠播。
六、如何在你的 Mac 上体验双源去重
- 打开菜单栏面板的偏好设置 →「连接」页,分别填写 Home Assistant 服务器地址 + 长期访问令牌,并点击「扫码登录米家账号」完成云端直连;
- 两端配置完成后无需额外开关,应用会自动并行连接并合并重复设备;
- 面板底部状态栏展示双源连接状态,右键卡片可查看/固定当前驱动来源。
合并后,面板上每台设备只有一张卡片,常用控制、场景胶囊与全关动作照常工作:
七、延伸阅读
想深挖 HA 侧identifiers/connections线格式与各小米集成的写入差异,项目内有一份源码级调研文档:docs/research/ha-xiaomi-device-identity.md。配对与评分的回归用例在 Tests/MijiaCoreTests/DualSourceMergeTests.swift,双端集成测试见 Tests/MijiaCoreTests/DualSourceIntegrationTests.swift。
| 模块 | 文件 |
|---|---|
| 去重合并核心 | Sources/MijiaCore/DeviceDeduplicator.swift |
| 身份规范化与主键注册表 | Sources/MijiaCore/DeviceSourceIdentity.swift |
| 双源 Provider 与指令路由 | Sources/MijiaCore/DualSourceHomeProvider.swift |
| 设计决策记录 | docs/adr/0008-dual-source-device-deduplication.md |
一句话总结:用硬件标识说话、用能力评分决胜负、用稳定主键守设置——这就是 MenuBarMijia 让 HA 与米家云同时在线却从不重复的完整思路。
【免费下载链接】MenuBarMijia
Control Xiaomi Mijia from your Mac menu bar or Windows tray. Home Assistant supported on macOS.
相关推荐
TheRemoteFreelancer资源去重算法:如何避免重复收录同一平台
TheRemoteFreelancer资源去重算法:如何避免重复收录同一平台 你是否曾在自由职业平台列表中遇到重复出现的网站?同一平台多次收录不仅浪费用户浏览时
教程戴森球计划工厂蓝图:7000+ 免费产线布局,4 步装进游戏
戴森球计划工厂蓝图:7000+ 免费产线布局,4 步装进游戏 戴森球计划工厂蓝图仓库 FactoryBluePrints 收录了社区贡献的 7000 多张免费工
数据集VideOCR 的 SSIM 帧去重算法:如何省下 90% 的重复 OCR 计算
VideOCR 的 SSIM 帧去重算法:如何省下 90% 的重复 OCR 计算 VideOCR 是一款通过图形界面从视频中提取硬字幕的开源工具,支持 200
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考