diff --git a/src/main/java/com/iflytop/gd/app/command/control/HeatStartCommand.java b/src/main/java/com/iflytop/gd/app/command/control/HeatStartCommand.java index 58007ab..b87bf71 100644 --- a/src/main/java/com/iflytop/gd/app/command/control/HeatStartCommand.java +++ b/src/main/java/com/iflytop/gd/app/command/control/HeatStartCommand.java @@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; import java.util.concurrent.CompletableFuture; /** @@ -25,36 +26,23 @@ import java.util.concurrent.CompletableFuture; public class HeatStartCommand extends BaseCommandHandler { private final HeatModuleService heatModuleService; private final DeviceStateService deviceStateService; - private final DevicePositionService devicePositionService; + @Override public CompletableFuture handle(CmdDTO cmdDTO) { String heatId = cmdDTO.getStringParam("heatId"); - Integer time = cmdDTO.getIntegerParam("time"); - Integer minutes = cmdDTO.getIntegerParam("minutes"); - Integer seconds = cmdDTO.getIntegerParam("seconds"); + Integer time = cmdDTO.getIntegerParam("time"); + Integer minutes = cmdDTO.getIntegerParam("minutes"); + Integer seconds = cmdDTO.getIntegerParam("seconds"); Double temperature = cmdDTO.getDoubleParam("temperature"); HeatModuleCode heatModuleCode = HeatModuleCode.valueOf(heatId); - double trayLower = devicePositionService.getPosition(DevicePositionCode.trayLower).getDistance(); - double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); - return runAsync(() -> { heatModuleService.heatRodOpen(cmdDTO.getCommandId(), cmdDTO.getCommand(), heatModuleCode, temperature); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setTargetTime(time); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setHeatTemperature(temperature); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setTargetTemperature(temperature); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setHeatingType(HeatingType.thermostatic); -// if (deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).getHeatingType() == HeatingType.thermostatic) { -// schedulerManager.scheduleOnce(heatModuleCode, () -> { -// try { -// heatModuleService.heaterMotorMove(cmdDTO.getCommandId(), cmdDTO.getCommand(), heatModuleCode, trayLift); -// deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setTrayUp(1); -// } catch (Exception e) { -// log.error("加热完毕抬起托盘错误{}", heatModuleCode, e); -// } -// }, deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).getTargetTime(), TimeUnit.SECONDS); -// } }); } } diff --git a/src/main/java/com/iflytop/gd/app/command/control/HeatStopCommand.java b/src/main/java/com/iflytop/gd/app/command/control/HeatStopCommand.java index e4c8841..2214e82 100644 --- a/src/main/java/com/iflytop/gd/app/command/control/HeatStopCommand.java +++ b/src/main/java/com/iflytop/gd/app/command/control/HeatStopCommand.java @@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; import java.util.concurrent.CompletableFuture; /** @@ -31,6 +32,7 @@ public class HeatStopCommand extends BaseCommandHandler { return runAsync(() -> { //关闭加热 heatModuleService.heatRodClose(cmdDTO.getCommandId(), cmdDTO.getCommand(), heatModuleCode); + deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setStartHeatTime(null); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setTargetTime(null); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setWarmUpTemperature(null); deviceStateService.getDeviceState().getHeatModuleByCode(heatModuleCode).setHeatTemperature(null); diff --git a/src/main/java/com/iflytop/gd/app/command/control/SolutionAddCommand.java b/src/main/java/com/iflytop/gd/app/command/control/SolutionAddCommand.java index b01ce7e..b8e94cb 100644 --- a/src/main/java/com/iflytop/gd/app/command/control/SolutionAddCommand.java +++ b/src/main/java/com/iflytop/gd/app/command/control/SolutionAddCommand.java @@ -5,6 +5,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.iflytop.gd.app.core.BaseCommandHandler; import com.iflytop.gd.app.model.dto.CmdDTO; +import com.iflytop.gd.app.model.entity.Container; import com.iflytop.gd.app.service.api.ContainerService; import com.iflytop.gd.app.service.device.DeviceStateService; import com.iflytop.gd.app.service.device.module.SolutionModuleService; @@ -21,6 +22,7 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; /** @@ -46,13 +48,13 @@ public class SolutionAddCommand extends BaseCommandHandler { || deviceStateService.getCommandMutexState().get().isShakeStartCommandExecuting()) { throw new AppException(ResultCode.CMD_BUSY); } - if(deviceStateService.getDeviceState().getSolutionModule().getTrayStatus() != 1){ + if (deviceStateService.getDeviceState().getSolutionModule().getTrayStatus() != 1) { throw new AppException(ResultCode.SOLUTION_MODULE_NO_TRAY); } deviceStateService.getCommandMutexState().get().setSolutionAddCommandExecuting(true); deviceStateService.getDeviceState().getSolutionModule().setPumping(true); return runAsync(() -> { - try{ + try { JSONArray dataList = JSONUtil.parseArray(cmdDTO.getParams().get("dataList")); for (int i = 0; i < dataList.size(); i++) {//遍历前端传入的加液配置 JSONObject tubeSol = dataList.getJSONObject(i); @@ -68,11 +70,17 @@ public class SolutionAddCommand extends BaseCommandHandler { JSONObject addSolution = solutionList.getJSONObject(k); Long solId = addSolution.getLong("solutionId"); Double volume = addSolution.getDouble("volume"); - AcidPumpDeviceCode acidPumpDevice = containerService.getPumpBySolutionId(solId);//获取溶液对应的泵 - if (acidPumpDevice == null) { + //AcidPumpDeviceCode acidPumpDevice = containerService.getPumpBySolutionId(solId);//获取溶液对应的泵 + Container container = containerService.getContainerBySolutionId(solId); + if (container == null) { throw new AppException(ResultCode.CRAFT_CONTAINER_NOT_FOUND);//未找到对应溶液容器 } - CommandFuture deviceCommandFuture = solutionModuleService.acidPumpMoveBy(cmdDTO.getCommandId(), cmdDTO.getCommand(), acidPumpDevice, volume);//添加溶液 + AcidPumpDeviceCode acidPumpDevice = AcidPumpDeviceCode.valueOf(container.getPumpId());//泵 + int scale = container.getScale() == null ? 120 : container.getScale();//系数 +// Integer scale = Optional.ofNullable(container) +// .map(Container::getScale) +// .orElse(500); + CommandFuture deviceCommandFuture = solutionModuleService.acidPumpMoveBy(cmdDTO.getCommandId(), cmdDTO.getCommand(), acidPumpDevice, volume * ((double) scale /100));//添加溶液 futuresList.add(deviceCommandFuture); } CommandUtil.wait(futuresList.toArray(new CommandFuture[0])); @@ -81,7 +89,7 @@ public class SolutionAddCommand extends BaseCommandHandler { solutionModuleService.dualRobotOrigin(); deviceStateService.getCommandMutexState().get().setSolutionAddCommandExecuting(false); deviceStateService.getDeviceState().getSolutionModule().setPumping(false); - }finally { + } finally { deviceStateService.getCommandMutexState().get().setSolutionAddCommandExecuting(false); } diff --git a/src/main/java/com/iflytop/gd/app/model/bo/status/device/HeatModuleState.java b/src/main/java/com/iflytop/gd/app/model/bo/status/device/HeatModuleState.java index 2d40dfa..b4e37bc 100644 --- a/src/main/java/com/iflytop/gd/app/model/bo/status/device/HeatModuleState.java +++ b/src/main/java/com/iflytop/gd/app/model/bo/status/device/HeatModuleState.java @@ -9,6 +9,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; + @Schema(description = "加热模块") @Data @Component @@ -46,6 +48,9 @@ public class HeatModuleState { @Schema(description = "加热器目标加热时间,单位秒") private Integer targetTime = null; + @Schema(description = "开始加热时间") + private LocalDateTime startHeatTime = null; + @Schema(description = "加热器当前温度") private Double temperature = null; diff --git a/src/main/java/com/iflytop/gd/app/service/scheduled/HeatCountdownScheduledTask.java b/src/main/java/com/iflytop/gd/app/service/scheduled/HeatCountdownScheduledTask.java index 079f665..a7806c7 100644 --- a/src/main/java/com/iflytop/gd/app/service/scheduled/HeatCountdownScheduledTask.java +++ b/src/main/java/com/iflytop/gd/app/service/scheduled/HeatCountdownScheduledTask.java @@ -1,7 +1,6 @@ package com.iflytop.gd.app.service.scheduled; import com.iflytop.gd.app.model.bo.status.device.HeatModuleState; -import com.iflytop.gd.app.model.bo.status.device.TrayState; import com.iflytop.gd.app.model.vo.HeatCountdownVO; import com.iflytop.gd.app.service.api.DevicePositionService; import com.iflytop.gd.app.service.device.DeviceStateService; @@ -10,7 +9,6 @@ import com.iflytop.gd.app.ws.server.WebSocketSender; import com.iflytop.gd.common.enums.HeatingType; import com.iflytop.gd.common.enums.data.DevicePositionCode; import com.iflytop.gd.common.utils.LocalDateTimeUtil; -import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; @@ -22,7 +20,7 @@ import java.util.ArrayList; import java.util.List; /** - * 加热时间到自动抬起 + * 加热倒计时 */ @Slf4j @Service @@ -33,42 +31,58 @@ public class HeatCountdownScheduledTask { private final HeatModuleService heatModuleService; private final WebSocketSender webSocketSender; - @Scheduled(fixedDelay = 1000) + private double trayLift; + + private void init() { + trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); + } + + @Scheduled(fixedRate = 1000) public void fetchTemperature() { try { LocalDateTime now = LocalDateTime.now(); + List heatCountdownVOList = new ArrayList<>(); for (HeatModuleState heatModuleState : deviceStateService.getDeviceState().getHeatModule()) { - //工艺除外 - TrayState trayState = deviceStateService.getDeviceState().getTrayStateByHeatModuleCode(heatModuleState.getModuleCode()); - if (trayState != null && trayState.getCrafts() != null) { - continue; - } if (heatModuleState.getHeatingType() == HeatingType.thermostatic) {//如果这个加热模块在加热中 if (heatModuleState.getTemperature() + 1 > heatModuleState.getHeatTemperature()) {//当前温度达到目标温度,允许有1度以内的误差 - heatModuleState.setStartHeatTime(now); heatModuleState.setHeatingType(HeatingType.constant);//修改状态为恒温中 - } - } else if (heatModuleState.getHeatingType() == HeatingType.constant) { - LocalDateTime endTime = heatModuleState.getStartHeatTime().plusSeconds(heatModuleState.getTargetTime()); - //判断是否达到目标加热时间 - long diffSeconds = Duration.between(now, endTime).getSeconds();//计算剩余时间 - if (diffSeconds <= 0) {//加热完毕 - double trayLift = devicePositionService.getPosition(DevicePositionCode.trayLift).getDistance(); - //抬起托盘 - heatModuleService.heaterMotorMove(heatModuleState.getModuleCode(), trayLift); - heatModuleState.setTrayUp(1); - //关闭加棒 - heatModuleService.heatRodClose(heatModuleState.getModuleCode()); - //还原状态 - heatModuleState.setStartHeatTime(null);//开始加热时间 - heatModuleState.setTargetTime(null);//加热器目标加热时间 - heatModuleState.setWarmUpTemperature(null);//加热器预热温度 - heatModuleState.setHeatTemperature(null);//加热器加热温度 - heatModuleState.setTargetTemperature(null);//加热器目标温度 - heatModuleState.setHeatingType(HeatingType.finish); + if (heatModuleState.getStartHeatTime() == null) { + //设定开始加热时间 + heatModuleState.setStartHeatTime(now); + } else { + LocalDateTime endTime = heatModuleState.getStartHeatTime().minusSeconds(heatModuleState.getTargetTime()); + //判断是否达到目标加热时间 + if (endTime.isBefore(now)) {//加热完毕 + //抬起托盘 + heatModuleService.heaterMotorMove(heatModuleState.getModuleCode(), trayLift); + heatModuleState.setTrayUp(1); + //关闭加棒 + heatModuleService.heatRodClose(heatModuleState.getModuleCode()); + heatModuleState.setHeatingType(HeatingType.stop); + //还原状态 + heatModuleState.setStartHeatTime(null); + heatModuleState.setTargetTime(null); + heatModuleState.setWarmUpTemperature(null); + heatModuleState.setHeatTemperature(null); + heatModuleState.setTargetTemperature(null); + heatModuleState.setHeatingType(HeatingType.stop); + } else {//加热中 + long diffSeconds = Duration.between(now, endTime).getSeconds();//计算剩余时间 + HeatCountdownVO heatCountdownVO = new HeatCountdownVO(); + heatCountdownVO.setHeatModuleCode(heatModuleState.getModuleCode()); + heatCountdownVO.setCountdown((int) diffSeconds); + heatCountdownVO.setCountdownStr(LocalDateTimeUtil.formatSecondsToHMS(diffSeconds)); + heatCountdownVO.setStartTime(heatModuleState.getStartHeatTime()); + heatCountdownVO.setEndTime(endTime); + heatCountdownVOList.add(heatCountdownVO); + } + } } } } + if (!heatCountdownVOList.isEmpty()) { + webSocketSender.pushHeatCountdown(heatCountdownVOList); + } } catch (Exception e) { log.error("加热倒计时错误", e); } diff --git a/src/main/java/com/iflytop/gd/app/ws/server/WebSocketSender.java b/src/main/java/com/iflytop/gd/app/ws/server/WebSocketSender.java index fecdb26..8746903 100644 --- a/src/main/java/com/iflytop/gd/app/ws/server/WebSocketSender.java +++ b/src/main/java/com/iflytop/gd/app/ws/server/WebSocketSender.java @@ -16,7 +16,7 @@ public class WebSocketSender { websocketResult.setType(type); websocketResult.setData(data); WebSocketServer.sendMessageToClients(JSONUtil.toJsonStr(websocketResult)); -// log.info("WS::{}", JSONUtil.toJsonStr(websocketResult)); + log.info("WS::{}", JSONUtil.toJsonStr(websocketResult)); } public void pushCraftsDebug(Object data) { diff --git a/src/main/java/com/iflytop/gd/common/enums/HeatingType.java b/src/main/java/com/iflytop/gd/common/enums/HeatingType.java index dd0c4b2..99e6f66 100644 --- a/src/main/java/com/iflytop/gd/common/enums/HeatingType.java +++ b/src/main/java/com/iflytop/gd/common/enums/HeatingType.java @@ -8,6 +8,16 @@ import lombok.Getter; @Getter public enum HeatingType { stop, + /** + * 预热中 + */ warm_up, + /** + * 加热中 + */ thermostatic, + /** + * 恒温中 + */ + constant, } diff --git a/src/main/java/com/iflytop/gd/common/utils/LocalDateTimeUtil.java b/src/main/java/com/iflytop/gd/common/utils/LocalDateTimeUtil.java index c9e1c9a..5c8a751 100644 --- a/src/main/java/com/iflytop/gd/common/utils/LocalDateTimeUtil.java +++ b/src/main/java/com/iflytop/gd/common/utils/LocalDateTimeUtil.java @@ -3,13 +3,16 @@ package com.iflytop.gd.common.utils; public class LocalDateTimeUtil { /** - * 秒数格式化为 “mm:ss” 格式。 + * 秒数格式化为 “HH:mm:ss” 格式。 + * @param diffSeconds 两个时间点相差的秒数(可以为正或负) + * @return 格式化后的 “HH:mm:ss” 字符串 */ public static String formatSecondsToHMS(long diffSeconds) { long absSeconds = Math.abs(diffSeconds); - long minutes = absSeconds / 60; + long hours = absSeconds / 3600; + long minutes = (absSeconds % 3600) / 60; long seconds = absSeconds % 60; - return String.format("%02d:%02d", minutes, seconds); + return String.format("%02d:%02d:%02d", hours, minutes, seconds); } } \ No newline at end of file diff --git a/src/main/resources/sql/init.sql b/src/main/resources/sql/init.sql index fea1fb0..c789160 100644 --- a/src/main/resources/sql/init.sql +++ b/src/main/resources/sql/init.sql @@ -56,10 +56,10 @@ CREATE TABLE IF NOT EXISTS container ); INSERT OR IGNORE INTO container (id, type, code, solution_id, pump_id, scale,capacity_total, capacity_used) -VALUES (1, 0, 'container_01', 1, 'acid_pump_01', 364,5000, 0), - (2, 0, 'container_02', 2, 'acid_pump_02', 133,5000, 2500), - (3, 0, 'container_03', 3, 'acid_pump_03', 160,5000, 2600), - (4, 0, 'container_04', 4, 'acid_pump_04', 163,5000, 4000), +VALUES (1, 0, 'container_01', 1, 'acid_pump_01', 120,5000, 0), + (2, 0, 'container_02', 2, 'acid_pump_02', 100,5000, 2500), + (3, 0, 'container_03', 3, 'acid_pump_03', 111,5000, 2600), + (4, 0, 'container_04', 4, 'acid_pump_04', 107,5000, 4000), (5, 0, 'container_05', 5, 'acid_pump_05', 117,5000, 2400), (6, 0, 'container_06', 6, 'acid_pump_06', 105,5000, 4500), (7, 0, 'container_07', 7, 'acid_pump_07', 187,5000, 4900),