package com.zy.core.utils.station; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zy.asrs.domain.enums.NotifyMsgType; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.entity.BasStation; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.service.BasStationService; import com.zy.asrs.service.WrkAnalysisService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.utils.NotifyUtils; import com.zy.common.entity.FindCrnNoResult; import com.zy.common.service.CommonService; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.cache.SlaveConnection; import com.zy.core.dispatch.StationCommandDispatchResult; import com.zy.core.dispatch.StationCommandDispatcher; import com.zy.core.enums.RedisKeyType; import com.zy.core.enums.SlaveType; import com.zy.core.enums.StationCommandType; import com.zy.core.enums.WrkStsType; import com.zy.core.model.StationObjModel; import com.zy.core.model.command.StationCommand; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.model.protocol.StationTaskBufferItem; import com.zy.core.move.StationMoveCoordinator; import com.zy.core.thread.StationThread; import com.zy.core.utils.station.model.DispatchLimitConfig; import com.zy.core.utils.station.model.LoadGuardState; import com.zy.core.utils.station.model.LoopHitResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; @Component public class StationRegularDispatchProcessor { @Autowired private BasDevpService basDevpService; @Autowired private WrkMastService wrkMastService; @Autowired private CommonService commonService; @Autowired private RedisUtil redisUtil; @Autowired private WrkAnalysisService wrkAnalysisService; @Autowired private BasStationService basStationService; @Autowired private NotifyUtils notifyUtils; @Autowired private StationMoveCoordinator stationMoveCoordinator; @Autowired(required = false) private StationCommandDispatcher stationCommandDispatcher; @Autowired private StationDispatchLoadSupport stationDispatchLoadSupport; public void stationInExecute() { try { DispatchLimitConfig baseLimitConfig = stationDispatchLoadSupport.getDispatchLimitConfig(null, null); int[] currentStationTaskCountRef = new int[]{stationDispatchLoadSupport.countCurrentStationTask()}; LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(baseLimitConfig); List basDevps = basDevpService.list(new QueryWrapper<>()); for (BasDevp basDevp : basDevps) { StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo()); if (stationThread == null) { continue; } Map stationMap = stationThread.getStatusMap(); List stationList = basDevp.getBarcodeStationList$(); for (StationObjModel entity : stationList) { 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) { continue; } WrkMast wrkMast = wrkMastService.getOne(new QueryWrapper().eq("barcode", stationProtocol.getBarcode())); if (wrkMast == null || !Objects.equals(wrkMast.getWrkSts(), WrkStsType.NEW_INBOUND.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; } DispatchLimitConfig limitConfig = stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), targetStationId); LoopHitResult loopHitResult = stationDispatchLoadSupport.findPathLoopHit( limitConfig, stationProtocol.getStationId(), targetStationId, loadGuardState ); if (stationDispatchLoadSupport.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; } Date now = new Date(); wrkMast.setWrkSts(WrkStsType.INBOUND_STATION_RUN.sts); wrkMast.setSourceStaNo(stationProtocol.getStationId()); wrkMast.setStaNo(targetStationId); wrkMast.setSystemMsg(""); wrkMast.setIoTime(now); wrkMast.setModiTime(now); if (wrkMastService.updateById(wrkMast)) { wrkAnalysisService.markInboundStationStart(wrkMast, now); boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "stationInExecute"); if (offered && stationMoveCoordinator != null) { stationMoveCoordinator.recordDispatch( wrkMast.getWrkNo(), stationProtocol.getStationId(), "stationInExecute", command, false ); } News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command)); redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5); loadGuardState.reserveLoopTask(loopHitResult.getLoopNo()); stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult); } } } } catch (Exception e) { e.printStackTrace(); } } public void stationOutExecuteFinish() { try { List wrkMasts = wrkMastService.list(new QueryWrapper().eq("wrk_sts", WrkStsType.STATION_RUN.sts)); for (WrkMast wrkMast : wrkMasts) { Integer wrkNo = wrkMast.getWrkNo(); Integer targetStaNo = wrkMast.getStaNo(); if (wrkNo == null || targetStaNo == null) { continue; } boolean complete = false; Integer targetDeviceNo = null; StationThread stationThread = null; BasStation basStation = basStationService.getOne(new QueryWrapper().eq("station_id", targetStaNo)); if (basStation != null) { targetDeviceNo = basStation.getDeviceNo(); stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo()); if (stationThread != null) { Map statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap.get(basStation.getStationId()); if (stationProtocol != null && wrkNo.equals(stationProtocol.getTaskNo())) { complete = true; } } } if (complete) { attemptClearTaskPath(stationThread, wrkNo); completeStationRunTask(wrkMast, targetDeviceNo); } } } catch (Exception e) { e.printStackTrace(); } } public void checkTaskToComplete() { try { List wrkMasts = wrkMastService.list(new QueryWrapper().eq("wrk_sts", WrkStsType.STATION_RUN_COMPLETE.sts)); for (WrkMast wrkMast : wrkMasts) { Integer wrkNo = wrkMast.getWrkNo(); Integer targetStaNo = wrkMast.getStaNo(); Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkNo); if (lock != null) { continue; } BasStation basStation = basStationService.getOne(new QueryWrapper().eq("station_id", targetStaNo)); if (basStation == null) { continue; } StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo()); if (stationThread == null) { continue; } Map statusMap = stationThread.getStatusMap(); StationProtocol stationProtocol = statusMap.get(basStation.getStationId()); if (stationProtocol == null) { continue; } if (!Objects.equals(stationProtocol.getTaskNo(), wrkNo)) { if (stationMoveCoordinator != null) { stationMoveCoordinator.finishSession(wrkNo); } wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts); wrkMast.setIoTime(new Date()); wrkMastService.updateById(wrkMast); } } } catch (Exception e) { e.printStackTrace(); } } private void attemptClearTaskPath(StationThread stationThread, Integer taskNo) { if (stationThread == null || taskNo == null || taskNo <= 0) { return; } try { boolean cleared = stationThread.clearPath(taskNo); if (cleared) { News.info("输送站点任务运行完成后清理残留路径,工作号={}", taskNo); } } catch (Exception e) { News.error("输送站点任务运行完成后清理残留路径异常,工作号={}", taskNo, e); } } private void completeStationRunTask(WrkMast wrkMast, Integer deviceNo) { if (wrkMast == null || wrkMast.getWrkNo() == null) { return; } if (stationMoveCoordinator != null) { stationMoveCoordinator.finishSession(wrkMast.getWrkNo()); } Date now = new Date(); wrkMast.setWrkSts(WrkStsType.STATION_RUN_COMPLETE.sts); wrkMast.setIoTime(now); wrkMast.setModiTime(now); wrkMastService.updateById(wrkMast); wrkAnalysisService.markOutboundStationComplete(wrkMast, now); if (deviceNo != null) { notifyUtils.notify(String.valueOf(SlaveType.Devp), deviceNo, 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); } private boolean offerDevpCommandWithDedup(Integer deviceNo, StationCommand command, String scene) { StationCommandDispatchResult dispatchResult = stationCommandDispatcher.dispatch(deviceNo, command, "station-operate-process", scene); return dispatchResult.isAccepted(); } }