refactor: 重大架构升级 — HomeID/RoomID int64化 + 设备驱动重构 + 结构化日志
主要变更: **类型系统重构** - HomeInfo.ID/RoomInfo.ID/HomeID 从 string 改为 int64,json tag 使用 ,string - GetHome/GetRooms/GetRoomDevices 接口同步修改 - 新增 int64FromStr 工具函数,更新 parseHomeInfo 解析逻辑 **新增 Speaker 设备** - 新增 KindSpeaker 类型 - classify 映射覆盖 speaker/bluetooth-speaker/alarm-clock/media-player/playback/music **设备驱动重构** - AC 驱动彻底重写:从硬编码常量改为基于 SPEC ValueList 的动态 valMapper - 所有设备(Fan/Humidifier/Light/OccupancySensor/Switch/TempHumiditySensor/Thermostat/Vacuum/WaterHeater/Cover)新增 GetState() 和 FetchState(ctx) 接口 - base.go 新增 specResolver.format() 方法 **MIoT 模块增强** - MIoTClient 新增 homeIDs 字段,支持按家庭过滤设备 - RefreshDevices 支持 homeIDs 参数 - SpecStdLib 引入 logger.Logger,log.Printf 全部迁移为结构化日志 **其他** - Config 新增 RedirectURL 和 HomeIDs 字段 - AuthInfo.ExpiresIn 类型从 int 改为 int32 - UUID 生成简化为 hex.EncodeToString - 新增 github.com/sirupsen/logrus 依赖 - .gitignore 新增 examples/*/data/ 忽略规则 - 删除已提交的 config.json 敏感配置
This commit is contained in:
+25
-11
@@ -6,6 +6,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"xiaomihome/logger"
|
||||
"xiaomihome/miot"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,7 @@ type Client struct {
|
||||
mipsCloud *miot.MipsCloudClient
|
||||
specParser *miot.MIoTSpecParser
|
||||
uuid string
|
||||
lgr logger.Logger
|
||||
deviceMu sync.RWMutex
|
||||
devices map[string]*miot.MIoTDevice
|
||||
|
||||
@@ -70,35 +72,47 @@ func NewClient(ctx context.Context, cfg Config) (*Client, error) {
|
||||
)
|
||||
miotClient.SetMipsCloud(mipsCloud)
|
||||
|
||||
var ids []string
|
||||
if len(cfg.HomeIDs) > 0 {
|
||||
ids = make([]string, len(cfg.HomeIDs))
|
||||
for i, v := range cfg.HomeIDs {
|
||||
ids[i] = fmt.Sprintf("%d", v)
|
||||
}
|
||||
miotClient.SetHomeIDs(ids)
|
||||
}
|
||||
|
||||
if err := miotClient.Init(); err != nil {
|
||||
return nil, fmt.Errorf("xiaomi: init: %w", err)
|
||||
}
|
||||
|
||||
_ = miotClient.RefreshDevices()
|
||||
// Use the same homeIDs slice from above (nil if not set)
|
||||
_ = miotClient.RefreshDevices(ids)
|
||||
|
||||
if err := mipsCloud.Connect(); err != nil {
|
||||
return nil, fmt.Errorf("xiaomi: mips connect: %w", err)
|
||||
}
|
||||
|
||||
// 启动后台 token 自动刷新
|
||||
if cfg.OnTokenRefreshed != nil {
|
||||
miotClient.SetTokenRefreshCallback(cfg.OnTokenRefreshed)
|
||||
}
|
||||
miotClient.RequestRefreshAuthInfo(10)
|
||||
|
||||
return &Client{
|
||||
c := &Client{
|
||||
cfg: cfg,
|
||||
inner: miotClient,
|
||||
http: httpClient,
|
||||
mipsCloud: mipsCloud,
|
||||
uuid: uuid,
|
||||
lgr: logger.Default(),
|
||||
specParser: miot.NewMIoTSpecParser("en", miot.NewMIoTStorage(cfg.DataDir), cfg.DataDir+"/specs"),
|
||||
devices: make(map[string]*miot.MIoTDevice),
|
||||
propSubs: make(map[string]string),
|
||||
eventSubs: make(map[string]string),
|
||||
}, nil
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// SetLogger 设置日志记录器。
|
||||
func (c *Client) SetLogger(l logger.Logger) { c.lgr = l }
|
||||
|
||||
// SetHomeIDs 动态设置 miot 层的家庭过滤,供后台定时 RefreshDevices 使用。
|
||||
func (c *Client) SetHomeIDs(homeIDs []string) { c.inner.SetHomeIDs(homeIDs) }
|
||||
|
||||
// Close 关闭客户端。
|
||||
func (c *Client) Close() error {
|
||||
if c.mipsCloud != nil {
|
||||
@@ -119,7 +133,7 @@ func (c *Client) RefreshToken(ctx context.Context) (*TokenResult, error) {
|
||||
return &TokenResult{
|
||||
AccessToken: strVal(result, "access_token"),
|
||||
RefreshToken: strVal(result, "refresh_token"),
|
||||
ExpiresIn: intVal(result, "expires_in"),
|
||||
ExpiresIn: int32(intVal(result, "expires_in")),
|
||||
ExpiresTS: int64(intVal(result, "expires_ts")),
|
||||
UID: strVal(result, "uid"),
|
||||
}, nil
|
||||
@@ -140,7 +154,7 @@ func (c *Client) getOrCreateDevice(did string, info map[string]interface{}) *mio
|
||||
if err == nil {
|
||||
spec = s
|
||||
} else {
|
||||
fmt.Printf("[xiaomi] spec parse failed for %s (%s): %v\n", did, urn, err)
|
||||
c.lgr.Warnf("[xiaomi] spec parse failed for %s (%s): %v", did, urn, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user