支持ota升级结果相应处理
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -65,22 +64,34 @@ func NewAreaControllerResponse(ac *models.AreaController) (*AreaControllerRespon
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var props map[string]interface{}
|
// 解析 firmware_version
|
||||||
|
var firmwareVersion string
|
||||||
|
// 使用模型上的辅助方法来解析强类型属性
|
||||||
|
acProps := &models.AreaControllerProperties{}
|
||||||
|
if err := ac.ParseProperties(acProps); err == nil {
|
||||||
|
firmwareVersion = acProps.FirmwareVersion
|
||||||
|
}
|
||||||
|
// 如果解析出错,firmwareVersion 将保持为空字符串,这通常是可接受的降级行为
|
||||||
|
|
||||||
|
// 解析完整的 properties 以便向后兼容或用于其他未知属性
|
||||||
|
var allProps map[string]interface{}
|
||||||
if len(ac.Properties) > 0 && string(ac.Properties) != "null" {
|
if len(ac.Properties) > 0 && string(ac.Properties) != "null" {
|
||||||
if err := json.Unmarshal(ac.Properties, &props); err != nil {
|
// 这里我们使用通用的 ParseProperties 方法
|
||||||
return nil, fmt.Errorf("解析区域主控属性失败 (ID: %d): %w", ac.ID, err)
|
if err := ac.ParseProperties(&allProps); err != nil {
|
||||||
|
return nil, fmt.Errorf("解析区域主控完整属性失败 (ID: %d): %w", ac.ID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &AreaControllerResponse{
|
return &AreaControllerResponse{
|
||||||
ID: ac.ID,
|
ID: ac.ID,
|
||||||
Name: ac.Name,
|
Name: ac.Name,
|
||||||
NetworkID: ac.NetworkID,
|
NetworkID: ac.NetworkID,
|
||||||
Location: ac.Location,
|
FirmwareVersion: firmwareVersion,
|
||||||
Status: ac.Status,
|
Location: ac.Location,
|
||||||
Properties: props,
|
Status: ac.Status,
|
||||||
CreatedAt: ac.CreatedAt.Format(time.RFC3339),
|
Properties: allProps, // 填充完整的 properties
|
||||||
UpdatedAt: ac.UpdatedAt.Format(time.RFC3339),
|
CreatedAt: ac.CreatedAt.Format(time.RFC3339),
|
||||||
|
UpdatedAt: ac.UpdatedAt.Format(time.RFC3339),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,14 +78,15 @@ type DeviceResponse struct {
|
|||||||
|
|
||||||
// AreaControllerResponse 定义了返回给客户端的单个区域主控信息的结构
|
// AreaControllerResponse 定义了返回给客户端的单个区域主控信息的结构
|
||||||
type AreaControllerResponse struct {
|
type AreaControllerResponse struct {
|
||||||
ID uint32 `json:"id"`
|
ID uint32 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
NetworkID string `json:"network_id"`
|
NetworkID string `json:"network_id"`
|
||||||
Location string `json:"location"`
|
FirmwareVersion string `json:"firmware_version"`
|
||||||
Status string `json:"status"`
|
Location string `json:"location"`
|
||||||
Properties map[string]interface{} `json:"properties"`
|
Status string `json:"status"`
|
||||||
CreatedAt string `json:"created_at"`
|
Properties map[string]interface{} `json:"properties"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeviceTemplateResponse 定义了返回给客户端的单个设备模板信息的结构
|
// DeviceTemplateResponse 定义了返回给客户端的单个设备模板信息的结构
|
||||||
|
|||||||
@@ -57,9 +57,7 @@ func (l *loraListener) HandleInstruction(upstreamCtx context.Context, sourceAddr
|
|||||||
return l.handleCollectResult(ctx, sourceAddr, p.CollectResult)
|
return l.handleCollectResult(ctx, sourceAddr, p.CollectResult)
|
||||||
|
|
||||||
case *proto.Instruction_OtaUpgradeStatus:
|
case *proto.Instruction_OtaUpgradeStatus:
|
||||||
logger.Infow("收到OTA升级状态,暂未实现处理逻辑", "来源地址", sourceAddr, "状态", p.OtaUpgradeStatus)
|
return l.handleOtaStatus(ctx, sourceAddr, p.OtaUpgradeStatus)
|
||||||
// TODO: 在这里实现OTA升级状态的处理逻辑
|
|
||||||
return nil
|
|
||||||
|
|
||||||
case *proto.Instruction_LogUploadRequest:
|
case *proto.Instruction_LogUploadRequest:
|
||||||
logger.Infow("收到设备日志上传请求,暂未实现处理逻辑", "来源地址", sourceAddr, "日志条数", len(p.LogUploadRequest.Entries))
|
logger.Infow("收到设备日志上传请求,暂未实现处理逻辑", "来源地址", sourceAddr, "日志条数", len(p.LogUploadRequest.Entries))
|
||||||
@@ -275,3 +273,35 @@ func (l *loraListener) recordSensorData(ctx context.Context, areaControllerID ui
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleOtaStatus 处理设备上报的OTA升级状态。
|
||||||
|
func (l *loraListener) handleOtaStatus(ctx context.Context, sourceAddr string, status *proto.OtaUpgradeStatus) error {
|
||||||
|
reqCtx, logger := logs.Trace(ctx, l.selfCtx, "handleOtaStatus")
|
||||||
|
logger.Infow("开始处理OTA升级状态",
|
||||||
|
"来源地址", sourceAddr,
|
||||||
|
"状态码", status.StatusCode,
|
||||||
|
"处理结果", status.StatusCode == 0,
|
||||||
|
"当前版本", status.CurrentFirmwareVersion,
|
||||||
|
)
|
||||||
|
|
||||||
|
// 1. 查找区域主控
|
||||||
|
areaController, err := l.areaControllerRepo.FindByNetworkID(reqCtx, sourceAddr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("处理OTA状态失败:无法找到区域主控: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 更新固件版本号
|
||||||
|
// 我们信任设备上报的版本号,无论成功失败都进行更新
|
||||||
|
if status.CurrentFirmwareVersion != "" {
|
||||||
|
err = l.areaControllerRepo.UpdateFirmwareVersion(reqCtx, areaController.ID, status.CurrentFirmwareVersion)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorw("更新区域主控固件版本号失败", "主控ID", areaController.ID, "error", err)
|
||||||
|
return fmt.Errorf("更新固件版本号失败: %w", err)
|
||||||
|
}
|
||||||
|
logger.Infow("成功更新区域主控固件版本号", "主控ID", areaController.ID, "新版本", status.CurrentFirmwareVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 后续可以在这里增加逻辑,比如记录一条操作日志,或者发送一个通知
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user