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

2.9 KiB
Raw Permalink Blame History

RefreshDeviceAllProps 方案

现状

版本 单个入队 批量执行 全量刷新
Python request_refresh_prop(did,siid,piid) __refresh_props_handler 200ms 聚合 150/批 MIoTDevice.__refresh_props_value()
Go RequestRefreshProp(did,siid,piid) refreshPropsHandler 200ms 聚合 150/批 ❌ 缺失

方案

在 miot_client_prop.go 新增:

// RefreshDeviceAllProps 刷新指定设备的所有可读属性
// 遍历 device.ServiceList → service.Properties → RequestRefreshProp
func (c *MIoTClient) RefreshDeviceAllProps(did string) error {
    // 1. 查找设备
    c.deviceListMu.RLock()
    info, exists := c.deviceListCache[did]
    c.deviceListMu.RUnlock()
    if !exists {
        return fmt.Errorf("device %s not found", did)
    }

    // 2. 获取 SPEC(需要 MIoTDevice 或 MIoTSpecParser)
    device := c.getOrCreateDevice(did, info)
    if device == nil {
        return fmt.Errorf("failed to create device for %s", did)
    }

    // 3. 遍历所有 service → property,入队可读属性
    for _, svc := range device.ServiceList() {
        for _, prop := range svc.Properties {
            if !prop.Readable() {
                continue
            }
            c.RequestRefreshProp(did, prop.SIID, prop.PIID)
        }
    }
    return nil
}

前置依赖

需要 MIoTClient 能按 did 获取/创建 MIoTDevice 实例。可在 miot_client.go 或 miot_client_device.go 中新增内部方法:

// getOrCreateDevice 从缓存获取或创建 MIoTDevice
func (c *MIoTClient) getOrCreateDevice(did string, info map[string]interface{}) *MIoTDevice {
    // 尝试从已有列表读取
    if dev, ok := c.devices[did]; ok {
        return dev
    }
    // 创建新实例(需要 SPEC 解析器)
    if c.specParser == nil {
        return nil
    }
    urn, _ := info["urn"].(string)
    model, _ := info["model"].(string)
    spec, err := c.specParser.Parse(urn, model)
    if err != nil {
        return nil
    }
    dev := NewMIoTDevice(c, info, spec)
    c.devices[did] = dev
    return dev
}

需要在 MIoTClient 结构体新增字段

// miot_client.go
type MIoTClient struct {
    // ...
    specParser *MIoTSpecParser   // SPEC 解析器
    devices    map[string]*MIoTDevice  // did → 设备实例缓存
}

Setter

func (c *MIoTClient) SetSpecParser(p *MIoTSpecParser) {
    c.specParser = p
}

影响范围

文件 改动
miot_client.go +2 字段 (specParser, devices) + 1 setter
miot_client_prop.go +1 方法 RefreshDeviceAllProps
miot_client_device.go +1 方法 getOrCreateDevice

验证

// 用法示例
client.RefreshDevices()                     // 获取设备列表
client.RefreshDeviceAllProps("did_xxx")     // 一次刷新该设备所有属性
// 200ms 后属性到达 → OnPropMsg → 分发给订阅者