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:
+51
-19
@@ -41,7 +41,7 @@ func (c *MIoTClient) RefreshDeviceAllProps(did string) error {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("[MIoTClient] RefreshDeviceAllProps: %s → %d props enqueued\n", did, count)
|
||||
c.lgr.Infof("[MIoTClient] RefreshDeviceAllProps: %s → %d props enqueued\n", did, count)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (c *MIoTClient) RequestRefreshProp(did string, siid, piid int) {
|
||||
|
||||
// Check if already in refresh list
|
||||
if _, exists := c.refreshPropsList[key]; exists {
|
||||
fmt.Printf("[MIoTClient] RequestRefreshProp: SKIPPED (already queued) %s\n", key)
|
||||
c.lgr.Infof("[MIoTClient] RequestRefreshProp: SKIPPED (already queued) %s\n", key)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (c *MIoTClient) RequestRefreshProp(did string, siid, piid int) {
|
||||
|
||||
// Schedule refresh if not already scheduled
|
||||
if c.refreshPropsTimer == nil {
|
||||
fmt.Printf("[MIoTClient] RequestRefreshProp: Scheduling refresh timer for %s\n", key)
|
||||
c.lgr.Infof("[MIoTClient] RequestRefreshProp: Scheduling refresh timer for %s\n", key)
|
||||
// Reset retry count for new batch
|
||||
c.refreshRetryCount = 0
|
||||
|
||||
@@ -80,14 +80,14 @@ func (c *MIoTClient) RequestRefreshProp(did string, siid, piid int) {
|
||||
c.refreshPropsTimer = nil
|
||||
c.mu.Unlock()
|
||||
|
||||
fmt.Printf("[MIoTClient] RequestRefreshProp: Timer fired, calling refreshPropsHandler()\n")
|
||||
c.lgr.Infof("[MIoTClient] RequestRefreshProp: Timer fired, calling refreshPropsHandler()\n")
|
||||
c.refreshPropsHandler()
|
||||
})
|
||||
} else {
|
||||
fmt.Printf("[MIoTClient] RequestRefreshProp: Timer already scheduled, added to queue: %s\n", key)
|
||||
c.lgr.Infof("[MIoTClient] RequestRefreshProp: Timer already scheduled, added to queue: %s\n", key)
|
||||
}
|
||||
|
||||
fmt.Printf("[MIoTClient] RequestRefreshProp: QUEUED %s (queue size: %d)\n", key, len(c.refreshPropsList))
|
||||
c.lgr.Infof("[MIoTClient] RequestRefreshProp: QUEUED %s (queue size: %d)\n", key, len(c.refreshPropsList))
|
||||
}
|
||||
|
||||
// refreshPropsHandler handles property refresh from cloud.
|
||||
@@ -107,7 +107,7 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
c.refreshPropsList = make(map[string]map[string]interface{})
|
||||
c.mu.Unlock()
|
||||
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: START, %d props to refresh\n", len(propsToRefresh))
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: START, %d props to refresh\n", len(propsToRefresh))
|
||||
|
||||
// Group props by source (cloud / gateway / lan)
|
||||
cloudParams := make([]PropParam, 0)
|
||||
@@ -123,6 +123,38 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
siid, _ := prop["siid"].(int)
|
||||
piid, _ := prop["piid"].(int)
|
||||
|
||||
// siid=0 && piid=0 → 通配符,展开为设备所有可读属性
|
||||
if siid == 0 && piid == 0 {
|
||||
if info, ok := c.deviceListCache[did]; ok {
|
||||
dev := c.getOrCreateDevice(did, info)
|
||||
if dev != nil {
|
||||
for _, svc := range dev.ServiceList() {
|
||||
if svc == nil {
|
||||
continue
|
||||
}
|
||||
for _, p := range svc.Properties {
|
||||
if p == nil || !p.Readable() {
|
||||
continue
|
||||
}
|
||||
param := PropParam{DID: did, Siid: p.SIID, Piid: p.PIID}
|
||||
source := c.subSourceList[did]
|
||||
if source == "" {
|
||||
source = "cloud"
|
||||
}
|
||||
if source == "cloud" {
|
||||
cloudParams = append(cloudParams, param)
|
||||
} else if source == "lan" {
|
||||
lanParams = append(lanParams, param)
|
||||
} else {
|
||||
gatewayParams[source] = append(gatewayParams[source], param)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
param := PropParam{DID: did, Siid: siid, Piid: piid}
|
||||
|
||||
source, exists := c.subSourceList[did]
|
||||
@@ -155,12 +187,12 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
batch := cloudParams[i:end]
|
||||
results, err := c.http.GetProps(batch)
|
||||
if err != nil {
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: cloud GetProps FAILED: %v\n", err)
|
||||
c.lgr.Errorf("[MIoTClient] refreshPropsHandler: cloud GetProps FAILED: %v\n", err)
|
||||
c.retryProps(propsToRefresh)
|
||||
return
|
||||
}
|
||||
allResults = append(allResults, results...)
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: cloud batch %d returned %d results\n", i/150+1, len(results))
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: cloud batch %d returned %d results\n", i/150+1, len(results))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +200,7 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
for groupID, params := range gatewayParams {
|
||||
mips, exists := c.mipsLocal[groupID]
|
||||
if !exists {
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: gateway %s not found, routing to cloud\n", groupID)
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: gateway %s not found, routing to cloud\n", groupID)
|
||||
// Fallback to cloud
|
||||
if c.http != nil {
|
||||
results, err := c.http.GetProps(params)
|
||||
@@ -180,7 +212,7 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
}
|
||||
results, err := mips.GetProps(params, MipsRequestTimeoutDefault*time.Millisecond)
|
||||
if err != nil {
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: gateway %s GetProps FAILED: %v\n", groupID, err)
|
||||
c.lgr.Errorf("[MIoTClient] refreshPropsHandler: gateway %s GetProps FAILED: %v\n", groupID, err)
|
||||
// Fallback to cloud
|
||||
if c.http != nil {
|
||||
results, err := c.http.GetProps(params)
|
||||
@@ -191,7 +223,7 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
continue
|
||||
}
|
||||
allResults = append(allResults, results...)
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: gateway %s returned %d results\n", groupID, len(results))
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: gateway %s returned %d results\n", groupID, len(results))
|
||||
}
|
||||
|
||||
// LAN source
|
||||
@@ -200,7 +232,7 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
if ok {
|
||||
results, err := lan.GetProps(lanParams)
|
||||
if err != nil {
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: LAN GetProps FAILED: %v\n", err)
|
||||
c.lgr.Errorf("[MIoTClient] refreshPropsHandler: LAN GetProps FAILED: %v\n", err)
|
||||
// Fallback to cloud
|
||||
if c.http != nil {
|
||||
results, err := c.http.GetProps(lanParams)
|
||||
@@ -210,7 +242,7 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
}
|
||||
} else {
|
||||
allResults = append(allResults, results...)
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: LAN returned %d results\n", len(results))
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: LAN returned %d results\n", len(results))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,16 +252,16 @@ func (c *MIoTClient) refreshPropsHandler() {
|
||||
c.refreshRetryCount = 0
|
||||
c.mu.Unlock()
|
||||
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: total %d results\n", len(allResults))
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: total %d results\n", len(allResults))
|
||||
|
||||
// Dispatch results to subscribers
|
||||
for _, result := range allResults {
|
||||
if result.Code != 0 {
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: FAILED %s/%d/%d, code=%d\n", result.DID, result.Siid, result.Piid, result.Code)
|
||||
c.lgr.Errorf("[MIoTClient] refreshPropsHandler: FAILED %s/%d/%d, code=%d\n", result.DID, result.Siid, result.Piid, result.Code)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: SUCCESS %s/%d/%d = %v\n", result.DID, result.Siid, result.Piid, result.Value)
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: SUCCESS %s/%d/%d = %v\n", result.DID, result.Siid, result.Piid, result.Value)
|
||||
params := map[string]interface{}{
|
||||
"did": result.DID,
|
||||
"siid": result.Siid,
|
||||
@@ -248,7 +280,7 @@ func (c *MIoTClient) retryProps(props []map[string]interface{}) {
|
||||
c.mu.Unlock()
|
||||
|
||||
if retryCount >= RefreshPropsRetryMax {
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: GIVING UP after %d retries\n", retryCount)
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: GIVING UP after %d retries\n", retryCount)
|
||||
c.mu.Lock()
|
||||
c.refreshPropsList = make(map[string]map[string]interface{})
|
||||
c.refreshRetryCount = 0
|
||||
@@ -256,7 +288,7 @@ func (c *MIoTClient) retryProps(props []map[string]interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("[MIoTClient] refreshPropsHandler: RETRYING (%d/%d)\n", retryCount, RefreshPropsRetryMax)
|
||||
c.lgr.Infof("[MIoTClient] refreshPropsHandler: RETRYING (%d/%d)\n", retryCount, RefreshPropsRetryMax)
|
||||
c.mu.Lock()
|
||||
for _, prop := range props {
|
||||
key := fmt.Sprintf("%s|%d|%d", prop["did"].(string), prop["siid"].(int), prop["piid"].(int))
|
||||
|
||||
Reference in New Issue
Block a user