EdgexAgent/device-ble-go/internal/driver/service.go
2025-07-10 20:40:32 +08:00

173 lines
5.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package driver
import (
"device-ble/internal/interfaces"
"device-ble/pkg/ble"
"device-ble/pkg/dataparse"
"fmt"
"strings"
"time"
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/logger"
)
const (
TopicBLEUp = "edgex/service/data/device_ble/up"
TopicBLEDown = "edgex/service/data/device_ble/dwon"
TopicAllStatusReq = "edgex/core/commandquery/request/all"
TopicResponse = "edgex/response/#"
TopicReadingReq = "edgex/core/command/request"
)
// CommandService 负责上行命令分发和业务处理。
type CommandService struct {
Logger logger.LoggingClient
MessageBusClient interfaces.MessageBusClient
BleController interfaces.BLEController
}
// HandleCommand 处理命令分发。
func (cs *CommandService) HandleCommand(cmd string) {
if strings.Contains(cmd, "allstatus") {
// cmd数据格式+COMMAND:allstatus
cs.Logger.Infof("【运维 — allstatus】开始查询所有设备状态")
data, err := cs.requestAndParseAll(TopicAllStatusReq, TopicResponse, 5*time.Second)
if err != nil {
cs.Logger.Errorf("【运维 — allstatus 请求&解析失败: %v", err)
return
}
err = ble.SendJSONOverBLE(cs.BleController.GetQueue(), data)
data = nil
if err != nil {
cs.Logger.Errorf("【运维 — allstatus】发送响应失败: %v", err)
return
}
} else if strings.Contains(cmd, "monitor") {
// cmd数据格式monitor,<deviceNamce>,<resourceName>
// +COMMAND:monitor,Random-Integer-Device,Int8
cs.Logger.Infof("【运维 — monitor】开始设备监控 %v", cmd)
parts := strings.Split(cmd, ",")
if len(parts) >= 3 {
deviceName := parts[1]
resourceName := parts[2]
// 使用 deviceName 和 resourceName 继续处理逻辑
cs.Logger.Infof("【运维 — monitor】 device: %s, resource: %s\n", deviceName, resourceName)
cs.Logger.Infof("【运维 — monitor】开始监控指定设备数据")
TopicReadingRequest := fmt.Sprintf("%s/%s/%s/%s", TopicReadingReq, deviceName, resourceName, "get")
data, err := cs.requestAndParseReading(TopicReadingRequest, TopicResponse, 5*time.Second)
if err != nil {
cs.Logger.Errorf("【运维 — monitor】 请求&解析失败: %v", err)
return
}
err = ble.SendJSONOverBLE(cs.BleController.GetQueue(), data)
data = nil
if err != nil {
cs.Logger.Errorf("【运维 — monitor】发送响应失败: %v", err)
return
}
} else {
cs.Logger.Errorf("【运维 — monitor】命令格式错误应为monitor,<deviceName>,<resourceName>")
return
}
} else {
cs.Logger.Warnf("命名不支持!!")
err := ble.SendJSONOverBLE(cs.BleController.GetQueue(), "命名不支持!!")
if err != nil {
cs.Logger.Errorf("【运维——status】发送响应失败: %v", err)
return
}
return
}
}
func (cs *CommandService) requestAndParseAll(
reqTopic string,
respTopic string,
timeout time.Duration,
) (interface{}, error) {
cs.Logger.Infof("【运维】准备订阅响应主题: %s", respTopic)
if err := cs.MessageBusClient.SubscribeResponse(respTopic); err != nil {
cs.Logger.Errorf("订阅响应失败: %v", err)
return nil, err
}
cs.Logger.Infof("【运维】订阅响应成功: %s", respTopic)
cs.MessageBusClient.SetTimeout(timeout)
resp, err := cs.MessageBusClient.Request(reqTopic, "")
if err != nil {
cs.Logger.Errorf("请求失败 [%s]: %v", reqTopic, err)
return nil, err
}
cs.Logger.Infof("【运维】收到响应")
data, err := dataparse.ParseDeviceLists(&resp)
if err != nil {
cs.Logger.Errorf("响应数据解析失败: %v", err)
return nil, err
}
return data, nil
}
func (cs *CommandService) requestAndParseReading(
reqTopic string,
respTopic string,
timeout time.Duration,
) (interface{}, error) {
cs.Logger.Infof("【运维】准备订阅响应主题: %s", respTopic)
if err := cs.MessageBusClient.SubscribeResponse(respTopic); err != nil {
cs.Logger.Errorf("订阅响应失败: %v", err)
return nil, err
}
cs.Logger.Infof("【运维】订阅响应成功: %s", respTopic)
cs.MessageBusClient.SetTimeout(timeout)
resp, err := cs.MessageBusClient.Request(reqTopic, "")
if err != nil {
cs.Logger.Errorf("请求失败 [%s]: %v", reqTopic, err)
return nil, err
}
cs.Logger.Infof("【运维】收到响应 %v", resp)
data, err := dataparse.ParseReading(&resp)
if err != nil {
cs.Logger.Errorf("响应数据解析失败: %v", err)
return nil, err
}
return data, nil
}
// AgentService 负责透明代理上行数据处理。
type AgentService struct {
Logger logger.LoggingClient
MessageBusClient interfaces.MessageBusClient
}
// HandleAgentData 处理透明代理数据。
func (as *AgentService) HandleAgentData(data string) {
if data == "" {
return
}
type Payload struct {
Timestamp int64
Data string
}
as.Logger.Infof("【透明代理(↑)】:收到上行数据: %s", data)
p := Payload{
Timestamp: time.Now().UnixNano(),
Data: data,
}
if as.MessageBusClient != nil {
err := as.MessageBusClient.Publish(TopicBLEUp, p)
if err != nil {
as.Logger.Errorf("【透明代理(↑)】转发至消息总线失败 ❌: %v", err)
} else {
as.Logger.Infof("【透明代理(↑)】转发至消息总线成功 ✔")
}
}
}