package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.exception.CoolException; import com.zy.asrs.domain.enums.TaskStatusType; import com.zy.asrs.domain.enums.WorkNoType; import com.zy.asrs.entity.*; import com.zy.asrs.entity.param.GenerateAgvTaskParam; import com.zy.asrs.mapper.*; import com.zy.asrs.service.*; import com.zy.asrs.utils.Utils; import com.zy.common.service.CommonService; import com.zy.common.utils.HttpHandler; import com.zy.core.DevpThread; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.*; import com.zy.core.model.CrnSlave; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.SiemensDevpThread; import com.zy.system.entity.Config; import com.zy.system.service.ConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.util.*; /** * 立体仓库WCS系统主流程业务 */ @Slf4j @Service("mainService") @Transactional public class MainServiceImpl { public static final long COMMAND_TIMEOUT = 5 * 1000; @Autowired private SlaveProperties slaveProperties; @Autowired private LocMastService locMastService; @Autowired private BasDevpService basDevpService; @Autowired private TaskWrkMapper taskWrkMapper; @Autowired private TaskWrkService taskWrkService; @Autowired private ConfigService configService; @Autowired private StaDescMapper staDescMapper; @Autowired private CommandInfoService commandInfoService; @Autowired private ApiLogService apiLogService; @Autowired private OpenService openService; @Autowired private CommonService commonService; @Value("${wcs.urlWcs}") private String wcsUrl; @Value("${wcs.inboundTaskApplyPathWcs}") private String wcsInboundTaskApplyPath; public synchronized void demo() { boolean demoEnable = false; Config demoEnableConfig = configService.selectByCode("demoEnable"); if(demoEnableConfig != null) { demoEnable = Boolean.parseBoolean(demoEnableConfig.getValue()); } if (!demoEnable) { return; } //演示模式-AGV出库 demoAgvOut(); //演示模式-AGV入库 demoAgvIn(); //演示模式-四向库出库 demoShuttleOut(); //演示模式-四向库入库 demoShuttleIn(); } //演示模式-AGV出库 private synchronized void demoAgvOut() { LocMast locMast = locMastService.selectByLocNo("0900601"); if(locMast == null) { return; } if (!locMast.getLocSts().equals("O")) { return; } List locMasts = locMastService.selectList(new EntityWrapper() .eq("mk", "agv") .eq("loc_sts", "F") .notIn("loc_no", "1100601") ); if (locMasts.isEmpty()) { return; } LocMast originLocMast = locMasts.get(0); //生成AGV出库任务 GenerateAgvTaskParam param = new GenerateAgvTaskParam(); param.setOriginPoint(originLocMast.getLocNo()); param.setTargetPoint(locMast.getLocNo()); openService.generateAgvTask(param); } //演示模式-AGV入库 private synchronized void demoAgvIn() { LocMast locMast = locMastService.selectByLocNo("1100601"); if(locMast == null) { return; } if (!locMast.getLocSts().equals("F")) { return; } List locMasts = locMastService.selectList(new EntityWrapper() .eq("mk", "agv") .eq("loc_sts", "O") .notIn("loc_no", "0900601") ); if (locMasts.isEmpty()) { return; } LocMast targetLocMast = locMasts.get(0); //生成AGV出库任务 GenerateAgvTaskParam param = new GenerateAgvTaskParam(); param.setOriginPoint(locMast.getLocNo()); param.setTargetPoint(targetLocMast.getLocNo()); openService.generateAgvTask(param); } //演示模式-四向库出库 private synchronized void demoShuttleOut() { LocMast locMast = locMastService.selectByLocNo("1100601"); if(locMast == null) { return; } if (!locMast.getLocSts().equals("O")) { return; } ArrayList disableLevList = new ArrayList<>(); disableLevList.add(1); //query in task List taskWrks = taskWrkService.selectList(new EntityWrapper() .eq("io_type", 1)); for (TaskWrk taskWrk : taskWrks) { int lev = Utils.getLev(taskWrk.getTargetPoint()); if(!disableLevList.contains(lev)) { disableLevList.add(lev); } } List locMasts = locMastService.selectList(new EntityWrapper() .notIn("lev1", disableLevList) .eq("loc_sts", "F") ); if(locMasts.isEmpty()) { return; } LocMast locMast1 = locMasts.get(0); Date now = new Date(); TaskWrk taskWrk = new TaskWrk(); int workNo1 = commonService.getWorkNo(WorkNoType.PAKOUT.type);//获取入库工作号 taskWrk.setTaskNo(String.valueOf(workNo1));//任务号 taskWrk.setWrkNo(workNo1); taskWrk.setStatus(TaskStatusType.RECEIVE.id);//任务状态:接收 taskWrk.setWrkSts(11); taskWrk.setCreateTime(now); taskWrk.setIoType(2);//出库 taskWrk.setIoPri(100);//优先级 taskWrk.setStartPoint(locMast1.getLocNo()); taskWrk.setTargetPoint("101");//终点 taskWrk.setBarcode(locMast1.getBarcode()); boolean result = taskWrkService.insert(taskWrk); locMast1.setLocSts("R"); locMast1.setModiTime(now); locMastService.updateById(locMast1); locMast.setLocSts("S"); locMast.setModiTime(now); locMastService.updateById(locMast); } //演示模式-四向库入库 private synchronized void demoShuttleIn() { LocMast locMast = locMastService.selectByLocNo("0900601"); if(locMast == null) { return; } if (!locMast.getLocSts().equals("F")) { return; } ArrayList disableLevList = new ArrayList<>(); disableLevList.add(1); //query out task List taskWrks = taskWrkService.selectList(new EntityWrapper() .eq("io_type", 2)); for (TaskWrk taskWrk : taskWrks) { int lev = Utils.getLev(taskWrk.getTargetPoint()); if(!disableLevList.contains(lev)) { disableLevList.add(lev); } } List locMasts = locMastService.selectList(new EntityWrapper() .notIn("lev1", disableLevList) .eq("loc_sts", "O") ); if(locMasts.isEmpty()) { return; } LocMast locMast1 = locMasts.get(0); Date now = new Date(); TaskWrk taskWrk = new TaskWrk(); int workNo1 = commonService.getWorkNo(WorkNoType.PAKIN.type);//获取入库工作号 taskWrk.setTaskNo(String.valueOf(workNo1));//任务号 taskWrk.setWrkNo(workNo1); taskWrk.setStatus(TaskStatusType.RECEIVE.id);//任务状态:接收 taskWrk.setWrkSts(1); taskWrk.setCreateTime(now); taskWrk.setIoType(1);//入库 taskWrk.setIoPri(100);//优先级 taskWrk.setOriginStartPoint("1"); taskWrk.setOriginTargetPoint(String.valueOf(Utils.getLev(locMast1.getLocNo()))); taskWrk.setTargetPoint(locMast1.getLocNo());//终点 taskWrk.setBarcode(locMast.getBarcode()); boolean result = taskWrkService.insert(taskWrk); locMast1.setLocSts("S"); locMast1.setModiTime(now); locMastService.updateById(locMast1); locMast.setLocSts("R"); locMast.setModiTime(now); locMastService.updateById(locMast); } /** * 堆垛机站出库到出库站 */ public synchronized void crnStnToOutStn() { for (CrnSlave crnSlave : slaveProperties.getCrn()) { // 遍历堆垛机出库站 for (CrnSlave.CrnStn crnStn : crnSlave.getCrnOutStn()) { List staDescs = staDescMapper.selectList(new EntityWrapper().eq("crn_no", crnSlave.getId()).eq("crn_stn", crnStn.getStaNo())); for (StaDesc staDesc : staDescs) { try { // 获取堆垛机出库站信息 DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId()); StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()); if (staProtocol == null) { continue; } else { staProtocol = staProtocol.clone(); } if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == 0)) { // 查询工作档 TaskWrk taskWrk = taskWrkMapper.selectCrnStaWorking(crnSlave.getId(), staDesc.getStnNo().toString()); if (taskWrk == null) { continue; } log.info("下发输送线任务:taskWrk:" + JSON.toJSONString(taskWrk)); // R r = siteController.siteDetlUpdate(Integer.valueOf(taskWrk.getTargetPoint()), taskWrk.getWrkNo().shortValue(), (short) 0, "Y", false, false); staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue()); staProtocol.setStaNo(staDesc.getStnNo().shortValue()); boolean offer = false; try { offer = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol)); } catch (Exception e) { log.error("下发输送线任务失败:异常:" + e); log.error("下发输送线任务失败:异常:offer:" + offer); } // JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(r)); if (offer) { log.info("下发输送线任务成功:taskWrk:" + JSON.toJSONString(taskWrk)); taskWrk.setStatus(5); taskWrk.setWrkSts(14); taskWrkService.updateById(taskWrk); } else { log.error("下发输送线任务失败:taskWrk:" + JSON.toJSONString(taskWrk)); // log.error("下发输送线任务失败:异常信息:"+JSON.toJSONString(r)); } } } catch (Exception e) { log.error("出库到出库站异常:异常信息:" + e); } } } } } /** * 入出库 ===>> 调用RCS进行入出库 */ public synchronized void crnIoExecute() throws IOException { for (CrnSlave crn : slaveProperties.getCrn()) { this.crnStnToLoc(crn); // 入库 this.locToCrnStn(crn); // 出库 // 库位移转 // this.locToLoc(crn, crnProtocol); } } /** * 入库 ===>> 堆垛机站到库位 */ public synchronized void crnStnToLoc(CrnSlave slave) throws IOException { for (CrnSlave.CrnStn crnStn : slave.getCrnInStn()) { List staDescs = staDescMapper.selectList(new EntityWrapper().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo())); for (StaDesc staDesc : staDescs) { boolean flag = false; // 获取堆垛机入库站信息 DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId()); StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()); if (staProtocol == null) { continue; } else { staProtocol = staProtocol.clone(); } // 查询站点详细信息 BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo()); if (staDetl == null) { log.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo()); continue; } if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staProtocol.isInEnable() && staDetl.getCanining() != null && staDetl.getCanining().equals("Y")) { flag = true; } if (!flag) { continue; } // 获取工作状态为2(设备上走)的入库工作档 TaskWrk taskWrk = taskWrkMapper.selectPakIn(slave.getId(), staProtocol.getWorkNo().intValue(), staDesc.getStnNo().toString()); if (null == taskWrk) { continue; } String mbz=taskWrk.getTargetPoint().substring(5); HashMap hashMap = new HashMap<>(); hashMap.put("taskNo",taskWrk.getTaskNo());//wms任务号 hashMap.put("sourceStaNo",staDetl.getDevNo());//源站点 hashMap.put("staNo",Integer.parseInt(mbz)+"");//目标站 hashMap.put("locNo",taskWrk.getTargetPoint());//目标库位 String response = ""; Boolean bool = false; try { //开始上报,出库任务开始时,WCS回调WMS response = new HttpHandler.Builder() .setUri(wcsUrl) .setPath(wcsInboundTaskApplyPath) .setJson(JSON.toJSONString(hashMap)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); if(jsonObject.get("code").equals(200)){ bool = true; taskWrk.setStatus(TaskStatusType.DISTRIBUTE.id);//派发状态 taskWrk.setAssignTime(new Date());//派发时间 taskWrk.setWrkSts(3);//工作状态 3.成功下发入库任务给RCS taskWrk.setCrnNo(staDesc.getCrnNo());//堆垛机号 taskWrk.setModiTime(new Date()); taskWrk.setModiUser(9988L); } } catch (Exception e) { }finally { apiLogService.save("wcs派发入库任务给RCS" , wcsUrl + wcsInboundTaskApplyPath , null , "127.0.0.1" , JSON.toJSONString(hashMap) , response , bool ); } } } } /** * 出库 ===>> 库位到堆垛机站 * 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库 */ public synchronized void locToCrnStn(CrnSlave slave) { List taskWrksInitial = taskWrkMapper.selectPakOut(slave.getId(), null); if (taskWrksInitial.size() == 0) { return; } for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) { List staDescs = staDescMapper.selectList(new EntityWrapper().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo())); for (StaDesc staDesc : staDescs) { // 获取工作状态为11(生成出库ID)的出库工作档 List taskWrks = taskWrkMapper.selectPakOut(slave.getId(), staDesc.getStnNo().toString()); for (TaskWrk taskWrk : taskWrks) { if (taskWrk == null) { continue; } // 工作档状态判断 if (taskWrk.getIoType() != 2 || taskWrk.getTargetPoint() == null || taskWrk.getStartPoint() == null) { log.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", taskWrk.getWrkNo(), taskWrk.getStartPoint(), taskWrk.getIoType()); continue; } LocMast locMast = locMastService.selectByLocNo(taskWrk.getStartPoint()); //判断其库位是否为深库位,如果为深库位找其浅库位是都有货 //预留 // 获取堆垛机出库站信息 SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId()); StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo()); if (staProtocol == null) { break; } else { staProtocol = staProtocol.clone(); } // 查询站点详细信息 BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo()); if (staDetl == null) { log.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo()); break; } // 判断堆垛机出库站状态 if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y") && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) { // 命令下发区 -------------------------------------------------------------------------- // 已经存在吊车执行任务时,则过滤 if (taskWrkMapper.selectCrnWorking(slave.getId()) != null) { break; } try { // 修改工作档状态 11.生成出库ID => 12.吊车出库中 Date now = new Date(); taskWrk.setWrkSts(12); taskWrk.setModiTime(now); if (taskWrkMapper.updateById(taskWrk) == 0) { log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", taskWrk.getWrkNo()); } } catch (Exception e) { log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", taskWrk.getWrkNo()); log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,异常:" + e); } // try { // HashMap headParam = new HashMap<>(); // headParam.put("taskNo", taskWrk.getTaskNo()); // headParam.put("status", taskWrk.getStatus()); // headParam.put("ioType", taskWrk.getIoType()); // headParam.put("barcode", taskWrk.getBarcode()); // String response; // response = new HttpHandler.Builder() // // .setHeaders(headParam) // .setUri(wmsUrl) // .setPath(taskStatusFeedbackPath) // .setJson(JSON.toJSONString(headParam)) // .build() // .doPost(); // JSONObject jsonObject = JSON.parseObject(response); // apiLogService.save("wcs派发出库任务上报wms" // , wmsUrl + taskStatusFeedbackPath // , null // , "127.0.0.1" // , JSON.toJSONString(headParam) // , response // , true // ); // } catch (Exception e) { // log.error("wcs派发出库任务上报wms失败", JSON.toJSONString(taskWrk)); //// throw new CoolException("wcs派发入库任务上报wms失败"); // } } } } } } //自动派发任务 public synchronized void autoDistribute() { Config config = configService.selectByCode("autoDistribute"); if (config == null) { return; } if (config.getValue().equals("false")) {//判断是否开启自动派发任务 return; } for (TaskWrk taskWrk : taskWrkService.selectReceive()) { try { taskWrkService.distribute(taskWrk.getTaskNo(), 9527L); } catch (CoolException e) { log.info(e.getMessage()); } } } //agv取放货任务完成 public synchronized void autoCompleteAGV() { List basDevps = basDevpService.selectList(new EntityWrapper<>()); try { Thread.sleep(500); } catch (Exception e) { } for (BasDevp basDevp : basDevps) { DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = devpThread.getStation().get(basDevp.getDevNo()); if (staProtocol == null) { continue; } else { staProtocol = staProtocol.clone(); } if (basDevp.getWrkNo() != 0) { if (basDevp.getAgvTargetPick() != 0) {//取货 staProtocol.setAgvTypeSign((short) 0); staProtocol.setStaNo(basDevp.getDevNo().shortValue()); MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol)); } boolean sign = true; if (basDevp.getAgvTargetPlace() != 0) { sign = false; basDevp.setAgvTargetPlace(0); basDevpService.updateById(basDevp); staProtocol.setAgvTypeSign((short) 3);//1 staProtocol.setStaNo(basDevp.getDevNo().shortValue()); MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol)); } } else { if (basDevp.getAgvTargetPlace() != 0) { if (basDevp.getLoading().equals("Y")) { staProtocol.setAgvTypeSign((short) 1); staProtocol.setStaNo(basDevp.getDevNo().shortValue()); MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol)); } else { log.error("AGV放货完成但输送线无物,复位信号 ===>> [staNo:{}] [basDevp:{}]", basDevp.getDevNo(), basDevp); basDevp.setAgvTargetPlace(0); basDevpService.updateById(basDevp); staProtocol.setAgvTypeSign((short) 3);//1 staProtocol.setStaNo(basDevp.getDevNo().shortValue()); MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol)); } } if (basDevp.getAgvTargetPick() != 0) { basDevp.setAgvTargetPick(0); basDevpService.updateById(basDevp); staProtocol.setAgvTypeSign((short) 2);//0 staProtocol.setStaNo(basDevp.getDevNo().shortValue()); MessageQueue.offer(SlaveType.Devp, 1, new Task(4, staProtocol)); } } } } public synchronized void autoCompleteTask() { List taskWrks = taskWrkMapper.selectWorkingTask(); for (TaskWrk taskWrk : taskWrks) { //获取命令集合 List commandInfos = commandInfoService.selectByTaskNo(taskWrk.getTaskNo()); if (taskWrk.getCommandStep() < commandInfos.size()) { continue;//当前步序没有到达最后一条命令 } //判断末端命令是否执行完成 CommandInfo commandInfo = commandInfos.get(commandInfos.size() - 1); if (commandInfo.getCommandStatus() != CommandStatusType.COMPLETE.id) { continue;//指令未完成 } Date now = new Date(); //指令已完成,更新任务 if (taskWrk.getIoType() == 1) { //入库任务 taskWrk.setWrkSts(4);//3.吊车入库中 => 4.入库完成 //taskWrk.setStatus(TaskStatusType.COMPLETE.id); taskWrk.setModiTime(now); taskWrkService.updateById(taskWrk); //更新库位状态 LocMast locMast = locMastService.selectByLocNo(taskWrk.getTargetPoint()); locMast.setLocSts("F");//F.在库 locMast.setBarcode(taskWrk.getBarcode());//托盘码 locMast.setModiTime(now); locMast.setModiUser(9999L); locMastService.updateById(locMast); } else if (taskWrk.getIoType() == 2) { //出库任务 taskWrk.setWrkSts(14);//12.吊车出库中 => 14.出库完成 // taskWrk.setStatus(TaskStatusType.COMPLETE.id); taskWrk.setModiTime(now); taskWrkService.updateById(taskWrk); //更新库位状态 LocMast locMast = locMastService.selectByLocNo(taskWrk.getStartPoint()); locMast.setLocSts("O");//O.空库位 locMast.setBarcode("");//托盘码 locMast.setModiTime(now); locMast.setModiUser(9999L); locMastService.updateById(locMast); } } } }