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

107 lines
2.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.
# 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` 新增:
```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` 中新增内部方法:
```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` 结构体新增字段
```go
// miot_client.go
type MIoTClient struct {
// ...
specParser *MIoTSpecParser // SPEC 解析器
devices map[string]*MIoTDevice // did → 设备实例缓存
}
```
### Setter
```go
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` |
## 验证
```go
// 用法示例
client.RefreshDevices() // 获取设备列表
client.RefreshDeviceAllProps("did_xxx") // 一次刷新该设备所有属性
// 200ms 后属性到达 → OnPropMsg → 分发给订阅者
```