From 445ad6d95b6f65c3ea7cfdaa02e7694471b612c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Wed, 30 Apr 2025 17:16:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=B0=81=E8=A3=85=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debug/ColdTrapStartHeatingCommandHandler.java | 10 ++- .../gd/app/service/DeviceCommandService.java | 96 ++++++++++++++++++++++ .../com/iflytop/gd/common/cmd/CommandHandler.java | 2 +- .../gd/hardware/service/HardwareService.java | 5 +- 4 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java diff --git a/src/main/java/com/iflytop/gd/app/cmd/debug/ColdTrapStartHeatingCommandHandler.java b/src/main/java/com/iflytop/gd/app/cmd/debug/ColdTrapStartHeatingCommandHandler.java index 9950e41..22af28d 100644 --- a/src/main/java/com/iflytop/gd/app/cmd/debug/ColdTrapStartHeatingCommandHandler.java +++ b/src/main/java/com/iflytop/gd/app/cmd/debug/ColdTrapStartHeatingCommandHandler.java @@ -2,7 +2,11 @@ package com.iflytop.gd.app.cmd.debug; import com.iflytop.gd.app.core.BaseCommandHandler; import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.service.DeviceCommandService; import com.iflytop.gd.common.annotation.CommandMapping; +import com.iflytop.gd.common.cmd.CommandFuture; +import com.iflytop.gd.common.cmd.DeviceCommand; +import com.iflytop.gd.common.cmd.DeviceCommandGenerator; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -15,9 +19,13 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor @CommandMapping("debug_cold_trap_start_heating") public class ColdTrapStartHeatingCommandHandler extends BaseCommandHandler { + private final DeviceCommandService deviceCommandService; @Override - public void handle(CmdDTO cmdDTO) { + public void handle(CmdDTO cmdDTO) throws Exception { + DeviceCommand deviceCommand = DeviceCommandGenerator.coldTrapOpenHeart(); + CommandFuture deviceCommandFuture = deviceCommandService.sendCommand(cmdDTO.getCommandId(), cmdDTO.getCommand(), deviceCommand); + commandWait(deviceCommandFuture); } } diff --git a/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java b/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java new file mode 100644 index 0000000..88de838 --- /dev/null +++ b/src/main/java/com/iflytop/gd/app/service/DeviceCommandService.java @@ -0,0 +1,96 @@ +package com.iflytop.gd.app.service; + + +import cn.hutool.json.JSONObject; +import com.iflytop.gd.common.cmd.CommandFuture; +import com.iflytop.gd.common.cmd.CyclicNumberGenerator; +import com.iflytop.gd.common.cmd.DeviceCommand; +import com.iflytop.gd.hardware.service.HardwareService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DeviceCommandService { + + private final ConcurrentMap commandFutureMap = new ConcurrentHashMap<>(); + + private final WebSocketService webSocketService; + private final HardwareService hardwareService; + + + + public CommandFuture executeCommand(DeviceCommand cmdToDevice) { + int cmdId = CyclicNumberGenerator.getInstance().generateNumber(); + cmdToDevice.setCmdId(cmdId); + CommandFuture cmdFuture = new CommandFuture(); + commandFutureMap.put(cmdToDevice.getCmdId(), cmdFuture); + cmdFuture.setStartSendTime(System.currentTimeMillis()); + if (!hardwareService.sendCommand(cmdToDevice)) { + commandFutureMap.remove(cmdToDevice.getCmdId()); + throw new RuntimeException("向设备发送指令失败"); + } + + cmdFuture.getResponseFuture().whenComplete((result, ex) -> { + commandFutureMap.remove(cmdToDevice.getCmdId()); + }); + + return cmdFuture; + } + + + public CommandFuture sendCommandNoFront(DeviceCommand deviceCommand) { + return executeCommand(deviceCommand); + } + + public CommandFuture sendCommand(String cmdId, String cmdCode, DeviceCommand deviceCommand){ + CommandFuture commandFuture = executeCommand(deviceCommand); + commandFuture.setCmdId(cmdId); + commandFuture.setCmdCode(cmdCode); + commandFuture.setDeviceCommand(deviceCommand); +// webSocketService.push(FrontResponseGenerator.generateJson(cmdId, cmdCode, CommandStatus.DEVICE_SEND, deviceCommand.getCmdName() + "指令,已发给设备", deviceCommand)); + return commandFuture; + } + + public void completeCommandResponse(JSONObject deviceResult) { + Integer cmdId = deviceResult.getInt("cmdId"); + if (cmdId != null) { + CommandFuture future = commandFutureMap.get(cmdId); + if (future != null) { + future.setEndSendTime(System.currentTimeMillis()); + Boolean success = deviceResult.getBool("success"); //数据验证 + if (success == null || !success) { //response失败 + if (future.getCmdId() != null) { +// webSocketService.push(FrontResponseGenerator.generateJson(future.getCmdId(), future.getCmdCode(), CommandStatus.DEVICE_ERROR, +// future.getDeviceCommand().getCmdName() + "指令,设备response错误,耗时:" + (future.getEndSendTime() - future.getStartSendTime()), deviceResult)); + } + future.completeResponseExceptionally(new RuntimeException("response失败:" + deviceResult)); + } else { + if (future.getCmdId() != null) { +// webSocketService.push(FrontResponseGenerator.generateJson(future.getCmdId(), future.getCmdCode(), CommandStatus.DEVICE_RESULT, +// future.getDeviceCommand().getCmdName() + "指令,设备response正常,耗时:" + (future.getEndSendTime() - future.getStartSendTime()), deviceResult)); + } + future.completeResponse(deviceResult); + } + } + } + } + + /** + * 取消等待中的future并从map中移除 + */ + public synchronized void releaseAllCommandFutures() { + for (Integer key : commandFutureMap.keySet()) { + CommandFuture future = commandFutureMap.remove(key); + if (future != null) { + future.getResponseFuture().cancel(true); + } + } + } + +} diff --git a/src/main/java/com/iflytop/gd/common/cmd/CommandHandler.java b/src/main/java/com/iflytop/gd/common/cmd/CommandHandler.java index fc57d89..1224a54 100644 --- a/src/main/java/com/iflytop/gd/common/cmd/CommandHandler.java +++ b/src/main/java/com/iflytop/gd/common/cmd/CommandHandler.java @@ -3,5 +3,5 @@ package com.iflytop.gd.common.cmd; import com.iflytop.gd.app.model.dto.CmdDTO; public interface CommandHandler { - void handle(CmdDTO cmdDTO); + void handle(CmdDTO cmdDTO) throws Exception; } \ No newline at end of file diff --git a/src/main/java/com/iflytop/gd/hardware/service/HardwareService.java b/src/main/java/com/iflytop/gd/hardware/service/HardwareService.java index e27d0b0..1e88c98 100644 --- a/src/main/java/com/iflytop/gd/hardware/service/HardwareService.java +++ b/src/main/java/com/iflytop/gd/hardware/service/HardwareService.java @@ -6,13 +6,14 @@ import com.iflytop.gd.common.cmd.DeviceCommand; import com.iflytop.gd.common.enums.cmd.CmdDevice; import com.iflytop.gd.hardware.command.CommandHandler; import com.iflytop.gd.hardware.command.SupportMethod; +import org.springframework.stereotype.Component; import java.security.InvalidParameterException; import java.util.HashMap; import java.util.Map; - +@Component public class HardwareService { private final Map cmdHandlers = new HashMap<>(); @@ -21,7 +22,7 @@ public class HardwareService { // cmdHandlers.put(CmdDevice.door, new FanHandler(0)); } - boolean sendCommand(DeviceCommand cmd) + public boolean sendCommand(DeviceCommand cmd) { try { String strMethod = cmd.getCmdCode();