Files
xiaomihome/README.md
T
4566704 7ae32bd012 docs: 补充「与 Python 原版的有意差异」说明与设备剔除/风速映射文档
- README 新增有意差异一节:设备列表语义(剔除米家已删设备)与缓存持久化内容的两条有意偏离及其原因、剔除判定规则
- README 架构概览补齐 xiaomi/、bridge/ 两层目录说明
- xiaomi/README 更新 GetDevices/RefreshDevices 签名(ctx),补充设备列表语义、家庭范围刷新示例与数字档位风速映射说明
2026-09-15 19:51:38 +08:00

310 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: 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*