diff --git a/src/main/java/com/qyft/gd/common/constant/WebSocketMessageType.java b/src/main/java/com/qyft/gd/common/constant/WebSocketMessageType.java new file mode 100644 index 0000000..cc7efbb --- /dev/null +++ b/src/main/java/com/qyft/gd/common/constant/WebSocketMessageType.java @@ -0,0 +1,20 @@ +package com.qyft.gd.common.constant; + +public class WebSocketMessageType { + /** + * 设备状态 + */ + public static final String STATUS = "status"; + /** + * 设备报警 + */ + public static final String ALARM = "alarm"; + /** + * 设备指令反馈 + */ + public static final String FEEDBACK = "feedback"; + /** + * 工艺执行反馈 + */ + public static final String CRAFTS = "crafts"; +} diff --git a/src/main/java/com/qyft/gd/controller/CraftsController.java b/src/main/java/com/qyft/gd/controller/CraftsController.java index 629c0e0..39a0c33 100644 --- a/src/main/java/com/qyft/gd/controller/CraftsController.java +++ b/src/main/java/com/qyft/gd/controller/CraftsController.java @@ -68,7 +68,7 @@ public class CraftsController { @Operation(summary = "开始执行工艺") @PostMapping("/start") - public Result startCrafts(@Parameter(description = "工艺id") @RequestParam Long craftId, @Parameter(description = "加热区id") @RequestParam Long heatId) { + public Result startCrafts(@Parameter(description = "工艺id") @RequestParam Long craftId, @Parameter(description = "加热区id") @RequestParam String heatId) { boolean isSuccess = craftsStepService.startCrafts(craftId, heatId); if (isSuccess) { return Result.success(); @@ -78,7 +78,7 @@ public class CraftsController { @Operation(summary = "停止执行工艺") @PostMapping("/stop") - public Result stopCrafts(@Parameter(description = "加热区id") @RequestParam Long heatId) { + public Result stopCrafts(@Parameter(description = "加热区id") @RequestParam String heatId) { boolean isSuccess = craftsStepService.stopCrafts(heatId); if (isSuccess) { return Result.success(); diff --git a/src/main/java/com/qyft/gd/device/handler/DeviceMessageHandler.java b/src/main/java/com/qyft/gd/device/handler/DeviceMessageHandler.java index 8c6d6d7..6c3d21f 100644 --- a/src/main/java/com/qyft/gd/device/handler/DeviceMessageHandler.java +++ b/src/main/java/com/qyft/gd/device/handler/DeviceMessageHandler.java @@ -1,6 +1,7 @@ package com.qyft.gd.device.handler; import cn.hutool.json.JSONUtil; +import com.qyft.gd.common.constant.WebSocketMessageType; import com.qyft.gd.device.common.constant.TcpMessageType; import com.qyft.gd.device.common.jsonrpc.JsonRpcResponse; import com.qyft.gd.device.model.bo.DeviceAlarm; @@ -44,7 +45,7 @@ public class DeviceMessageHandler extends ChannelInboundHandlerAdapter { deviceStateService.updateDeviceStatus(deviceStatus); // 更新设备状态 } else if (TcpMessageType.ALARM.equals(jsonRpcResponse.getType())) {//设备报警 DeviceAlarm deviceAlarm = JSONUtil.toBean(jsonRpcResponse.getData(), DeviceAlarm.class); - webSocketService.pushMsg("alarm", deviceAlarm); + webSocketService.pushMsg(WebSocketMessageType.ALARM, deviceAlarm); } else if (TcpMessageType.FEEDBACK.equals(jsonRpcResponse.getType())) {//设备指令反馈 DeviceFeedback deviceFeedback = JSONUtil.toBean(jsonRpcResponse.getData(), DeviceFeedback.class); this.handleTcpResponse(deviceFeedback); diff --git a/src/main/java/com/qyft/gd/model/bo/CraftsStepMethod.java b/src/main/java/com/qyft/gd/model/bo/CraftsStepMethod.java new file mode 100644 index 0000000..71559a8 --- /dev/null +++ b/src/main/java/com/qyft/gd/model/bo/CraftsStepMethod.java @@ -0,0 +1,52 @@ +package com.qyft.gd.model.bo; + +import lombok.Data; + +/** + * 工艺步骤执行方法 + */ +@Data +public class CraftsStepMethod { + /** + * 上升托盘 + */ + public static final String UP_TRAY = "upTray"; + /** + * 降下托盘 + */ + public static final String DOWN_TRAY = "downTray"; + /** + * 加液 + */ + public static final String ADD_LIQUID = "addLiquid"; + /** + * 移动到溶液位置 + */ + public static final String MOVE_TO_SOL = "moveToSol"; + /** + * 移动到加热器位置 + */ + public static final String MOVE_TO_HEATER = "moveToHeater"; + /** + * 摇晃 + */ + public static final String SHAKING = "shaking"; + /** + * 开始加热 + */ + public static final String START_HEATING = "startHeating"; + /** + * 停止加热 + */ + public static final String STOP_HEATING = "stopHeating"; + /** + * 拍照 + */ + public static final String TAKE_PHOTO = "takePhoto"; + /** + * 等待 + */ + public static final String DELAY = "delay"; + + +} diff --git a/src/main/java/com/qyft/gd/model/bo/CraftsStepStatus.java b/src/main/java/com/qyft/gd/model/bo/CraftsStepStatus.java new file mode 100644 index 0000000..41872e4 --- /dev/null +++ b/src/main/java/com/qyft/gd/model/bo/CraftsStepStatus.java @@ -0,0 +1,35 @@ +package com.qyft.gd.model.bo; + +import lombok.Data; + +/** + * 工艺步骤执行状态 + */ +@Data +public class CraftsStepStatus { + + /** + * 未执行 + */ + public static final int NOT_EXECUTED = 0; + /** + * 正在执行 + */ + public static final int IN_PROGRESS = 1; + /** + * 暂停执行 + */ + public static final int PAUSED = 2; + /** + * 停止执行 + */ + public static final int STOPPED = 3; + /** + * 执行错误 + */ + public static final int ERROR = 4; + /** + * 执行完成 + */ + public static final int FINISH = 6; +} diff --git a/src/main/java/com/qyft/gd/model/vo/CraftsStepResult.java b/src/main/java/com/qyft/gd/model/vo/CraftsStepResult.java new file mode 100644 index 0000000..2e311b6 --- /dev/null +++ b/src/main/java/com/qyft/gd/model/vo/CraftsStepResult.java @@ -0,0 +1,23 @@ +package com.qyft.gd.model.vo; + +import lombok.Data; + +/** + * 工艺步骤执行状态 + */ +@Data +public class CraftsStepResult { + /** + * 加热区id + */ + private String heatId; + /** + * 当前工艺执行状态 0未执行 1正在执行 2暂停执行 3停止执行 + */ + private Integer status; + /** + * 当前工艺执行的方法 + */ + private String method; + +} diff --git a/src/main/java/com/qyft/gd/service/CraftsStepService.java b/src/main/java/com/qyft/gd/service/CraftsStepService.java index 0ae58b3..9a69544 100644 --- a/src/main/java/com/qyft/gd/service/CraftsStepService.java +++ b/src/main/java/com/qyft/gd/service/CraftsStepService.java @@ -3,9 +3,13 @@ package com.qyft.gd.service; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.qyft.gd.common.constant.WebSocketMessageType; import com.qyft.gd.device.service.DeviceStepService; +import com.qyft.gd.model.bo.CraftsStepMethod; +import com.qyft.gd.model.bo.CraftsStepStatus; import com.qyft.gd.model.bo.TubeSol; import com.qyft.gd.model.entity.Crafts; +import com.qyft.gd.model.vo.CraftsStepResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -26,12 +30,18 @@ public class CraftsStepService { private final CraftsService craftsService; private final DeviceStepService deviceStepService; + private final WebSocketService webSocketService; private final ExecutorService executorService = Executors.newCachedThreadPool(); - private final ConcurrentHashMap> taskMap = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> taskMap = new ConcurrentHashMap<>(); - // 启动任务的方法 - public synchronized boolean startCrafts(Long craftId, Long heatId) { + /** + * 启动工艺 + * + * @param craftId 工艺id + * @param heatId 加热区id + */ + public synchronized boolean startCrafts(Long craftId, String heatId) { Future taskFuture = taskMap.get(heatId); if (taskFuture != null) { return false; @@ -42,145 +52,244 @@ public class CraftsStepService { return true; } - // 停止任务的方法,通过ID来指定 - public synchronized boolean stopCrafts(Long heatId) { + /** + * 通过加热区id来停止任务 + * + * @param heatId 加热区id + */ + public synchronized boolean stopCrafts(String heatId) { Future taskFuture = taskMap.get(heatId); if (taskFuture != null) { boolean cancelled = taskFuture.cancel(true); if (cancelled) { taskMap.remove(heatId); } + return cancelled; } return false; } - class CraftsTask implements Runnable { - private final Long heatId; + private final String heatId; private final Long craftId; - public CraftsTask(Long craftId, Long heatId) { + private static String currentMethod = null; + private static int currentStatus = CraftsStepStatus.NOT_EXECUTED; + + public CraftsTask(Long craftId, String heatId) { this.heatId = heatId; this.craftId = craftId; } @Override public void run() { - while (!Thread.currentThread().isInterrupted()) { - Crafts crafts = craftsService.findCraftsById(craftId); - log.info("开始执行工艺,加热区 {},工艺 {}", heatId, crafts.getName()); - String steps = crafts.getSteps(); - JSONArray stepsJsonArray = JSONUtil.parseArray(steps); - for (Object stepsJsonObject : stepsJsonArray) { + currentStatus = CraftsStepStatus.IN_PROGRESS; + Crafts crafts = craftsService.findCraftsById(craftId); + log.info("开始执行工艺,加热区 {},工艺 {}", heatId, crafts.getName()); + String steps = crafts.getSteps(); + JSONArray stepsJsonArray = JSONUtil.parseArray(steps); + for (Object stepsJsonObject : stepsJsonArray) { + if (!Thread.currentThread().isInterrupted()) { JSONObject stepsJson = (JSONObject) stepsJsonObject; String method = stepsJson.get("method").toString(); JSONObject params = (JSONObject) stepsJson.get("params"); boolean result = switch (method) { - case "upTray" -> upTray(params); - case "downTray" -> downTray(params); - case "addLiquid" -> addLiquid(params); - case "moveToSol" -> moveToSol(params); - case "moveToHeater" -> moveToHeater(params); - case "shaking" -> shaking(params); - case "startHeating" -> startHeating(params); - case "stopHeating" -> stopHeating(params); - case "takePhoto" -> takePhoto(); - case "moveToExc" -> delay(params); + case CraftsStepMethod.UP_TRAY -> this.upTray(); + case CraftsStepMethod.DOWN_TRAY -> this.downTray(); + case CraftsStepMethod.ADD_LIQUID -> this.addLiquid(params); + case CraftsStepMethod.MOVE_TO_SOL -> this.moveToSol(); + case CraftsStepMethod.MOVE_TO_HEATER -> this.moveToHeater(); + case CraftsStepMethod.SHAKING -> this.shaking(params); + case CraftsStepMethod.START_HEATING -> this.startHeating(params); + case CraftsStepMethod.STOP_HEATING -> this.stopHeating(); + case CraftsStepMethod.TAKE_PHOTO -> this.takePhoto(); + case CraftsStepMethod.DELAY -> this.delay(params); default -> false; }; if (!result) { - //TODO 向前端反馈执行失败 + pushMsg(heatId, CraftsStepStatus.ERROR); return; } + pushMsg(heatId, currentStatus, currentMethod); + } else { + pushMsg(heatId, CraftsStepStatus.STOPPED); + return; } } + pushMsg(heatId, CraftsStepStatus.FINISH); + } + + /** + * 抬起托盘 + */ + private boolean upTray() { + currentMethod = CraftsStepMethod.UP_TRAY; + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.upTray(heatId); + return true; } - } + /** + * 降下托盘 + */ + private boolean downTray() { + currentMethod = CraftsStepMethod.DOWN_TRAY; + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.downTray(heatId); + return true; + } - /** - * 抬起托盘 - */ - private boolean upTray(JSONObject params) { - String heaterId = params.get("heaterId").toString(); - return deviceStepService.upTray(heaterId); - } + /** + * 添加溶液 + */ + private boolean addLiquid(JSONObject params) { + currentMethod = CraftsStepMethod.ADD_LIQUID; - /** - * 降下托盘 - */ - private boolean downTray(JSONObject params) { - String heaterId = params.get("heaterId").toString(); - return deviceStepService.downTray(heaterId); - } + JSONArray tubeSolJSONArray = params.getJSONArray("tubeSolList"); + List tubeSolList = JSONUtil.toList(tubeSolJSONArray.toString(), TubeSol.class); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.addLiquid(tubeSolList); + return true; + } - /** - * 添加溶液 - */ - private boolean addLiquid(JSONObject params) { - JSONArray tubeSolJSONArray = params.getJSONArray("tubeSolList"); - List tubeSolList = JSONUtil.toList(tubeSolJSONArray.toString(), TubeSol.class); - return deviceStepService.addLiquid(tubeSolList); - } + /** + * 将指定加热区的托盘移至加液区 + */ + private boolean moveToSol() { + currentMethod = CraftsStepMethod.MOVE_TO_SOL; + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.moveToSol(heatId); + return true; + } - /** - * 将指定加热区的托盘移至加液区 - */ - private boolean moveToSol(JSONObject params) { - String heaterId = params.get("heaterId").toString(); - return deviceStepService.moveToSol(heaterId); - } + /** + * 移至加热 + */ + private boolean moveToHeater() { + currentMethod = CraftsStepMethod.MOVE_TO_HEATER; + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.moveToHeater(heatId); + return true; + } - /** - * 移至加热 - */ - private boolean moveToHeater(JSONObject params) { - String heaterId = params.get("heaterId").toString(); - return deviceStepService.moveToHeater(heaterId); - } + /** + * 摇匀 + */ + private boolean shaking(JSONObject params) { + currentMethod = CraftsStepMethod.SHAKING; - //摇匀 - private boolean shaking(JSONObject params) { - Integer second = params.getInt("second"); - return deviceStepService.shaking(second); - } + Integer second = params.getInt("second"); + try { + Thread.sleep(second * 1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.shaking(second); + return true; + } - //开始加热 - private boolean startHeating(JSONObject params) { - String heaterId = params.get("heaterId").toString(); - Double temperature = params.getDouble("temperature"); - return deviceStepService.startHeating(heaterId, temperature); - } + /** + * 开始加热 + */ + private boolean startHeating(JSONObject params) { + currentMethod = CraftsStepMethod.START_HEATING; - //停止加热 - private boolean stopHeating(JSONObject params) { - String heaterId = params.get("heaterId").toString(); - return deviceStepService.stopHeating(heaterId); - } + Double temperature = params.getDouble("temperature"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.startHeating(heatId, temperature); + return true; + } - //拍照 - private boolean takePhoto() { - return deviceStepService.takePhoto(); - } + /** + * 停止加热 + */ + private boolean stopHeating() { + currentMethod = CraftsStepMethod.STOP_HEATING; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.stopHeating(heatId); + return true; + } + + /** + * 拍照 + */ + private boolean takePhoto() { + currentMethod = CraftsStepMethod.TAKE_PHOTO; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } +// return deviceStepService.takePhoto(); + return true; + } + + /** + * 移至异常 + */ + private boolean moveToExc() { + return true; + } + + /** + * 移除异常 + */ + private boolean moveOutToExc() { + return true; + } + + /** + * 等待 + */ + private boolean delay(JSONObject params) { + currentMethod = CraftsStepMethod.DELAY; + + Integer second = params.getInt("second"); + return deviceStepService.delay(second); + } - //移至异常 - private boolean moveToExc() { - return true; } - //移除异常 - private boolean moveOutToExc() { - return true; + private void pushMsg(String heatId, Integer status) { + this.pushMsg(heatId, status, null); } - /** - * 等待 - */ - private boolean delay(JSONObject params) { - Integer second = params.getInt("second"); - return deviceStepService.delay(second); + private void pushMsg(String heatId, Integer status, String method) { + CraftsStepResult craftsStepResult = new CraftsStepResult(); + craftsStepResult.setHeatId(heatId); + craftsStepResult.setStatus(status); + craftsStepResult.setMethod(method); + webSocketService.pushMsg(WebSocketMessageType.CRAFTS, craftsStepResult); } }