自动化立体仓库 - WCS系统
#
lsh
2024-06-07 dd847919b364920268ede17bb1034e8c09d57040
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -104,9 +104,12 @@
    private RgvOneSignMapper rgvOneSignMapper;
    @Autowired
    private WrkMastCrnMapper wrkMastCrnMapper;
    @Autowired
    private WrkMastSplitTwinMapper wrkMastSplitTwinMapper;
    @Value("${wms.url}")
    private String wmsUrl;
    private WrkMastSplitTwinServiceImpl wrkMastSplitTwinService;
    /**
     * 组托
@@ -1229,131 +1232,255 @@
        for (CrnSlave crnSlave : slaveProperties.getCrn()) {
            // 遍历堆垛机出库站
            for (CrnSlave.CrnStn crnStn : crnSlave.getCrnOutStn()) {
                // 获取堆垛机出库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
                StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                switch (crnSlave.getId()){
                    case 1:
                    case 2:
                        crnStnToOutStnOne(crnStn);
                        continue;
                    case 3:
                    case 4:
                    case 5:
                        crnStnToOutStnTwo(crnStn,1);
                        continue;
                    case 6:
                    case 7:
                        crnStnToOutStnThree(crnStn);
                        continue;
                    default:
                        break;
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                    // 查询工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
                    if (wrkMast == null) {
                        continue;
            }
        }
    }
    /**
     * 堆垛机站出库到出库站
     */
    public synchronized boolean crnStnToOutStnOne(CrnSlave.CrnStn crnStn ) {
        try{
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                return false;
            } else {
                staProtocol = staProtocol.clone();
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                // 查询工作档
                WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
                if (wrkMast == null) {
                    return false;
                }
                // 判断工作档条件
                if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) {
                    return false;
                }
                // 判断吊车是否实际已完成,且电脑状态在move中,以备电脑进行更新工作档
                CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, wrkMast.getCrnNo());
                CrnProtocol crnProtocol = crnThread.getCrnProtocol();
                if (crnProtocol.statusType == CrnStatusType.FETCHING || crnProtocol.statusType == CrnStatusType.PUTTING) {
                    // 移动中
                    return false;
                }
                WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(crnProtocol.getTaskNo().intValue());
                if (!Cools.isEmpty(wrkMastCrn) && wrkMastCrn.getWrkSts().equals(12L)){
                    wrkMast = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNo().intValue());
                } else {
                    return false;
                }
                //  判断堆垛机状态等待确认
                if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue())
                        && crnProtocol.statusType == CrnStatusType.WAITING
                        && crnProtocol.forkPosType == CrnForkPosType.HOME) {
                    // 命令下发区 --------------------------------------------------------------------------
                    StaProtocol staProtocolOther = devpThread.getStation().get(crnStn.getStaNoOther());
                    if (staProtocolOther == null) {
                        return false;
                    } else {
                        staProtocolOther = staProtocolOther.clone();
                    }
                    // 判断工作档条件
                    if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) {
                        continue;
                    if (staProtocolOther.isAutoing() && staProtocolOther.isLoading() && (staProtocolOther.getWorkNo() == 0 || staProtocolOther.getStaNo() == null)) {
//                        WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(wrkMast.getWrkNo());
                        WrkMast wrkMastOne = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoOne().intValue());
                        WrkMast wrkMastTwo = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoTwo().intValue());
                        WrkMast wrkMast1 = null;
                        WrkMast wrkMast2 = null;
                        if (Utils.getRow(wrkMastOne.getSourceLocNo()) == wrkMast.getCrnNo()*4){
                            wrkMast1 = wrkMastTwo;
                            wrkMast2 = wrkMastOne;
                        }else {
                            wrkMast2 = wrkMastTwo;
                            wrkMast1 = wrkMastOne;
                        }
                        // 下发站点信息
                        staProtocolOther.setWorkNo(Cools.isEmpty(wrkMast1.getWorkNoOther())? wrkMast1.getWrkNo():wrkMast1.getWorkNoOther());
                        staProtocolOther.setStaNo(wrkMast1.getStaNo());
                        if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocolOther))) {
                            return false;
                        }
                        // 下发站点信息
                        staProtocol.setWorkNo(Cools.isEmpty(wrkMast2.getWorkNoOther())? wrkMast2.getWrkNo():wrkMast2.getWorkNoOther());
//                                    staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                        staProtocol.setStaNo(wrkMast2.getStaNo());
                        if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                            return false;
                        }
                        boolean sign = true;
                        // 更新工作档状态为14失败
                        wrkMastCrn.setWrkSts(14L);
                        if (wrkMastCrnMapper.updateById(wrkMastCrn) != 0) {
                        } else {
                            sign = false;
                            log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                        // 更新工作档状态为14失败
                        wrkMastOne.setWrkSts(14L);
                        wrkMastOne.setCrnEndTime(new Date());
                        if (wrkMastMapper.updateById(wrkMastOne) != 0) {
                        } else {
                            sign = false;
                            log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                        // 更新工作档状态为14失败
                        wrkMastTwo.setWrkSts(14L);
                        wrkMastTwo.setCrnEndTime(new Date());
                        if (wrkMastMapper.updateById(wrkMastTwo) != 0) {
                        } else {
                            sign = false;
                            log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                        if (sign){
                            // 复位堆垛机
                            crnThread.setResetFlag(true);
                            return true;
                        }
                    }
                    // 判断吊车是否实际已完成,且电脑状态在move中,以备电脑进行更新工作档
                    CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, wrkMast.getCrnNo());
                    CrnProtocol crnProtocol = crnThread.getCrnProtocol();
                }
            }
        }catch (Exception e){
            log.error("更新工作档的工作状态为14失败!!! [出库站:{}]", crnStn.getStaNo());
        }
        return false;
    }
    public synchronized boolean crnStnToOutStnTwo(CrnSlave.CrnStn crnStn ,Integer conStation) {
        try{
            Date now = new Date();
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                return false;
            } else {
                staProtocol = staProtocol.clone();
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                // 查询工作档
                WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
                if (wrkMast == null) {
                    return false;
                }
                // 判断工作档条件
                if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) {
                    return false;
                }
                // 判断吊车是否实际已完成,且电脑状态在move中,以备电脑进行更新工作档
                CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, wrkMast.getCrnNo());
                CrnProtocol crnProtocol = crnThread.getCrnProtocol();
                if (conStation==1){
                    if (crnProtocol.statusType == CrnStatusType.FETCHING || crnProtocol.statusType == CrnStatusType.PUTTING) {
                        // 移动中
                        continue;
                    }
                    if (crnProtocol.getCrnNo()<=2){
                        WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(crnProtocol.getTaskNo().intValue());
                        if (!Cools.isEmpty(wrkMastCrn) && wrkMastCrn.getWrkSts().equals(12L)){
                            wrkMast = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNo().intValue());
                        }
                        return false;
                    }
                    //  判断堆垛机状态等待确认
                    if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue())
                            && crnProtocol.statusType == CrnStatusType.WAITING
                            && crnProtocol.forkPosType == CrnForkPosType.HOME) {
                        // 命令下发区 --------------------------------------------------------------------------
                        if (crnProtocol.getCrnNo()<=2){
                            StaProtocol staProtocolOther = devpThread.getStation().get(crnStn.getStaNoOther());
                            if (staProtocolOther == null) {
                                continue;
                            } else {
                                staProtocolOther = staProtocolOther.clone();
                            && crnProtocol.forkPosType == CrnForkPosType.HOME
                            && crnProtocol.getLoaded()==0) {
                        List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinMapper.getWrkMastSplitTwin(wrkMast.getCrnNo(), conStation, null, 2, 3);
                        if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                            log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",wrkMast.getCrnNo(),"存在多笔可执行作业,请删除无效作业!!!",conStation,2,3);
                        }
                        for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                            if (wrkMastSplitTwin.getWrkNo()!=wrkMast.getWrkNo().longValue()){
                                log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={},工作任务号={},执行任务号={}",wrkMast.getCrnNo(),"工作任务与执行任务不匹配",conStation,2,3,wrkMast.getWrkNo(),wrkMastSplitTwin.getWrkNo());
                                return false;
                            }
                            if (staProtocolOther.isAutoing() && staProtocolOther.isLoading() && (staProtocolOther.getWorkNo() == 0 || staProtocolOther.getStaNo() == null)) {
                                WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(wrkMast.getWrkNo());
                                if (Cools.isEmpty(wrkMastCrn)){
                                    continue;
                                }
                                WrkMast wrkMastOne = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoOne().intValue());
                                WrkMast wrkMastTwo = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoTwo().intValue());
                                WrkMast wrkMast1 = null;
                                WrkMast wrkMast2 = null;
                                if (Utils.getRow(wrkMastOne.getSourceLocNo()) == wrkMast.getCrnNo()*4){
                                    wrkMast1 = wrkMastTwo;
                                    wrkMast2 = wrkMastOne;
                                }else {
                                    wrkMast2 = wrkMastTwo;
                                    wrkMast1 = wrkMastOne;
                                }
                                // 下发站点信息
                                staProtocolOther.setWorkNo(Cools.isEmpty(wrkMast1.getWorkNoOther())? wrkMast1.getWrkNo():wrkMast1.getWorkNoOther());
                                staProtocolOther.setStaNo(wrkMast1.getStaNo());
                                if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocolOther))) {
                                    continue;
                                }
                                // 下发站点信息
                                staProtocol.setWorkNo(Cools.isEmpty(wrkMast2.getWorkNoOther())? wrkMast2.getWrkNo():wrkMast2.getWorkNoOther());
//                                    staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                                staProtocol.setStaNo(wrkMast2.getStaNo());
                                if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                    continue;
                                }
                                boolean sign = true;
                                // 更新工作档状态为14失败
                                wrkMastCrn.setWrkSts(14L);
                                if (wrkMastCrnMapper.updateById(wrkMastCrn) != 0) {
                                } else {
                                    sign = false;
                                    log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                                }
                                // 更新工作档状态为14失败
                                wrkMastOne.setWrkSts(14L);
                                wrkMastOne.setCrnEndTime(new Date());
                                if (wrkMastMapper.updateById(wrkMastOne) != 0) {
                                } else {
                                    sign = false;
                                    log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                                }
                                // 更新工作档状态为14失败
                                wrkMastTwo.setWrkSts(14L);
                                wrkMastTwo.setCrnEndTime(new Date());
                                if (wrkMastMapper.updateById(wrkMastTwo) != 0) {
                                } else {
                                    sign = false;
                                    log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                                }
                                if (sign){
                                    // 复位堆垛机
                                    crnThread.setResetFlag(true);
                                }
                            }
                        }else {
                            // 命令下发区 --------------------------------------------------------------------------
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                            if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                continue;
                                return false;
                            }
                            // 更新工作档状态为14失败
                            wrkMast.setWrkSts(14L);
                            wrkMast.setCrnEndTime(new Date());
                            wrkMast.setCrnEndTime(now);
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                // 复位堆垛机
                                crnThread.setResetFlag(true);
                                wrkMastSplitTwin.setWrkSts(wrkMastSplitTwin.getWrkSts()+1);
                                wrkMastSplitTwin.setUpdateTime(now);
                                // 修改成功后复位堆垛机
                                if (wrkMastSplitTwinService.updateById(wrkMastSplitTwin)) {
                                    // 堆垛机复位
                                    crnThread.setResetFlag(true);
                                    return true;
                                }else {
                                    log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",wrkMast.getCrnNo(),"修改执行档案失败",conStation,2,3);
                                }
                            } else {
                                log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                            }
                        }
                    }
                }else if (conStation==2){
                    if (crnProtocol.statusTypeTwo == CrnStatusType.FETCHING || crnProtocol.statusTypeTwo == CrnStatusType.PUTTING) {
                        // 移动中
                        return false;
                    }
                    //  判断堆垛机状态等待确认
                    if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNoTwo().equals(wrkMast.getWrkNo().shortValue())
                            && crnProtocol.statusTypeTwo == CrnStatusType.WAITING
                            && crnProtocol.forkPosTypeTwo == CrnForkPosType.HOME
                            && crnProtocol.getLoadedTwo()==0) {
                        List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinMapper.getWrkMastSplitTwin(wrkMast.getCrnNo(), conStation, null, 2, 3);
                        if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                            log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",wrkMast.getCrnNo(),"存在多笔可执行作业,请删除无效作业!!!",conStation,2,3);
                        }
                        for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                            if (wrkMastSplitTwin.getWrkNo()!=wrkMast.getWrkNo().longValue()){
                                log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={},工作任务号={},执行任务号={}",wrkMast.getCrnNo(),"工作任务与执行任务不匹配",conStation,2,3,wrkMast.getWrkNo(),wrkMastSplitTwin.getWrkNo());
                                return false;
                            }
                            // 命令下发区 --------------------------------------------------------------------------
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                            if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                return false;
                            }
                            // 更新工作档状态为14失败
                            wrkMast.setWrkSts(14L);
                            wrkMast.setCrnEndTime(now);
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                wrkMastSplitTwin.setWrkSts(wrkMastSplitTwin.getWrkSts()+1);
                                wrkMastSplitTwin.setUpdateTime(now);
                                // 修改成功后复位堆垛机
                                if (wrkMastSplitTwinService.updateById(wrkMastSplitTwin)) {
                                    // 堆垛机复位
                                    crnThread.setResetFlagTwo(true);
                                    return true;
                                }else {
                                    log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",wrkMast.getCrnNo(),"修改执行档案失败",conStation,2,3);
                                }
                            } else {
                                log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                            }
@@ -1361,7 +1488,66 @@
                    }
                }
            }
        }catch (Exception e){
            log.error("更新工作档的工作状态为14失败!!! [出库站:{}]", crnStn.getStaNo());
        }
        return false;
    }
    public synchronized boolean crnStnToOutStnThree(CrnSlave.CrnStn crnStn ) {
        try{
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                return false;
            } else {
                staProtocol = staProtocol.clone();
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                // 查询工作档
                WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
                if (wrkMast == null) {
                    return false;
                }
                // 判断工作档条件
                if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) {
                    return false;
                }
                // 判断吊车是否实际已完成,且电脑状态在move中,以备电脑进行更新工作档
                CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, wrkMast.getCrnNo());
                CrnProtocol crnProtocol = crnThread.getCrnProtocol();
                if (crnProtocol.statusType == CrnStatusType.FETCHING || crnProtocol.statusType == CrnStatusType.PUTTING) {
                    // 移动中
                    return false;
                }
                //  判断堆垛机状态等待确认
                if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue())
                        && crnProtocol.statusType == CrnStatusType.WAITING
                        && crnProtocol.forkPosType == CrnForkPosType.HOME) {
                    // 命令下发区 --------------------------------------------------------------------------
                    // 下发站点信息
                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                    staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                    if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                        return false;
                    }
                    // 更新工作档状态为14失败
                    wrkMast.setWrkSts(14L);
                    wrkMast.setCrnEndTime(new Date());
                    if (wrkMastMapper.updateById(wrkMast) != 0) {
                        // 复位堆垛机
                        crnThread.setResetFlag(true);
                        return true;
                    } else {
                        log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                    }
                }
            }
        }catch (Exception e){
            log.error("更新工作档的工作状态为14失败!!! [出库站:{}]", crnStn.getStaNo());
        }
        return false;
    }
    /**
@@ -1371,55 +1557,14 @@
        for (CrnSlave crnSlave : slaveProperties.getCrn()) {
            // 遍历堆垛机出库站
            for (CrnSlave.CrnStn crnStn : crnSlave.getCrnOutStn()) {
                // 获取堆垛机出库站信息
                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() == null)) {
                    // 查询工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
                    if (wrkMast == null) {
                switch (crnSlave.getId()){
                    case 3:
                    case 4:
                    case 5:
                        crnStnToOutStnTwo(crnStn,2);
                        continue;
                    }
                    // 判断工作档条件
                    if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null) {
                        continue;
                    }
                    // 判断吊车是否实际已完成,且电脑状态在move中,以备电脑进行更新工作档
                    CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, wrkMast.getCrnNo());
                    CrnProtocol crnProtocol = crnThread.getCrnProtocol();
                    if (crnProtocol.statusTypeTwo == CrnStatusType.FETCHING || crnProtocol.statusTypeTwo == CrnStatusType.PUTTING) {
                        // 移动中
                        continue;
                    }
                    //  判断堆垛机状态等待确认
                    if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNoTwo().equals(wrkMast.getWrkNo().shortValue())
                            && crnProtocol.statusTypeTwo == CrnStatusType.WAITING
                            && crnProtocol.forkPosTypeTwo == CrnForkPosType.HOME) {
                        // 命令下发区 --------------------------------------------------------------------------
                        // 下发站点信息
                        staProtocol.setWorkNo(wrkMast.getWrkNo());
                        staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                        if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                            continue;
                        }
                        // 更新工作档状态为14失败
                        wrkMast.setWrkSts(14L);
                        wrkMast.setCrnEndTime(new Date());
                        if (wrkMastMapper.updateById(wrkMast) != 0) {
                            // 复位堆垛机
                            crnThread.setResetFlagTwo(true);
                        } else {
                            log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                    }
                    default:
                        break;
                }
            }
        }
@@ -1971,6 +2116,12 @@
                continue;
            }
            // 已经存在吊车执行任务时,则过滤
            if (wrkMastSplitTwinMapper.selectCount(new EntityWrapper<WrkMastSplitTwin>().eq("wrk_no", wrkMast.getWrkNo().longValue())) != 0) {
                break;
//                        return;
            }
            // 双深库位且浅库位有货,则需先对浅库位进行库位移转
            if (Utils.isDeepLoc(slaveProperties, wrkMast.getLocNo())) {
                String shallowLocNo = Utils.getShallowLoc(slaveProperties, wrkMast.getLocNo());
@@ -2029,9 +2180,27 @@
                wrkMast.setWrkSts(3L);
                wrkMast.setCrnStrTime(now);
                wrkMast.setModiTime(now);
                WrkMastSplitTwin wrkMastSplitTwin = new WrkMastSplitTwin(wrkMast,crnStation,now);
                wrkMastSplitTwin.setWrkSts(1);
                wrkMastSplitTwin.setWrkStart(wrkMast.getStaNo().toString());
                wrkMastSplitTwin.setWrkEnd(wrkMast.getLocNo());
                wrkMastSplitTwin.setStartRow(crnStn.getRow());
                wrkMastSplitTwin.setStartBay(crnStn.getBay());
                wrkMastSplitTwin.setStartLev(crnStn.getLev());
                wrkMastSplitTwin.setEndRow(locMast.getRow1());
                wrkMastSplitTwin.setEndBay(locMast.getBay1());
                wrkMastSplitTwin.setEndLev(locMast.getLev1());
                wrkMastSplitTwin.setWrkType(1);
                wrkMastSplitTwin.setIoType(1);
                if (wrkMastMapper.updateById(wrkMast) == 0) {
                    log.error("修改工作档状态 2.设备上走 => 3.吊车入库中 失败!!,工作号={}", wrkMast.getWrkNo());
                }
                if (wrkMastSplitTwinMapper.insert(wrkMastSplitTwin)==0){
                    log.error("创建 堆垛机执行任务 失败!!,工作号={},堆垛机号={}", wrkMast.getWrkNo(),wrkMast.getCrnNo());
                }
                break;
            }
        }
    }
@@ -2083,6 +2252,10 @@
            if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo().equals(wrkMast.getWrkNo())
                    && staProtocol.isInEnable() && staDetl.getCanining() != null && staDetl.getCanining().equals("Y")) {
                flag = true;
            }
            if (staProtocol.getWorkNo().equals(staProtocolOther.getWorkNo())){
                continue;
            }
            // 查询站点详细信息
@@ -2893,6 +3066,12 @@
//                        return;
                }
                // 已经存在吊车执行任务时,则过滤
                if (wrkMastSplitTwinMapper.selectCount(new EntityWrapper<WrkMastSplitTwin>().eq("wrk_no", wrkMast.getWrkNo().longValue())) != 0) {
                    break;
//                        return;
                }
                // 1.堆垛机开始移动
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
@@ -2902,9 +3081,9 @@
                crnCommand.setSourcePosX(sourceSta.getRow1().shortValue());     // 源库位排
                crnCommand.setSourcePosY(sourceSta.getBay1().shortValue());     // 源库位列
                crnCommand.setSourcePosZ(sourceSta.getLev1().shortValue());     // 源库位层
                crnCommand.setDestinationPosX(crnStn.getRow().shortValue());     // 目标库位排
                crnCommand.setDestinationPosY(crnStn.getBay().shortValue());     // 目标库位列
                crnCommand.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                crnCommand.setDestinationPosX((short)0);     // 目标库位排
                crnCommand.setDestinationPosY((short)0);     // 目标库位列
                crnCommand.setDestinationPosZ((short)0);     // 目标库位层
                if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(crnStation==1? 2:5, crnCommand))) {
                    log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
                } else {
@@ -2913,8 +3092,24 @@
                    wrkMast.setWrkSts(12L);
                    wrkMast.setCrnStrTime(now);
                    wrkMast.setModiTime(now);
                    WrkMastSplitTwin wrkMastSplitTwin = new WrkMastSplitTwin(wrkMast,crnStation,now);
                    wrkMastSplitTwin.setWrkSts(1);
                    wrkMastSplitTwin.setWrkStart(wrkMast.getSourceLocNo());
                    wrkMastSplitTwin.setWrkEnd(wrkMast.getSourceStaNo().toString());
                    wrkMastSplitTwin.setStartRow(sourceSta.getRow1());
                    wrkMastSplitTwin.setStartBay(sourceSta.getBay1());
                    wrkMastSplitTwin.setStartLev(sourceSta.getLev1());
                    wrkMastSplitTwin.setEndRow(crnStn.getRow());
                    wrkMastSplitTwin.setEndBay(crnStn.getBay());
                    wrkMastSplitTwin.setEndLev(crnStn.getLev());
                    wrkMastSplitTwin.setWrkType(1);
                    wrkMastSplitTwin.setIoType(2);
                    if (wrkMastMapper.updateById(wrkMast) == 0) {
                        log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo());
                    }
                    if (wrkMastSplitTwinMapper.insert(wrkMastSplitTwin)==0){
                        log.error("创建 堆垛机执行任务 失败!!,工作号={},堆垛机号={}", wrkMast.getWrkNo(),wrkMast.getCrnNo());
                    }
                    break;
                }
@@ -3136,44 +3331,69 @@
    /**
     * 执行对工作档的完成操作
     */
    public synchronized void storeFinished() {
        for (CrnSlave crn : slaveProperties.getCrn()) {
            switch (crn.getId()){
                case 1:
                case 2:
                    storeFinishedExecuteOne(crn);
                    continue;
                case 3:
                case 4:
                case 5:
                    storeFinishedExecuteTwo(crn);
                    continue;
                case 6:
                case 7:
                    storeFinishedExecuteThree(crn);
                    continue;
                default:
                    continue;
            }
        }
    }
    public synchronized boolean storeFinishedExecuteOne(CrnSlave crn) {
        try{
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                continue;
                return false;
            }
            if (crnProtocol.modeType != CrnModeType.AUTO){
                return false;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
                if (crnProtocol.getTaskNo() == 32222) {
                    // 堆垛机复位
                    crnThread.setResetFlag(true);
                } else if (crnProtocol.getCrnNo()<3) {
                } else {
                    // 获取入库待确认工作档
                    WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(crnProtocol.getTaskNo().intValue());
                    if (wrkMastCrn == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                        return false;
                    }
                    // 获取入库待确认工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNo().intValue());
                    if (wrkMast == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                        return false;
                    }
                    // 获取入库待确认工作档
                    WrkMast wrkMastOther = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoTwo().intValue());
                    if (wrkMastOther == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                        return false;
                    }
                    // 入库 + 库位转移  ==> 4.入库完成
                    if (wrkMastCrn.getWrkSts() == 3 || (wrkMastCrn.getWrkSts() == 12 && wrkMastCrn.getIoType() == 11)) {
                        wrkMastCrn.setWrkSts(4L);
                    } else {
                        continue;
                        return false;
                    }
                    Date now = new Date();
                    wrkMastCrn.setModiTime(now);
@@ -3189,19 +3409,134 @@
                    if (wrkMastCrnMapper.updateById(wrkMastCrn) > 0 && wrkMastMapper.updateById(wrkMast) > 0 && wrkMastMapper.updateById(wrkMastOther) > 0 ) {
                        // 堆垛机复位
                        crnThread.setResetFlag(true);
                        return true;
                    }
                }
            }
        }catch (Exception e){
            log.error("堆垛机工位一完成等待确认异常,堆垛机号={},异常信息={},工位号={}",crn.getId(),e.getMessage(),1);
        }
        return false;
    }
    public synchronized boolean storeFinishedExecuteTwo(CrnSlave crn) {
        try{
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                return false;
            }
            if (crnProtocol.modeType != CrnModeType.AUTO){
                return false;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
                if (crnProtocol.getTaskNo() == 32222) {
                    // 堆垛机复位
                    crnThread.setResetFlag(true);
                    return true;
                } else {
                    // 获取入库待确认工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNo().intValue());
                    if (wrkMast == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                        return false;
                    }
                    // 入库 + 库位转移  ==> 4.入库完成
                    if (wrkMast.getWrkSts() == 3 || (wrkMast.getWrkSts() == 12 && wrkMast.getIoType() == 11)) {
                        wrkMast.setWrkSts(4L);
                    } else {
                        continue;
                        return false;
                    }
                    Date now = new Date();
                    wrkMast.setCrnEndTime(now);
                    wrkMast.setModiTime(now);
                    // 堆垛机复位
                    List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinMapper.getWrkMastSplitTwin(crn.getId(), 1, null, 2, 3);
                    if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                        log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"存在多笔可执行作业,请删除无效作业!!!",1,2,3);
                    }
                    for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                        if (wrkMastSplitTwin.getWrkNo()!=wrkMast.getWrkNo().longValue()){
                            log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={},工作任务号={},执行任务号={}",crn.getId(),"工作任务与执行任务不匹配",1,2,3,wrkMast.getWrkNo(),wrkMastSplitTwin.getWrkNo());
                            return false;
                        }
                        wrkMastSplitTwin.setWrkSts(wrkMastSplitTwin.getWrkSts()+1);
                        wrkMastSplitTwin.setUpdateTime(now);
                        // 修改成功后复位堆垛机
                        if (wrkMastMapper.updateById(wrkMast) > 0) {
                            // 修改成功后复位堆垛机
                            if (wrkMastSplitTwinService.updateById(wrkMastSplitTwin)) {
                                // 堆垛机复位
                                crnThread.setResetFlag(true);
                                return true;
                            }else {
                                log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"修改执行档案失败",1,2,3);
                            }
                        }else {
                            log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"修改工作档案失败!",1,2,3);
                        }
                    }
                    return false;
                }
            }else if (crnProtocol.statusType == CrnStatusType.SEPARATE_WAITING && crnProtocol.getTaskNo() != 0  && crnProtocol.getLoaded()==1){
                if (crnProtocol.getTaskNo() == 32222) {
                    // 堆垛机复位
                    crnThread.setResetFlag(true);
                    return true;
                } else {
                    List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinMapper.getWrkMastSplitTwin(crn.getId(), 1, null, 1, 1);
                    if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                        log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"存在多笔可执行作业,请删除无效作业!!!",1,1,1);
                    }
                    for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                        Date now = new Date();
                        wrkMastSplitTwin.setWrkSts(wrkMastSplitTwin.getWrkSts()+1);
                        wrkMastSplitTwin.setUpdateTime(now);
                        // 修改成功后复位堆垛机
                        if (wrkMastSplitTwinService.updateById(wrkMastSplitTwin)) {
                            // 堆垛机复位
                            crnThread.setResetFlag(true);
                            return true;
                        }else {
                            log.error("堆垛机放货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"修改执行档案失败",1,2,3);
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("堆垛机工位一完成等待确认异常,堆垛机号={},异常信息={},工位号={}",crn.getId(),e.getMessage(),1);
        }
        return false;
    }
    public synchronized boolean storeFinishedExecuteThree(CrnSlave crn) {
        try{
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                return false;
            }
            if (crnProtocol.modeType != CrnModeType.AUTO){
                return false;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
                if (crnProtocol.getTaskNo() == 32222) {
                    // 堆垛机复位
                    crnThread.setResetFlag(true);
                } else {
                    // 获取入库待确认工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNo().intValue());
                    if (wrkMast == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        return false;
                    }
                    // 入库 + 库位转移  ==> 4.入库完成
                    if (wrkMast.getWrkSts() == 3 || (wrkMast.getWrkSts() == 12 && wrkMast.getIoType() == 11)) {
                        wrkMast.setWrkSts(4L);
                    } else {
                        return false;
                    }
                    Date now = new Date();
                    wrkMast.setCrnEndTime(now);
@@ -3210,25 +3545,43 @@
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        // 堆垛机复位
                        crnThread.setResetFlag(true);
                        return true;
                    }
                }
            }
        }catch (Exception e){
            log.error("堆垛机工位一完成等待确认异常,堆垛机号={},异常信息={},工位号={}",crn.getId(),e.getMessage(),1);
        }
        return false;
    }
    /**
     * 执行对工作档的完成操作
     */
    public synchronized void storeFinishedTwo() {
        for (CrnSlave crn : slaveProperties.getCrn()) {
            if (crn.getId()<3 || crn.getId()>5){
                continue;
            switch (crn.getId()){
                case 3:
                case 4:
                case 5:
                    storeFinishedTwoExecute(crn);
                    continue;
                default:
                    continue;
            }
        }
    }
    public synchronized boolean storeFinishedTwoExecute(CrnSlave crn) {
        try{
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                continue;
                return false;
            }
            if (crnProtocol.modeType != CrnModeType.AUTO){
                return false;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.statusTypeTwo == CrnStatusType.WAITING && crnProtocol.getTaskNoTwo() != 0) {
@@ -3240,26 +3593,73 @@
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNoTwo().intValue());
                    if (wrkMast == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNoTwo());
                        continue;
                        return false;
                    }
                    // 入库 + 库位转移  ==> 4.入库完成
                    if (wrkMast.getWrkSts() == 3 || (wrkMast.getWrkSts() == 12 && wrkMast.getIoType() == 11)) {
                        wrkMast.setWrkSts(4L);
                    } else {
                        continue;
                        return false;
                    }
                    Date now = new Date();
                    wrkMast.setCrnEndTime(now);
                    wrkMast.setModiTime(now);
                    // 修改成功后复位堆垛机
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        // 堆垛机复位
                        crnThread.setResetFlagTwo(true);
                    // 堆垛机复位
                    List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinMapper.getWrkMastSplitTwin(crn.getId(), 2, null, 2, 3);
                    if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                        log.error("堆垛机取货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"存在多笔可执行作业,请删除无效作业!!!",2,2,3);
                    }
                    for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                        if (wrkMastSplitTwin.getWrkNo()!=wrkMast.getWrkNo().longValue()){
                            log.error("堆垛机取货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={},工作任务号={},执行任务号={}",crn.getId(),"工作任务与执行任务不匹配",1,2,3,wrkMast.getWrkNo(),wrkMastSplitTwin.getWrkNo());
                            return false;
                        }
                        wrkMastSplitTwin.setWrkSts(wrkMastSplitTwin.getWrkSts()+1);
                        wrkMastSplitTwin.setUpdateTime(now);
                        // 修改成功后复位堆垛机
                        if (wrkMastMapper.updateById(wrkMast) > 0) {
                            // 修改成功后复位堆垛机
                            if (wrkMastSplitTwinService.updateById(wrkMastSplitTwin)) {
                                // 堆垛机复位
                                crnThread.setResetFlagTwo(true);
                                return true;
                            }else {
                                log.error("堆垛机取货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"修改执行档案失败",2,2,3);
                            }
                        }else {
                            log.error("堆垛机取货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"修改工作档案失败!",2,2,3);
                        }
                    }
                    return false;
                }
            }else if (crnProtocol.statusTypeTwo == CrnStatusType.SEPARATE_WAITING && crnProtocol.getTaskNoTwo() != 0  && crnProtocol.getLoadedTwo()==1){
                if (crnProtocol.getTaskNoTwo() == 32222) {
                    // 堆垛机复位
                    crnThread.setResetFlagTwo(true);
                } else {
                    List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinMapper.getWrkMastSplitTwin(crn.getId(), 2, null, 1, 1);
                    if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                        log.error("堆垛机取货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"存在多笔可执行作业,请删除无效作业!!!",2,1,1);
                    }
                    for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                        Date now = new Date();
                        wrkMastSplitTwin.setWrkSts(wrkMastSplitTwin.getWrkSts()+1);
                        wrkMastSplitTwin.setUpdateTime(now);
                        // 修改成功后复位堆垛机
                        if (wrkMastSplitTwinService.updateById(wrkMastSplitTwin)) {
                            // 堆垛机复位
                            crnThread.setResetFlagTwo(true);
                            return true;
                        }else {
                            log.error("堆垛机取货完成等待确认异常,堆垛机号={},异常信息={},工位号={},工作类型={},工作状态={}",crn.getId(),"修改执行档案失败",2,2,3);
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("堆垛机工位二完成等待确认异常,堆垛机号={},异常信息={},工位号={}",crn.getId(),e.getMessage(),2);
        }
        return false;
    }
    /**
@@ -5832,5 +6232,145 @@
    public synchronized boolean steIoExecute(Integer sign) {
        return false;
    }
    /**
     * 入出库  ===>>  堆垛机入出库作业下发
     */
    public synchronized void crnIoExecuteTwoExecute() {
        for (CrnSlave crn : slaveProperties.getCrn()) {
            try{
                switch (crn.getId()){
                    case 3:
                    case 4:
                    case 5:
                        crnWrkMastSplitTwinExecute(crn);
                        continue;
                    default:
                        continue;
                }
            }catch (Exception e){
                log.error("堆垛机出入库执行任务下发报错,堆垛机号={},异常信息={}",crn.getId(),e.getMessage());
            }
        }
    }
    public synchronized boolean crnWrkMastSplitTwinExecute(CrnSlave crn){
        try{
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                return false;
            }
            BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
            if (basCrnp == null) {
                log.error("{}号堆垛机尚未在数据库进行维护!", crn.getId());
                return false;
            }
            int[] sign = new int[]{0,0};
            // 只有当堆垛机自动时才继续执行
            if (crnProtocol.getModeType() == CrnModeType.AUTO) {
                // 只有当堆垛机工位1取货或者有物 并且 工位2无任务时才继续执行
                if (crnProtocol.getStatusType() == CrnStatusType.IDLE
                        && crnProtocol.getTaskNo() == 0
                        && crnProtocol.getLoaded() == 0
                        && crnProtocol.getForkPos() == 0) {
                    sign[0] = 1;
                    sign[1] = 1;
                } else if (crnProtocol.getStatusTypeTwo() == CrnStatusType.IDLE
                        && crnProtocol.getTaskNoTwo() == 0
                        && crnProtocol.getLoadedTwo() == 0
                        && crnProtocol.getForkPosTwo() == 0){
                    sign[0] = 1;
                    sign[1] = 2;
                } else if (crnProtocol.getStatusType() == CrnStatusType.SEPARATE_IDLE
                        && crnProtocol.getTaskNo() == 0
                        && crnProtocol.getLoaded() == 1
                        && crnProtocol.getForkPos() == 0) {
                    sign[0] = 2;
                    sign[1] = 1;
                } else if (crnProtocol.getStatusTypeTwo() == CrnStatusType.SEPARATE_IDLE
                        && crnProtocol.getTaskNoTwo() == 0
                        && crnProtocol.getLoadedTwo() == 1
                        && crnProtocol.getForkPosTwo() == 0){
                    sign[0] = 2;
                    sign[1] = 2;
                }
            }
            if (sign[0]!=0){
                List<WrkMastSplitTwin> wrkMastSplitTwinList = wrkMastSplitTwinService.getWrkMastSplitTwin(crn.getId(),sign[1],null,sign[0],0);
                if (!wrkMastSplitTwinList.isEmpty() && wrkMastSplitTwinList.size()!=1){
                    log.error("堆垛机出入库下发异常,堆垛机号={},异常信息={},工位号={},工作类型={}",crn.getId(),"存在多笔可执行作业,请删除无效作业!!!",sign[1],sign[0]);
                }
                for (WrkMastSplitTwin wrkMastSplitTwin:wrkMastSplitTwinList){
                    return sign[0] == 1? crnExecuteTakeFull(crn.getId(), wrkMastSplitTwin, sign[1]) : crnExecutePutFull(crn.getId(), wrkMastSplitTwin, sign[1]);
                }
            }
        }catch (Exception e){
            log.error("堆垛机出入库下发报错,堆垛机号={},异常信息={}",crn.getId(),e.getMessage());
        }
        return false;
    }
    /*
     * 堆垛机取货至工位任务
     * */
    public synchronized boolean crnExecuteTakeFull(Integer crnNo,WrkMastSplitTwin wrkMastSplitTwin, Integer crnStation){
        try{
            //  命令下发区 --------------------------------------------------------------------------
            // 1.堆垛机开始移动
            CrnCommand crnCommand = new CrnCommand();
            crnCommand.setCrnNo(crnNo); // 堆垛机编号
            crnCommand.setTaskNo(wrkMastSplitTwin.getWrkNo().shortValue()); // 工作号
            crnCommand.setAckFinish((short) 0);  // 任务完成确认位
            crnCommand.setTaskMode(CrnTaskModeType.SEPARATE_TAKE); // 任务模式:  单取货
            crnCommand.setSourcePosX(wrkMastSplitTwin.getStartRow().shortValue());     // 源库位排
            crnCommand.setSourcePosY(wrkMastSplitTwin.getStartBay().shortValue());     // 源库位列
            crnCommand.setSourcePosZ(wrkMastSplitTwin.getStartLev().shortValue());     // 源库位层
            crnCommand.setDestinationPosX((short)0);     // 目标库位排
            crnCommand.setDestinationPosY((short)0);     // 目标库位列
            crnCommand.setDestinationPosZ((short)0);     // 目标库位层
            if (!MessageQueue.offer(SlaveType.Crn, wrkMastSplitTwin.getCrnNo(), new Task(crnStation==1? 2:5, crnCommand))) {
                log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMastSplitTwin.getCrnNo(), JSON.toJSON(crnCommand));
                return false;
            } else {
                return true;
            }
        }catch (Exception e){
            return false;
        }
    }
    /*
     * 堆垛机放货货至出库站点任务
     * */
    public synchronized boolean crnExecutePutFull(Integer crnNo,WrkMastSplitTwin wrkMastSplitTwin, Integer crnStation){
        try{
            //  命令下发区 --------------------------------------------------------------------------
            // 1.堆垛机开始移动
            CrnCommand crnCommand = new CrnCommand();
            crnCommand.setCrnNo(crnNo); // 堆垛机编号
            crnCommand.setTaskNo(wrkMastSplitTwin.getWrkNo().shortValue()); // 工作号
            crnCommand.setAckFinish((short) 0);  // 任务完成确认位
            crnCommand.setTaskMode(CrnTaskModeType.SEPARATE_PUT); // 任务模式:  单放货
            crnCommand.setSourcePosX((short)0);     // 源库位排
            crnCommand.setSourcePosY((short)0);     // 源库位列
            crnCommand.setSourcePosZ((short)0);     // 源库位层
            crnCommand.setDestinationPosX(wrkMastSplitTwin.getEndRow().shortValue());     // 目标库位排
            crnCommand.setDestinationPosY(wrkMastSplitTwin.getEndBay().shortValue());     // 目标库位列
            crnCommand.setDestinationPosZ(wrkMastSplitTwin.getEndLev().shortValue());     // 目标库位层
            if (!MessageQueue.offer(SlaveType.Crn, wrkMastSplitTwin.getCrnNo(), new Task(crnStation==1? 2:5, crnCommand))) {
                log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMastSplitTwin.getCrnNo(), JSON.toJSON(crnCommand));
                return false;
            } else {
                return true;
            }
        }catch (Exception e){
            return false;
        }
    }
}