Files
xiaomihome/xiaomi/migration/EXAMPLES_PLAN.md
T
4566704 a3d94c4b9f 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 示例(风扇/窗帘/传感器控制)
2026-06-29 08:51:21 +08:00

9.3 KiB
Raw Blame History

xiaomi 封装层示例程序规划

状态:Completed | 版本:v1.0 | 日期:2026-06-28 | 完成日期:2026-06-29


一、现状分析

已有示例

文件 状态 问题
xiaomi/examples/main.go 存在(224 行) 几乎全是 fmt.Println 伪代码,非可运行的完整示例

目标

对标 ARCH_PLAN.md v1.1 的最终形态,覆盖完整 API 面,每个示例独立可理解、贴近实战。


二、示例架构

xiaomi/examples/
├── 01_user_home/             # 用户 + 家庭 + 房间信息
│   └── main.go
├── 02_device_list/           # 设备列表 + 过滤
│   └── main.go
├── 03_switch_control/        # 开关控制
│   └── main.go
├── 04_light_control/         # 灯光控制
│   └── main.go
├── 05_ac_control/            # 空调控制
│   └── main.go
├── 06_fan_cover/             # 风扇 + 窗帘控制
│   └── main.go
├── 07_prop_subscribe/        # 属性/事件/状态订阅
│   └── main.go
├── 08_adv_filter_classify/   # 高级过滤 + 分类 + 工厂
│   └── main.go
├── 09_spec_parser/           # SPEC 解析器独立使用(已有完整代码)
│   └── main.go
└── config/                   # 共享配置模块(敏感信息统一管理)
    └── config.go

三、各示例详述

01_user_home — 用户/家庭/房间信息

覆盖 API:

  • client.GetUserInfo(ctx) → *UserInfo
  • client.GetHomeList(ctx) → []*HomeInfo(含经纬度、地址)
  • client.GetHome(ctx, homeID) → *HomeInfo
  • client.GetRooms(ctx, homeID) → []*RoomInfo
  • client.GetRoomDevices(ctx, homeID, roomID) → []string

演示重点:

  • context.WithTimeout 控制超时
  • HomeInfo 的地里位置字段(CityID, Longitude, Latitude, Address)
  • for-range 遍历家庭→房间→设备层级结构

02_device_list — 设备列表与过滤

覆盖 API:

  • client.GetDevices(ctx, opts...) → []*DeviceInfo
  • client.GetDevice(ctx, did) → *DeviceInfo
  • client.RefreshDevices(ctx) → error
  • FilterByHome / FilterByRoom / FilterByOnline / FilterByModel / FilterByKind
  • DeviceInfo.DeviceKind() 分类

演示重点:

  • 多种过滤组合(在线+客厅、按型号、按种类)
  • DeviceKind() 输出
  • RefreshDevices 刷新时机

03_switch_control — 开关控制

覆盖 API:

  • devices.Create(client, info) 工厂 → Switch
  • Switch.{TurnOn, TurnOff, Toggle, IsOn}(ctx)
  • Switch.OnStateChanged(handler) 状态订阅

演示重点:

  • 工厂创建单设备
  • TurnOn/TurnOff/Toggle 完整链路
  • IsOn 状态查询
  • OnStateChanged 回调演示

04_light_control — 灯光控制

覆盖 API:

  • Light.{TurnOn, TurnOff, Toggle}(ctx)
  • Light.{SetBrightness, GetBrightness}(ctx, pct)
  • Light.{SetColorTemp, GetColorTemp}(ctx, kelvin)
  • Light.{SetColor, GetColor}(ctx, r, g, b)
  • Light.OnStateChanged(handler)

演示重点:

  • 亮度 0-100 调节
  • 色温 2700K-6500K 调节
  • RGB 颜色控制
  • 不支持功能的降级处理(GetBrightness 返回 -1 → 跳过)

05_ac_control — 空调控制

覆盖 API:

  • AirConditioner.{TurnOn, TurnOff, IsOn}(ctx)
  • SetMode(ctx, ACMode) / GetMode(ctx) — cool/heat/dry/fan/auto
  • SetTargetTemp(ctx, celsius) / GetTargetTemp(ctx) / GetCurrentTemp(ctx)
  • SetFanSpeed(ctx, FanSpeed) / GetFanSpeed(ctx) — low/medium/high/auto
  • SetSwing(ctx, SwingMode) / GetSwing(ctx) — off/vertical/horizontal/both
  • SetTargetHumidity(ctx, pct) / GetTargetHumidity(ctx) / GetCurrentHumidity(ctx)
  • SetAuxHeat(ctx, on) / GetAuxHeat(ctx)
  • SetEco(ctx, on) / GetEco(ctx)
  • OnStateChanged(handler) → ACState

演示重点:

  • 完整空调控制链路(开→设制冷→设26°C→自动风速→垂直摆风)
  • OnStateChanged 实时状态回调
  • 不支持的功能优雅降级(如无湿度传感器,跳过湿度设置)

06_fan_cover — 风扇 + 窗帘控制

覆盖 API:

  • Fan.{TurnOn, TurnOff, SetSpeed, SetOscillation, SetNaturalWind}(ctx)
  • Cover.{Open, Close, Stop, SetPosition, GetPosition}(ctx)

演示重点:

  • 风扇 4 档调速 + 摇头 + 自然风切换
  • 窗帘百分比定位(0%=关, 100%=全开, 50%=半开)
  • Cover 的 Open/Close/Stop 语义对比 SetPosition

07_prop_subscribe — 属性/事件/状态订阅

覆盖 API:

  • client.SubProp(did, siid, piid, PropHandler) → subID
  • client.UnsubProp(did, subID)
  • client.SubEvent(did, siid, eiid, EventHandler) → subID
  • client.UnsubEvent(did, subID)
  • client.SubDeviceState(did, DeviceStateHandler)
  • client.UnsubDeviceState(did)

演示重点:

  • 订阅前后属性值对比
  • 等待N秒展示属性/事件推送
  • 取消订阅后不再收到回调
  • 设备上下线状态监听

08_adv_filter_classify — 高级过滤 + 分类 + 工厂模式

覆盖 API:

  • devices.Classify(info) → Kind 枚举
  • FilterByKind(kind) 过滤器
  • devices.Create(client, info) 工厂 → 各设备接口
  • devices.Kind 所有枚举值

演示重点:

  • 获取全部设备 → 按 Kind 分类 → 统计各类型数量
  • 工厂批量创建:遍历 DeviceInfo → Create → type switch 分流
  • 不支持的设备返回 nil → continue 跳过
  • 输出表格:"设备名 | 型号 | 种类 | 状态"

09_spec_parser — SPEC 解析器独立使用

覆盖 API:

  • specs 包全部公开 API(如果 specs 是公开的)
  • SPEC 属性/事件/动作的枚举和查询

演示重点:

  • 无需设备在线即可解析 SPEC
  • 打印设备有哪些属性(text/switch/select/number/sensor)
  • 打印设备有哪些事件和动作

四、共享配置模块 config/config.go

package config

type Config struct {
    ClientID     string
    ClientSecret string
    AccessToken  string // OAuth token(从环境变量或文件读取)
}

// LoadFromEnv 从环境变量加载配置
func LoadFromEnv() (*Config, error)

// LoadFromFile 从 JSON 文件加载配置
func LoadFromFile(path string) (*Config, error)

设计原则:

  • 所有示例复用一个 config 加载逻辑,避免重复
  • 仅 3 个字段,对应 xiaomi.Config
  • 敏感信息从环境变量或文件读取,不硬编码

五、编码规范

5.1 统一约定

1. 每个示例的 main() 必须有 context.WithTimeout(30s)
2. 所有 IO 操作带 ctx
3. 错误必须处理(不忽略 err)
4. defer cancel() 放在 func main() 顶部
5. 日志用 log 包,不用 fmt.Print(方便区分日志级别)
6. 每个示例一句话说明功能(注释在 main 函数上方)

5.2 模板骨架

// Package main demonstrates <功能简述>.
// 运行前提:已配置环境变量 XIAOMI_CLIENT_ID / XIAOMI_CLIENT_SECRET / XIAOMI_ACCESS_TOKEN。
package main

import (
    "context"
    "log"
    "time"

    "xiaomihome/xiaomi"
    "xiaomihome/xiaomi/devices"
    "xiaomihome/xiaomi/examples/config"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    // 1. 加载配置
    cfg, err := config.LoadFromEnv()
    if err != nil {
        log.Fatal("配置加载失败:", err)
    }

    // 2. 创建客户端(零 miot 引用)
    client, err := xiaomi.NewClient(ctx, xiaomi.Config{
        ClientID:     cfg.ClientID,
        ClientSecret: cfg.ClientSecret,
        AccessToken:  cfg.AccessToken,
    })
    if err != nil {
        log.Fatal("创建客户端失败:", err)
    }
    defer client.Close()

    // 3. 业务逻辑(根据示例不同)
    // ...
}

六、与 ARCH_PLAN.md 的对应关系

ARCH_PLAN.md 目标 对应示例
用户/家庭/房间信息(GetUserInfo / GetHomeList) 01_user_home
设备列表 + Filter 02_device_list
Switch 控制 + OnStateChanged 03_switch_control
Light 控制 04_light_control
AirConditioner 完整控制 05_ac_control
Fan / Cover 控制 06_fan_cover
SubProp / SubEvent / SubDeviceState 订阅 07_prop_subscribe
Classify / FilterByKind / Create 工厂 08_adv_filter_classify
SPEC 解析器 09_spec_parser
context.Context + 错误处理 全部示例

七、实施计划

序号 示例 文件 优先级 复杂度
0 config 共享模块 config/config.go P0 小
1 用户/家庭/房间 01_user_home/main.go P0 小
2 设备列表+过滤 02_device_list/main.go P0 中
3 开关控制 03_switch_control/main.go P0 小
4 灯光控制 04_light_control/main.go P0 中
5 空调控制 05_ac_control/main.go P0 大
6 风扇+窗帘 06_fan_cover/main.go P1 中
7 订阅通知 07_prop_subscribe/main.go P1 大
8 高级过滤+工厂 08_adv_filter_classify/main.go P1 中
9 SPEC 解析 09_spec_parser/main.go P2 小
— 统一 README examples/README.md P2 小

八、与现有 main.go 的关系

现有 xiaomi/examples/main.go 将被替换为上述 9 个独立示例。如果作为归档保留,可移到 examples/_archive/main_old.go。


本文档已全部实施完成。