pang.jiabao
2026-04-24 7b8021d7ff94015d7034ead10fea5006d0032301
src/main/java/com/zy/service/impl/MainServiceImpl.java
@@ -22,15 +22,20 @@
import com.zy.core.model.Task;
import com.zy.core.model.command.CrnCommand;
import com.zy.core.model.command.LedCommand;
import com.zy.core.model.command.RgvCommand;
import com.zy.core.model.protocol.CrnProtocol;
import com.zy.core.model.protocol.RgvProtocol;
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.BarcodeThread;
import com.zy.core.thread.LedThread;
import com.zy.core.thread.RgvThread;
import com.zy.core.thread.SiemensDevpThread;
import com.zy.entity.*;
import com.zy.mapper.*;
import com.zy.service.*;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import com.zy.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -93,7 +98,7 @@
    @Value("${wms.url}")
    private String wmsUrl;
    public Integer wrkNo = 9901;
    public Integer wrkNo = 9997;
    /**
     * 组托
@@ -147,20 +152,13 @@
                    errMsg = "超重";
                    back = true;
                }
                if (!back && staProtocol.isBarcodeErr()) {
                if (!back && (staProtocol.isBarcodeErr()||Cools.isEmpty(barcode))) {
                    errMsg = "扫码失败";
                    back = true;
                }
                // 退回
                if (back) {
                if (back && (staProtocol.getWorkNo() == 9999 || staProtocol.getWorkNo() == 9998)  && staProtocol.isInEnable() && staProtocol.isLoading() && staProtocol.isPakMk()) {
                    MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errMsg));
                    if (!staProtocol.isLoading()){
                        continue;
                    }
                    if (!staProtocol.isPakMk()) {
                        continue;
                    }
                    staProtocol.setWorkNo(wrkNo);
                    News.info("{}入库回退:{},任务号:{}", inSta.getStaNo(), errMsg,wrkNo);
                    staProtocol.setStaNo(inSta.getBackSta().shortValue());
@@ -175,8 +173,9 @@
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && !staProtocol.isEmptyMk()
                        && staProtocol.isPakMk()) {
                        && staProtocol.isPakMk() && staProtocol.getWorkNo() == 9999) {
                    if(Cools.isEmpty(barcode) || "NG".endsWith(barcode) || "NoRead".equals(barcode) || "00000000".equals(barcode)) {
                        News.info("{}条码扫描错误:{}",barcodeThread.getSlave().getId(),barcode);
                        continue;
                    }
                    // 判断重复工作档
@@ -209,14 +208,12 @@
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            barcodeThread.setBarcode("");
                            staProtocol.setWorkNo(dto.getWorkNo());
                            staProtocol.setStaNo(RouteUtils.SouStaEnd(dto.getStaNo(),dto.getSourceStaNo()));
                            staProtocol.setStaNo(dto.getStaNo().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            log.error("输送线下发2:"+dto.getWorkNo()+","+dto.getStaNo());
                            if (!result) {
                                News.error(methodName + ":更新plc站点信息失败");
                                throw new CoolException("更新plc站点信息失败");
                            }else {
                                ledThread.errorReset();
                            }
@@ -237,7 +234,6 @@
                    }
                }
            }
        }
@@ -274,7 +270,7 @@
                    staProtocol = staProtocol.clone();
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && staProtocol.isPakMk()) {
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && staProtocol.isPakMk() && staProtocol.getWorkNo() == 9999) {
                    News.warnNoLog(""+mark+" - 0"+" - 开始执行");
                    WrkMast wrkMast = wrkMastMapper.selectPickStep(barcode);
                    if (wrkMast == null) {
@@ -298,7 +294,7 @@
                        staProtocol.setStaNo((short) (pickSta.getStaNo().shortValue()-(short)1));
                        devpThread.setPakMk(staProtocol.getSiteId(), false);
                        MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                        log.error("输送线下发4:"+9989+","+(pickSta.getStaNo().shortValue()-(short)1));
                        log.error("输送线下发4:"+wrkNo+","+(pickSta.getStaNo().shortValue()-(short)1));
                        //LED
                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, pickSta.getLed());
                        // led 异常显示
@@ -326,11 +322,12 @@
                        wrkMast.setIoTime(now);
                        wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
                        wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
                        wrkMast.setSourceStaNo(wrkMast.getStaNo()); // 源站
                        wrkMast.setSourceStaNo(pickSta.getStaNo()); // 源站
                        wrkMast.setStaNo(staNo); // 目标站
                        wrkMast.setLocNo(wrkMast.getSourceLocNo()); // 目标库位 = 出库时的源库位
                        wrkMast.setSourceLocNo(""); // 源库位清空
                        wrkMast.setModiTime(now);
                        wrkMast.setWhsType(0);
                        if (wrkMastMapper.updateById(wrkMast) == 0) {
                            throw new CoolException("更新工作档数据状态失败");
                        }
@@ -351,7 +348,7 @@
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                    staProtocol.setStaNo((short) 161);
                    staProtocol.setStaNo(staDesc.getCrnStn().shortValue());
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    log.error("输送线下发5:"+wrkMast.getWrkNo()+","+wrkMast.getStaNo());
@@ -419,8 +416,14 @@
                        wrkMast.setCrnEndTime(new Date());
                        if (wrkMastMapper.updateById(wrkMast) != 0) {
                            // 复位堆垛机
                            log.info("出库任务完成下发堆垛机复位,任务号:{}",wrkMast.getWrkNo());
                            crnThread.setResetFlag(true);
                            News.info("出库任务完成下发堆垛机复位,任务号:{}",wrkMast.getWrkNo());
                            // 堆垛机复位
                            if (!MessageQueue.offer(SlaveType.Crn, crnThread.getCrnProtocol().getCrnNo(), new Task(3, null))) {
                                News.error(crnThread.getCrnProtocol().getCrnNo() + "出库任务完成下发堆垛机复位,下发复位命令失败");
                            } else {
                                News.warnNoLog(""+mark+" - 2"+" - 出库任务完成下发堆垛机复位成功 : 堆垛机号={}",crnThread.getCrnProtocol().getCrnNo());
                            }
//                            crnThread.setResetFlag(true);
                        } else {
                            News.error(""+mark+" - 1"+" - 更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
@@ -429,7 +432,7 @@
                        News.errorNoLog(""+mark+" - 6"+" - 堆垛机信息不符合入库条件!!!"
                                +" 堆垛机状态:"+crnProtocol.modeType+"==自动AUTO:" + CrnModeType.AUTO
                                +"、堆垛机任务号:"+crnProtocol.getTaskNo()+"==工作档任务号:" + wrkMast.getWrkNo().shortValue()
                                +"、状态枚举:"+crnProtocol.statusType+"==WAITING:90 //任务完成等待WCS确认):" + CrnStatusType.WAITING
                                +"、状态枚举:"+crnProtocol.statusType+"==WAITING:10 //任务完成等待WCS确认):" + CrnStatusType.WAITING
                                +"、货叉位置:"+crnProtocol.forkPosType+"==HOME:0  // 货叉原位:" + CrnForkPosType.HOME);
                    }
@@ -458,7 +461,7 @@
            // 只有当堆垛机空闲 并且 无任务时才继续执行
            if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO
                    && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0) {
                    && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0 && crnProtocol.getAlarm() == 0) {
                News.warnNoLog(""+mark+" - 0"+" - 开始执行堆垛机入出库作业下发");
                // 如果最近一次是入库模式
                if (crnProtocol.getLastIo().equals("I")) {
@@ -557,40 +560,42 @@
                News.warnNoLog(""+mark+" - 1"+" - 8"+" - 双深库位且浅库位有货,则需先对浅库位进行库位移转 : 开始执行 任务号={}",wrkMast.getWrkNo());
                String shallowLocNo = Utils.getShallowLoc(slaveProperties, wrkMast.getLocNo());
                LocMast shallowLoc = locMastService.selectById(shallowLocNo);
                // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!
                if (shallowLoc.getLocSts().equals("P") || shallowLoc.getLocSts().equals("R")) {
                    News.warnNoLog(""+mark+" - 1"+" - 9"+" - // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!库位状态={}",shallowLoc.getLocSts());
                    WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                    if (null == waitWrkMast) {
                        News.error(""+mark+" - 1"+" - 10"+" - {}库位异常,未检索到相应工作档!", shallowLocNo);
                    } else {
                        waitWrkMast.setIoPri(15D);
                        waitWrkMast.setModiTime(new Date());
                        if (wrkMastMapper.updateById(waitWrkMast) == 0) {
                            News.error(""+mark+" - 1"+" - 11"+" - 调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo());
                if(shallowLoc != null) {
                    // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!
                    if (shallowLoc.getLocSts().equals("P") || shallowLoc.getLocSts().equals("R")) {
                        News.warnNoLog(""+mark+" - 1"+" - 9"+" - // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!库位状态={}",shallowLoc.getLocSts());
                        WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                        if (null == waitWrkMast) {
                            News.error(""+mark+" - 1"+" - 10"+" - {}库位异常,未检索到相应工作档!", shallowLocNo);
                        } else {
                            waitWrkMast.setIoPri(15D);
                            waitWrkMast.setModiTime(new Date());
                            if (wrkMastMapper.updateById(waitWrkMast) == 0) {
                                News.error(""+mark+" - 1"+" - 11"+" - 调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo());
                            }
                            continue;
                        }
                    } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) {
                        News.warnNoLog(""+mark+" - 1"+" - 12"+" - // F、D  库位状态={}",shallowLoc.getLocSts());
                        // 此标记避免多次执行移库任务
                        if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk())) {
                            wrkMast.setUpdMk("Y");
                            wrkMast.setIoPri(14D);
                            wrkMastMapper.updateById(wrkMast);
                            // 生成工作档,将浅库位移转到新的库位中
                            moveLocForDeepLoc(slave, shallowLoc,mark);
                            // 生成工作档、改变浅库位的源库/目标库 库位状态、下发堆垛机命令(立马执行)
//                        moveLocForDeepLocPakin(slave, shallowLoc, wrkMast);
                        }
                        continue;
                    }
                } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) {
                    News.warnNoLog(""+mark+" - 1"+" - 12"+" - // F、D  库位状态={}",shallowLoc.getLocSts());
                    // 此标记避免多次执行移库任务
                    if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk())) {
                        wrkMast.setUpdMk("Y");
                        wrkMast.setIoPri(14D);
                        wrkMastMapper.updateById(wrkMast);
                        // 生成工作档,将浅库位移转到新的库位中
                        moveLocForDeepLoc(slave, shallowLoc,mark);
                        // 生成工作档、改变浅库位的源库/目标库 库位状态、下发堆垛机命令(立马执行)
//                        moveLocForDeepLocPakin(slave, shallowLoc, wrkMast);
                    }
                    continue;
                } else if (shallowLoc.getLocSts().equals("Q")) {
                    News.warnNoLog(""+mark+" - 1"+" - 13"+" - // Q  库位状态={}",shallowLoc.getLocSts());
                    WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                    if (null != waitWrkMast && waitWrkMast.getWrkSts() == 4) {
                        News.infoNoLog(""+mark+" - 1"+" - 14"+" - // F、D  工作状态(判断条件为==4)={}",waitWrkMast.getWrkSts());
                        continue;
                    } else if (shallowLoc.getLocSts().equals("Q")) {
                        News.warnNoLog(""+mark+" - 1"+" - 13"+" - // Q  库位状态={}",shallowLoc.getLocSts());
                        WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                        if (null != waitWrkMast && waitWrkMast.getWrkSts() == 4) {
                            News.infoNoLog(""+mark+" - 1"+" - 14"+" - // F、D  工作状态(判断条件为==4)={}",waitWrkMast.getWrkSts());
                            continue;
                        }
                    }
                }
            }
@@ -610,7 +615,8 @@
            crnCommand.setDestinationPosX(locMast.getRow1().shortValue());     // 目标库位排
            crnCommand.setDestinationPosY(locMast.getBay1().shortValue());     // 目标库位列
            crnCommand.setDestinationPosZ(locMast.getLev1().shortValue());     // 目标库位层
            crnCommand.setTraySize(locMast.getLocType1() == 2);
            crnCommand.setCommand((short) 1);     // 任务确认
//            crnCommand.setTraySize(locMast.getLocType1() == 2);
            if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                News.error(""+mark+" - 1"+" - 16"+" - 堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
            } else {
@@ -628,12 +634,22 @@
        News.infoNoLog(""+mark+" - 1"+" - 0"+" - 堆垛机入出库作业下发 : 入库执行完毕");
    }
    @Resource
    private ConfigService configService;
    /**
     * 出库  ===>>  库位到堆垛机站
     * 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库
     */
    public synchronized void locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol,Integer mark) {
        News.warnNoLog(""+mark+" - 2"+" - 0"+" - 堆垛机入出库作业下发:执行出库");
        // 控制是否允许连续出库,不判断出库站点状态(根据状态启用)
        boolean crnAvailableOut = false;
        Config config = configService.selectOne(new EntityWrapper<Config>().eq("code","removeCrnAvailableOut"));
        if (config != null && config.getStatus() == 1) {
            crnAvailableOut = true;
        }
        for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
            // 获取工作状态为11(生成出库ID)的出库工作档
            List<WrkMast> wrkMasts = wrkMastMapper.selectPakOutStep11(slave.getId(), crnStn.getStaNo());
@@ -672,8 +688,8 @@
                }
                // 判断堆垛机出库站状态
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")
                        && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                if (staProtocol.isAutoing() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")
                        && (crnAvailableOut || !staProtocol.isLoading()&& staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable())) {
                    // 堆垛机控制过滤
                    if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
//                        continue;
@@ -685,46 +701,48 @@
                        News.warnNoLog(""+mark+" - 2"+" - 6"+" - 双深库位且浅库位有货,则需先对浅库位进行库位移转 : 开始执行 任务号={}",wrkMast.getWrkNo());
                        String shallowLocNo = Utils.getShallowLoc(slaveProperties, wrkMast.getSourceLocNo());
                        LocMast shallowLoc = locMastService.selectById(shallowLocNo);
                        // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!
                        if (shallowLoc.getLocSts().equals("P") || shallowLoc.getLocSts().equals("R")) {
                            News.warnNoLog(""+mark+" - 2"+" - 7"+" - // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!库位状态={}",shallowLoc.getLocSts());
                            WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                            if (null == waitWrkMast) {
                                News.error("{}库位异常,未检索到相应工作档!", shallowLocNo);
                            } else {
                                if (waitWrkMast.getWrkSts() == 11) {
                                    waitWrkMast.setIoPri(15D);
                                    waitWrkMast.setModiTime(new Date());
                                    if (wrkMastMapper.updateById(waitWrkMast) == 0) {
                                        News.error(""+mark+" - 2"+" - 8"+" - 调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo());
                                    }
                                    continue;
                        if (shallowLoc != null) {
                            // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!
                            if (shallowLoc.getLocSts().equals("P") || shallowLoc.getLocSts().equals("R")) {
                                News.warnNoLog(""+mark+" - 2"+" - 7"+" - // O.空库位、Q.拣料/盘点/并板再入库、S.入库预约、X.禁用 直接搬!库位状态={}",shallowLoc.getLocSts());
                                WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                                if (null == waitWrkMast) {
                                    News.error("{}库位异常,未检索到相应工作档!", shallowLocNo);
                                } else {
                                    if (waitWrkMast.getWrkSts() == 11) {
                                        waitWrkMast.setIoPri(15D);
                                        waitWrkMast.setModiTime(new Date());
                                        if (wrkMastMapper.updateById(waitWrkMast) == 0) {
                                            News.error(""+mark+" - 2"+" - 8"+" - 调整工作档优先级失败!工作号={}", waitWrkMast.getWrkNo());
                                        }
                                        continue;
                                    } else {
                                    }
                                }
                            }
                        } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) {
                            News.warnNoLog(""+mark+" - 2"+" - 9"+" - // F、D  库位状态={}",shallowLoc.getLocSts());
                            } else if (shallowLoc.getLocSts().equals("F") || shallowLoc.getLocSts().equals("D")) {
                                News.warnNoLog(""+mark+" - 2"+" - 9"+" - // F、D  库位状态={}",shallowLoc.getLocSts());
//                            WrkMast waitWrkMast = wrkMastMapper.selectByLocNo(shallowLocNo);
                            //2022-08-16 modify,不根据updmk标记移库任务(容易被取消导致堵塞),查询工作档是否存在任务
                            WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
                            // 此标记避免多次执行移库任务
                                //2022-08-16 modify,不根据updmk标记移库任务(容易被取消导致堵塞),查询工作档是否存在任务
                                WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
                                // 此标记避免多次执行移库任务
//                            if (Cools.isEmpty(wrkMast.getUpdMk()) || "N".equals(wrkMast.getUpdMk())
//                                || Cools.isEmpty(waitWrkMast)) {
                            if (Cools.isEmpty(waitWrkMast)) {
                                wrkMast.setUpdMk("Y");
                                wrkMastMapper.updateById(wrkMast);
                                // 生成工作档,将浅库位移转到新的库位中
                                moveLocForDeepLoc(slave, shallowLoc,mark);
                            }
                            News.error("{}任务出库失败,浅库位堵塞!浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo);
                            break;
                        } else if (shallowLoc.getLocSts().equals("Q") || shallowLoc.getLocSts().equals("S")) {
                            News.warnNoLog(""+mark+" - 2"+" - 10"+" - // Q、S  库位状态={}",shallowLoc.getLocSts());
                            WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
                            if (null != waitWrkMast && waitWrkMast.getWrkSts() == 4) {
                                News.infoNoLog(""+mark+" - 2"+" - 11"+" - // F、D  工作状态(判断条件为==4)={}",waitWrkMast.getWrkSts());
                                continue;
                                if (Cools.isEmpty(waitWrkMast)) {
                                    wrkMast.setUpdMk("Y");
                                    wrkMastMapper.updateById(wrkMast);
                                    // 生成工作档,将浅库位移转到新的库位中
                                    moveLocForDeepLoc(slave, shallowLoc,mark);
                                }
                                News.error("{}任务出库失败,浅库位堵塞!浅库位号:{}", wrkMast.getWrkNo(), shallowLocNo);
                                break;
                            } else if (shallowLoc.getLocSts().equals("Q") || shallowLoc.getLocSts().equals("S")) {
                                News.warnNoLog(""+mark+" - 2"+" - 10"+" - // Q、S  库位状态={}",shallowLoc.getLocSts());
                                WrkMast waitWrkMast = wrkMastMapper.selectByLocNo1(shallowLocNo);
                                if (null != waitWrkMast && waitWrkMast.getWrkSts() == 4) {
                                    News.infoNoLog(""+mark+" - 2"+" - 11"+" - // F、D  工作状态(判断条件为==4)={}",waitWrkMast.getWrkSts());
                                    continue;
                                }
                            }
                        }
                    }
@@ -751,7 +769,8 @@
                    crnCommand.setDestinationPosX(crnStn.getRow().shortValue());     // 目标库位排
                    crnCommand.setDestinationPosY(crnStn.getBay().shortValue());     // 目标库位列
                    crnCommand.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                    crnCommand.setTraySize(sourceSta.getLocType1() == 2);     //库位类型
                    crnCommand.setCommand((short)1);     // 任务确认
//                    crnCommand.setTraySize(sourceSta.getLocType1() == 2);     //库位类型
                    if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                        News.error(""+mark+" - 2"+" - 13"+" - 堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
                    } else {
@@ -797,7 +816,7 @@
            News.error(""+mark+" - 3"+" - 2"+" - 工作档库位移转失败,原因:检索目标库位失败!工作号={},源库位={}", wrkMast.getWrkNo(), wrkMast.getLocNo());
            return;
        }
        if(sta.getLocType1() != sourceSta.getLocType1()){
        if(!Objects.equals(sta.getLocType1(), sourceSta.getLocType1())){
            News.error("移库目标库位类型与源库位类型不符");
            return;
        }
@@ -825,7 +844,7 @@
        CrnCommand crnCommand = new CrnCommand();
        crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
        crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号
        crnCommand.setAckFinish((short) 0);  // 任务完成确认位
//        crnCommand.setAckFinish((short) 0);  // 任务完成确认位
        crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
        crnCommand.setSourcePosX(sourceSta.getRow1().shortValue());     // 源库位排
        crnCommand.setSourcePosY(sourceSta.getBay1().shortValue());     // 源库位列
@@ -833,7 +852,8 @@
        crnCommand.setDestinationPosX(sta.getRow1().shortValue());     // 目标库位排
        crnCommand.setDestinationPosY(sta.getBay1().shortValue());     // 目标库位列
        crnCommand.setDestinationPosZ(sta.getLev1().shortValue());     // 目标库位层
        crnCommand.setTraySize(sourceSta.getLocType1() == 2);     //库位类型
        crnCommand.setCommand((short)1);     // 任务确认
//        crnCommand.setTraySize(sourceSta.getLocType1() == 2);     //库位类型
        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
            News.error(""+mark+" - 3"+" - 4"+" - 堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
        } else {
@@ -863,11 +883,12 @@
                continue;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
            if (crnProtocol.getMode().intValue() == CrnModeType.AUTO.id && crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
                News.warnNoLog(""+mark+" - 0"+" - 开始执行对工作档的完成操作");
                if (crnProtocol.getTaskNo() == 9999) {
                    // 堆垛机复位
                    crnThread.setResetFlag(true);
                    if (!MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(3, null))) {
                        News.error(crn.getId() + "堆垛机回原点任务,下发复位命令失败");
                    }
                } else {
                    // 获取入库待确认工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNo().intValue());
@@ -887,8 +908,11 @@
                    // 修改成功后复位堆垛机
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        // 堆垛机复位
                        News.warnNoLog(""+mark+" - 2"+" - 修改成功后复位堆垛机 : 堆垛机号={}",crnThread.getCrnProtocol().getCrnNo());
                        crnThread.setResetFlag(true);
                        if (!MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(3, null))) {
                            News.error(crn.getId() + "入库完成,下发复位命令失败");
                        } else {
                            News.warnNoLog(""+mark+" - 2"+" - 入库完成复位堆垛机 : 堆垛机号={}",crnThread.getCrnProtocol().getCrnNo());
                        }
                    }
                }
@@ -973,7 +997,7 @@
                            String errName = crnError == null ? String.valueOf(crnProtocol.getAlarm()) : crnError.getErrName();
                            BasErrLog basErrLog = new BasErrLog(
                                    null,    // 编号
                                    null,    // 工作号
                                    crnProtocol.getTaskNo().intValue(),    // 工作号
                                    now,    // 发生时间
                                    null,    // 结束时间
                                    null,    // 工作状态
@@ -1047,7 +1071,7 @@
                        && staProtocol.isInEnable()
                        && staProtocol.isEmptyMk()
                        && staProtocol.isPakMk()
                        && (staProtocol.getWorkNo() !=0 && staProtocol.getWorkNo() > 9700)
                        && staProtocol.getWorkNo() == 9998 // 9997 回退 9998 空 9999 满
                        ) {
                    News.warnNoLog(""+mark+" - 0"+" - 开始执行:空栈板初始化入库,叉车入库站放货");
@@ -1070,7 +1094,7 @@
                            // 更新站点信息 且 下发plc命令
                            staProtocol.setWorkNo(dto.getWorkNo());
                            staProtocol.setStaNo(staProtocol.getSiteId().shortValue());
                            staProtocol.setStaNo(dto.getStaNo().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            log.error("输送线下发6:"+dto.getWorkNo()+","+staProtocol.getSiteId());
@@ -1094,7 +1118,7 @@
//                                ledThread.errorReset();
                            }
                        } else {
                            staProtocol.setWorkNo(wrkNo++);
                            staProtocol.setWorkNo(wrkNo);
                            staProtocol.setStaNo(emptyInSta.getBackSta().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
@@ -1179,7 +1203,7 @@
                                        "任务中异常"    // 备注
                                );
                                if (!basDevpErrLogService.insert(basErrLog)) {
                                    log.error("输送线异常信息插入表asr_bas_devp_err_log异常:{}", basErrLog);
                                    News.error("输送线异常信息插入表asr_bas_devp_err_log异常:{}", basErrLog);
                                }
                            }
                        } else {
@@ -1189,7 +1213,7 @@
                                latestByTaskNo.setUpdateTime(now);
                                latestByTaskNo.setStatus(2);
                                if (!basDevpErrLogService.updateById(latestByTaskNo)) {
                                    log.error("输送线异常记录修复失败asr_bas_devp_err_log异常:{}", latestByTaskNo);
                                    News.error("输送线异常记录修复失败asr_bas_devp_err_log异常:{}", latestByTaskNo);
                                }
                            }
                        }
@@ -1202,7 +1226,7 @@
                            if (latest == null || !latest.getError().equals(plcErr) || latest.getStatus() == 2 ) {
                                BasDevpErrLog basErrLog = new BasDevpErrLog(
                                        null,    // 编号
                                        null,    // 工作号
                                        staProtocol.getWorkNo(),    // 工作号
                                        now,    // 发生时间
                                        null,    // 结束时间
                                        null,    // 工作状态
@@ -1224,7 +1248,7 @@
                                        "无任务异常"    // 备注
                                );
                                if (!basDevpErrLogService.insert(basErrLog)) {
                                    log.error("输送线异常记录asr_bas_devp_err_log异常:{}", basErrLog);
                                    News.error("输送线异常记录asr_bas_devp_err_log异常:{}", basErrLog);
                                }
                            }
                            // 无异常
@@ -1235,7 +1259,7 @@
                                latest.setUpdateTime(now);
                                latest.setStatus(2);
                                if (!basDevpErrLogService.updateById(latest)) {
                                    log.error("输送线异常记录修复失败asr_bas_devp_err_log异常:{}", latest);
                                    News.error("输送线异常记录修复失败asr_bas_devp_err_log异常:{}", latest);
                                }
                            }
                        }
@@ -1296,7 +1320,7 @@
    /**
     * 出库  ===>> 工作档信息写入led显示器
     */
    public synchronized void ledExecute(Integer mark) {
    public synchronized void ledExecute() {
        for (LedSlave led : slaveProperties.getLed()) {
            // 获取输送线plc线程
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, led.getDevpPlcId());
@@ -1348,32 +1372,16 @@
                        News.error("任务入出库类型错误!!![工作号:{}] [入出库类型:{}]", wrkMast.getWrkNo(), wrkMast.getIoType());
                        break;
                }
                ledCommand.setLocNo(wrkMast.getLocNo());
                ledCommand.setSourceLocNo(wrkMast.getSourceLocNo());
                ledCommand.setStaNo(wrkMast.getStaNo());
                ledCommand.setBarcode(wrkMast.getBarcode());
                if (wrkMast.getIoType() != 110 && wrkMast.getIoType() != 10) {
                    List<WrkDetl> wrkDetls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo()));
//                    List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo());
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getSpecs(),wrkDetl.getManuDate(),wrkDetl.getModel(),wrkDetl.getWeight(),wrkDetl.getLength(),wrkDetl.getVolume())));
//                    wrkDetls.forEach(wrkDetl -> {
//                        Double total = 0.0;
//                        EntityWrapper<LocDetl> wrapper = new EntityWrapper<>();
//                        LocDetl locDetl = locDetlService.selectOne(wrapper.eq("zpallet", wrkDetl.getZpallet()).eq("matnr", wrkDetl.getMatnr()));
//                        if (Cools.isEmpty(locDetl)) {
//                            total = wrkDetl.getAnfme();
//                        } else {
//                            total = locDetl.getAnfme();
//                        }
//                        if (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 1) {
//                            ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getBatch(), wrkDetl.getSpecs(), wrkDetl.getManu(), wrkDetl.getMemo(), wrkDetl.getAnfme(),total));
//                        }
//                        if (wrkMast.getIoType() == 103 && (null == wrkDetl.getInspect() || 0 == wrkDetl.getInspect())) {
//                            ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getBatch(), wrkDetl.getSpecs(), wrkDetl.getManu(), wrkDetl.getMemo(), wrkDetl.getAnfme(),total));
//                        }
//                        if (wrkMast.getIoType() == 107) {
//                            ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getBatch(), wrkDetl.getSpecs(), wrkDetl.getManu(), wrkDetl.getMemo(), wrkDetl.getAnfme(),total));
//                        }
//                    });
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl.getOrderNo(),wrkDetl.getMatnr(),wrkDetl.getMaktx(),
                            wrkDetl.getBatch(), wrkDetl.getSpecs(),wrkDetl.getManuDate(),wrkDetl.getModel(),wrkDetl.getAnfme())));
                } else {
                    ledCommand.getMatDtos().add(new MatDto("","","","","","","",1.0));
                }
                commands.add(ledCommand);
            }
@@ -1440,7 +1448,7 @@
                }
                ledThread.errorReset();
                if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(2, new ArrayList<>()))) {
                    News.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort());
                    News.error("显示默认内容{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort());
                }
            }
        }
@@ -1477,7 +1485,7 @@
            if (null == loc) {
                for (Integer row : rows) {
                    if (Utils.isShallowLoc(slaveProperties, row)) {
                        loc = locMastService.queryFreeLocMast(row, shallowLoc.getLocType2());
                        loc = locMastService.queryFreeLocMast(row, shallowLoc.getLocType1());
                        if (null != loc) {//对应深库位非在库状态,不能移库
                            String deepLoc = Utils.getDeepLoc(slaveProperties, loc.getLocNo());
@@ -1598,7 +1606,10 @@
     * 堆垛机回原点
     */
    public synchronized void originGo() throws InterruptedException {
        Config config = configService.selectOne(new EntityWrapper<Config>().eq("code", "crnAutoHome").eq("status", 1));
        if (config == null || Cools.isEmpty(config.getValue()) || !config.getValue().equals("Y")) {
            return;
        }
        for (CrnSlave crn : slaveProperties.getCrn()) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
@@ -1609,7 +1620,7 @@
            if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO
                    && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0) {
                // 判断是不是已在原点
                if(crnProtocol.getBay() == 0 && crnProtocol.getLevel() == 1) {
                if(crnProtocol.getBay() == 1 && crnProtocol.getLevel() == 1) {
                    continue;
                }
                // 判断是不是空闲三分钟
@@ -1623,7 +1634,7 @@
                if(diffInMillis < 10 * 1000) { // 空闲小于10秒则跳过
                    continue;
                } else {  // 有入库任务或大于2分钟,回原点
                    int count = wrkMastService.selectCount(new EntityWrapper<WrkMast>().eq("io_type", 1).eq("crn_no", crn.getId()).in("wrk_sts", 2, 9, 10));
                    int count = wrkMastService.selectCount(new EntityWrapper<WrkMast>().eq("io_type", 1).eq("crn_no", crn.getId()).in("wrk_sts", 2));
                    if(count == 0 && diffInMillis < 2 * 60 * 1000) {
                        continue;
                    }
@@ -1638,13 +1649,15 @@
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setCrnNo(crn.getId()); // 堆垛机编号
                crnCommand.setTaskNo((short) 9999); // 工作号
                crnCommand.setAckFinish((short)0);
                crnCommand.setTaskMode(CrnTaskModeType.GO_ORIGIN); // 任务模式:  回原点
                crnCommand.setSourcePosX((short) (crn.getId() == 1 ? 4 : crn.getId() == 2 ? 6 : crn.getId() == 3 ? 7 : 11));     // 源库位排
                crnCommand.setSourcePosX((short) 0);     // 源库位排
                crnCommand.setSourcePosY((short) 0);     // 源库位列
                crnCommand.setSourcePosZ((short) 1);     // 源库位层
                crnCommand.setSourcePosZ((short) 0);     // 源库位层
                crnCommand.setDestinationPosX((short) 0);     // 目标库位排
                crnCommand.setDestinationPosY((short) 0);     // 目标库位列
                crnCommand.setDestinationPosZ((short) 0);     // 目标库位层
                crnCommand.setCommand((short)1);
                if (!MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(2, crnCommand))) {
                    News.error("回原点任务下发失败", crn.getId(), JSON.toJSON(crnCommand));
                } else {
@@ -1657,4 +1670,82 @@
        }
    }
    public static final HashMap<Integer,Integer> wrkStaNoToRgvStaMap = new HashMap<>();
    static {
        wrkStaNoToRgvStaMap.put(1101,1114);
        wrkStaNoToRgvStaMap.put(1201,1203);
        wrkStaNoToRgvStaMap.put(1206,1203);
        wrkStaNoToRgvStaMap.put(1301,1303);
        wrkStaNoToRgvStaMap.put(1306,1303);
        wrkStaNoToRgvStaMap.put(1408,1413);
    }
    public static final HashMap<Integer,Integer> wrkSourceStaNoToRgvStaMap = new HashMap<>();
    static {
        wrkSourceStaNoToRgvStaMap.put(1112,1114);
        wrkSourceStaNoToRgvStaMap.put(1109,1114);
        wrkSourceStaNoToRgvStaMap.put(1209,1213);
        wrkSourceStaNoToRgvStaMap.put(1309,1313);
        wrkSourceStaNoToRgvStaMap.put(1402,1403);
        wrkSourceStaNoToRgvStaMap.put(1407,1403);
    }
    public synchronized void rgvCarry() {
        for(int i = 1; i <= 4; i ++) {
            List<Integer> rgvCarrySiteList;
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, i);
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                continue;
            }
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, i);
            if(rgvProtocol.modeType == RgvModeType.AUTO && rgvProtocol.statusType == RgvStatusType.IDLE && rgvProtocol.loaded1 == 0
            && rgvProtocol.alarm == 0 && rgvProtocol.getTaskNo1() == 0) {
                switch (i) {
                    case 1: rgvCarrySiteList = Arrays.asList(1114,1118,1120); break;
                    case 2: rgvCarrySiteList = Arrays.asList(1213,1216,1218,1220); break;
                    case 3: rgvCarrySiteList = Arrays.asList(1313,1316,1318,1320); break;
                    case 4: rgvCarrySiteList = Arrays.asList(1403,1418,1420); break;
                    default:
                        return;
                }
                List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>().ne("wrk_no", 0).in("dev_no", rgvCarrySiteList));
                if(!basDevps.isEmpty()) {
                    List<Integer> wrkNos = basDevps.stream().map(BasDevp::getWrkNo).distinct().collect(Collectors.toList());
                    List<WrkMast> wrkMastList = wrkMastService.selectList(new EntityWrapper<WrkMast>().in("wrk_no", wrkNos)
                            .last("ORDER BY CASE WHEN crn_end_time IS NULL THEN 0 ELSE 1 END,crn_end_time ASC"));
                    Optional<WrkMast> first = wrkMastList.stream().filter(wrkMast -> wrkMast.getWhsType() == 1).findFirst();
                    if(first.isPresent()) {
                        log.warn("有任务处在{}号小车搬运中,任务号{}",i,first.get().getWrkNo());
                        continue;
                    }
                    for(WrkMast wrkMast:wrkMastList) {
                        // 判断目标站点是否可用
                        StaProtocol staProtocol = devpThread.getStation().get(wrkStaNoToRgvStaMap.get(wrkMast.getStaNo()) == null ?
                                wrkMast.getStaNo() : wrkStaNoToRgvStaMap.get(wrkMast.getStaNo()));
                        if (staProtocol != null && staProtocol.isAutoing() && !staProtocol.isLoading() && staProtocol.getWorkNo() == 0) {
                            RgvCommand rgvCommand = new RgvCommand();
                            rgvCommand.setRgvNo(rgvProtocol.getRgvNo());
//                            rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                            rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue());
                            rgvCommand.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 工位1任务模式:  取放货
                            Integer sourcesStaNo = wrkSourceStaNoToRgvStaMap.get(wrkMast.getSourceStaNo());
                            rgvCommand.setSourceStaNo1(sourcesStaNo == null ? wrkMast.getSourceStaNo().shortValue() : sourcesStaNo.shortValue());   //工位1起点
                            rgvCommand.setDestinationStaNo1(wrkMast.getStaNo().shortValue());   //工位1目标站点
                            rgvCommand.setCommand((short) 1);   //工位1任务确认
                            if (!MessageQueue.offer(SlaveType.Rgv, rgvProtocol.getRgvNo(), new Task(2, rgvCommand))) {
                                log.error("RGV命令下发失败,RGV号={},任务数据={}", rgvProtocol.getRgvNo(), JSON.toJSON(rgvCommand));
                                break;
                            }
                            wrkMast.setWhsType(1);
                            wrkMastService.updateById(wrkMast);
                            break;
                        }
                    }
                }
            }
        }
    }
}