EdgexAgent/device-ble-go/internal/driver/handle.go

198 lines
6.1 KiB
Go
Raw Normal View History

2025-07-10 20:40:32 +08:00
package driver
import (
"device-ble/internal/interfaces"
"fmt"
"log"
blecommand "device-ble/pkg/ble"
dsModels "github.com/edgexfoundry/device-sdk-go/v4/pkg/models"
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
"github.com/edgexfoundry/go-mod-core-contracts/v4/models"
)
/* Web UI 需求
1支持设置蓝牙模块配置
*/
// HandleReadCommands 处理读取命令。
// 获取蓝牙的固件版本号 AT+QVERSION
// 本机 BLE MAC 地址 AT+QBLEADDR?
// 蓝牙的广播参数 AT+QBLEADVPARAM?
func (d *Driver) HandleReadCommands(
deviceName string,
protocols map[string]models.ProtocolProperties,
reqs []dsModels.CommandRequest,
) (responses []*dsModels.CommandValue, err error) {
d.logger.Debugf("处理设备 [%s] 的读取命令", deviceName)
d.logger.Debugf("协议信息: %+v", protocols)
d.logger.Debugf("读取请求列表: %+v", reqs)
// 初始化返回结果列表
responses = make([]*dsModels.CommandValue, 0, len(reqs))
// 遍历每个请求,根据资源名称生成对应的 CommandValue
for _, req := range reqs {
var (
cv *dsModels.CommandValue
)
switch req.DeviceResourceName {
case "GetVERSION":
res, err := d.BleController.SendSingleWithResponse(blecommand.GetVersion())
if err != nil {
return nil, err
}
cv, err = dsModels.NewCommandValue(req.DeviceResourceName, common.ValueTypeString, res)
case "GetBLEADDR":
res, err := d.BleController.SendSingleWithResponse(blecommand.QueryAddress())
if err != nil {
return nil, err
}
cv, err = dsModels.NewCommandValue(req.DeviceResourceName, common.ValueTypeString, res)
}
responses = append(responses, cv)
}
return responses, nil
}
// HandleWriteCommands 处理写入命令。
func (d *Driver) HandleWriteCommands(deviceName string, protocols map[string]models.ProtocolProperties, reqs []dsModels.CommandRequest, params []*dsModels.CommandValue) error {
d.logger.Debugf("处理设备 %s 的写入命令", deviceName)
// TODO: 实现UI具体的写入逻辑
fmt.Printf("deviceName: \n\t%s,\n protocols: \n\t%v,\n reqs:\t%v,\n params:\n\t%v\n", deviceName, protocols, reqs, params)
for _, param := range params {
if err := d.handleWrite(param, d.BleController); err != nil {
return err
}
}
return nil
}
// handleWrite 对set命令进行分类处理
func (d *Driver) handleWrite(param *dsModels.CommandValue, ble interfaces.BLEController) error {
switch param.DeviceResourceName {
case "Setting&&PeripheralInit":
objValue, err := param.ObjectValue()
if err != nil {
return fmt.Errorf("resourceObjectArray.write: failed to get object array value: %v", err)
}
cmd := objValue.(map[string]interface{})
fmt.Printf("Setting&&PeripheralInit: %v\n", cmd)
// 数据合法性检查
cmdName, ok := cmd["BleName"].(string)
if !ok {
return fmt.Errorf("输入的BleName不是String类型")
}
return d.handleSetPeripheralInit(cmdName, ble)
case "SetTxPower":
{
int8Value, err := param.Int8Value()
if err != nil {
return fmt.Errorf("resourceObjectArray.write: failed to get int8 value: %v", err)
}
fmt.Printf("SetTxPower: %v\n", param.Value)
return d.handleSetTxPower(int8Value, d.BleController)
}
case "SetBaud":
{
int64Value, err := param.Int64Value()
if err != nil {
return fmt.Errorf("resourceObjectArray.write: failed to get int64 value: %v", err)
}
fmt.Printf("SetBaud: %v\n", param.Value)
return d.handleSetBaud(int64Value, d.BleController)
}
case "SendString":
{
stringValue, err := param.StringValue()
if err != nil {
return fmt.Errorf("resourceObjectArray.write: failed to get int64 value: %v", err)
}
fmt.Printf("SendString: %v\n", param.Value)
return d.handleSendString(stringValue, d.BleController)
}
}
return nil
}
// 自定义初始化蓝牙模块
// TODO还需要加入自定义特征值并同步到jsonSender当中
func (d *Driver) handleSetPeripheralInit(BleName string, ble interfaces.BLEController) error {
var cmds []string
// 1. 添加通用模块控制命令
cmds = append(cmds, blecommand.Restart()) // AT+QRST\r\n
// 2. 添加 BLE 初始化与配置命令
if cmd, err := blecommand.Init(2); err == nil { // Peripheral 角色
cmds = append(cmds, cmd) // AT+QBLEINIT=2\r\n
} else {
log.Printf("Error generating Init: %v", err)
}
// 3. 设置BLE名称
if cmd, err := blecommand.SetDeviceName(BleName); err == nil {
cmds = append(cmds, cmd) // AT+QBLENAME="<BleName>"\r\n
} else {
log.Printf("Error generating SetDeviceName: %v", err)
}
// 4. 添加 GATT 服务端命令
if cmd, err := blecommand.AddService("fff1"); err == nil { // 示例 UUID
cmds = append(cmds, cmd) // AT+QBLEGATTSSRV=180F\r\n
} else {
log.Printf("Error generating AddService: %v", err)
}
// 5. 添加 GATT 服务端特征值
if cmd, err := blecommand.AddCharacteristic("fff2"); err == nil { // 默认Read + Notify
cmds = append(cmds, cmd) // AT+QBLEGATTSCHAR=2A19\r\n
} else {
log.Printf("Error generating AddCh aracteristic: %v", err)
}
// 6. 完成 GATT 服务配置
cmds = append(cmds, blecommand.FinishGATTServer()) // AT+QBLEGATTSSRVDONE\r\n
// 7. 开始广播
cmds = append(cmds, blecommand.StartAdvertising()) // AT+QBLEADVSTART\r\n
// 打印 cmds 切片内容
// fmt.Println("Generated AT Commands:")
for i, cmd := range cmds {
fmt.Printf("%d: %s", i, cmd)
}
return ble.CustomInitializeBle(cmds)
}
func (d *Driver) handleSetTxPower(TxPower int8, ble interfaces.BLEController) error {
if cmd, err := blecommand.SetTxPower(TxPower); err != nil {
return fmt.Errorf("Error generating SetBaud: %v", err)
} else {
return ble.SendSingle(cmd)
}
}
func (d *Driver) handleSetBaud(Baud int64, ble interfaces.BLEController) error {
if cmd, err := blecommand.SetBaud(Baud); err != nil {
return fmt.Errorf("Error generating SetBaud: %v", err)
} else {
return ble.SendSingle(cmd)
}
}
func (d *Driver) handleSendString(Str string, ble interfaces.BLEController) error {
if len(Str) > 223 {
return fmt.Errorf("Error, Becuase sending str out of range (240bit)")
}
if cmd, err := blecommand.SendNotify("fff2", Str); err != nil {
return fmt.Errorf("Error generating SendString")
} else {
return ble.SendSingle(cmd)
}
}