- 改动:go.mod module 声明与全部内部导入路径补全为完整域名路径,README 同步 - 原因:裸模块名无法被 go get 解析,发版前必须修正为 GOPRIVATE 可拉取路径
310 lines
12 KiB
Markdown
310 lines
12 KiB
Markdown
# go-xiaomihome 项目介绍
|
||
|
||
## 项目概述
|
||
|
||
**go-xiaomihome** 是小米智能家居 Home Assistant 集成(`ha_xiaomi_home`)的 **Golang 移植版**。
|
||
|
||
将原 Python 版核心 `miot` 包完整移植为 Go 版本,保持 API 语义与行为严格对齐,目标是提供一个高性能、可独立使用的小米 IoT(MIoT)核心 SDK。
|
||
(对齐是默认原则,少数**有意偏离**的地方集中在[「与 Python 原版的有意差异」](#与-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`):
|
||
|
||
1. 云端返回**空列表**时跳过剔除(接口抖动/鉴权异常不清库);
|
||
2. 候选集是「**缓存 ∪ 云列表**」——必须遍历缓存,否则启动时 `deviceListCloud` 尚为空,
|
||
会漏掉「服务停机期间在米家被删除」的设备;
|
||
3. 网关或局域网仍报告在线的设备保留(云端列表可能还没同步到);
|
||
4. 子设备 DID(`xxx.s1`)不参与判定,它被归并到父设备的 `sub_devices` 中;
|
||
5. 传入 `homeIDs` 时只在**这些家庭范围内**剔除,不会误删其它家庭的设备。
|
||
|
||
`bridge` 层同步处理:`pruneControllers` 会剔除已删设备的控制器,`AC()`/`Switch()` 等
|
||
访问器不再为米家已删除的设备返回实例。
|
||
|
||
---
|
||
|
||
## 架构概览
|
||
|
||
```
|
||
go-xiaomihome/
|
||
├── go.mod # Go 模块定义 (module: git.zeroonesoft.cn/golib/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 Broker
|
||
- `MipsLocalClient`:连接本地网关 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
|
||
// 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*
|