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.WrkMast; import com.zy.asrs.service.WrkAnalysisService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.utils.NotifyUtils; 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.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.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 com.zy.core.utils.station.model.OutOrderDispatchDecision; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.Map; @Component public class StationOutboundDispatchProcessor { @Autowired private WrkMastService wrkMastService; @Autowired private WrkAnalysisService wrkAnalysisService; @Autowired private RedisUtil redisUtil; @Autowired private NotifyUtils notifyUtils; @Autowired private StationMoveCoordinator stationMoveCoordinator; @Autowired(required = false) private StationCommandDispatcher stationCommandDispatcher; @Autowired private StationDispatchLoadSupport stationDispatchLoadSupport; @Autowired private StationOutboundDecisionSupport stationOutboundDecisionSupport; public void crnStationOutExecute() { try { DispatchLimitConfig baseLimitConfig = stationDispatchLoadSupport.getDispatchLimitConfig(null, null); int[] currentStationTaskCountRef = new int[]{stationDispatchLoadSupport.countCurrentStationTask()}; LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(baseLimitConfig); List wrkMasts = wrkMastService.list(new QueryWrapper() .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts) .isNotNull("crn_no")); List outOrderList = stationOutboundDecisionSupport.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 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; } if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0) { Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast); OutOrderDispatchDecision dispatchDecision = stationOutboundDecisionSupport.resolveOutboundDispatchDecision( stationProtocol.getStationId(), wrkMast, outOrderList, pathLenFactor ); Integer moveStaNo = dispatchDecision == null ? null : dispatchDecision.getTargetStationId(); if (moveStaNo == null) { continue; } DispatchLimitConfig limitConfig = stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), moveStaNo); LoopHitResult loopHitResult = stationDispatchLoadSupport.findPathLoopHit( limitConfig, stationProtocol.getStationId(), moveStaNo, loadGuardState, wrkMast, pathLenFactor ); if (stationDispatchLoadSupport.isDispatchBlocked( limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) { return; } StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand( stationThread, wrkMast, stationProtocol.getStationId(), moveStaNo, pathLenFactor ); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); continue; } Date now = new Date(); wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(now); wrkMast.setModiTime(now); if (wrkMastService.updateById(wrkMast)) { wrkAnalysisService.markOutboundStationStart(wrkMast, now); boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute"); if (offered && stationMoveCoordinator != null) { stationMoveCoordinator.recordDispatch( wrkMast.getWrkNo(), stationProtocol.getStationId(), "crnStationOutExecute", command, false ); } 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()); stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult); } } } } catch (Exception e) { e.printStackTrace(); } } public void dualCrnStationOutExecute() { try { List wrkMasts = wrkMastService.list(new QueryWrapper() .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts) .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; } StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class); StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { continue; } Map 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; } if (stationProtocol.isAutoing() && stationProtocol.isLoading() && stationProtocol.getTaskNo() == 0) { Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast); StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand( stationThread, wrkMast, stationProtocol.getStationId(), wrkMast.getStaNo(), pathLenFactor ); if (command == null) { News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败"); continue; } wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "dualCrnStationOutExecute"); if (offered && stationMoveCoordinator != null) { stationMoveCoordinator.recordDispatch( wrkMast.getWrkNo(), stationProtocol.getStationId(), "dualCrnStationOutExecute", command, false ); } 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) { e.printStackTrace(); } } private boolean offerDevpCommandWithDedup(Integer deviceNo, StationCommand command, String scene) { StationCommandDispatchResult dispatchResult = stationCommandDispatcher .dispatch(deviceNo, command, "station-operate-process", scene); return dispatchResult.isAccepted(); } }