| src/main/java/com/zy/core/plugin/XiaosongProcess.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/core/task/MainProcessAsyncTaskScheduler.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/core/task/MainProcessLane.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/core/task/MainProcessTaskSubmitter.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/core/utils/StationOperateProcessUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/application.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/zy/core/plugin/XiaosongProcess.java
@@ -24,6 +24,8 @@ import com.zy.core.model.command.StationCommand; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.plugin.api.MainProcessPluginApi; import com.zy.core.task.MainProcessLane; import com.zy.core.task.MainProcessTaskSubmitter; import com.zy.core.thread.StationThread; import com.zy.core.utils.CrnOperateProcessUtils; import com.zy.core.utils.DualCrnOperateProcessUtils; @@ -40,6 +42,8 @@ @Slf4j @Component public class XiaosongProcess implements MainProcessPluginApi { private static final long DISPATCH_INTERVAL_MS = 200L; private static final long MAINTENANCE_INTERVAL_MS = 500L; @Autowired private CrnOperateProcessUtils crnOperateUtils; @@ -57,36 +61,46 @@ private WmsOperateUtils wmsOperateUtils; @Autowired private DualCrnOperateProcessUtils dualCrnOperateProcessUtils; @Autowired private MainProcessTaskSubmitter mainProcessTaskSubmitter; @Override public void run() { //检测入库站是否有任务生成,并启动入库 checkInStationHasTask(); //请求生成入库任务 generateStoreWrkFile(); // 检测入库站是否有任务生成,并按站点 lane 异步启动入库 stationOperateProcessUtils.submitStationEnableInTasks(DISPATCH_INTERVAL_MS); // 请求生成入库任务,放入独立 lane,避免拖慢其他主流程方法 submitGenerateStoreWrkFileTask(); //执行堆垛机任务 crnOperateUtils.crnIoExecute(); //堆垛机任务执行完成 crnOperateUtils.crnIoExecuteFinish(); //执行输送站点入库任务 stationOperateProcessUtils.stationInExecute(); //执行堆垛机输送站点出库任务 stationOperateProcessUtils.crnStationOutExecute(); //执行双工位堆垛机输送站点出库任务 stationOperateProcessUtils.dualCrnStationOutExecute(); //检测输送站点出库任务执行完成 stationOperateProcessUtils.stationOutExecuteFinish(); // 执行堆垛机任务 crnOperateUtils.submitCrnIoTasks(DISPATCH_INTERVAL_MS); // 堆垛机任务执行完成 crnOperateUtils.submitCrnIoExecuteFinishTasks(DISPATCH_INTERVAL_MS); // 执行输送站点入库任务 stationOperateProcessUtils.submitStationInTasks(DISPATCH_INTERVAL_MS); // 执行堆垛机输送站点出库任务 stationOperateProcessUtils.submitCrnStationOutTasks(DISPATCH_INTERVAL_MS); // 执行双工位堆垛机输送站点出库任务 stationOperateProcessUtils.submitDualCrnStationOutTasks(DISPATCH_INTERVAL_MS); // 检测输送站点出库任务执行完成 stationOperateProcessUtils.submitStationOutExecuteFinishTasks(DISPATCH_INTERVAL_MS); // 检测任务转完成 stationOperateProcessUtils.checkTaskToComplete(); //检测输送站点是否运行堵塞 stationOperateProcessUtils.checkStationRunBlock(); stationOperateProcessUtils.submitCheckTaskToCompleteTasks(DISPATCH_INTERVAL_MS); // 检测输送站点是否运行堵塞 stationOperateProcessUtils.submitCheckStationRunBlockTasks(MAINTENANCE_INTERVAL_MS); // 执行双工位堆垛机任务 dualCrnOperateProcessUtils.dualCrnIoExecute(); dualCrnOperateProcessUtils.submitDualCrnIoTasks(DISPATCH_INTERVAL_MS); // 双工位堆垛机任务执行完成 dualCrnOperateProcessUtils.dualCrnIoExecuteFinish(); dualCrnOperateProcessUtils.submitDualCrnIoExecuteFinishTasks(DISPATCH_INTERVAL_MS); } private void submitGenerateStoreWrkFileTask() { mainProcessTaskSubmitter.submitSerialTask( MainProcessLane.GENERATE_STORE, "generateStoreWrkFile", DISPATCH_INTERVAL_MS, this::generateStoreWrkFile ); } /** src/main/java/com/zy/core/task/MainProcessAsyncTaskScheduler.java
New file @@ -0,0 +1,161 @@ package com.zy.core.task; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.PreDestroy; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; /** * 主流程异步任务调度器。 * 按执行通道串行执行任务,并对同名任务提供最小提交间隔和不重入保护。 */ @Slf4j @Component public class MainProcessAsyncTaskScheduler { private static final long DEFAULT_SHUTDOWN_TIMEOUT_SECONDS = 5L; private final Map<String, SerialTaskLane> laneMap = new ConcurrentHashMap<>(); private final Map<String, TaskGuard> taskGuardMap = new ConcurrentHashMap<>(); public boolean submit(String laneName, String taskName, long minIntervalMs, long slowLogThresholdMs, Runnable task) { if (isBlank(laneName) || isBlank(taskName) || task == null) { return false; } long now = System.currentTimeMillis(); String taskKey = buildTaskKey(laneName, taskName); TaskGuard taskGuard = taskGuardMap.computeIfAbsent(taskKey, key -> new TaskGuard()); synchronized (taskGuard) { if (taskGuard.lastSubmitTimeMs > 0L && now - taskGuard.lastSubmitTimeMs < minIntervalMs) { return false; } if (!taskGuard.running.compareAndSet(false, true)) { return false; } taskGuard.lastSubmitTimeMs = now; taskGuard.lastQueueEnterTimeMs = now; } try { ensureLane(laneName).executorService.execute(() -> executeTask(laneName, taskName, slowLogThresholdMs, taskGuard, task)); return true; } catch (Exception e) { taskGuard.running.set(false); log.error("MainProcess async task submit error, lane={}, task={}", laneName, taskName, e); return false; } } private void executeTask(String laneName, String taskName, long slowLogThresholdMs, TaskGuard taskGuard, Runnable task) { long startMs = System.currentTimeMillis(); long queueWaitMs = taskGuard.lastQueueEnterTimeMs > 0L ? startMs - taskGuard.lastQueueEnterTimeMs : 0L; try { task.run(); } catch (Exception e) { log.error("MainProcess async task execute error, lane={}, task={}", laneName, taskName, e); } finally { long costMs = System.currentTimeMillis() - startMs; if (slowLogThresholdMs > 0L && costMs > slowLogThresholdMs) { log.warn("MainProcess async task executed slowly, lane={}, task={}, cost={}ms, queueWaitMs={}ms", laneName, taskName, costMs, queueWaitMs); } taskGuard.running.set(false); } } private SerialTaskLane ensureLane(String laneName) { SerialTaskLane lane = laneMap.get(laneName); if (lane != null && !lane.executorService.isShutdown()) { return lane; } synchronized (laneMap) { lane = laneMap.get(laneName); if (lane == null || lane.executorService.isShutdown()) { lane = new SerialTaskLane(Executors.newSingleThreadExecutor(new NamedThreadFactory("main-process-" + laneName + "-"))); laneMap.put(laneName, lane); } return lane; } } @PreDestroy public void shutdown() { for (SerialTaskLane lane : laneMap.values()) { if (lane == null || lane.executorService == null) { continue; } lane.executorService.shutdownNow(); } for (Map.Entry<String, SerialTaskLane> entry : laneMap.entrySet()) { SerialTaskLane lane = entry.getValue(); if (lane == null || lane.executorService == null) { continue; } try { if (!lane.executorService.awaitTermination(DEFAULT_SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { log.warn("MainProcess async task lane did not terminate in time, lane={}", entry.getKey()); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } } } private String buildTaskKey(String laneName, String taskName) { return laneName + "::" + taskName; } private boolean isBlank(String value) { return value == null || value.trim().isEmpty(); } private static class SerialTaskLane { private final ExecutorService executorService; private SerialTaskLane(ExecutorService executorService) { this.executorService = executorService; } } private static class TaskGuard { private final AtomicBoolean running = new AtomicBoolean(false); private volatile long lastSubmitTimeMs = 0L; private volatile long lastQueueEnterTimeMs = 0L; } private static class NamedThreadFactory implements ThreadFactory { private final String prefix; private final AtomicInteger index = new AtomicInteger(1); private NamedThreadFactory(String prefix) { this.prefix = prefix; } @Override public Thread newThread(Runnable runnable) { Thread thread = new Thread(runnable, prefix + index.getAndIncrement()); thread.setDaemon(true); return thread; } } } src/main/java/com/zy/core/task/MainProcessLane.java
New file @@ -0,0 +1,47 @@ package com.zy.core.task; public enum MainProcessLane { CRN("crn"), CRN_IO("crn-io-"), CRN_IO_FINISH("crn-io-finish-"), DUAL_CRN_IO("dual-crn-io-"), DUAL_CRN_IO_FINISH("dual-crn-io-finish-"), STATION("station"), STATION_ENABLE_IN("station-enable-in-"), STATION_IN("station-in-"), STATION_OUT("station-out-"), DUAL_STATION_OUT("dual-station-out-"), STATION_OUT_FINISH("station-out-finish-"), STATION_IN_ARRIVAL("station-in-arrival-"), STATION_COMPLETE("station-complete-"), STATION_OUT_ORDER("station-out-order-"), STATION_RUN_BLOCK("station-run-block-"), GENERATE_STORE("generate-store-"), FAKE_CRN_IO("fake-crn-io-"), FAKE_CRN_IO_FINISH("fake-crn-io-finish-"), FAKE_STATION_IN("fake-station-in-"), FAKE_STATION_OUT("fake-station-out-"), FAKE_STATION_OUT_ORDER("fake-station-out-order-"), FAKE_STATION_RUN_BLOCK("fake-station-run-block-"), FAKE_DUAL_CRN_IO("fake-dual-crn-io-"), FAKE_DUAL_CRN_IO_FINISH("fake-dual-crn-io-finish-"), FAKE_GENERATE_STORE("fake-generate-store-"), FAKE_ASYNC("fake-async-"); private final String laneName; MainProcessLane(String laneName) { this.laneName = laneName; } public String laneName() { return laneName; } public String keyedLaneName(Object laneKey) { if (laneKey == null) { return null; } return laneName + laneKey; } } src/main/java/com/zy/core/task/MainProcessTaskSubmitter.java
New file @@ -0,0 +1,62 @@ package com.zy.core.task; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MainProcessTaskSubmitter { private static final long DEFAULT_SLOW_LOG_THRESHOLD_MS = 1000L; @Autowired private MainProcessAsyncTaskScheduler mainProcessAsyncTaskScheduler; public boolean submitSerialTask(String laneName, String taskName, long minIntervalMs, Runnable task) { return mainProcessAsyncTaskScheduler.submit( laneName, taskName, minIntervalMs, DEFAULT_SLOW_LOG_THRESHOLD_MS, task ); } public boolean submitSerialTask(MainProcessLane lane, String taskName, long minIntervalMs, Runnable task) { if (lane == null) { return false; } return submitSerialTask(lane.laneName(), taskName, minIntervalMs, task); } public boolean submitKeyedSerialTask(String lanePrefix, Object laneKey, String taskName, long minIntervalMs, Runnable task) { if (laneKey == null) { return false; } return submitSerialTask(lanePrefix + laneKey, taskName, minIntervalMs, task); } public boolean submitKeyedSerialTask(MainProcessLane lane, Object laneKey, String taskName, long minIntervalMs, Runnable task) { if (lane == null) { return false; } String laneName = lane.keyedLaneName(laneKey); if (laneName == null) { return false; } return submitSerialTask(laneName, taskName, minIntervalMs, task); } } src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -27,6 +27,8 @@ import com.zy.core.model.command.CrnCommand; import com.zy.core.model.protocol.CrnProtocol; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.task.MainProcessLane; import com.zy.core.task.MainProcessTaskSubmitter; import com.zy.core.thread.CrnThread; import com.zy.core.thread.StationThread; import org.springframework.beans.factory.annotation.Autowired; @@ -56,6 +58,8 @@ private NotifyUtils notifyUtils; @Autowired private StationOperateProcessUtils stationOperateProcessUtils; @Autowired private MainProcessTaskSubmitter mainProcessTaskSubmitter; public synchronized void crnIoExecute() { Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); @@ -69,81 +73,103 @@ } } public void crnIoExecute(BasCrnp basCrnp) { if (basCrnp == null || basCrnp.getCrnNo() == null) { return; } Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); if (systemConfigMapObj != null) { HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj; if ("solver".equals(systemConfigMap.get("crnRunMethod"))) { plannerExecute(basCrnp); } else { crnIoExecuteNormal(basCrnp); } } else { crnIoExecuteNormal(basCrnp); } } //入出库 ===>> 堆垛机入出库作业下发 public synchronized void crnIoExecuteNormal() { List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if(crnThread == null){ continue; crnIoExecuteNormal(basCrnp); } } public void crnIoExecuteNormal(BasCrnp basCrnp) { if (basCrnp == null || basCrnp.getCrnNo() == null) { return; } CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if(crnThread == null){ return; } CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ return; } List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("crn_no", basCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts) .orderBy("batch_seq", false) ); if(!wrkMasts.isEmpty()){ return; } // 只有当堆垛机空闲 并且 无任务时才继续执行 if (crnProtocol.getMode() == CrnModeType.AUTO.id && crnProtocol.getTaskNo() == 0 && crnProtocol.getStatus() == CrnStatusType.IDLE.id && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0 && crnProtocol.getAlarm() == 0 ) { Object clearLock = redisUtil.get(RedisKeyType.CLEAR_CRN_TASK_LIMIT.key + basCrnp.getCrnNo()); if (clearLock != null) { return; } CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ continue; } List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("crn_no", basCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts) .orderBy("batch_seq", false) ); if(!wrkMasts.isEmpty()){ continue; } // 只有当堆垛机空闲 并且 无任务时才继续执行 if (crnProtocol.getMode() == CrnModeType.AUTO.id && crnProtocol.getTaskNo() == 0 && crnProtocol.getStatus() == CrnStatusType.IDLE.id && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0 && crnProtocol.getAlarm() == 0 ) { Object clearLock = redisUtil.get(RedisKeyType.CLEAR_CRN_TASK_LIMIT.key + basCrnp.getCrnNo()); if (clearLock != null) { continue; } // 如果最近一次是入库模式 if (crnProtocol.getLastIo().equals("I")) { if (basCrnp.getInEnable().equals("Y")) { boolean result = this.crnExecuteIn(basCrnp, crnThread);// 入库 crnProtocol.setLastIo("O"); if (result) { break; } } else if (basCrnp.getOutEnable().equals("Y")) { boolean result = this.crnExecuteOut(basCrnp, crnThread);// 出库 crnProtocol.setLastIo("I"); if (result) { break; } // 如果最近一次是入库模式 if (crnProtocol.getLastIo().equals("I")) { if (basCrnp.getInEnable().equals("Y")) { boolean result = this.crnExecuteIn(basCrnp, crnThread);// 入库 crnProtocol.setLastIo("O"); if (result) { return; } } else if (basCrnp.getOutEnable().equals("Y")) { boolean result = this.crnExecuteOut(basCrnp, crnThread);// 出库 crnProtocol.setLastIo("I"); if (result) { return; } } // 如果最近一次是出库模式 else if (crnProtocol.getLastIo().equals("O")) { if (basCrnp.getOutEnable().equals("Y")) { boolean result = this.crnExecuteOut(basCrnp, crnThread);// 出库 crnProtocol.setLastIo("I"); if (result) { break; } } else if (basCrnp.getInEnable().equals("Y")) { boolean result = this.crnExecuteIn(basCrnp, crnThread);// 入库 crnProtocol.setLastIo("O"); if (result) { break; } } // 如果最近一次是出库模式 else if (crnProtocol.getLastIo().equals("O")) { if (basCrnp.getOutEnable().equals("Y")) { boolean result = this.crnExecuteOut(basCrnp, crnThread);// 出库 crnProtocol.setLastIo("I"); if (result) { return; } } else if (basCrnp.getInEnable().equals("Y")) { boolean result = this.crnExecuteIn(basCrnp, crnThread);// 入库 crnProtocol.setLastIo("O"); if (result) { return; } } //库位移转 boolean transfer = this.crnExecuteLocTransfer(basCrnp, crnThread); if (transfer) { break; } } //库位移转 this.crnExecuteLocTransfer(basCrnp, crnThread); } } @@ -587,168 +613,184 @@ public synchronized void crnIoExecuteFinish() { List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if(crnThread == null){ continue; crnIoExecuteFinish(basCrnp); } } public void crnIoExecuteFinish(BasCrnp basCrnp) { if (basCrnp == null || basCrnp.getCrnNo() == null) { return; } CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if(crnThread == null){ return; } CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ return; } if (crnProtocol.getMode() == CrnModeType.AUTO.id && crnProtocol.getTaskNo() > 0 && crnProtocol.getStatus() == CrnStatusType.WAITING.id ) { Object lock = redisUtil.get(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo()); if(lock != null){ return; } CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ continue; // 获取待确认工作档 WrkMast wrkMast = wrkMastService.selectByWorkNo(crnProtocol.getTaskNo()); if (wrkMast == null) { News.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo()); return; } if (crnProtocol.getMode() == CrnModeType.AUTO.id && crnProtocol.getTaskNo() > 0 && crnProtocol.getStatus() == CrnStatusType.WAITING.id ) { Object lock = redisUtil.get(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo()); if(lock != null){ continue; Long updateWrkSts = null; if(wrkMast.getWrkSts() == WrkStsType.INBOUND_RUN.sts){ updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts; notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null); }else if(wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts){ updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts; notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_COMPLETE, null); List<StationObjModel> outStationList = basCrnp.getOutStationList$(); if(outStationList.isEmpty()){ News.info("堆垛机:{} 出库站点未设置", basCrnp.getCrnNo()); return; } // 获取待确认工作档 WrkMast wrkMast = wrkMastService.selectByWorkNo(crnProtocol.getTaskNo()); if (wrkMast == null) { News.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo()); continue; } Long updateWrkSts = null; if(wrkMast.getWrkSts() == WrkStsType.INBOUND_RUN.sts){ updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts; notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null); }else if(wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts){ updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts; notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_COMPLETE, null); List<StationObjModel> outStationList = basCrnp.getOutStationList$(); if(outStationList.isEmpty()){ News.info("堆垛机:{} 出库站点未设置", basCrnp.getCrnNo()); return; StationObjModel outStationObjModel = null; for (StationObjModel stationObjModel : outStationList) { if (stationObjModel.getStationId().equals(wrkMast.getSourceStaNo())) { outStationObjModel = stationObjModel; break; } StationObjModel outStationObjModel = null; for (StationObjModel stationObjModel : outStationList) { if (stationObjModel.getStationId().equals(wrkMast.getSourceStaNo())) { outStationObjModel = stationObjModel; break; } } redisUtil.set(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo(), JSON.toJSONString(outStationObjModel, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24); }else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){ updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts; notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null); }else{ News.error("堆垛机处于等待确认且任务完成状态,但工作状态异常。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo()); continue; } wrkMast.setWrkSts(updateWrkSts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo()); MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand)); News.info("堆垛机任务状态更新成功,堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo()); } redisUtil.set(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo(), "lock",10); redisUtil.set(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo(), JSON.toJSONString(outStationObjModel, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24); }else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){ updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts; notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null); }else{ News.error("堆垛机处于等待确认且任务完成状态,但工作状态异常。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo()); return; } wrkMast.setWrkSts(updateWrkSts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo()); MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand)); News.info("堆垛机任务状态更新成功,堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo()); } redisUtil.set(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo(), "lock",10); } } public synchronized void plannerExecute() { int nowSec = (int) (System.currentTimeMillis() / 1000); List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo(); List<Object> items = redisUtil.lGet(key, 0, -1); if (items == null || items.isEmpty()) { plannerExecute(basCrnp); } } public void plannerExecute(BasCrnp basCrnp) { if (basCrnp == null || basCrnp.getCrnNo() == null) { return; } int nowSec = (int) (System.currentTimeMillis() / 1000); String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo(); List<Object> items = redisUtil.lGet(key, 0, -1); if (items == null || items.isEmpty()) { return; } CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if (crnThread == null) { return; } CrnProtocol crnProtocol = crnThread.getStatus(); if (crnProtocol == null) { return; } List<WrkMast> running = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("crn_no", basCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts) ); if (!running.isEmpty()) { return; } if (!(crnProtocol.getMode() == CrnModeType.AUTO.id && crnProtocol.getTaskNo() == 0 && crnProtocol.getStatus() == CrnStatusType.IDLE.id && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0 && crnProtocol.getAlarm() == 0)) { return; } for (Object v : items) { String s = String.valueOf(v); JSONObject obj = null; try { obj = JSON.parseObject(s); } catch (Exception ignore) {} if (obj == null) { continue; } Integer startEpochSec = obj.getInteger("startEpochSec"); Integer endEpochSec = obj.getInteger("endEpochSec"); Integer taskId = obj.getInteger("taskId"); String taskType = obj.getString("taskType"); if (startEpochSec == null || taskId == null || taskType == null) { continue; } int earlySlackSec = 5; int lateSlackSec = 10; Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); if (systemConfigMapObj != null) { try { HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj; String es = systemConfigMap.getOrDefault("plannerEarlySlackSec", "60"); String ls = systemConfigMap.getOrDefault("plannerLateSlackSec", "10"); earlySlackSec = Integer.parseInt(es); lateSlackSec = Integer.parseInt(ls); } catch (Exception ignore) {} } if (nowSec < startEpochSec - earlySlackSec) { continue; } if (endEpochSec != null && nowSec > endEpochSec + lateSlackSec) { redisUtil.lRemove(key, 1, s); continue; } CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if (crnThread == null) { continue; } CrnProtocol crnProtocol = crnThread.getStatus(); if (crnProtocol == null) { continue; } List<WrkMast> running = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("crn_no", basCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts) ); if (!running.isEmpty()) { continue; } if (!(crnProtocol.getMode() == CrnModeType.AUTO.id && crnProtocol.getTaskNo() == 0 && crnProtocol.getStatus() == CrnStatusType.IDLE.id && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0 && crnProtocol.getAlarm() == 0)) { WrkMast wrkMast = wrkMastService.selectByWorkNo(taskId); if (wrkMast == null) { redisUtil.lRemove(key, 1, s); continue; } for (Object v : items) { String s = String.valueOf(v); JSONObject obj = null; try { obj = JSON.parseObject(s); } catch (Exception ignore) {} if (obj == null) { continue; } Integer startEpochSec = obj.getInteger("startEpochSec"); Integer endEpochSec = obj.getInteger("endEpochSec"); Integer taskId = obj.getInteger("taskId"); String taskType = obj.getString("taskType"); if (startEpochSec == null || taskId == null || taskType == null) { continue; } int earlySlackSec = 5; int lateSlackSec = 10; Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); if (systemConfigMapObj != null) { try { HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj; String es = systemConfigMap.getOrDefault("plannerEarlySlackSec", "60"); String ls = systemConfigMap.getOrDefault("plannerLateSlackSec", "10"); earlySlackSec = Integer.parseInt(es); lateSlackSec = Integer.parseInt(ls); } catch (Exception ignore) {} } if (nowSec < startEpochSec - earlySlackSec) { continue; } if (endEpochSec != null && nowSec > endEpochSec + lateSlackSec) { if ("IN".equalsIgnoreCase(taskType)) { boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);//入库 if (result) { redisUtil.lRemove(key, 1, s); continue; return; } WrkMast wrkMast = wrkMastService.selectByWorkNo(taskId); if (wrkMast == null) { } else if ("OUT".equalsIgnoreCase(taskType)) { boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);//出库 if (result) { redisUtil.lRemove(key, 1, s); continue; return; } if ("IN".equalsIgnoreCase(taskType)) { boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);//入库 if (result) { redisUtil.lRemove(key, 1, s); break; } } else if ("OUT".equalsIgnoreCase(taskType)) { boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);//出库 if (result) { redisUtil.lRemove(key, 1, s); break; } } else if ("MOVE".equalsIgnoreCase(taskType)) { boolean result = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);//移库 if (result) { redisUtil.lRemove(key, 1, s); break; } } else if ("MOVE".equalsIgnoreCase(taskType)) { boolean result = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);//移库 if (result) { redisUtil.lRemove(key, 1, s); return; } } } @@ -805,6 +847,48 @@ return false; } public void submitCrnIoTasks(long minIntervalMs) { submitCrnIoTasks(MainProcessLane.CRN_IO, minIntervalMs); } public void submitCrnIoTasks(MainProcessLane lane, long minIntervalMs) { List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { if (basCrnp == null || basCrnp.getCrnNo() == null) { continue; } final BasCrnp currentCrn = basCrnp; mainProcessTaskSubmitter.submitKeyedSerialTask( lane, currentCrn.getCrnNo(), "crnIoExecute", minIntervalMs, () -> crnIoExecute(currentCrn) ); } } public void submitCrnIoExecuteFinishTasks(long minIntervalMs) { submitCrnIoExecuteFinishTasks(MainProcessLane.CRN_IO_FINISH, minIntervalMs); } public void submitCrnIoExecuteFinishTasks(MainProcessLane lane, long minIntervalMs) { List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { if (basCrnp == null || basCrnp.getCrnNo() == null) { continue; } final BasCrnp currentCrn = basCrnp; mainProcessTaskSubmitter.submitKeyedSerialTask( lane, currentCrn.getCrnNo(), "crnIoExecuteFinish", minIntervalMs, () -> crnIoExecuteFinish(currentCrn) ); } } //检测浅库位状态 public synchronized boolean checkShallowLocStatus(String locNo, Integer taskNo) { String checkDeepLocOutTaskBlockReport = "Y"; src/main/java/com/zy/core/utils/DualCrnOperateProcessUtils.java
@@ -29,6 +29,8 @@ import com.zy.core.model.param.SendDualCrnCommandParam; import com.zy.core.model.protocol.DualCrnProtocol; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.task.MainProcessLane; import com.zy.core.task.MainProcessTaskSubmitter; import com.zy.core.thread.DualCrnThread; import com.zy.core.thread.StationThread; import org.springframework.beans.factory.annotation.Autowired; @@ -60,43 +62,52 @@ private CommonService commonService; @Autowired private NotifyUtils notifyUtils; @Autowired private MainProcessTaskSubmitter mainProcessTaskSubmitter; //入出库 ===>> 双工位堆垛机入出库作业下发 public synchronized void dualCrnIoExecute() { List<BasDualCrnp> basDualCrnps = basDualCrnpService.selectList(new EntityWrapper<>()); for (BasDualCrnp basDualCrnp : basDualCrnps) { DualCrnThread dualCrnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, basDualCrnp.getCrnNo()); if(dualCrnThread == null){ continue; } DualCrnProtocol dualCrnProtocol = dualCrnThread.getStatus(); if(dualCrnProtocol == null){ continue; } List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("dual_crn_no", basDualCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts) ); if(wrkMasts.size() >= 2){ continue; } if(dualCrnProtocol.getMode() != DualCrnModeType.AUTO.id) { continue; } if(dualCrnProtocol.getAlarm() != 0) { continue; } if(dualCrnProtocol.getTaskSend() != 0 || dualCrnProtocol.getTaskSendTwo() != 0) { continue; } this.crnExecute(basDualCrnp, dualCrnThread); dualCrnIoExecute(basDualCrnp); } } public void dualCrnIoExecute(BasDualCrnp basDualCrnp) { if (basDualCrnp == null || basDualCrnp.getCrnNo() == null) { return; } DualCrnThread dualCrnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, basDualCrnp.getCrnNo()); if(dualCrnThread == null){ return; } DualCrnProtocol dualCrnProtocol = dualCrnThread.getStatus(); if(dualCrnProtocol == null){ return; } List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("dual_crn_no", basDualCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts) ); if(wrkMasts.size() >= 2){ return; } if(dualCrnProtocol.getMode() != DualCrnModeType.AUTO.id) { return; } if(dualCrnProtocol.getAlarm() != 0) { return; } if(dualCrnProtocol.getTaskSend() != 0 || dualCrnProtocol.getTaskSendTwo() != 0) { return; } this.crnExecute(basDualCrnp, dualCrnThread); } private synchronized void crnExecute(BasDualCrnp basDualCrnp, DualCrnThread dualCrnThread) { @@ -691,33 +702,91 @@ public synchronized void dualCrnIoExecuteFinish() { List<BasDualCrnp> basDualCrnps = basDualCrnpService.selectList(new EntityWrapper<>()); for (BasDualCrnp basDualCrnp : basDualCrnps) { DualCrnThread dualCrnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, basDualCrnp.getCrnNo()); if(dualCrnThread == null){ continue; } dualCrnIoExecuteFinish(basDualCrnp); } } DualCrnProtocol dualCrnProtocol = dualCrnThread.getStatus(); if(dualCrnProtocol == null){ continue; } public void dualCrnIoExecuteFinish(BasDualCrnp basDualCrnp) { if (basDualCrnp == null || basDualCrnp.getCrnNo() == null) { return; } DualCrnThread dualCrnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, basDualCrnp.getCrnNo()); if(dualCrnThread == null){ return; } if(dualCrnProtocol.getMode() != DualCrnModeType.AUTO.id) { continue; } DualCrnProtocol dualCrnProtocol = dualCrnThread.getStatus(); if(dualCrnProtocol == null){ return; } if(dualCrnProtocol.getAlarm() != 0) { continue; } if(dualCrnProtocol.getMode() != DualCrnModeType.AUTO.id) { return; } if((dualCrnProtocol.getTaskNo() > 0 && dualCrnProtocol.getDeviceTaskNo() > 0) && dualCrnProtocol.getTaskSend() == 0 && dualCrnProtocol.getStatus().equals(DualCrnStatusType.WAITING.id)) { executeFinish(basDualCrnp, dualCrnThread, dualCrnProtocol, dualCrnProtocol.getTaskNo(), 1); continue; } if(dualCrnProtocol.getAlarm() != 0) { return; } if((dualCrnProtocol.getTaskNoTwo() > 0 && dualCrnProtocol.getDeviceTaskNoTwo() > 0) && dualCrnProtocol.getTaskSendTwo() == 0 && dualCrnProtocol.getStatusTwo().equals(DualCrnStatusType.WAITING.id)) { executeFinish(basDualCrnp, dualCrnThread, dualCrnProtocol, dualCrnProtocol.getTaskNoTwo(), 2); if((dualCrnProtocol.getTaskNo() > 0 && dualCrnProtocol.getDeviceTaskNo() > 0) && dualCrnProtocol.getTaskSend() == 0 && dualCrnProtocol.getStatus().equals(DualCrnStatusType.WAITING.id)) { executeFinish(basDualCrnp, dualCrnThread, dualCrnProtocol, dualCrnProtocol.getTaskNo(), 1); return; } if((dualCrnProtocol.getTaskNoTwo() > 0 && dualCrnProtocol.getDeviceTaskNoTwo() > 0) && dualCrnProtocol.getTaskSendTwo() == 0 && dualCrnProtocol.getStatusTwo().equals(DualCrnStatusType.WAITING.id)) { executeFinish(basDualCrnp, dualCrnThread, dualCrnProtocol, dualCrnProtocol.getTaskNoTwo(), 2); } } public void submitDualCrnIoTasks(long minIntervalMs) { submitDualCrnIoTasks(MainProcessLane.DUAL_CRN_IO, minIntervalMs); } public void submitDualCrnIoTasks(MainProcessLane lane, long minIntervalMs) { List<BasDualCrnp> basDualCrnps = basDualCrnpService.selectList(new EntityWrapper<>()); for (final BasDualCrnp basDualCrnp : basDualCrnps) { Integer crnNo = basDualCrnp == null ? null : basDualCrnp.getCrnNo(); if (crnNo == null) { continue; } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, crnNo, "dualCrnIoExecute", minIntervalMs, new Runnable() { @Override public void run() { dualCrnIoExecute(basDualCrnp); } } ); } } public void submitDualCrnIoExecuteFinishTasks(long minIntervalMs) { submitDualCrnIoExecuteFinishTasks(MainProcessLane.DUAL_CRN_IO_FINISH, minIntervalMs); } public void submitDualCrnIoExecuteFinishTasks(MainProcessLane lane, long minIntervalMs) { List<BasDualCrnp> basDualCrnps = basDualCrnpService.selectList(new EntityWrapper<>()); for (final BasDualCrnp basDualCrnp : basDualCrnps) { Integer crnNo = basDualCrnp == null ? null : basDualCrnp.getCrnNo(); if (crnNo == null) { continue; } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, crnNo, "dualCrnIoExecuteFinish", minIntervalMs, new Runnable() { @Override public void run() { dualCrnIoExecuteFinish(basDualCrnp); } } ); } } src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -26,6 +26,8 @@ import com.zy.core.model.Task; import com.zy.core.model.command.StationCommand; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.task.MainProcessLane; import com.zy.core.task.MainProcessTaskSubmitter; import com.zy.core.thread.StationThread; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -56,6 +58,203 @@ private BasStationService basStationService; @Autowired private StationCycleCapacityService stationCycleCapacityService; @Autowired private MainProcessTaskSubmitter mainProcessTaskSubmitter; public void submitStationEnableInTasks(long minIntervalMs) { submitStationEnableInTasks(MainProcessLane.STATION_ENABLE_IN, minIntervalMs); } public void submitStationEnableInTasks(MainProcessLane lane, long minIntervalMs) { List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>()); for (final BasDevp basDevp : basDevps) { StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { continue; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); if (stationMap == null || stationMap.isEmpty()) { continue; } List<StationObjModel> list = basDevp.getInStationList$(); for (final StationObjModel stationObjModel : list) { Integer stationId = stationObjModel == null ? null : stationObjModel.getStationId(); if (stationId == null || !stationMap.containsKey(stationId)) { continue; } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, stationId, "stationEnableInExecute", minIntervalMs, new Runnable() { @Override public void run() { stationEnableInExecute(basDevp, stationObjModel); } } ); } } } public void submitStationInTasks(long minIntervalMs) { submitStationInTasks(MainProcessLane.STATION_IN, minIntervalMs); } public void submitStationInTasks(MainProcessLane lane, long minIntervalMs) { // 入库下发依赖单轮共享的承载预占状态,必须整体串行,避免多个站点并发时同时通过容量检查。 mainProcessTaskSubmitter.submitSerialTask( MainProcessLane.STATION, "stationInExecute", minIntervalMs, new Runnable() { @Override public void run() { stationInExecute(); } } ); } public void submitCrnStationOutTasks(long minIntervalMs) { submitCrnStationOutTasks(MainProcessLane.STATION_OUT, minIntervalMs); } public void submitCrnStationOutTasks(MainProcessLane lane, long minIntervalMs) { // 出库站点下发同样会预占输送线/环线容量,与 stationInExecute 共用 STATION lane 串行。 mainProcessTaskSubmitter.submitSerialTask( MainProcessLane.STATION, "crnStationOutExecute", minIntervalMs, new Runnable() { @Override public void run() { crnStationOutExecute(); } } ); } public void submitDualCrnStationOutTasks(long minIntervalMs) { submitDualCrnStationOutTasks(MainProcessLane.DUAL_STATION_OUT, minIntervalMs); } public void submitDualCrnStationOutTasks(MainProcessLane lane, long minIntervalMs) { List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>() .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts) .isNotNull("dual_crn_no") ); for (final WrkMast wrkMast : wrkMasts) { Integer laneKey = wrkMast == null ? null : wrkMast.getSourceStaNo(); if (laneKey == null) { laneKey = wrkMast == null ? null : wrkMast.getWrkNo(); } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, laneKey, "dualCrnStationOutExecute", minIntervalMs, new Runnable() { @Override public void run() { dualCrnStationOutExecute(wrkMast); } } ); } } public void submitStationOutExecuteFinishTasks(long minIntervalMs) { submitStationOutExecuteFinishTasks(MainProcessLane.STATION_OUT_FINISH, minIntervalMs); } public void submitStationOutExecuteFinishTasks(MainProcessLane lane, long minIntervalMs) { List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN.sts)); for (final WrkMast wrkMast : wrkMasts) { Integer laneKey = wrkMast == null ? null : wrkMast.getStaNo(); if (laneKey == null) { laneKey = wrkMast == null ? null : wrkMast.getWrkNo(); } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, laneKey, "stationOutExecuteFinish", minIntervalMs, new Runnable() { @Override public void run() { stationOutExecuteFinish(wrkMast); } } ); } } public void submitCheckTaskToCompleteTasks(long minIntervalMs) { submitCheckTaskToCompleteTasks(MainProcessLane.STATION_COMPLETE, minIntervalMs); } public void submitCheckTaskToCompleteTasks(MainProcessLane lane, long minIntervalMs) { List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN_COMPLETE.sts)); for (final WrkMast wrkMast : wrkMasts) { Integer laneKey = wrkMast == null ? null : wrkMast.getStaNo(); if (laneKey == null) { laneKey = wrkMast == null ? null : wrkMast.getWrkNo(); } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, laneKey, "checkTaskToComplete", minIntervalMs, new Runnable() { @Override public void run() { checkTaskToComplete(wrkMast); } } ); } } public void submitCheckStationRunBlockTasks(long minIntervalMs) { submitCheckStationRunBlockTasks(MainProcessLane.STATION_RUN_BLOCK, minIntervalMs); } public void submitCheckStationRunBlockTasks(MainProcessLane lane, long minIntervalMs) { List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>()); for (final BasDevp basDevp : basDevps) { StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { continue; } List<StationProtocol> statusList = stationThread.getStatus(); for (StationProtocol stationProtocol : statusList) { final Integer stationId = stationProtocol == null ? null : stationProtocol.getStationId(); if (stationId == null) { continue; } if (!stationProtocol.isAutoing() || !stationProtocol.isLoading() || stationProtocol.getTaskNo() <= 0 || !stationProtocol.isRunBlock()) { continue; } mainProcessTaskSubmitter.submitKeyedSerialTask( lane, stationId, "checkStationRunBlock", minIntervalMs, new Runnable() { @Override public void run() { checkStationRunBlock(basDevp, stationId); } } ); } } } //执行输送站点入库任务 public synchronized void stationInExecute() { @@ -75,79 +274,165 @@ List<StationObjModel> list = basDevp.getBarcodeStationList$(); for (StationObjModel entity : list) { Integer stationId = entity.getStationId(); if (!stationMap.containsKey(stationId)) { continue; } StationProtocol stationProtocol = stationMap.get(stationId); if (stationProtocol == null) { continue; } Object lock = redisUtil.get(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId); if (lock != null) { continue; } //满足自动、有物、有工作号 if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() > 0 ) { //检测任务是否生成 WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("barcode", stationProtocol.getBarcode())); if (wrkMast == null) { continue; } if (wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) { continue; } String locNo = wrkMast.getLocNo(); FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo); if (findCrnNoResult == null) { News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo()); continue; } Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationId); if (targetStationId == null) { News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationId); continue; } LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), targetStationId, loadGuardState); if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) { return; } StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo()); continue; } wrkMast.setWrkSts(WrkStsType.INBOUND_DEVICE_RUN.sts); wrkMast.setSourceStaNo(stationProtocol.getStationId()); wrkMast.setStaNo(targetStationId); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command)); News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5); loadGuardState.reserveLoopTask(loopHitResult.getLoopNo()); saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult); } if (stationInExecute(basDevp, entity, limitConfig, currentStationTaskCountRef, loadGuardState)) { return; } } } } catch (Exception e) { e.printStackTrace(); } } public void stationEnableInExecute(BasDevp basDevp, StationObjModel stationObjModel) { try { if (basDevp == null || stationObjModel == null || stationObjModel.getStationId() == null) { return; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { return; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); if (stationMap == null) { return; } Integer stationId = stationObjModel.getStationId(); if (!stationMap.containsKey(stationId)) { return; } StationProtocol stationProtocol = stationMap.get(stationId); if (stationProtocol == null) { return; } Object lock = redisUtil.get(RedisKeyType.GENERATE_ENABLE_IN_STATION_DATA_LIMIT.key + stationId); if (lock != null) { return; } if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0 && stationProtocol.isEnableIn() ) { StationObjModel barcodeStation = stationObjModel.getBarcodeStation(); if (barcodeStation == null || barcodeStation.getStationId() == null) { return; } StationCommand command = stationThread.getCommand(StationCommandType.MOVE, commonService.getWorkNo(WrkIoType.ENABLE_IN.id), stationId, barcodeStation.getStationId(), 0); if (command == null) { News.info("{}站点启动入库失败,获取输送线命令失败", stationId); return; } MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command)); redisUtil.set(RedisKeyType.GENERATE_ENABLE_IN_STATION_DATA_LIMIT.key + stationId, "lock", 15); News.info("{}站点启动入库成功,数据包:{}", stationId, JSON.toJSONString(command)); } } catch (Exception e) { e.printStackTrace(); } } public void stationInExecute(BasDevp basDevp, StationObjModel stationObjModel) { try { DispatchLimitConfig limitConfig = getDispatchLimitConfig(); int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()}; LoadGuardState loadGuardState = buildLoadGuardState(limitConfig); stationInExecute(basDevp, stationObjModel, limitConfig, currentStationTaskCountRef, loadGuardState); } catch (Exception e) { e.printStackTrace(); } } private boolean stationInExecute(BasDevp basDevp, StationObjModel stationObjModel, DispatchLimitConfig limitConfig, int[] currentStationTaskCountRef, LoadGuardState loadGuardState) { if (basDevp == null || stationObjModel == null || stationObjModel.getStationId() == null) { return false; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { return false; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); Integer stationId = stationObjModel.getStationId(); if (stationMap == null || !stationMap.containsKey(stationId)) { return false; } StationProtocol stationProtocol = stationMap.get(stationId); if (stationProtocol == null) { return false; } Object lock = redisUtil.get(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId); if (lock != null) { return false; } //满足自动、有物、有工作号 if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() > 0 ) { //检测任务是否生成 WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("barcode", stationProtocol.getBarcode())); if (wrkMast == null) { return false; } if (wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) { return false; } String locNo = wrkMast.getLocNo(); FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo); if (findCrnNoResult == null) { News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo()); return false; } Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationId); if (targetStationId == null) { News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationId); return false; } LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), targetStationId, loadGuardState); if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) { return true; } StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo()); return false; } wrkMast.setWrkSts(WrkStsType.INBOUND_DEVICE_RUN.sts); wrkMast.setSourceStaNo(stationProtocol.getStationId()); wrkMast.setStaNo(targetStationId); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command)); News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5); loadGuardState.reserveLoopTask(loopHitResult.getLoopNo()); saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult); } } return false; } //执行堆垛机输送站点出库任务 @@ -164,80 +449,110 @@ List<Integer> outOrderList = getAllOutOrderList(); for (WrkMast wrkMast : wrkMasts) { Object infoObj = redisUtil.get(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo()); if (infoObj == null) { News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo()); continue; } StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class); StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { continue; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); StationProtocol stationProtocol = stationMap.get(stationObjModel.getStationId()); if (stationProtocol == null) { continue; } Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId()); if (lock != null) { continue; } //满足自动、有物、工作号0 if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0 ) { Integer moveStaNo = wrkMast.getStaNo(); if (!outOrderList.isEmpty()) { List<NavigateNode> nodes = navigateUtils.calcByStationId(stationProtocol.getStationId(), wrkMast.getStaNo()); for (int i = nodes.size() - 1; i >= 0; i--) { NavigateNode node = nodes.get(i); JSONObject v = JSONObject.parseObject(node.getNodeValue()); if (v != null) { Integer stationId = v.getInteger("stationId"); if (outOrderList.contains(stationId)) { moveStaNo = stationId; break; } } } } LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), moveStaNo, loadGuardState); if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) { return; } StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), moveStaNo, 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); continue; } wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command)); News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5); redisUtil.del(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo()); currentStationTaskCountRef[0]++; loadGuardState.reserveLoopTask(loopHitResult.getLoopNo()); saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult); } if (crnStationOutExecute(wrkMast, limitConfig, currentStationTaskCountRef, loadGuardState, outOrderList)) { return; } } } catch (Exception e) { e.printStackTrace(); } } public void crnStationOutExecute(WrkMast wrkMast) { try { DispatchLimitConfig limitConfig = getDispatchLimitConfig(); int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()}; LoadGuardState loadGuardState = buildLoadGuardState(limitConfig); List<Integer> outOrderList = getAllOutOrderList(); crnStationOutExecute(wrkMast, limitConfig, currentStationTaskCountRef, loadGuardState, outOrderList); } catch (Exception e) { e.printStackTrace(); } } private boolean crnStationOutExecute(WrkMast wrkMast, DispatchLimitConfig limitConfig, int[] currentStationTaskCountRef, LoadGuardState loadGuardState, List<Integer> outOrderList) { if (wrkMast == null || wrkMast.getWrkNo() == null) { return false; } Object infoObj = redisUtil.get(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo()); if (infoObj == null) { News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo()); return false; } StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class); if (stationObjModel == null) { return false; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { return false; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId()); if (stationProtocol == null) { return false; } Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId()); if (lock != null) { return false; } //满足自动、有物、工作号0 if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0 ) { Integer moveStaNo = wrkMast.getStaNo(); if (outOrderList != null && !outOrderList.isEmpty()) { List<NavigateNode> nodes = navigateUtils.calcByStationId(stationProtocol.getStationId(), wrkMast.getStaNo()); for (int i = nodes.size() - 1; i >= 0; i--) { NavigateNode node = nodes.get(i); JSONObject v = JSONObject.parseObject(node.getNodeValue()); if (v != null) { Integer stationId = v.getInteger("stationId"); if (outOrderList.contains(stationId)) { moveStaNo = stationId; break; } } } } LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), moveStaNo, loadGuardState); if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) { return true; } StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), moveStaNo, 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); return false; } wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command)); News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5); redisUtil.del(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo()); currentStationTaskCountRef[0]++; loadGuardState.reserveLoopTask(loopHitResult.getLoopNo()); saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult); } } return false; } //执行双工位堆垛机输送站点出库任务 @@ -248,50 +563,65 @@ .isNotNull("dual_crn_no") ); for (WrkMast wrkMast : wrkMasts) { Object infoObj = redisUtil.get(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo()); if (infoObj == null) { News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo()); continue; dualCrnStationOutExecute(wrkMast); } } catch (Exception e) { e.printStackTrace(); } } public void dualCrnStationOutExecute(WrkMast wrkMast) { try { if (wrkMast == null || wrkMast.getWrkNo() == null) { return; } Object infoObj = redisUtil.get(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo()); if (infoObj == null) { News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo()); return; } StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class); if (stationObjModel == null) { return; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { return; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId()); if (stationProtocol == null) { return; } Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId()); if (lock != null) { return; } //满足自动、有物、工作号0 if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0 ) { StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); return; } StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class); StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { continue; } Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap(); StationProtocol stationProtocol = stationMap.get(stationObjModel.getStationId()); if (stationProtocol == null) { continue; } Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId()); if (lock != null) { continue; } //满足自动、有物、工作号0 if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0 ) { StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); continue; } wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command)); notifyUtils.notify(String.valueOf(SlaveType.Devp), stationObjModel.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN, null); News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5); redisUtil.del(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo()); } wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command)); notifyUtils.notify(String.valueOf(SlaveType.Devp), stationObjModel.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN, null); News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5); redisUtil.del(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo()); } } } catch (Exception e) { @@ -304,37 +634,48 @@ try { List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN.sts)); for (WrkMast wrkMast : wrkMasts) { Integer wrkNo = wrkMast.getWrkNo(); Integer targetStaNo = wrkMast.getStaNo(); stationOutExecuteFinish(wrkMast); } } catch (Exception e) { e.printStackTrace(); } } boolean complete = false; BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo)); if (basStation == null) { continue; } public void stationOutExecuteFinish(WrkMast wrkMast) { try { if (wrkMast == null) { return; } Integer wrkNo = wrkMast.getWrkNo(); Integer targetStaNo = wrkMast.getStaNo(); StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo()); if (stationThread == null) { continue; } boolean complete = false; BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo)); if (basStation == null) { return; } Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap.get(basStation.getStationId()); if (stationProtocol == null) { continue; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo()); if (stationThread == null) { return; } if (stationProtocol.getTaskNo().equals(wrkNo)) { complete = true; } Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(basStation.getStationId()); if (stationProtocol == null) { return; } if (complete) { wrkMast.setWrkSts(WrkStsType.STATION_RUN_COMPLETE.sts); wrkMast.setIoTime(new Date()); wrkMastService.updateById(wrkMast); notifyUtils.notify(String.valueOf(SlaveType.Devp), basStation.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN_COMPLETE, null); redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkMast.getWrkNo(), "lock", 60); } if (stationProtocol.getTaskNo().equals(wrkNo)) { complete = true; } if (complete) { wrkMast.setWrkSts(WrkStsType.STATION_RUN_COMPLETE.sts); wrkMast.setIoTime(new Date()); wrkMastService.updateById(wrkMast); notifyUtils.notify(String.valueOf(SlaveType.Devp), basStation.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN_COMPLETE, null); redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkMast.getWrkNo(), "lock", 60); } } catch (Exception e) { e.printStackTrace(); @@ -346,40 +687,51 @@ try { List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN_COMPLETE.sts)); for (WrkMast wrkMast : wrkMasts) { Integer wrkNo = wrkMast.getWrkNo(); Integer targetStaNo = wrkMast.getStaNo(); checkTaskToComplete(wrkMast); } } catch (Exception e) { e.printStackTrace(); } } Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkNo); if (lock != null) { continue; } public void checkTaskToComplete(WrkMast wrkMast) { try { if (wrkMast == null) { return; } Integer wrkNo = wrkMast.getWrkNo(); Integer targetStaNo = wrkMast.getStaNo(); boolean complete = false; BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo)); if (basStation == null) { continue; } Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkNo); if (lock != null) { return; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo()); if (stationThread == null) { continue; } boolean complete = false; BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo)); if (basStation == null) { return; } Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap.get(basStation.getStationId()); if (stationProtocol == null) { continue; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo()); if (stationThread == null) { return; } if (!stationProtocol.getTaskNo().equals(wrkNo)) { complete = true; } Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(basStation.getStationId()); if (stationProtocol == null) { return; } if (complete) { wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts); wrkMast.setIoTime(new Date()); wrkMastService.updateById(wrkMast); } if (!stationProtocol.getTaskNo().equals(wrkNo)) { complete = true; } if (complete) { wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts); wrkMast.setIoTime(new Date()); wrkMastService.updateById(wrkMast); } } catch (Exception e) { e.printStackTrace(); @@ -523,6 +875,147 @@ } } public void checkStationRunBlock(BasDevp basDevp, Integer stationId) { try { if (basDevp == null || stationId == null) { return; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { return; } Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(stationId); if (stationProtocol == null) { return; } List<Integer> runBlockReassignLocStationList = new ArrayList<>(); for (StationObjModel stationObjModel : basDevp.getRunBlockReassignLocStationList$()) { runBlockReassignLocStationList.add(stationObjModel.getStationId()); } if (!(stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() > 0 && stationProtocol.isRunBlock())) { return; } WrkMast wrkMast = wrkMastService.selectByWorkNo(stationProtocol.getTaskNo()); if (wrkMast == null) { News.info("输送站点号={} 运行阻塞,但无法找到对应任务,工作号={}", stationProtocol.getStationId(), stationProtocol.getTaskNo()); return; } Object lock = redisUtil.get(RedisKeyType.CHECK_STATION_RUN_BLOCK_LIMIT_.key + stationProtocol.getTaskNo()); if (lock != null) { return; } redisUtil.set(RedisKeyType.CHECK_STATION_RUN_BLOCK_LIMIT_.key + stationProtocol.getTaskNo(), "lock", 15); if (wrkMast.getIoType() == WrkIoType.IN.id && runBlockReassignLocStationList.contains(stationProtocol.getStationId())) { //站点处于重新分配库位区域 //运行堵塞,重新申请任务 String response = wmsOperateUtils.applyReassignTaskLocNo(wrkMast.getWrkNo(), stationProtocol.getStationId()); if (response == null) { News.taskError(wrkMast.getWrkNo(), "请求WMS重新分配库位接口失败,接口未响应!!!response:{}", response); return; } JSONObject jsonObject = JSON.parseObject(response); if (jsonObject.getInteger("code").equals(200)) { StartupDto dto = jsonObject.getObject("data", StartupDto.class); String sourceLocNo = wrkMast.getLocNo(); String locNo = dto.getLocNo(); LocMast sourceLocMast = locMastService.queryByLoc(sourceLocNo); if (sourceLocMast == null) { News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 源库位信息不存在", sourceLocNo); return; } if (!sourceLocMast.getLocSts().equals("S")) { News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 源库位状态不处于入库预约", sourceLocNo); return; } LocMast locMast = locMastService.queryByLoc(locNo); if (locMast == null) { News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 目标库位信息不存在", locNo); return; } if (!locMast.getLocSts().equals("O")) { News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 目标库位状态不处于空库位", locNo); return; } FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo); if (findCrnNoResult == null) { News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo()); return; } Integer crnNo = findCrnNoResult.getCrnNo(); Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationProtocol.getStationId()); if (targetStationId == null) { News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationProtocol.getStationId()); return; } StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), targetStationId, 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo()); return; } //更新源库位 sourceLocMast.setLocSts("O"); sourceLocMast.setModiTime(new Date()); locMastService.updateById(sourceLocMast); //更新目标库位 locMast.setLocSts("S"); locMast.setModiTime(new Date()); locMastService.updateById(locMast); //更新工作档数据 wrkMast.setLocNo(locNo); wrkMast.setStaNo(targetStationId); if (findCrnNoResult.getCrnType().equals(SlaveType.Crn)) { wrkMast.setCrnNo(crnNo); } else if (findCrnNoResult.getCrnType().equals(SlaveType.DualCrn)) { wrkMast.setDualCrnNo(crnNo); } else { throw new CoolException("未知设备类型"); } if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command)); } } else { News.error("请求WMS接口失败!!!response:{}", response); } } else { //运行堵塞,重新计算路线 StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); return; } MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command)); News.info("输送站点堵塞后重新计算路径命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command)); } } catch (Exception e) { e.printStackTrace(); } } //获取输送线任务数量 public synchronized int getCurrentStationTaskCount() { return countCurrentStationTask(); src/main/resources/application.yml
@@ -86,21 +86,9 @@ platform: java pythonPlatformUrl: http://127.0.0.1:9000/ai/diagnose/askStream thinking: enable # base-url: https://api.siliconflow.cn/v1 # api-key: sk-sxdtebtquwrugzrmaqqqkzdzmrgzhzmplwwuowysdasccent # model: deepseek-ai/DeepSeek-V3.2 # base-url: http://47.76.147.249:9998/e/7g7kqxxt1ei2un71 # api-key: app-mP0O6aY5WpbfaHs7BNnjVkli # model: deepseek-ai/DeepSeek-V3.2 # base-url: http://34.2.134.223:3000/v1 # api-key: sk-WabrmtOezCFwVo7XvVOrO3QkmfcKG7T7jy0BaVnmQTWm5GXh # model: gemini-3-pro-preview # base-url: http://127.0.0.1:8317/v1 # api-key: WznOjAGJNVFKSe9kBZTr # model: gpt-5 base-url: https://api.xiaomimimo.com/v1 api-key: sk-cw7e4se9cal8cxdgjml8dmtn4pdmqtvfccg5fcermt0ddtys model: mimo-v2-flash base-url: http://127.0.0.1:8317/v1 api-key: WznOjAGJNVFKSe9kBZTr model: gpt-5 perf: methodTiming: