92 lines
3.2 KiB
Go
92 lines
3.2 KiB
Go
package lora
|
|
|
|
import (
|
|
"time"
|
|
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
|
"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"
|
|
"github.com/go-openapi/strfmt"
|
|
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/transport/lora/chirp_stack_proto/client"
|
|
)
|
|
|
|
// ChirpStackConfig 保存连接到 ChirpStack API 所需的配置。
|
|
type ChirpStackConfig struct {
|
|
// ServerAddress 是 ChirpStack API 服务器的地址,例如 "localhost:8080"。
|
|
ServerAddress string
|
|
// APIKey 是用于认证的 API 密钥。
|
|
APIKey string
|
|
// LoRaWAN 端口, 需要和设备一致
|
|
Fport int64
|
|
}
|
|
|
|
// GenerateAPIKey 用于补齐API Key作为请求头时缺失的部分
|
|
func (c ChirpStackConfig) GenerateAPIKey() string {
|
|
return "Bearer " + c.APIKey
|
|
}
|
|
|
|
// ChirpStackTransport 是一个客户端,用于封装与 ChirpStack REST API 的交互。
|
|
type ChirpStackTransport struct {
|
|
client *client.ChirpStackRESTAPI
|
|
authInfo runtime.ClientAuthInfoWriter
|
|
config ChirpStackConfig
|
|
|
|
logger *logs.Logger
|
|
}
|
|
|
|
// NewChirpStackTransport 创建一个新的通信实例,用于与 ChirpStack 通信。
|
|
func NewChirpStackTransport(config ChirpStackConfig, logger *logs.Logger) *ChirpStackTransport {
|
|
// 使用配置中的服务器地址创建一个 HTTP transport。
|
|
// 它会使用生成的客户端中定义的默认 base path 和 schemes。
|
|
transport := httptransport.New(config.ServerAddress, client.DefaultBasePath, client.DefaultSchemes)
|
|
|
|
// 使用 transport 和默认的字符串格式化器,创建一个 API 主客户端。
|
|
apiClient := client.New(transport, strfmt.Default)
|
|
|
|
// 使用 API Key 创建认证信息写入器。
|
|
authInfo := httptransport.APIKeyAuth("grpc-metadata-authorization", "header", config.GenerateAPIKey())
|
|
|
|
return &ChirpStackTransport{
|
|
client: apiClient,
|
|
authInfo: authInfo,
|
|
config: config,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
func (c *ChirpStackTransport) Send(deviceID string, payload []byte) error {
|
|
// 1. 构建 API 请求体。
|
|
// - Confirmed: true 表示确认消息, 设为false将不保证消息送达(但可以节约下行容量)。
|
|
// - Data: 经过 Base64 编码的数据。
|
|
// - FPort: LoRaWAN 端口。
|
|
body := device_service.DeviceServiceEnqueueBody{
|
|
QueueItem: &device_service.DeviceServiceEnqueueParamsBodyQueueItem{
|
|
Confirmed: true,
|
|
Data: payload,
|
|
FPort: c.config.Fport,
|
|
},
|
|
}
|
|
|
|
// 2. 构建 API 请求参数。
|
|
// - WithTimeout 设置一个合理的请求超时。
|
|
// - WithQueueItemDevEui 指定目标设备的 EUI。
|
|
// - WithBody 设置请求体。
|
|
params := device_service.NewDeviceServiceEnqueueParams().
|
|
WithTimeout(10 * time.Second).
|
|
WithQueueItemDevEui(deviceID).
|
|
WithBody(body)
|
|
|
|
// 3. 调用生成的客户端方法来发送请求。
|
|
// c.authInfo 是您在 NewChirpStackTransport 中创建的认证信息。
|
|
_, err := c.client.DeviceService.DeviceServiceEnqueue(params, c.authInfo)
|
|
if err != nil {
|
|
c.logger.Errorf("设备 %s 调用ChirpStack Enqueue失败: %v", deviceID, err)
|
|
return err
|
|
}
|
|
|
|
c.logger.Infof("设备 %s 调用ChirpStack Enqueue成功", deviceID)
|
|
return nil
|
|
}
|