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

198 lines
6.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"
"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)
}
}