issue-18 优化代码(只保证编译通过没检查)
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
package lora
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/config"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/transport"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/transport/lora/chirp_stack_proto/client/device_service"
|
||||
"github.com/go-openapi/runtime"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
@@ -20,19 +20,13 @@ type ChirpStackTransport struct {
|
||||
client *client.ChirpStackRESTAPI
|
||||
authInfo runtime.ClientAuthInfoWriter
|
||||
config config.ChirpStackConfig
|
||||
|
||||
deviceCommandLogRepo repository.DeviceCommandLogRepository
|
||||
deviceRepo repository.DeviceRepository
|
||||
|
||||
logger *logs.Logger
|
||||
logger *logs.Logger
|
||||
}
|
||||
|
||||
// NewChirpStackTransport 创建一个新的通信实例,用于与 ChirpStack 通信。
|
||||
func NewChirpStackTransport(
|
||||
config config.ChirpStackConfig,
|
||||
logger *logs.Logger,
|
||||
deviceCommandLogRepo repository.DeviceCommandLogRepository,
|
||||
deviceRepo repository.DeviceRepository,
|
||||
) *ChirpStackTransport {
|
||||
// 使用配置中的服务器地址创建一个 HTTP transport。
|
||||
// 它会使用生成的客户端中定义的默认 base path 和 schemes。
|
||||
@@ -45,16 +39,14 @@ func NewChirpStackTransport(
|
||||
authInfo := httptransport.APIKeyAuth("grpc-metadata-authorization", "header", config.GenerateAPIKey())
|
||||
|
||||
return &ChirpStackTransport{
|
||||
client: apiClient,
|
||||
authInfo: authInfo,
|
||||
config: config,
|
||||
logger: logger,
|
||||
deviceCommandLogRepo: deviceCommandLogRepo,
|
||||
deviceRepo: deviceRepo,
|
||||
client: apiClient,
|
||||
authInfo: authInfo,
|
||||
config: config,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChirpStackTransport) Send(address string, payload []byte) error {
|
||||
func (c *ChirpStackTransport) Send(address string, payload []byte) (*transport.SendResult, error) {
|
||||
// 1. 构建 API 请求体。
|
||||
// - Confirmed: true 表示确认消息, 设为false将不保证消息送达(但可以节约下行容量)。
|
||||
// - Data: 经过 Base64 编码的数据。
|
||||
@@ -72,7 +64,7 @@ func (c *ChirpStackTransport) Send(address string, payload []byte) error {
|
||||
// - WithQueueItemDevEui 指定目标设备的 EUI。
|
||||
// - WithBody 设置请求体。
|
||||
params := device_service.NewDeviceServiceEnqueueParams().
|
||||
WithTimeout(10 * time.Second).
|
||||
WithTimeout(5 * time.Second). // TODO 这里应该从配置文件里读
|
||||
WithQueueItemDevEui(address).
|
||||
WithBody(body)
|
||||
|
||||
@@ -81,53 +73,23 @@ func (c *ChirpStackTransport) Send(address string, payload []byte) error {
|
||||
resp, err := c.client.DeviceService.DeviceServiceEnqueue(params, c.authInfo)
|
||||
if err != nil {
|
||||
c.logger.Errorf("设备 %s 调用ChirpStack Enqueue失败: %v", address, err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 4. 成功发送后,尝试记录下行任务
|
||||
messageID := ""
|
||||
if resp != nil && resp.Payload != nil && resp.Payload.ID != "" { // 根据实际结构,使用 resp.Payload.ID
|
||||
messageID = resp.Payload.ID
|
||||
} else {
|
||||
c.logger.Warnf("ChirpStack Enqueue 响应未包含 MessageID (ID),无法记录下行任务。设备: %s", address)
|
||||
// 即使无法获取 MessageID,也认为发送成功,因为 ChirpStack Enqueue 成功了
|
||||
return nil
|
||||
if resp == nil || resp.Payload == nil || resp.Payload.ID == "" {
|
||||
// 这是一个需要明确处理的错误情况,因为调用方依赖 MessageID。
|
||||
errMsg := "ChirpStack Enqueue 响应未包含 MessageID (ID)"
|
||||
c.logger.Errorf(errMsg)
|
||||
return nil, errors.New(errMsg)
|
||||
}
|
||||
|
||||
// 调用私有方法记录下行任务
|
||||
if err := c.recordDownlinkTask(address, messageID); err != nil {
|
||||
// 记录失败不影响下行命令的发送成功
|
||||
c.logger.Errorf("记录下行任务失败 (MessageID: %s, DevEui: %s): %v", messageID, address, err)
|
||||
return nil
|
||||
c.logger.Infof("成功将 payload 发送到设备 %s 的队列 (MessageID: %s)", address, resp.Payload.ID)
|
||||
|
||||
// 将 MessageID 包装在 SendResult 中返回
|
||||
result := &transport.SendResult{
|
||||
MessageID: resp.Payload.ID,
|
||||
}
|
||||
|
||||
c.logger.Infof("设备 %s 调用ChirpStack Enqueue成功,并创建下行任务记录 (MessageID: %s)", address, messageID)
|
||||
return result, nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// recordDownlinkTask 记录下行任务到数据库
|
||||
func (c *ChirpStackTransport) recordDownlinkTask(devEui string, messageID string) error {
|
||||
// 获取区域主控的内部 DeviceID
|
||||
regionalController, err := c.deviceRepo.FindByDevEui(devEui)
|
||||
if err != nil {
|
||||
c.logger.Errorf("记录下行任务失败:无法通过 DevEui '%s' 找到区域主控设备: %v", devEui, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建 DeviceCommandLog
|
||||
record := &models.DeviceCommandLog{
|
||||
MessageID: messageID,
|
||||
DeviceID: regionalController.ID,
|
||||
SentAt: time.Now(),
|
||||
AcknowledgedAt: nil, // 初始状态为未确认
|
||||
}
|
||||
|
||||
if err := c.deviceCommandLogRepo.Create(record); err != nil {
|
||||
c.logger.Errorf("创建下行任务记录失败 (MessageID: %s, DeviceID: %d): %v", messageID, regionalController.ID, err)
|
||||
return err
|
||||
}
|
||||
|
||||
c.logger.Infof("成功创建下行任务记录 (MessageID: %s, DeviceID: %d)", messageID, regionalController.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user