| | |
| | | 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.common.Cools; |
| | | import com.zy.asrs.domain.enums.NotifyMsgType; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.asrs.utils.NotifyUtils; |
| | | import com.zy.asrs.utils.Utils; |
| | | import com.zy.common.model.*; |
| | | import com.zy.common.model.MapNode; |
| | | import com.zy.common.model.NavigateNode; |
| | | import com.zy.common.model.SearchLocParam; |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.model.enums.NavigationMapType; |
| | | import com.zy.common.service.CommonService; |
| | | import com.zy.common.utils.*; |
| | | import com.zy.core.News; |
| | | import com.zy.core.action.LiftAction; |
| | | import com.zy.core.action.ShuttleAction; |
| | | import com.zy.core.cache.MessageQueue; |
| | | import com.zy.core.cache.SlaveConnection; |
| | | import com.zy.core.dispatcher.ShuttleDispatchUtils; |
| | | import com.zy.core.enums.*; |
| | | import com.zy.core.model.*; |
| | | import com.zy.core.model.command.*; |
| | | import com.zy.core.model.command.LiftAssignCommand; |
| | | import com.zy.core.model.command.LiftCommand; |
| | | import com.zy.core.model.command.ShuttleAssignCommand; |
| | | import com.zy.core.model.command.ShuttleCommand; |
| | | import com.zy.core.model.protocol.*; |
| | | import com.zy.core.properties.SlaveProperties; |
| | | import com.zy.core.thread.*; |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.*; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 立体仓库WCS系统主流程业务 |
| | |
| | | private BasLiftOptService basLiftOptService; |
| | | @Autowired |
| | | private LiftAction liftAction; |
| | | |
| | | |
| | | private boolean isInEnable(DevpThread devpThread, Integer staNo) { |
| | | if (staNo == null) { |
| | | return false; |
| | | } |
| | | // 获取入库站信息 |
| | | switch (staNo) { |
| | | case 1011: |
| | | case 1012: |
| | | devpThread.getStation().get(1012).isInEnable(); |
| | | break; |
| | | case 1021: |
| | | case 1022: |
| | | case 1023: |
| | | devpThread.getStation().get(1022).isInEnable(); |
| | | break; |
| | | case 1031: |
| | | case 1032: |
| | | devpThread.getStation().get(1032).isInEnable(); |
| | | break; |
| | | case 1025: |
| | | case 1026: |
| | | devpThread.getStation().get(1025).isInEnable(); |
| | | break; |
| | | case 1013: |
| | | case 1014: |
| | | case 1015: |
| | | devpThread.getStation().get(1014).isInEnable(); |
| | | break; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private boolean isOutEnable(DevpThread devpThread, Integer staNo) { |
| | | if (staNo == null) { |
| | | return false; |
| | | } |
| | | // 获取入库站信息 |
| | | switch (staNo) { |
| | | case 1011: |
| | | case 1012: |
| | | devpThread.getStation().get(1012).isOutEnable(); |
| | | break; |
| | | case 1021: |
| | | case 1022: |
| | | case 1023: |
| | | devpThread.getStation().get(1022).isOutEnable(); |
| | | break; |
| | | case 1031: |
| | | case 1032: |
| | | devpThread.getStation().get(1032).isOutEnable(); |
| | | break; |
| | | case 1025: |
| | | case 1026: |
| | | devpThread.getStation().get(1025).isOutEnable(); |
| | | break; |
| | | case 1013: |
| | | case 1014: |
| | | case 1015: |
| | | devpThread.getStation().get(1014).isOutEnable(); |
| | | break; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 组托 |
| | | * 入库站,根据条码扫描生成入库工作档,工作状态 2 |
| | | */ |
| | | public synchronized void generateInboundWrk() { |
| | | try { |
| | | DevpSlave devpSlave = slaveProperties.getDevp().get(0); |
| | | // 遍历入库口 |
| | | for (DevpSlave.Sta inSta : devpSlave.getInSta()) { |
| | | // 获取入库站信息 |
| | | DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId()); |
| | | StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo()); |
| | | if (staProtocol == null) { |
| | | continue; |
| | | } else { |
| | | staProtocol = staProtocol.clone(); |
| | | } |
| | | Short workNo = staProtocol.getWorkNo(); |
| | | // 尺寸检测异常 |
| | | boolean back = false; |
| | | String errMsg = "异常:"; |
| | | if (staProtocol.isFrontErr()) { |
| | | errMsg = errMsg + "前超限;"; |
| | | back = true; |
| | | } |
| | | if (staProtocol.isBackErr()) { |
| | | errMsg = errMsg + "后超限"; |
| | | back = true; |
| | | } |
| | | if (staProtocol.isHighErr()) { |
| | | errMsg = errMsg + "高超限"; |
| | | back = true; |
| | | } |
| | | if (staProtocol.isLeftErr()) { |
| | | errMsg = errMsg + "左超限"; |
| | | back = true; |
| | | } |
| | | if (staProtocol.isRightErr()) { |
| | | errMsg = errMsg + "右超限"; |
| | | back = true; |
| | | } |
| | | if (staProtocol.isWeightErr()) { |
| | | errMsg = errMsg + "超重"; |
| | | back = true; |
| | | } |
| | | if (staProtocol.isBarcodeErr()) { |
| | | errMsg = errMsg + "扫码失败"; |
| | | back = true; |
| | | } |
| | | // 退回 |
| | | if (back) { |
| | | // led 异常显示 |
| | | LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed()); |
| | | if (ledThread != null) { |
| | | ledThread.error(errMsg); |
| | | } |
| | | continue; |
| | | } |
| | | // 判断是否满足入库条件 |
| | | if (staProtocol.isAutoing() && staProtocol.isLoading() |
| | | && isInEnable(devpThread, inSta.getStaNo()) |
| | | && !staProtocol.isEmptyMk() && (workNo == 0 || (workNo >= 9990 && workNo <= 9999)) |
| | | && staProtocol.isPakMk() |
| | | ) { |
| | | String barcode = staProtocol.getBarcode(); |
| | | if (!Cools.isEmpty(barcode)) { |
| | | News.info("条码扫描器检测条码信息:{}", barcode); |
| | | } |
| | | // 判断重复工作档 |
| | | WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>() |
| | | .eq("source_sta_no", inSta.getStaNo()) |
| | | .eq("wrk_sts", WrkStsType.NEW_INBOUND) |
| | | .eq("barcode", barcode)); |
| | | if (wrkMast != null) { |
| | | News.error("工作档已存在,工作号={}", wrkMast.getWrkNo()); |
| | | if (staProtocol.getWorkNo().intValue() != wrkMast.getWrkNo()) { |
| | | MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol)); |
| | | devpThread.setPakMk(staProtocol.getSiteId(), false); |
| | | News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast)); |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | try { |
| | | String wmsUrl = "127.0.0.1:8080/fyxcwms"; |
| | | SearchLocParam param = new SearchLocParam(); |
| | | param.setBarcode(barcode); |
| | | param.setIoType(1); |
| | | param.setSourceStaNo(inSta.getStaNo()); |
| | | param.setLocType1(staProtocol.getLocType1().shortValue()); |
| | | String response = new HttpHandler.Builder() |
| | | .setUri(wmsUrl) |
| | | .setPath("/rpc/pakin/loc/v1") |
| | | .setJson(JSON.toJSONString(param)) |
| | | .build() |
| | | .doPost(); |
| | | JSONObject jsonObject = JSON.parseObject(response); |
| | | Integer code = jsonObject.getInteger("code"); |
| | | if (code.equals(200)) { |
| | | MessageQueue.offer(SlaveType.Devp, devpSlave.getId(), new Task(2, staProtocol)); |
| | | devpThread.setPakMk(staProtocol.getSiteId(), false); |
| | | News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(wrkMast)); |
| | | |
| | | StartupDto dto = jsonObject.getObject("data", StartupDto.class); |
| | | |
| | | // String wmsLocNo = dto.getLocNo(); |
| | | // int row = Integer.parseInt(wmsLocNo.substring(0, 2)); |
| | | // int bay = Integer.parseInt(wmsLocNo.substring(2, 5)); |
| | | // int lev = Integer.parseInt(wmsLocNo.substring(5, 7)); |
| | | // String wcsLocNo = Utils.getLocNo(row, bay, lev); |
| | | // |
| | | // CreateInTaskParam createInTaskParam = new CreateInTaskParam(); |
| | | // createInTaskParam.setTaskNo(String.valueOf(dto.getWorkNo())); |
| | | // createInTaskParam.setDestLoc(wcsLocNo); |
| | | // createInTaskParam.setOriginSite(dto.getSourceStaNo().toString()); |
| | | // createInTaskParam.setDestSite(dto.getStaNo().toString()); |
| | | // createInTaskParam.setPriority(11); |
| | | // createInTaskParam.setBarcode(barcode); |
| | | // |
| | | // R result = openUtils.createInTask(createInTaskParam); |
| | | // News.info("创建入库任务,任务数据={},WMS响应={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject), JSON.toJSON(result)); |
| | | // try{ |
| | | // String msg = ""; |
| | | // HashMap<String, String> hashMap = new HashMap<>(); |
| | | // hashMap.put("msg", msg); |
| | | // hashMap.put("sta", inSta.getStaNo().toString()); |
| | | // new HttpHandler.Builder() |
| | | // .setUri(wmsUrl) |
| | | // .setPath("/rpc/led/getError") |
| | | // .setJson(JSON.toJSONString(hashMap)) |
| | | // .build() |
| | | // .doPost(); |
| | | // }catch (Exception e){ |
| | | // |
| | | // } |
| | | } else { |
| | | String msg = jsonObject.getString("msg"); |
| | | HashMap<String, String> hashMap = new HashMap<>(); |
| | | hashMap.put("msg", msg); |
| | | hashMap.put("sta", inSta.getStaNo().toString()); |
| | | new HttpHandler.Builder() |
| | | .setUri(wmsUrl) |
| | | .setPath("/rpc/led/getError") |
| | | .setJson(JSON.toJSONString(hashMap)) |
| | | .build() |
| | | .doPost(); |
| | | News.error("入库申请失败,任务数据={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject)); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 出库到出库口 |
| | | */ |
| | | public synchronized void stnToOutStn() { |
| | | DevpSlave devpSlave = slaveProperties.getDevp().get(0); |
| | | // 遍历堆垛机出库站 |
| | | for (DevpSlave.Sta outSta : devpSlave.getOutSta()) { |
| | | // 获取堆垛机出库站信息 |
| | | DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devpSlave.getId()); |
| | | StaProtocol staProtocol = devpThread.getStation().get(outSta.getStaNo()); |
| | | if (staProtocol == null) { |
| | | continue; |
| | | } else { |
| | | staProtocol = staProtocol.clone(); |
| | | } |
| | | if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) { |
| | | // 查询工作档 |
| | | // WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId()); |
| | | // if (wrkMast == null) { |
| | | // continue; |
| | | // } |
| | | // // 判断工作档条件 |
| | | // if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) { |
| | | // |
| | | // } |
| | | |
| | | // 判断输送线和小车状态状态等待确认 |
| | | // if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue()) |
| | | // && crnProtocol.statusType == CrnStatusType.WAITING |
| | | // && crnProtocol.forkPosType == CrnForkPosType.HOME) { |
| | | // log.info("堆垛机出库完成 - 开始执行"); |
| | | // |
| | | // // 命令下发区 -------------------------------------------------------------------------- |
| | | // |
| | | // // 下发站点信息 |
| | | // staProtocol.setWorkNo(wrkMast.getWrkNo()); |
| | | // staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(), wrkMast.getSourceStaNo())); |
| | | // if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) { |
| | | // log.info(staProtocol.getWorkNo() + "," + staProtocol.getStaNo() + "输送线出库命令下发失败"); |
| | | // continue; |
| | | // } else { |
| | | // log.info(staProtocol.getWorkNo() + "," + staProtocol.getStaNo() + "输送线出库命令下发成功"); |
| | | // } |
| | | // |
| | | // // 更新工作档状态为14失败 |
| | | // wrkMast.setWrkSts(14L); |
| | | // wrkMast.setCrnEndTime(new Date()); |
| | | // if (wrkMastMapper.updateById(wrkMast) != 0) { |
| | | // // 复位堆垛机 |
| | | // log.error("出库任务完成下发堆垛机复位,{}", wrkMast.getWrkNo()); |
| | | // crnThread.setResetFlag(true); |
| | | // } else { |
| | | // News.error("" + mark + " - 1" + " - 更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo()); |
| | | // } |
| | | // |
| | | // } else { |
| | | // News.errorNoLog("" + mark + " - 6" + " - 堆垛机信息不符合入库条件!!!" |
| | | // + " 堆垛机状态:" + crnProtocol.modeType + "==自动AUTO:" + CrnModeType.AUTO |
| | | // + "、堆垛机任务号:" + crnProtocol.getTaskNo() + "==工作档任务号:" + wrkMast.getWrkNo().shortValue() |
| | | // + "、状态枚举:" + crnProtocol.statusType + "==WAITING:90 //任务完成等待WCS确认):" + CrnStatusType.WAITING |
| | | // + "、货叉位置:" + crnProtocol.forkPosType + "==HOME:0 // 货叉原位:" + CrnForkPosType.HOME); |
| | | // } |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 初始化实时地图 |
| | |
| | | } |
| | | } else { |
| | | Object object = redisUtil.get(RedisKeyType.SHUTTLE_WORK_FLAG.key + shuttleProtocol.getTaskNo()); |
| | | if(object != null){ |
| | | if (object != null) { |
| | | ShuttleAssignCommand assignCommand = JSON.parseObject(object.toString(), ShuttleAssignCommand.class); |
| | | if (!assignCommand.getAuto()) { |
| | | //手动模式 |
| | |
| | | } |
| | | int errorCode = Integer.parseInt(shuttleProtocol.getErrorCode()); |
| | | BasShuttleErr basShuttleErr = basShuttleErrService.queryByCode(errorCode); |
| | | String errName = basShuttleErr==null? "未知异常":basShuttleErr.getErrName(); |
| | | String errName = basShuttleErr == null ? "未知异常" : basShuttleErr.getErrName(); |
| | | BasShuttleErrLog basShuttleErrLog = new BasShuttleErrLog( |
| | | null, // 编号 |
| | | wrkMast.getWrkNo(), // 工作号 |
| | |
| | | } |
| | | |
| | | BasLiftErr basLiftErr = basLiftErrService.queryByCode(Integer.parseInt(liftProtocol.getErrorCode())); |
| | | String errName = basLiftErr==null? "未知异常":basLiftErr.getErrName(); |
| | | String errName = basLiftErr == null ? "未知异常" : basLiftErr.getErrName(); |
| | | |
| | | BasLiftErrLog basLiftErrLog = new BasLiftErrLog( |
| | | null, // 编号 |
| | |
| | | ArrayList<String> locs = new ArrayList<>(); |
| | | locs.add(charge.getLocNo()); |
| | | Integer checkHasShuttle = Utils.checkGroupLocHasShuttle(locs); |
| | | if(checkHasShuttle != null) { |
| | | if (checkHasShuttle != null) { |
| | | //当前充电桩有穿梭车,不分配该充电桩 |
| | | continue; |
| | | } |
| | |
| | | //查询小车充电任务 |
| | | for (ShuttleSlave shuttle : slaveProperties.getShuttle()) { |
| | | WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttle.getId()); |
| | | if(wrkMast == null) { |
| | | if (wrkMast == null) { |
| | | continue; |
| | | } |
| | | |
| | |
| | | |
| | | //判断是否存在未完成的移动任务 |
| | | WrkMast moveWrk = wrkMastService.selectShuttleHasMoveWorking(wrkMast.getShuttleNo()); |
| | | if(moveWrk != null) { |
| | | if (moveWrk != null) { |
| | | return false; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | BasShuttleCharge basShuttleCharge = basShuttleChargeService.selectOne(new EntityWrapper<BasShuttleCharge>().eq("charge_id", wrkMast.getMk())); |
| | | if(basShuttleCharge == null) { |
| | | if (basShuttleCharge == null) { |
| | | return false; |
| | | } |
| | | |
| | |
| | | this.shuttleMoveExecuteTransportLift(wrkMast); |
| | | } else if ("TRANSPORT_DEVP".equals(wrkMast.getMk())) { |
| | | |
| | | }else { |
| | | } else { |
| | | this.shuttleMoveExecuteMove(wrkMast); |
| | | } |
| | | } |
| | |
| | | if (Utils.getRow(liftLocNo) == Utils.getRow(wrkMast.getSourceLocNo()) && Utils.getBay(liftLocNo) == Utils.getBay(wrkMast.getSourceLocNo())) { |
| | | //取货位置是提升机 |
| | | this.shuttleMoveExecuteTransportLiftTake(wrkMast); |
| | | }else { |
| | | } else { |
| | | //放货位置是提升机 |
| | | this.shuttleMoveExecuteTransportLiftPut(wrkMast); |
| | | } |
| | |
| | | wrkMast.setSystemMsg("");//清空消息 |
| | | wrkMastService.updateById(wrkMast); |
| | | return false; |
| | | }else { |
| | | } else { |
| | | liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); |
| | | if (liftThread == null) { |
| | | News.info("{}号提升机不存在", wrkMast.getLiftNo()); |
| | |
| | | wrkMast.setSystemMsg("");//清空消息 |
| | | wrkMastService.updateById(wrkMast); |
| | | return false; |
| | | }else { |
| | | } else { |
| | | liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); |
| | | if (liftThread == null) { |
| | | News.info("{}号提升机不存在", wrkMast.getLiftNo()); |
| | |
| | | return false;//路径解锁失败 |
| | | } |
| | | commands.addAll(moveCommands); |
| | | }else { |
| | | } else { |
| | | //小车在待机位,直接移动完成 |
| | | wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts);// 302.小车移动至站点 ==> 303.小车移动至站点完成 |
| | | wrkMast.setModiTime(now); |
| | |
| | | wrkMast.setSystemMsg("");//清空消息 |
| | | wrkMastService.updateById(wrkMast); |
| | | return false; |
| | | }else { |
| | | } else { |
| | | liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); |
| | | if (liftThread == null) { |
| | | News.info("{}号提升机不存在", wrkMast.getLiftNo()); |