调整 GeneralDeviceService

This commit is contained in:
2025-09-30 00:07:16 +08:00
parent 3a0e72a5c8
commit 56dbb680a7
4 changed files with 58 additions and 38 deletions

View File

@@ -10,6 +10,8 @@ import (
"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/utils/command_generater"
"github.com/google/uuid"
gproto "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
@@ -61,27 +63,40 @@ func (g *GeneralDeviceService) Switch(device *models.Device, action DeviceAction
return fmt.Errorf("解析设备 %v(id=%v) 的属性失败: %w", device.Name, device.ID, err)
}
var command models.SwitchCommands
// 前面的 device.DeviceTemplate.SelfCheck()保障了解析一定成功
_ = device.DeviceTemplate.ParseCommands(&command)
deviceAction := command.On
if action == DeviceActionStop {
deviceAction = command.Off
// 4. 解析设备模板中的开关指令参数
var switchCmd models.SwitchCommands
if err := device.DeviceTemplate.ParseCommands(&switchCmd); err != nil {
return fmt.Errorf("解析设备 %v(id=%v) 的开关指令失败: %w", device.Name, device.ID, err)
}
// 4. 构建 Protobuf 指令
data, err := anypb.New(&proto.Switch{
DeviceAction: deviceAction,
BusNumber: int32(deviceProps.BusNumber),
BusAddress: int32(deviceProps.BusAddress),
RelayChannel: int32(deviceProps.RelayChannel),
})
// 5. 根据 action 生成 Modbus RTU 写入指令
onOffState := true // 默认为开启
if action == DeviceActionStop { // 如果是停止动作,则设置为关闭
onOffState = false
}
modbusCommandBytes, err := command_generater.GenerateModbusRTUSwitchCommand(
deviceProps.BusAddress,
switchCmd.ModbusStartAddress,
onOffState,
)
if err != nil {
return fmt.Errorf("创建指令失败: %w", err)
return fmt.Errorf("生成Modbus RTU写入指令失败: %w", err)
}
// 6. 构建 Protobuf Raw485Command包含总线号
raw485Cmd := &proto.Raw485Command{
BusNumber: int32(deviceProps.BusNumber), // 添加总线号
CommandBytes: modbusCommandBytes,
}
data, err := anypb.New(raw485Cmd)
if err != nil {
return fmt.Errorf("创建 Raw485Command Any Protobuf 失败: %w", err)
}
instruction := &proto.Instruction{
Method: proto.MethodType_SWITCH,
Method: proto.MethodType_INSTRUCTION, // 使用通用指令类型
Data: data,
}
@@ -90,14 +105,14 @@ func (g *GeneralDeviceService) Switch(device *models.Device, action DeviceAction
return fmt.Errorf("序列化指令失败: %w", err)
}
// 5. 发送指令
// 7. 发送指令
networkID := areaController.NetworkID
sendResult, err := g.comm.Send(networkID, message)
if err != nil {
return fmt.Errorf("发送指令到 %s 失败: %w", networkID, err)
}
// 6. 创建并保存命令日志
// 8. 创建并保存命令日志
logRecord := &models.DeviceCommandLog{
MessageID: sendResult.MessageID,
DeviceID: areaController.ID,
@@ -144,7 +159,7 @@ func (g *GeneralDeviceService) Collect(regionalControllerID uint, devicesToColle
continue
}
// 使用模板的 ParseCommands 方法获取指令
// 使用模板的 ParseCommands 方法获取传感器指令参数
var sensorCmd models.SensorCommands
if err := dev.DeviceTemplate.ParseCommands(&sensorCmd); err != nil {
g.logger.Warnf("跳过设备 %d因其模板指令无法解析为 SensorCommands: %v", dev.ID, err)
@@ -158,10 +173,26 @@ func (g *GeneralDeviceService) Collect(regionalControllerID uint, devicesToColle
continue
}
// 生成 Modbus RTU 读取指令
modbusCommandBytes, err := command_generater.GenerateModbusRTUReadCommand(
deviceProps.BusAddress,
sensorCmd.ModbusFunctionCode,
sensorCmd.ModbusStartAddress,
sensorCmd.ModbusQuantity,
)
if err != nil {
g.logger.Warnf("跳过设备 %d因生成Modbus RTU读取指令失败: %v", dev.ID, err)
continue
}
// 构建 Raw485Command包含总线号
raw485Cmd := &proto.Raw485Command{
BusNumber: int32(deviceProps.BusNumber), // 添加总线号
CommandBytes: modbusCommandBytes,
}
collectTasks = append(collectTasks, &proto.CollectTask{
DeviceAction: sensorCmd.Read, // 使用从模板中获取的指令
BusNumber: int32(deviceProps.BusNumber),
BusAddress: int32(deviceProps.BusAddress),
Command: raw485Cmd,
})
childDeviceIDs = append(childDeviceIDs, dev.ID)
}
@@ -199,7 +230,7 @@ func (g *GeneralDeviceService) Collect(regionalControllerID uint, devicesToColle
return err
}
instruction := &proto.Instruction{
Method: proto.MethodType_COLLECT,
Method: proto.MethodType_COLLECT, // 使用 COLLECT 指令类型
Data: anyData,
}
payload, err := gproto.Marshal(instruction)