package com.zy.core.utils; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.zy.asrs.entity.BasCrnp; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.LocMastService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.utils.Utils; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.*; import com.zy.core.model.StationObjModel; import com.zy.core.model.Task; import com.zy.core.model.command.CrnCommand; import com.zy.core.model.command.StationCommand; import com.zy.core.model.protocol.CrnProtocol; import com.zy.core.model.protocol.StationProtocol; import com.zy.core.thread.CrnThread; import com.zy.core.thread.StationThread; 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 CrnOperateProcessUtils { @Autowired private WrkMastService wrkMastService; @Autowired private BasCrnpService basCrnpService; @Autowired private LocMastService locMastService; @Autowired private RedisUtil redisUtil; //入出库 ===>> 堆垛机入出库作业下发 public synchronized void crnIoExecute() { List basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if(crnThread == null){ continue; } CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ continue; } List wrkMasts = wrkMastService.selectList(new EntityWrapper() .eq("crn_no", basCrnp.getCrnNo()) .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts) ); 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 ) { // 如果最近一次是入库模式 if (crnProtocol.getLastIo().equals("I")) { if (basCrnp.getInEnable().equals("Y")) { this.crnExecuteIn(basCrnp, crnThread); // 入库 crnProtocol.setLastIo("O"); } else if (basCrnp.getOutEnable().equals("Y")) { this.crnExecuteOut(basCrnp, crnThread); // 出库 crnProtocol.setLastIo("I"); } } // 如果最近一次是出库模式 else if (crnProtocol.getLastIo().equals("O")) { if (basCrnp.getOutEnable().equals("Y")) { this.crnExecuteOut(basCrnp, crnThread); // 出库 crnProtocol.setLastIo("I"); } else if (basCrnp.getInEnable().equals("Y")) { this.crnExecuteIn(basCrnp, crnThread); // 入库 crnProtocol.setLastIo("O"); } } } } } private synchronized void crnExecuteIn(BasCrnp basCrnp, CrnThread crnThread) { CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ return; } if(!basCrnp.getInEnable().equals("Y")){ News.info("堆垛机:{} 可入信号不满足", basCrnp.getCrnNo()); return; } List inStationList = basCrnp.getInStationList$(); if(inStationList.isEmpty()){ News.info("堆垛机:{} 入库站点未设置", basCrnp.getCrnNo()); return; } Integer crnNo = basCrnp.getCrnNo(); for (StationObjModel stationObjModel : inStationList) { StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { continue; } Map stationProtocolMap = stationThread.getStatusMap(); StationProtocol stationProtocol = stationProtocolMap.get(stationObjModel.getStationId()); if (stationProtocol == null) { continue; } if (!stationProtocol.isAutoing()) { continue; } if (!stationProtocol.isLoading()) { continue; } if (stationProtocol.getTaskNo() <= 0) { continue; } if (!stationProtocol.isInEnable()) { News.taskInfo(stationProtocol.getTaskNo(), "取货站点:{} 没有可入信号", stationObjModel.getStationId()); continue; } // 获取任务 WrkMast wrkMast = wrkMastService.selectByWorkNo(stationProtocol.getTaskNo()); if (null == wrkMast) { News.taskInfo(stationProtocol.getTaskNo(), "工作号:{} 任务信息不存在", stationProtocol.getTaskNo()); continue; } if(wrkMast.getWrkSts() != WrkStsType.INBOUND_DEVICE_RUN.sts){ News.taskInfo(stationProtocol.getTaskNo(), "工作号:{} 任务状态异常", stationProtocol.getTaskNo()); continue; } // 获取库位信息 LocMast locMast = locMastService.selectById(wrkMast.getLocNo()); if (locMast == null) { News.taskInfo(wrkMast.getWrkNo(), "目标库位:{} 信息不存在", wrkMast.getLocNo()); continue; } if (!locMast.getLocSts().equals("S")) { News.taskInfo(wrkMast.getWrkNo(), "目标库位:{} 状态异常", wrkMast.getLocNo()); continue; } String sourceLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev()); CrnCommand command = crnThread.getPickAndPutCommand(sourceLocNo, wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo); wrkMast.setWrkSts(WrkStsType.INBOUND_RUN.sts); wrkMast.setCrnNo(crnNo); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command)); News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command)); } } } private synchronized void crnExecuteOut(BasCrnp basCrnp, CrnThread crnThread) { CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ return; } if(!basCrnp.getOutEnable().equals("Y")){ News.info("堆垛机:{} 可出信号不满足", basCrnp.getCrnNo()); return; } List outStationList = basCrnp.getOutStationList$(); if(outStationList.isEmpty()){ News.info("堆垛机:{} 出库站点未设置", basCrnp.getCrnNo()); return; } Integer crnNo = basCrnp.getCrnNo(); List wrkMasts = wrkMastService.selectList(new EntityWrapper() .eq("crn_no", crnNo) .eq("wrk_sts", WrkStsType.NEW_OUTBOUND.sts) ); for (WrkMast wrkMast : wrkMasts) { for (StationObjModel stationObjModel : outStationList) { StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo()); if (stationThread == null) { continue; } Map stationProtocolMap = stationThread.getStatusMap(); StationProtocol stationProtocol = stationProtocolMap.get(stationObjModel.getStationId()); if (stationProtocol == null) { continue; } if (!stationProtocol.isAutoing()) { continue; } if (stationProtocol.isLoading()) { continue; } if (stationProtocol.getTaskNo() != 0) { continue; } if (!stationProtocol.isOutEnable()) { News.info("放货站点:{} 没有可出信号", stationObjModel.getStationId()); continue; } // 获取库位信息 LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo()); if (locMast == null) { News.taskInfo(wrkMast.getWrkNo(), "源库位:{} 信息不存在", wrkMast.getSourceLocNo()); continue; } if (!locMast.getLocSts().equals("R")) { News.taskInfo(wrkMast.getWrkNo(), "源库位:{} 状态异常", wrkMast.getSourceLocNo()); continue; } String targetLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev()); CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), targetLocNo, wrkMast.getWrkNo(), crnNo); wrkMast.setWrkSts(WrkStsType.OUTBOUND_RUN.sts); wrkMast.setCrnNo(crnNo); wrkMast.setSystemMsg(""); wrkMast.setIoTime(new Date()); if (wrkMastService.updateById(wrkMast)) { MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command)); News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command)); return; } } } } //堆垛机任务执行完成 public synchronized void crnIoExecuteFinish() { List basCrnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp basCrnp : basCrnps) { CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo()); if(crnThread == null){ continue; } CrnProtocol crnProtocol = crnThread.getStatus(); if(crnProtocol == null){ continue; } 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; } // 获取待确认工作档 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; }else if(wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts){ updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts; }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.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); } } } }