chore: 提交高层 xiaomi 封装库及示例

- 新增 xiaomi/examples/ 下 8 个示例程序(用户/家庭查询、设备列表、开关/灯光/空调控制、属性订阅、高级过滤分类、SPEC 解析)
- miot_client_sub.go: 重构 SubProp/SubEvent,使用 buildPropTopic/buildEventTopic 支持通配符订阅(siid/piid=0 → +),并修复锁顺序问题(将 RequestRefreshProp 移到 Lock 外)
- spec_parser.go: 新增 downloadSpecFile 方法,本地 SPEC 文件缺失时自动从 miot-spec.org 下载
- ARCH_PLAN.md: 架构设计从 Proposed 更新为 Accepted(v1.0→v1.1),补充设备分类/工厂/SPEC 映射等模块设计
- xiaomi/: 新增 miot 上层强类型封装模块,包含 Client 主入口、用户/家庭/设备 API、属性读写、动作调用、订阅通知,以及 devices/ 设备控制抽象(Switch/Light/AirConditioner/Fan/Cover/Humidifier/Vacuum/WaterHeater/Thermostat)和 specs/ SPEC 查询辅助
- 更多 xiaomi 示例(风扇/窗帘/传感器控制)
This commit is contained in:
2026-06-29 08:51:21 +08:00
parent 35efed7d15
commit a3d94c4b9f
93 changed files with 7582 additions and 157 deletions
+89
View File
@@ -0,0 +1,89 @@
# xiaomi/ 封装层实施报告
> 状态:Phase 1-4 Complete | 日期:2026-06-28
---
## 实施摘要
按 ARCH_PLAN.md 完成了 `xiaomi/` 上层封装包的 Phase 1-4 全部实现。
### 文件清单(25 个 Go 源文件 + 文档)
```
xiaomi/
├── types.go # 强类型结构体定义
├── errors.go # 封装层错误定义
├── client.go # Client 主入口
├── convert.go # map → 类型安全提取工具
├── user.go # GetUserInfo
├── homes.go # GetHomeList/GetHome/GetRooms/GetRoomDevices
├── devices.go # GetDevices/GetDevice/RefreshDevices + DeviceFilter
├── properties.go # GetProp/SetProp/GetProps/SetProps
├── actions.go # Action
├── subscribe.go # SubProp/SubEvent/SubDeviceState(强类型回调)
│
├── devices/
│ ├── base.go # BaseDevice 基础实现
│ ├── switch.go # Switch 接口 + impl
│ ├── light.go # Light 接口 + impl
│ ├── air_conditioner.go # AirConditioner 接口 + impl(含 ACMode/FanSpeed/SwingMode)
│ ├── fan.go # Fan 接口 + impl
│ ├── cover.go # Cover 接口 + impl
│ ├── humidifier.go # Humidifier 接口 + impl
│ ├── vacuum.go # Vacuum 接口 + impl
│ ├── water_heater.go # WaterHeater 接口 + impl
│ ├── thermostat.go # Thermostat 接口 + impl
│ └── factory.go # Create() 工厂函数(URN 自动路由)
│
├── specs/
│ └── resolver.go # PropertyResolver(SPEC 语义→siid/piid)
│
├── examples/
│ └── main.go # 完整使用示例
│
├── migration/
│ └── IMPLEMENTATION.md # 本实施报告
│
└── README.md # API 文档
```
### 测试文件(5 个,对应 3 个包)
```
xiaomi/
├── convert_test.go # strVal/intVal/boolVal/strSliceVal
├── errors_test.go # 哨兵错误/ClientError/wrapErr
├── types_test.go # DeviceInfo/HomeInfo 解析 + JSON 序列化
├── devices_test.go # DeviceFilter 组合
├── subscribe_test.go # PropHandler/EventHandler/DeviceStateHandler
xiaomi/devices/
└── devices_test.go # toInt/toFloat/常量一致性/matchURN/Create
xiaomi/specs/
└── resolver_test.go # FindByType/FindByFormat/FindByDescription/FindAction
```
### 关键设计决策
| 决策 | 说明 |
|------|------|
| **子包非独立 module** | `xiaomihome/xiaomi` 作为主模块子包,无独立 go.mod |
| **NewClient 双参数** | `(inner *miot.MIoTClient, httpClient *miot.MIoTHttpClient)`,因 GetUserInfo/GetHomeInfos 仅在 MIoTHttpClient 上 |
| **设备构造降级策略** | 可选属性(如电辅热/摆风)独立解析,失败不阻塞构造 |
| **内置 specResolver** | BaseDevice 内置轻量 SPEC 解析器,避免所有设备文件都 import specs 包 |
### 验证状态
- `go build ./xiaomi/...` — 通过
- `go vet ./xiaomi/...` — 通过
- `go test ./xiaomi/...` — 3 个测试包全部通过
### 测试覆盖
| 包 | 测试文件 | 测试函数 | 状态 |
|----|---------|---------|------|
| `xiaomi` | 5 | 18 | PASS |
| `xiaomi/devices` | 1 | 7 | PASS |
| `xiaomi/specs` | 1 | 8 | PASS |