Files
xiaomihome/miot/migration/01-miot-client.md
T
4566704 3a44cb9e6a feat: 初始化小米 IoT (MIoT) 智能家居 Go 库
- 实现 MIoT 客户端核心功能(MQTT 连接、设备管理、属性读写)
- 支持云端 API 调用与局域网设备发现(mDNS)
- 集成国际化(i18n)多语言支持
- 添加 MIoT 设备规约解析器(spec_parser)
- 包含单元测试与使用示例
2026-06-28 22:05:49 +08:00

285 lines
7.9 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.
# 01 - miot_client.py 移植计划
## 概览
| 项目 | 内容 |
|------|------|
| **Python 文件** | `py-miot/miot_client.py` (837行) |
| **Go 文件** | `go-miot/miot_client.go` + `miot_client_api.go` + `miot_client_prop.go` + `miot_client_sub.go` |
| **状态** | ⚠️ 部分实现 |
| **优先级** | 🔴 P0 |
| **预计工作量** | 8-12 小时 |
## Python 版本分析
### 核心类
#### MIoTClient
**位置**:第 31-837 行
**主要职责**:
- 小米 IoT 设备的主客户端类
- 管理设备列表、属性刷新、命令发送
- 协调多个子模块(OAuth、Cloud、MIPS)
**核心方法**:
| 方法名 | 行号 | 功能 | Go 状态 |
|--------|------|------|---------|
| `__init__` | 31 | 初始化客户端,加载配置 | ✅ 已完成 |
| `load_config` | 47 | 加载配置文件 | ✅ 已完成 |
| `save_config` | 68 | 保存配置文件 | ✅ 已完成 |
| `discover_devices` | 89 | 发现设备(从云端或本地) | ⚠️ 部分实现 |
| `get_devices` | 125 | 获取设备列表 | ✅ 已完成 |
| `get_device` | 142 | 根据 DID 获取单个设备 | ✅ 已完成 |
| `refresh_devices` | 163 | 刷新设备列表(从云端) | ⚠️ 部分实现 |
| `refresh_properties` | 201 | 批量刷新设备属性 | ⚠️ 部分实现 |
| `send_command` | 267 | 发送控制命令 | ⚠️ 部分实现 |
| `subscribe_prop` | 345 | 订阅属性变化 | ❌ 缺失 |
| `unsubscribe_prop` | 389 | 取消订阅属性变化 | ❌ 缺失 |
| `start_monitor` | 423 | 启动属性监控线程 | ❌ 缺失 |
| `stop_monitor` | 467 | 停止属性监控线程 | ❌ 缺失 |
| `poll_devices` | 501 | 轮询设备状态 | ❌ 缺失 |
| `call_action` | 567 | 调用设备动作(如开启、关闭) | ⚠️ 部分实现 |
| `get_device_prop` | 623 | 获取设备属性值 | ✅ 已完成 |
| `set_device_prop` | 659 | 设置设备属性值 | ✅ 已完成 |
| `run_mips_script` | 721 | 运行 MIPS 脚本 | ❌ 缺失 |
| `close` | 789 | 关闭客户端,释放资源 | ⚠️ 部分实现 |
### 辅助函数
| 函数名 | 行号 | 功能 | Go 状态 |
|--------|------|------|---------|
| `load_token_from_env` | 812 | 从环境变量加载 token | ❌ 缺失 |
| `parse_device_list` | 826 | 解析设备列表 JSON | ✅ 已完成 |
## Go 版本现状
### 已实现的文件结构
```
go-miot/
├── miot_client.go # 主客户端类(对应 Python 的 MIoTClient)
├── miot_client_api.go # API 调用方法(对应 Python 的网络请求)
├── miot_client_prop.go # 属性相关方法(对应 Python 的 refresh_properties 等)
├── miot_client_sub.go # 订阅相关方法(对应 Python 的 subscribe_prop 等)
└── miot_device.go # 设备类(对应 Python 的 MIoTDevice)
```
### 缺失的功能
#### 1. 设备发现 (`discover_devices`)
**Python 实现**:
```python
def discover_devices(self, source: str = "cloud"):
"""发现设备"""
if source == "cloud":
return self.refresh_devices()
elif source == "lan":
return self._discover_lan_devices()
else:
raise ValueError(f"Unknown source: {source}")
```
**Go 缺失**:
- ❌ LAN 设备发现(需要 `miot_lan.py`)
- ⚠️ 云端设备发现已部分实现
#### 2. 属性订阅系统 (`subscribe_prop`, `unsubscribe_prop`)
**Python 实现**:
- 使用回调机制
- 支持多设备、多属性订阅
- 后台线程轮询
**Go 缺失**:
- ❌ 完整的订阅系统
- ❌ 回调机制
- ❌ 后台轮询线程
#### 3. 属性监控 (`start_monitor`, `stop_monitor`)
**Python 实现**:
- 启动后台线程
- 定期轮询订阅的属性
- 触发回调
**Go 缺失**:
- ❌ 后台 goroutine 管理
- ❌ 定时轮询
- ❌ 回调触发
#### 4. MIPS 脚本支持 (`run_mips_script`)
**Python 实现**:
- 调用 MIPS 客户端
- 执行自动化脚本
**Go 缺失**:
- ❌ MIPS 客户端集成
- ❌ 脚本执行接口
## 移植建议
### 第一批任务(核心功能)
1. **补全 `discover_devices`** (2小时)
- 实现 LAN 设备发现接口(占位)
- 统一云端和本地发现的返回格式
2. **实现属性订阅系统** (4小时)
- 设计回调接口(`PropertyChangeCallback`)
- 实现 `SubscribeProp` 方法
- 实现 `UnsubscribeProp` 方法
- 管理订阅列表
3. **实现属性监控** (3小时)
- 启动后台 goroutine
- 定时轮询订阅的属性
- 比较属性变化,触发回调
- 实现优雅停止
### 第二批任务(高级功能)
4. **MIPS 脚本支持** (2小时)
- 集成 MIPS 客户端
- 实现 `RunMipsScript` 方法
5. **环境变量支持** (1小时)
- 实现 `load_token_from_env`
- 支持从环境变量读取配置
## 技术难点
### 1. 并发安全
**问题**:Python 版本使用线程,Go 版本需要使用 goroutine
**建议**:
- 使用 `sync.RWMutex` 保护共享状态
- 使用 channel 进行 goroutine 通信
- 避免全局变量
### 2. 回调机制
**问题**:Python 使用函数回调,Go 需要使用接口或 channel
**建议**:
```go
// 方案 1:接口
type PropertyChangeCallback interface {
OnPropertyChange(device *MIoTDevice, prop *Property, oldValue, newValue interface{})
}
// 方案 2:函数类型
type PropertyChangeHandler func(device *MIoTDevice, prop *Property, oldValue, newValue interface{})
// 方案 3:Channel
type PropertyChangeEvent struct {
Device *MIoTDevice
Property *Property
OldValue interface{}
NewValue interface{}
}
var PropertyChangeChan = make(chan PropertyChangeEvent, 100)
```
### 3. 后台任务管理
**问题**:Python 使用 `threading.Thread`,Go 需要使用 goroutine 和 context
**建议**:
```go
type MIoTClient struct {
// ...
monitorCtx context.Context
monitorCancel context.CancelFunc
monitorWg sync.WaitGroup
}
func (c *MIoTClient) StartMonitor(interval time.Duration) error {
c.monitorCtx, c.monitorCancel = context.WithCancel(context.Background())
c.monitorWg.Add(1)
go func() {
defer c.monitorWg.Done()
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-c.monitorCtx.Done():
return
case <-ticker.C:
c.pollSubscribedProperties()
}
}
}()
return nil
}
```
## 测试计划
### 单元测试
1. **设备发现测试**
- 测试云端设备发现
- 测试本地设备发现(需要 mock)
2. **属性订阅测试**
- 测试订阅和取消订阅
- 测试回调触发
- 测试并发订阅
3. **属性监控测试**
- 测试启动和停止
- 测试定时轮询
- 测试优雅停止
### 集成测试
1. **端到端测试**
- 使用真实设备测试
- 测试完整流程:发现 → 订阅 → 监控 → 控制
## 依赖关系
| 依赖文件 | 关系 | 说明 |
|---------|------|------|
| `miot_device.py` | 强依赖 | 设备类 |
| `miot_cloud.py` | 强依赖 | 云端 API |
| `miot_oauth.py` | 强依赖 | OAuth 认证 |
| `miot_storage.py` | 强依赖 | 配置存储 |
| `miot_mips.py` | 弱依赖 | MIPS 脚本 |
| `miot_lan.py` | 弱依赖 | LAN 控制 |
## 移植优先级
| 任务 | 优先级 | 理由 |
|------|--------|------|
| 补全 `discover_devices` | 🔴 高 | 核心功能,影响设备发现 |
| 实现属性订阅 | 🔴 高 | 核心功能,影响实时监控 |
| 实现属性监控 | 🔴 高 | 核心功能,影响实时监控 |
| MIPS 脚本支持 | 🟡 中 | 高级功能,可选 |
| 环境变量支持 | 🟢 低 | 辅助功能,方便配置 |
## 进度跟踪
- [ ] 补全 `discover_devices` (预计 2小时)
- [ ] 实现属性订阅系统 (预计 4小时)
- [ ] 实现属性监控 (预计 3小时)
- [ ] MIPS 脚本支持 (预计 2小时)
- [ ] 环境变量支持 (预计 1小时)
- [ ] 单元测试 (预计 4小时)
- [ ] 集成测试 (预计 2小时)
**总计**:18小时
---
**创建时间**:2026-06-28
**最后更新**:2026-06-28
**负责人**:待定