Files
4566704 04333750ab feat: State→Props 命名统一 + 新增 Plug/Gateway 设备 + 分类系统重构
**命名统一(State → Props)**
- 所有设备类型:XxxState → XxxProps,GetState() → GetProps(),FetchState() → FetchProps()
- 回调接口:OnStateChanged → OnPropsChanged
- Bridge 层类型别名、示例代码、文档同步更名

**新增设备类型**
- KindPlug + Plug 驱动:智能插座/插头(TurnOn/TurnOff/IsOn/OnPropsChanged)
- KindGateway + Gateway 驱动:网关设备类型识别
- KindOccupancySensor 从 KindSensor 独立,添加 OccupancyProps

**设备分类系统改进**
- classifyByModel 改为按 key 长度降序匹配(防止 sensor 先于 sensor-occupy)
- 新增下划线变体识别(sensor_occupy、sensor_temp 等)
- outlet 重新归类为 Plug(非 Switch)
- 新增 Or() 组合过滤器

**连接桥增强**
- 设备创建成功后自动订阅属性变更
- 新增 nil 防护检查
- 支持 Plug/Speaker/Gateway/Occupancy 类型的 FetchProps 刷新
- 日志级别 Info → Debug

**AC 驱动增强**
- 新增 HasPower()、GetElectricPower()、GetPowerConsumption() 功率接口
- ACProps 新增 ElectricPower、PowerConsumption 字段
- valMapper:Desc 为空时 fallback 用 Name,key 统一小写

**MIoT 核心**
- 设备列表刷新改用 reflect.DeepEqual 全字段变更检测
- 移除 BLE/代理设备默认在线 hack
- RefreshDeviceAllProps 增加离线检查
- 新增 miot_errors.go:MIoT 错误码定义
- 全局日志级别 Info→Debug/Warn(降低噪音)

**示例与文档**
- 所有示例代码同步 API 变更
- 传感器示例改用 Or 组合过滤器
- ARCH_PLAN 等迁移文档同步更新
2026-08-05 17:54:08 +08:00

9.3 KiB
Raw Permalink 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.OnPropsChanged(handler) 状态订阅

演示重点:

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

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.OnPropsChanged(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)
  • OnPropsChanged(handler) → ACState

演示重点:

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

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 控制 + OnPropsChanged 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。


本文档已全部实施完成。