- README 新增有意差异一节:设备列表语义(剔除米家已删设备)与缓存持久化内容的两条有意偏离及其原因、剔除判定规则 - README 架构概览补齐 xiaomi/、bridge/ 两层目录说明 - xiaomi/README 更新 GetDevices/RefreshDevices 签名(ctx),补充设备列表语义、家庭范围刷新示例与数字档位风速映射说明
12 KiB
go-xiaomihome 项目介绍
项目概述
go-xiaomihome 是小米智能家居 Home Assistant 集成(ha_xiaomi_home)的 Golang 移植版。
将原 Python 版核心 miot 包完整移植为 Go 版本,保持 API 语义与行为严格对齐,目标是提供一个高性能、可独立使用的小米 IoT(MIoT)核心 SDK。
(对齐是默认原则,少数有意偏离的地方集中在「与 Python 原版的有意差异」一节,改动前请先读它。)
Python 原版:
ha_xiaomi_home/custom_components/xiaomi_home/miot/
Go 移植版:go-xiaomihome/miot/
核心目标
- 严格对齐:Go 版
miot包与 Python 版功能严格对齐,行为一致(有意差异见下一节) - 独立可用:移植后的
miot包可作为独立 SDK 被任何 Go 项目引用 - 高性能:利用 Go 的并发优势,提升设备发现、消息订阅等场景的性能
- 易维护:保留 Python 版的文件/模块结构,对应关系清晰
与 Python 原版的有意差异
移植以「行为对齐」为默认原则,但以下差异是有意为之,请勿以「对齐上游」为由改回去:
| # | 差异点 | Python 原版 | 本库 | 原因 |
|---|---|---|---|---|
| 1 | 设备列表语义 | 设备从云端消失时只把 _device_list_cloud[did]['online'] 置为 None、并把 _device_list_cache 里该项重算为离线(miot_client.py __update_devices_from_cloud_async),永不删除缓存项 |
RefreshDevices 会把云端已不存在的设备真正剔除(pruneRemovedDevicesLocked),并连带清理网关/局域网状态、设备实例与 MQTT 订阅 |
原版服务于 Home Assistant 的设备注册表,需要长期保留历史设备;本库使用方的契约是「设备列表 == 米家当前设备」,列表接口不该返回米家已删除的设备 |
| 2 | 设备缓存持久化的内容 | .dict(miot_devices)保留所有曾见过的设备,含已被删除的 |
.dict 只保留米家当前设备 |
剔除结果在刷新末尾即落盘;否则下次启动 loadCacheDevice 会把已删设备从磁盘「复活」 |
第 1 条的剔除判定规则(实现在 miot/miot_client_device.go):
- 云端返回空列表时跳过剔除(接口抖动/鉴权异常不清库);
- 候选集是「缓存 ∪ 云列表」——必须遍历缓存,否则启动时
deviceListCloud尚为空, 会漏掉「服务停机期间在米家被删除」的设备; - 网关或局域网仍报告在线的设备保留(云端列表可能还没同步到);
- 子设备 DID(
xxx.s1)不参与判定,它被归并到父设备的sub_devices中; - 传入
homeIDs时只在这些家庭范围内剔除,不会误删其它家庭的设备。
bridge 层同步处理:pruneControllers 会剔除已删设备的控制器,AC()/Switch() 等
访问器不再为米家已删除的设备返回实例。
架构概览
go-xiaomihome/
├── go.mod # Go 模块定义 (module: xiaomihome)
├── go.sum
├── README.md # (待完善)
├── miot/ # 核心 MIoT SDK (与 Python miot/ 严格对齐)
├── miot_client.go # 主客户端 (设备管理和协调核心)
├── miot_client_api.go # 外部 API 接口
├── miot_client_device.go # 设备管理方法
├── miot_client_prop.go # 属性刷新管理
├── miot_client_sub.go # 订阅管理 (MQTT/mDNS/LAN)
├── miot_cloud.go # 云服务 HTTP API 客户端 + OAuth
├── miot_device.go # 设备模型 (MIoTDevice)
├── miot_error.go # 错误码定义
├── miot_storage.go # 本地存储 (cert/dict/device data)
├── miot_lan.go # LAN 局域网控制 (UDP 9588)
├── miot_mdns.go # mDNS 服务发现 (MIPS)
├── miot_network.go # 网络状态监控
├── mips_client.go # MIPS MQTT 客户端 (云端+本地)
├── spec_parser.go # MIoT SPEC 解析器 (设备能力描述)
├── miot_i18n.go # 国际化 (i18n/)
├── miot_matcher.go # 订阅匹配器 (Matcher)
├── common.go # 工具函数
├── const.go # 常量定义
├── web_pages.go # OAuth 重定向页面
├── examples/ # 使用示例 (9个)
├── i18n/ # 多语言 JSON 文件 (12种语言)
├── specs/ # SPEC 解析配套文件
├── lan/ # LAN 控制配套文件
├── migration/ # 移植文档 (13个模块详细对照)
└── *_test.go # 单元测试
├── xiaomi/ # miot 的强类型上层封装 (Client + devices 控制抽象)
├── client.go # xiaomi.Client,包装 MIoTClient + MIoTHttpClient
├── devices.go # GetDevices/GetDevice/RefreshDevices + DeviceFilter
├── properties.go # 属性读写
├── actions.go # Action 调用
├── subscribe.go # 属性/事件/在线状态订阅
├── devices/ # 设备控制抽象 (AirConditioner/Light/Switch/Fan/Cover/...)
└── specs/ # SPEC 属性解析器 (按功能语义查 siid/piid)
└── bridge/ # 业务桥接层 (Pool 连接池 + Bridge 类型化访问器)
├── bridge.go # Bridge/Pool、控制器集合、pruneControllers
├── account.go # 账号/Token/家庭/设备刷新
└── subscribe.go # 属性变化 / 在线状态回调分发
核心模块说明
1. MIoTClient (miot_client.go)
主客户端,管理所有子模块,是整个 SDK 的入口。
核心职责:
- 设备管理(云端/网关/本地三路合并)
- 定时器管理(Token 刷新、证书刷新、属性刷新)
- 订阅协调(云端 MQTT / 本地 MIPS / LAN)
- 回调通知(
persistenceNotify)
对齐 Python:miot_client.py MIoTClient 类
2. MIoTHttpClient + MIoTOauthClient (miot_cloud.go)
小米云服务的 HTTP API 客户端,包含 OAuth2 授权流程。
核心功能:
MIoTHttpClient:封装所有 REST API 调用(设备列表、属性读写、SSEC 加密等)MIoTOauthClient:OAuth2 授权码流程(生成授权 URL、轮询 token、刷新 token)- SSEC 服务端加密(AES-128-CBC)
对齐 Python:miot_cloud.py MIoTHttpClient + MIoTOauthClient
3. MIoTDevice (miot_device.go)
设备模型,描述单个小米设备的完整状态。
核心字段:
- 设备元数据(did/model/name/online 等)
- SPEC 实例(MIoTSpecService 树)
- 属性/事件/Action 的读写缓存
- LAN 控制相关(token/io 端口/宏定义)
对齐 Python:miot_device.py MIoTDevice 类
4. MIoTSpecParser (spec_parser.go)
解析小米 IoT SPEC 描述文件,构建设备能力模型。
核心功能:
- 从云端或本地加载 SPEC 标准库(14 天缓存)
- 解析 JSON 格式 SPEC,生成
MIoTSpecService/MIoTSpecProperty/MIoTSpecEvent/MIoTSpecAction树 - 支持多语言(从
i18n/加载)
对齐 Python:miot_spec.py MIoTSpecParser
5. MIoTLan (miot_lan.go)
局域网控制,通过 UDP 9588 端口与设备直接通信。
核心功能:
- 设备发现(广播
{"dev": "1234"}) - 属性读取(
get_prop) - 属性写入(
set_prop/enable_prop) - Action 调用(
action) - 事件订阅(通过
MIoTMatcher)
对齐 Python:miot_lan.py MIoTLan
6. MipsClient (mips_client.go)
MIPS(小米智能平台服务)的 MQTT 客户端,支持云端和本地两种模式。
核心功能:
MipsCloudClient:连接小米云端 MQTT BrokerMipsLocalClient:连接本地网关 MQTT Broker- 设备状态订阅/发布
- 自动重连
对齐 Python:miot_mips.py MipsCloudClient + MipsLocalClient
7. MIoTStorage (miot_storage.go)
本地存储管理,处理证书、设备字典、SPEC 等文件的读写。
存储内容:
cert/:MQTT 证书(PEM 格式)miot_devices/:设备字典(.dict文件)miot_specs/:SPEC 标准库(.dict文件)logs/:日志文件
对齐 Python:miot_storage.py MIoTStorage
8. MIoTMdns (miot_mdns.go)
mDNS 服务发现,用于发现本地网络中的 MIPS 网关。
核心功能:
- 监听
_miot_mips._tcp.local.服务记录 - 解析 SRV/TXT 记录,提取 group_id/IP/port
- 服务状态变化回调
对齐 Python:miot_mdns.py MipsService
9. 其他模块
| 模块 | 文件 | 功能 |
|---|---|---|
| 错误码 | miot_error.go |
定义 MIoTErrorCode 枚举和 MIoTError 结构体 |
| 常量 | const.go |
OAuth URL、平台列表、不支持型号等常量 |
| 网络监控 | miot_network.go |
网卡状态监控、ping 检测 |
| 国际化 | miot_i18n.go |
多语言翻译,加载 i18n/*.json |
| Matcher | miot_matcher.go |
属性/事件订阅的快速匹配器 |
| 工具函数 | common.go |
CalcGroupID、LoadJSONFile、Slugify 等 |
移植进度
根据 MIGRATION_PLAN.md,移植工作分四批完成:
| 批次 | 优先级 | 模块数 | 状态 |
|---|---|---|---|
| 第一批 | P0 基础架构 | 7 | ✅ 完成 |
| 第二批 | P1 高级功能 | 3 | ✅ 完成 |
| 第三批 | P2 LAN 控制 | 2 | ✅ 完成 |
| 第四批 | P3 附加功能 | 2 | ✅ 完成 |
总计:14/14 全部完成
详细审核结果见各批次 BATCH*_REVIEW.md 和 ROUND*_REVIEW.md。
依赖项
// go.mod
require (
github.com/eclipse/paho.mqtt.golang v1.5.1 // MQTT 客户端
github.com/hashicorp/mdns v1.0.7 // mDNS 服务发现
gopkg.in/yaml.v3 v3.0.1 // YAML 解析
)
使用示例
miot/examples/ 下提供了 9 个独立可运行示例:
| 示例 | 路径 | 功能 |
|---|---|---|
| 完整客户端 | examples/full_client/ |
演示完整 MIoTClient 使用流程 |
| 云端设备 | examples/cloud_devices/ |
从云端获取设备列表 |
| OAuth 授权 | examples/cloud_oauth/ |
OAuth2 授权码流程 |
| LAN 控制 | examples/lan_control/ |
局域网设备控制 |
| mDNS 发现 | examples/mdns_discovery/ |
发现本地 MIPS 网关 |
| MIPS 订阅 | examples/mips_subscribe/ |
订阅设备状态变化 |
| 网络监控 | examples/network_monitor/ |
网络状态监控 |
| SPEC 解析 | examples/spec_parser/ |
解析设备 SPEC |
| 存储管理 | examples/storage_manage/ |
证书/设备管理 |
文件对照表
| Python 文件 | Go 文件 | 状态 |
|---|---|---|
miot_error.py |
miot_error.go |
✅ |
const.py |
const.go |
✅ |
common.py |
common.go |
✅ |
miot_storage.py |
miot_storage.go |
✅ |
miot_cloud.py |
miot_cloud.go |
✅ |
miot_client.py |
miot_client.go + api/device/prop/sub.go |
✅ |
miot_device.py |
miot_device.go |
✅ |
miot_spec.py |
spec_parser.go |
✅ |
miot_mips.py |
mips_client.go |
✅ |
miot_network.py |
miot_network.go |
✅ |
miot_mdns.py |
miot_mdns.go |
✅ |
miot_lan.py |
miot_lan.go |
✅ |
miot_i18n.py |
miot_i18n.go |
✅ |
web_pages.py |
web_pages.go |
✅ |
开发文档
移植过程中的详细文档均保存在 miot/migration/ 目录:
01-miot-client.md~13-miot-mdns.md:各模块第一轮移植详细设计R2-01-*.md~R2-14-*.md:第二轮方法级对齐审核记录MIGRATION_PLAN.md:总索引和进度跟踪ROUND2_PLAN.md/ROUND3_PLAN.md:后续优化轮次计划
许可证
与 Python 原版一致,遵循 Xiaomi proprietary license(非商业用途 Home Assistant 使用授权)。
最后更新:2026-09-15