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

7.9 KiB
Raw Permalink Blame History

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 实现:

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
    • 定时轮询订阅的属性
    • 比较属性变化,触发回调
    • 实现优雅停止

第二批任务(高级功能)

  1. MIPS 脚本支持 (2小时)

    • 集成 MIPS 客户端
    • 实现 RunMipsScript 方法
  2. 环境变量支持 (1小时)

    • 实现 load_token_from_env
    • 支持从环境变量读取配置

技术难点

1. 并发安全

问题:Python 版本使用线程,Go 版本需要使用 goroutine

建议:

  • 使用 sync.RWMutex 保护共享状态
  • 使用 channel 进行 goroutine 通信
  • 避免全局变量

2. 回调机制

问题:Python 使用函数回调,Go 需要使用接口或 channel

建议:

// 方案 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

建议:

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 负责人:待定