自动化立体仓库 - WCS系统
#
LSH
2024-02-27 4895bf508f01967e71a31eea0e33150abc3eef3a
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -47,6 +47,7 @@
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -98,6 +99,10 @@
    private WrkMastStaMapper wrkMastStaMapper;
    @Autowired
    private BasRgvMapMapper basRgvMapMapper;
    @Autowired
    private RgvOneSignMapper rgvOneSignMapper;
    @Autowired
    private WrkMastCrnMapper wrkMastCrnMapper;
    @Value("${wms.url}")
    private String wmsUrl;
@@ -135,6 +140,47 @@
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                // 尺寸检测异常
                boolean back = false;
                String errMsg = "异常:";
                if (staProtocol.isFrontErr()) {
                    errMsg = errMsg+"前超限;";
                    back = true;
                }
                if (staProtocol.isBackErr()) {
                    errMsg = errMsg+"后超限";
                    back = true;
                }
                if (staProtocol.isHighErr()) {
                    errMsg = errMsg+"高超限";
                    back = true;
                }
                if (staProtocol.isLeftErr()) {
                    errMsg = errMsg+"左超限";
                    back = true;
                }
                if (staProtocol.isRightErr()) {
                    errMsg = errMsg+"右超限";
                    back = true;
                }
                if (staProtocol.isWeightErr()) {
                    errMsg = errMsg+"超重";
                    back = true;
                }
                if (staProtocol.isBarcodeErr()) {
                    errMsg = errMsg+"扫码失败";
                    back = true;
                }
                // 退回
                if (back) {
                    // led 异常显示
                    LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                    if (ledThread != null) {
                        MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(5, errMsg));
                    }
                    continue;
                }
                // 入出库模式判断
@@ -196,6 +242,9 @@
                        if (jsonObject.getInteger("code").equals(200)) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                            barcodeThread.setBarcode("");
                            staProtocol.setWorkNo(dto.getWorkNo());
@@ -228,6 +277,399 @@
    }
    /**
     * 组托
     * 入库站,根据条码扫描生成入库工作档,工作状态 2
     */
    public synchronized void generateStoreWrkFileSingle() {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库口
            for (DevpSlave.Sta inSta : devp.getInSingleSta()) {
                // 获取条码扫描仪信息
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, inSta.getBarcode());
                if (barcodeThread == null) {
                    continue;
                }
                String barcode = barcodeThread.getBarcode();
                if (!Cools.isEmpty(barcode)) {
//                    log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode);
                    if ("NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                        continue;
                    }
                } else {
                    continue;
                }
                // 获取入库站信息
//                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                // 尺寸检测异常
                boolean back = false;
                String errMsg = "异常:";
                if (staProtocol.isFrontErr()) {
                    errMsg = errMsg+"前超限;";
                    back = true;
                }
                if (staProtocol.isBackErr()) {
                    errMsg = errMsg+"后超限";
                    back = true;
                }
                if (staProtocol.isHighErr()) {
                    errMsg = errMsg+"高超限";
                    back = true;
                }
                if (staProtocol.isLeftErr()) {
                    errMsg = errMsg+"左超限";
                    back = true;
                }
                if (staProtocol.isRightErr()) {
                    errMsg = errMsg+"右超限";
                    back = true;
                }
                if (staProtocol.isWeightErr()) {
                    errMsg = errMsg+"超重";
                    back = true;
                }
                if (staProtocol.isBarcodeErr()) {
                    errMsg = errMsg+"扫码失败";
                    back = true;
                }
                // 退回
                if (back) {
                    // led 异常显示
                    LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                    if (ledThread != null) {
                        MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(5, errMsg));
                    }
                    continue;
                }
                // 入出库模式判断
//                if ( inSta.getStaNo()==203 && devpThread.ioModeOf2F != IoModeType.PAKIN_MODE) { continue; }
//                if (inSta.getStaNo() == 203 && devpThread.ioModeOf2F == IoModeType.PAKOUT_MODE) {
//                    continue;
//                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && !staProtocol.isEmptyMk()
                        && staProtocol.getWorkNo() == 0
                        && staProtocol.isPakMk()) {// && !Cools.isEmpty(barcode)) {
                    if(Cools.isEmpty(barcode) || "NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                        log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode);
//                        //条码为空或者不符合,退库到172站点
//                        staProtocol.setWorkNo((short)32222);
//                        staProtocol.setStaNo((short)172);
//                        devpThread.setPakMk(staProtocol.getSiteId(), false);
//                        boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                        if (!result) {
//                            throw new CoolException("更新plc站点信息失败");
//                        }
                        continue;
                    }
                    // 判断重复工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep1(inSta.getStaNo(), barcode);
                    if (wrkMast != null) {
                        log.error("工作档中已存在该站状态为( 2.设备上走 )的数据,工作号={}", wrkMast.getWrkNo());
                        continue;
                    }
//                    // 获取入库通知档
//                    List<WaitPakin> waitPakins = waitPakinMapper.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", barcode).eq("io_status", "N"));
//                    if (waitPakins.isEmpty()) {
//                        log.error("无此入库条码数据。条码号={}", barcode);
//                        continue;
//                    }
                    try {
                        LocTypeDto locTypeDto = new LocTypeDto(staProtocol);
                        SearchLocParam param = new SearchLocParam();
                        param.setBarcode(barcode);
                        param.setIoType(1);
                        param.setSourceStaNo(inSta.getStaNo());
                        param.setLocType1(locTypeDto.getLocType1());
                        String response = new HttpHandler.Builder()
                                .setUri(wmsUrl)
                                .setPath("/rpc/pakin/pair/station/single/loc/v1")
                                .setJson(JSON.toJSONString(param))
                                .build()
                                .doPost();
                        JSONObject jsonObject = JSON.parseObject(response);
                        if (jsonObject.getInteger("code").equals(200)) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                            barcodeThread.setBarcode("");
                            staProtocol.setWorkNo(dto.getWorkNo());
                            if(Cools.isEmpty(dto.getRgvNo()) || dto.getRgvNo() <= 0) {
                                staProtocol.setStaNo(dto.getStaNo());
                            } else {//如果存在RGV编号,说明需要RGV接驳,先下发任务到RGV源站
                                staProtocol.setStaNo(dto.getRgvSstaNo());
                            }
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            if (!result) {
                                throw new CoolException("更新plc站点信息失败");
                            }
                        } else {
                            log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/pair/station/single/loc/v1", JSON.toJSONString(param), response);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }
                }
            }
        }
    }
    /**
     * 组托
     * 入库站,根据条码扫描生成入库工作档,工作状态 2
     */
    public synchronized void generateStoreWrkFileLarge() {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库口
            for (DevpSlave.Sta inSta : devp.getInLargeSta()) {
                // 获取条码扫描仪信息
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, inSta.getBarcode());
                if (barcodeThread == null) {
                    continue;
                }
                String barcode = barcodeThread.getBarcode();
                if (!Cools.isEmpty(barcode)) {
//                    log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode);
                    if ("NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                        continue;
                    }
                } else {
                    continue;
                }
                // 获取入库站信息
//                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                // 尺寸检测异常
                boolean back = false;
                String errMsg = "异常:";
                if (staProtocol.isFrontErr()) {
                    errMsg = errMsg+"前超限;";
                    back = true;
                }
                if (staProtocol.isBackErr()) {
                    errMsg = errMsg+"后超限";
                    back = true;
                }
                if (staProtocol.isHighErr()) {
                    errMsg = errMsg+"高超限";
                    back = true;
                }
                if (staProtocol.isLeftErr()) {
                    errMsg = errMsg+"左超限";
                    back = true;
                }
                if (staProtocol.isRightErr()) {
                    errMsg = errMsg+"右超限";
                    back = true;
                }
                if (staProtocol.isWeightErr()) {
                    errMsg = errMsg+"超重";
                    back = true;
                }
                if (staProtocol.isBarcodeErr()) {
                    errMsg = errMsg+"扫码失败";
                    back = true;
                }
                // 退回
                if (back) {
                    // led 异常显示
                    LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                    if (ledThread != null) {
                        MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(5, errMsg));
                    }
                    continue;
                }
                // 入出库模式判断
//                if ( inSta.getStaNo()==203 && devpThread.ioModeOf2F != IoModeType.PAKIN_MODE) { continue; }
//                if (inSta.getStaNo() == 203 && devpThread.ioModeOf2F == IoModeType.PAKOUT_MODE) {
//                    continue;
//                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && !staProtocol.isEmptyMk()
                        && staProtocol.getWorkNo() == 0
                        && staProtocol.isPakMk()) {// && !Cools.isEmpty(barcode)) {
                    if(Cools.isEmpty(barcode) || "NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                        log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode);
//                        //条码为空或者不符合,退库到172站点
//                        staProtocol.setWorkNo((short)32222);
//                        staProtocol.setStaNo((short)172);
//                        devpThread.setPakMk(staProtocol.getSiteId(), false);
//                        boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                        if (!result) {
//                            throw new CoolException("更新plc站点信息失败");
//                        }
                        continue;
                    }
                    // 判断重复工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep1(inSta.getStaNo(), barcode);
                    if (wrkMast != null) {
                        log.error("工作档中已存在该站状态为( 2.设备上走 )的数据,工作号={}", wrkMast.getWrkNo());
                        continue;
                    }
//                    // 获取入库通知档
//                    List<WaitPakin> waitPakins = waitPakinMapper.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", barcode).eq("io_status", "N"));
//                    if (waitPakins.isEmpty()) {
//                        log.error("无此入库条码数据。条码号={}", barcode);
//                        continue;
//                    }
                    try {
                        LocTypeDto locTypeDto = new LocTypeDto(staProtocol);
                        SearchLocParam param = new SearchLocParam();
                        param.setBarcode(barcode);
                        param.setIoType(1);
                        param.setSourceStaNo(inSta.getStaNo());
                        param.setLocType1(locTypeDto.getLocType1());
                        String response = new HttpHandler.Builder()
                                .setUri(wmsUrl)
                                .setPath("/rpc/pakin/pair/station/large/loc/v1")
                                .setJson(JSON.toJSONString(param))
                                .build()
                                .doPost();
                        JSONObject jsonObject = JSON.parseObject(response);
                        if (jsonObject.getInteger("code").equals(200)) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                            barcodeThread.setBarcode("");
                            staProtocol.setWorkNo(dto.getWorkNo());
                            if(Cools.isEmpty(dto.getRgvNo()) || dto.getRgvNo() <= 0) {
                                staProtocol.setStaNo(dto.getStaNo());
                            } else {//如果存在RGV编号,说明需要RGV接驳,先下发任务到RGV源站
                                staProtocol.setStaNo(dto.getRgvSstaNo());
                            }
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            if (!result) {
                                throw new CoolException("更新plc站点信息失败");
                            }
                        } else {
                            log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/pair/station/single/loc/v1", JSON.toJSONString(param), response);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }
                }
            }
        }
    }
    /**
     * 组托
     * 入库站,根据条码扫描通知桁架码垛
     */
    public synchronized void generateStoreWrkFileFull2LouM() {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历码垛口
            for (DevpSlave.Sta driveSta : devp.getDriveSta()) {
                // 获取条码扫描仪信息
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, driveSta.getBarcode());
                if (barcodeThread == null) {
                    continue;
                }
                String barcode = barcodeThread.getBarcode();
                if (!Cools.isEmpty(barcode) && !barcode.equals("") && !barcode.equals("      ")) {
                    if ("NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                        continue;
                    }
                } else {
                    continue;
                }
                // 获取码垛口信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(driveSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && staProtocol.isEmptyMk()
                        && (staProtocol.getWorkNo() == 0 || (staProtocol.getWorkNo()>9899 && staProtocol.getWorkNo()<10000) )
                ) {
                    try {
                        BasDevp basDevp = basDevpService.selectById(driveSta.getStaNo());
                        if (basDevp.getReportSign()>0){
                            continue;
                        }
                        basDevp.setBarcode(barcode);
                        basDevp.setReportSign(1);
                        basDevpService.updateById(basDevp);
                    } catch (Exception e) {
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }
                }
            }
        }
    }
    /**
     * wms入库
     * 入库站,根据条码扫描生成入库工作档,工作状态 1 ==>> 2
     */
@@ -235,7 +677,7 @@
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库口
            for (DevpSlave.Sta inSta : devp.getInSta()) {
            for (DevpSlave.Sta inSta : devp.getInWmsSta()) {
                // 获取入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
@@ -246,9 +688,9 @@
                }
//                // 入出库模式判断
                if (inSta.getStaNo() == 203 && devpThread.ioModeOf2F != IoModeType.PAKIN_MODE) {
                    continue;
                }
//                if (inSta.getStaNo() == 203 && devpThread.ioModeOf2F != IoModeType.PAKIN_MODE) {
//                    continue;
//                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable()
@@ -264,7 +706,11 @@
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                    staProtocol.setStaNo(wrkMast.getStaNo());
                    Integer staNo = wrkMast.getStaNo();
                    if (wrkMast.getSourceStaNo()==145){
                        staNo = 147;
                    }
                    staProtocol.setStaNo(staNo);
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (result) {
@@ -322,7 +768,7 @@
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && staProtocol.isPakMk()) {
//                    WrkMast wrkMast = wrkMastMapper.selectPickStep(barcode);
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(staProtocol.getWorkNo());
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep5(staProtocol.getSiteId(),"7");
                    if (wrkMast == null) {
                        // 无拣料数据
                        continue;
@@ -332,73 +778,67 @@
                        continue;
                    }
                    // 拣、盘、并 作业站转换
//                    int stnNo = 0;
//                    if (wrkMast.getStaNo() == 109) {
//                        stnNo = 127;
//                    } else if (wrkMast.getStaNo() == 113) {
//                        stnNo = 128;
//                    } else {
//                        log.error("{}号任务数据异常!", wrkMast.getWrkNo());
//                    }
                    // 获取目标站
                    Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                            .eq("type_no", wrkMast.getIoType() - 50)
                            .eq("stn_no", pickSta.getStaNo()) // 作业站点 = 拣料出库的目标站
                            .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
                    StaDesc staDesc = staDescService.selectOne(wrapper);
                    if (Cools.isEmpty(staDesc)) {
                        log.error("入库路径不存在!type_no={},stn_no={},crn_no={}", wrkMast.getIoType(), pickSta.getStaNo(), wrkMast.getCrnNo());
                        continue;
                    }
                    //   获取库位号
                    try {
                        // 保存工作明细档历史档
                        if (wrkMastMapper.saveWrkDetlLog(wrkMast.getWrkNo()) == 0) {
                            throw new CoolException("保存工作明细档历史档失败");
                        SearchLocParam param = new SearchLocParam();
                        param.setBarcode(wrkMast.getBarcode());
                        param.setIoType(wrkMast.getIoType());
                        param.setSourceStaNo(pickSta.getStaNo()); //作业站点
                        param.setLocType1((short)1);
                        String response = "";
                        log.info("入库作业站"+pickSta.getStaNo()+"盘点再入库任务请求WMS===>>参数:" + param);
                        try {
                            response = new HttpHandler.Builder()
                                    .setUri(wmsUrl)
                                    .setPath("/rpc/pakin2/loc/v1")
                                    .setJson(JSON.toJSONString(param))
                                    .setTimeout(15, TimeUnit.SECONDS)
                                    .build()
                                    .doPost();
                        } catch(Exception e){
                            log.error("入库作业站"+pickSta.getStaNo()+"盘点再入库任务请求WMS===>>参数:" + param);
                            log.error("stnToCrnStnPick2===>>盘点查库位入库接口失败", e);
                            e.printStackTrace();
                            continue;
                        }
                        // 保存工作主档历史档
                        if (wrkMastMapper.saveWrkMastLog(wrkMast.getWrkNo()) == 0) {
                            throw new CoolException("保存工作主档历史档失败");
                        log.info("入库作业站"+pickSta.getStaNo()+"盘点再入库任务请求WMS===>>参数:" + param);
                        log.info("入库作业站"+pickSta.getStaNo()+"下发盘点再入库任务请求WMS返回结果===>>" + response);
                        if(response.equals("")) {
                            continue;
                        }
                        Date now = new Date();
                        // 堆垛机站点(目标站)
                        Integer staNo = staDesc.getCrnStn();
                        // 更新工作档数据状态
                        wrkMast.setIoTime(now);
                        wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
                        wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
                        wrkMast.setSourceStaNo(wrkMast.getStaNo()); // 源站
                        wrkMast.setStaNo(staNo); // 目标站
                        wrkMast.setLocNo(wrkMast.getSourceLocNo()); // 目标库位 = 出库时的源库位
                        wrkMast.setSourceLocNo(""); // 源库位清空
                        wrkMast.setModiTime(now);
                        if (wrkMastMapper.updateById(wrkMast) == 0) {
                            throw new CoolException("更新工作档数据状态失败");
                        }
                        // 更新明细档io_time (历史档关联使用)
                        wrkDetlService.updateIoTime(wrkMast.getWrkNo(), now);
                        // 修改库位状态 Q.拣料/盘点/并板再入库
                        LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
                        locMast.setLocSts("Q");
                        locMast.setModiTime(new Date());
                        if (!locMastService.updateById(locMast)) {
                            throw new CoolException("修改库位状态失败");
                        JSONObject jsonObject = JSON.parseObject(response);
//                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, pickSta.getLed());
                        Integer code = jsonObject.getInteger("code");
                        if (code == 200) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            if (Cools.isEmpty(dto) || Cools.isEmpty(dto.getStaNo())) {
                                log.error("任务号"+wrkMast.getWrkNo()+"盘点再入库查询库位失败===>>" + jsonObject.toJSONString());
                            } else {
                                log.info("任务号"+wrkMast.getWrkNo()+"盘点再入库查询库位成功===>>" + jsonObject.toJSONString());
                                try {
                                    // 更新站点信息 且 下发plc命令
                                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                                    staProtocol.setStaNo(dto.getStaNo());
                                    devpThread.setPakMk(staProtocol.getSiteId(), false);
//                                    ledThread.errorReset();
                                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                                    if (!result) {
                                        log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                                    }
                                    log.info("任务号"+wrkMast.getWrkNo()+"盘点/拣料再入库任务下发成功===>>" + staProtocol);
                                } catch (Exception e) {
                                    log.error("盘点再入库失败===>>" + e);
                                    e.printStackTrace();
                                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                }
                            }
                        } else {
                            log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin2/loc/v1", JSON.toJSONString(param), response);
                        }
                    } catch (Exception e) {
                        log.error("stnToCrnStnPick2===>>fail", e);
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        continue;
                    }
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                    staProtocol.setStaNo(wrkMast.getStaNo());
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
                        log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                    }
                }
@@ -433,19 +873,6 @@
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep4(staProtocol.getSiteId(),"3");
                    if (wrkMast == null) {
                        WrkMast wrkMast1 = wrkMastMapper.selectPakInStep5(staProtocol.getSiteId(),"3");
                        if (Cools.isEmpty(wrkMast1) && staProtocol.isEmptyMk()){
                            WrkMastSta wrkMastSta = wrkMastStaMapper.selectByWrkNo(staProtocol.getSiteId() + 9999L);
                            if (Cools.isEmpty(wrkMastSta)){
                                WrkMastSta wrkMastSta1 = new WrkMastSta(new Date(),staProtocol.getSiteId());
                                wrkMastSta1.setType(2);
                                wrkMastSta1.setWrkType(1);
                                wrkMastStaMapper.insert(wrkMastSta1);
                            }
                            continue;
                        }
//                        log.error("站点号"+staProtocol.getSiteId()+"未查询到工作档案!");
                        // 无拣料数据
                        continue;
                    }
                    if (staProtocol.isEmptyMk()){
@@ -457,70 +884,340 @@
                        continue;
                    }
                    // 获取目标站
                    Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                            .eq("type_no", wrkMast.getIoType() - 50)
                            .eq("stn_no", pickSta.getStaNo()) // 作业站点 = 拣料出库的目标站
                            .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
                    StaDesc staDesc = staDescService.selectOne(wrapper);
                    if (Cools.isEmpty(staDesc)) {
                        log.error("入库路径不存在!type_no={},stn_no={},crn_no={}", wrkMast.getIoType(), pickSta.getStaNo(), wrkMast.getCrnNo());
                    String barcode = wrkMast.getBarcode();
                    if(!Cools.isEmpty(barcode)) {
                        if("NG".endsWith(barcode) || "NoRead".equals(barcode) || "empty".equals(barcode)) {
                            continue;
                        }
                    } else {
                        continue;
                    }
                    //   获取库位号
                    try {
                        // 保存工作明细档历史档
                        if (wrkMastMapper.saveWrkDetlLog(wrkMast.getWrkNo()) == 0) {
                            throw new CoolException("保存工作明细档历史档失败");
                        SearchLocParam param = new SearchLocParam();
                        param.setBarcode(barcode);
                        param.setIoType(wrkMast.getIoType());
                        param.setSourceStaNo(pickSta.getStaNo()); //作业站点
                        param.setLocType1((short)1);
                        String response = "";
                        log.info("入库作业站"+pickSta.getStaNo()+"盘点再入库任务请求WMS===>>参数:" + param);
                        try {
                            response = new HttpHandler.Builder()
                                    .setUri(wmsUrl)
                                    .setPath("/rpc/pakin2/loc/v1")
                                    .setJson(JSON.toJSONString(param))
                                    .setTimeout(15, TimeUnit.SECONDS)
                                    .build()
                                    .doPost();
                        } catch(Exception e){
                            log.error("入库作业站"+pickSta.getStaNo()+"盘点再入库任务请求WMS===>>参数:" + param);
                            log.error("stnToCrnStnPick2===>>盘点查库位入库接口失败", e);
                            e.printStackTrace();
                            continue;
                        }
                        // 保存工作主档历史档
                        if (wrkMastMapper.saveWrkMastLog(wrkMast.getWrkNo()) == 0) {
                            throw new CoolException("保存工作主档历史档失败");
                        log.info("入库作业站"+pickSta.getStaNo()+"盘点再入库任务请求WMS===>>参数:" + param);
                        log.info("入库作业站"+pickSta.getStaNo()+"下发盘点再入库任务请求WMS返回结果===>>" + response);
                        if(response.equals("")) {
                            continue;
                        }
                        Date now = new Date();
                        // 堆垛机站点(目标站)
                        Integer staNo = staDesc.getCrnStn();
                        // 更新工作档数据状态
                        wrkMast.setIoTime(now);
                        wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
                        wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
                        wrkMast.setSourceStaNo(wrkMast.getStaNo()); // 源站
                        wrkMast.setStaNo(staNo); // 目标站
                        wrkMast.setLocNo(wrkMast.getSourceLocNo()); // 目标库位 = 出库时的源库位
                        wrkMast.setSourceLocNo(""); // 源库位清空
                        wrkMast.setModiTime(now);
                        if (wrkMastMapper.updateById(wrkMast) == 0) {
                            throw new CoolException("更新工作档数据状态失败");
                        }
                        // 更新明细档io_time (历史档关联使用)
                        wrkDetlService.updateIoTime(wrkMast.getWrkNo(), now);
                        // 修改库位状态 Q.拣料/盘点/并板再入库
                        LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
                        locMast.setLocSts("Q");
                        locMast.setModiTime(new Date());
                        if (!locMastService.updateById(locMast)) {
                            throw new CoolException("修改库位状态失败");
                        JSONObject jsonObject = JSON.parseObject(response);
//                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, pickSta.getLed());
                        Integer code = jsonObject.getInteger("code");
                        if (code == 200) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            if (Cools.isEmpty(dto) || Cools.isEmpty(dto.getStaNo())) {
                                log.error("任务号"+wrkMast.getWrkNo()+"盘点再入库查询库位失败===>>" + jsonObject.toJSONString());
                            } else {
                                log.info("任务号"+wrkMast.getWrkNo()+"盘点再入库查询库位成功===>>" + jsonObject.toJSONString());
                                try {
                                    // 更新站点信息 且 下发plc命令
                                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                                    staProtocol.setStaNo(dto.getStaNo());
                                    devpThread.setPakMk(staProtocol.getSiteId(), false);
//                                    ledThread.errorReset();
                                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                                    if (!result) {
                                        log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                                    }
                                    log.info("任务号"+wrkMast.getWrkNo()+"盘点/拣料再入库任务下发成功===>>" + staProtocol);
                                } catch (Exception e) {
                                    log.error("盘点再入库失败===>>" + e);
                                    e.printStackTrace();
                                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                }
                            }
                        } else {
                            log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin2/loc/v1", JSON.toJSONString(param), response);
                        }
                    } catch (Exception e) {
                        log.error("stnToCrnStnPick2===>>fail", e);
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        continue;
                    }
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                    staProtocol.setStaNo(wrkMast.getStaNo());
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
                        log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                    }
//                    // 获取目标站
//                    Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
//                            .eq("type_no", wrkMast.getIoType() - 50)
//                            .eq("stn_no", pickSta.getStaNo()) // 作业站点 = 拣料出库的目标站
//                            .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
//                    StaDesc staDesc = staDescService.selectOne(wrapper);
//                    if (Cools.isEmpty(staDesc)) {
//                        log.error("入库路径不存在!type_no={},stn_no={},crn_no={}", wrkMast.getIoType(), pickSta.getStaNo(), wrkMast.getCrnNo());
//                        continue;
//                    }
//
//                    try {
//                        // 保存工作明细档历史档
//                        if (wrkMastMapper.saveWrkDetlLog(wrkMast.getWrkNo()) == 0) {
//                            throw new CoolException("保存工作明细档历史档失败");
//                        }
//                        // 保存工作主档历史档
//                        if (wrkMastMapper.saveWrkMastLog(wrkMast.getWrkNo()) == 0) {
//                            throw new CoolException("保存工作主档历史档失败");
//                        }
//
//                        Date now = new Date();
//                        // 堆垛机站点(目标站)
//                        Integer staNo = staDesc.getCrnStn();
//                        // 更新工作档数据状态
//                        wrkMast.setIoTime(now);
//                        wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
//                        wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
//                        wrkMast.setSourceStaNo(wrkMast.getStaNo()); // 源站
//                        wrkMast.setStaNo(staNo); // 目标站
//                        wrkMast.setLocNo(wrkMast.getSourceLocNo()); // 目标库位 = 出库时的源库位
//                        wrkMast.setSourceLocNo(""); // 源库位清空
//                        wrkMast.setModiTime(now);
//                        if (wrkMastMapper.updateById(wrkMast) == 0) {
//                            throw new CoolException("更新工作档数据状态失败");
//                        }
//                        // 更新明细档io_time (历史档关联使用)
//                        wrkDetlService.updateIoTime(wrkMast.getWrkNo(), now);
//                        // 修改库位状态 Q.拣料/盘点/并板再入库
//                        LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
//                        locMast.setLocSts("Q");
//                        locMast.setModiTime(new Date());
//                        if (!locMastService.updateById(locMast)) {
//                            throw new CoolException("修改库位状态失败");
//                        }
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                        continue;
//                    }
//
//                    // 更新站点信息 且 下发plc命令
//                    staProtocol.setWorkNo(wrkMast.getWrkNo());
//                    staProtocol.setStaNo(wrkMast.getStaNo());
//                    devpThread.setPakMk(staProtocol.getSiteId(), false);
//                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                    if (!result) {
//                        log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
//                    }
                }
            }
        }
    }
    /**
     * 2楼212呼叫空板
     */
    public synchronized void stnToCrnStnPick3Auto(Integer sign) {
        try{
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 2);
            StaProtocol staProtocol = devpThread.getStation().get(212);
            if (staProtocol == null) {
                return;
            } else {
                staProtocol = staProtocol.clone();
            }
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staProtocol.getWorkNo()==0 ){
                switch (sign){
                    //执行小车货物搬运任务
                    case 1:
                    case 4:
                        stnToCrnStnPick3();
                        return;
                    //执行小车空板搬运任务
                    case 2://放//拆盘
                    case 5://放//拆盘
                        stnToCrnStnPick4();
                        return;
                    default:
                        return;
                }
            } else if (staProtocol.isAutoing() && staProtocol.isLoading()){
                switch (sign){
                    case 3://满放
                    case 6://满放
                        stnToCrnStnPick5();
                        return;
                    default:
                        return;
                }
            }
        }catch (Exception e){
            log.error("2楼212呼叫空板"+e);
        }
    }
    /**
     * 2楼212呼叫空板
     */
    public synchronized void stnToCrnStnPick3() {
        WrkMast wrkMast = wrkMastMapper.selectWrkMastUnstackingOne212();
        if (Cools.isEmpty(wrkMast) || wrkMast.getWrkSts()!=61){//61、等待空板
            return;
        }
        for (DevpSlave devp : slaveProperties.getDevp()) {
            for (DevpSlave.Sta driveSta : devp.getDriveSta()) {
                if (driveSta.getStaNo()!=215){
                    continue;
                }
                // 获取拣料入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(driveSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo()==0
                        || (staProtocol.getWorkNo()>9899 && staProtocol.getWorkNo()<10000)) ){
                    boolean result1 = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(3, staProtocol));
                    staProtocol.setWorkNo(wrkMast.getWrkNo()-1);
                    staProtocol.setStaNo(driveSta.getStaNo()==215? 217:221);
                    boolean result2 = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result2) {
                        log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                    }
                    wrkMast.setWrkSts(62L);
                    wrkMastMapper.updateById(wrkMast);
                    boolean result3 = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(4, staProtocol));
                    return;
                }
            }
        }
    }
    /**
     * 2楼212呼叫空板
     */
    public synchronized void stnToCrnStnPick4() {
        WrkMast wrkMast = wrkMastMapper.selectWrkMastUnstackingOne212();
        if (Cools.isEmpty(wrkMast) || wrkMast.getWrkSts()!=62){//62、等待小车搬运
            return;
        }
        for (DevpSlave devp : slaveProperties.getDevp()) {
            for (DevpSlave.Sta driveSta : devp.getInSta()) {
                if (driveSta.getStaNo()!=217){
                    continue;
                }
                // 获取拣料入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(driveSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                StaProtocol staProtocol212 = devpThread.getStation().get(212);
                if (staProtocol212 == null) {
                    continue;
                } else {
                    staProtocol212 = staProtocol212.clone();
                }
                if (staProtocol212.isAutoing() && !staProtocol212.isLoading() && staProtocol212.getWorkNo()==0){
                    if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo()==0
                            || (staProtocol.getWorkNo()>9899 && staProtocol.getWorkNo()<10000) || staProtocol.getWorkNo()==wrkMast.getWrkNo()-1) ){
//                        boolean result1 = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(3, staProtocol));
                        staProtocol.setWorkNo(wrkMast.getWrkNo());
                        staProtocol.setStaNo(212);
                        boolean result2 = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                        if (!result2) {
                            log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                        }
                        wrkMast.setWrkSts(63L);
                        wrkMastMapper.updateById(wrkMast);
//                        boolean result3 = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(4, staProtocol));
                        return;
                    }
                }
            }
        }
    }
    /**
     * 2楼212呼叫空板
     */
    public synchronized void stnToCrnStnPick5() {
        WrkMast wrkMast = wrkMastMapper.selectWrkMastUnstackingOne212();
        if (Cools.isEmpty(wrkMast) || wrkMast.getWrkSts()!=63){//63、等待完成
            return;
        }
        // 获取拣料入库站信息
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 2);
        StaProtocol staProtocol = devpThread.getStation().get(212);
        if (staProtocol == null) {
            return;
        } else {
            staProtocol = staProtocol.clone();
        }
        if (staProtocol.isAutoing() && staProtocol.isLoading()){
//            boolean result1 = MessageQueue.offer(SlaveType.Devp, 2, new Task(3, staProtocol));
            wrkMast.setWrkSts(64L);
            wrkMastMapper.updateById(wrkMast);
//            boolean result3 = MessageQueue.offer(SlaveType.Devp, 2, new Task(4, staProtocol));
            return;
        }
    }
    /**
     * 拣料、并板、盘点再入库  拆垛位置
     */
    public synchronized void storeEmptyPlt4() {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历叠盘入库口
            for (DevpSlave.Sta pickSta : devp.getEmptyInSta2()) {
                // 获取入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(pickSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                BasDevp basDevp = basDevpService.selectById(staProtocol.getSiteId());
                if (Cools.isEmpty(basDevp) || basDevp.getReportSign()!=1){
                    continue;
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isPakMk() && staProtocol.getWorkNo()==0 && !staProtocol.isOutEnable() && staProtocol.isInEnable()) {
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep4(staProtocol.getSiteId(),"3");
                    if (wrkMast == null) {
                        WrkMast wrkMast1 = wrkMastMapper.selectPakInStep5(staProtocol.getSiteId(),"3");
                        if (Cools.isEmpty(wrkMast1) && staProtocol.isEmptyMk()){
                            WrkMastSta wrkMastSta = wrkMastStaMapper.selectByWrkNo(staProtocol.getSiteId() + 19999L);
                            if (Cools.isEmpty(wrkMastSta)){
                                WrkMastSta wrkMastSta1 = new WrkMastSta(new Date(),staProtocol.getSiteId());
                                wrkMastSta1.setType(2);
                                wrkMastSta1.setWrkType(1);
                                wrkMastStaMapper.insert(wrkMastSta1);
                            }
                        }
                    }
                }
            }
        }
    }
@@ -556,32 +1253,111 @@
                        // 移动中
                        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());
                        }
                    }
                    //  判断堆垛机状态等待确认
                    if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue())
                            && crnProtocol.statusType == CrnStatusType.WAITING
                            && crnProtocol.forkPosType == CrnForkPosType.HOME) {
                        // 命令下发区 --------------------------------------------------------------------------
                        if (crnProtocol.getCrnNo()<=2){
                        // 下发站点信息
                        staProtocol.setWorkNo(wrkMast.getWrkNo());
                        staProtocol.setStaNo(RouteUtils.CrnStaEnd(wrkMast.getStaNo(),wrkMast.getSourceStaNo()));
                        if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                            continue;
                            StaProtocol staProtocolOther = devpThread.getStation().get(crnStn.getStaNoOther());
                            if (staProtocolOther == null) {
                                continue;
                            } else {
                                staProtocolOther = staProtocolOther.clone();
                            }
                            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;
                            }
                            // 更新工作档状态为14失败
                            wrkMast.setWrkSts(14L);
                            wrkMast.setCrnEndTime(new Date());
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                // 复位堆垛机
                                crnThread.setResetFlag(true);
                            } else {
                                log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                            }
                        }
                        // 更新工作档状态为14失败
                        wrkMast.setWrkSts(14L);
                        wrkMast.setCrnEndTime(new Date());
                        if (wrkMastMapper.updateById(wrkMast) != 0) {
                            // 复位堆垛机
                            crnThread.setResetFlag(true);
                        } else {
                            log.error("更新工作档的工作状态为14失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                    }
                }
            }
        }
@@ -614,20 +1390,48 @@
                    // 如果最近一次是入库模式
                    if (crnProtocol.getLastIo().equals("I")) {
                        if (basCrnp.getInEnable().equals("Y")) {
                            this.crnStnToLoc1(crn, crnProtocol); //  入库
                            switch (crn.getId()){
                                case 1:
                                case 2:
                                    this.crnStnToLoc1Single(crn, crnProtocol); //  入库
                                    break;
                                default:
                                    this.crnStnToLoc1(crn, crnProtocol); //  入库
                            }
                            crnProtocol.setLastIo("O");
                        } else if (basCrnp.getOutEnable().equals("Y")) {
                            this.locToCrnStn1(crn, crnProtocol); //  出库
                            switch (crn.getId()){
                                case 1:
                                case 2:
                                    this.locToCrnStn1Single(crn, crnProtocol); //  出库
                                    break;
                                default:
                                    this.locToCrnStn1(crn, crnProtocol); //  出库
                            }
                            crnProtocol.setLastIo("I");
                        }
                    }
                    // 如果最近一次是出库模式
                    else if (crnProtocol.getLastIo().equals("O")) {
                        if (basCrnp.getOutEnable().equals("Y")) {
                            this.locToCrnStn1(crn, crnProtocol); //  出库
                            switch (crn.getId()){
                                case 1:
                                case 2:
                                    this.locToCrnStn1Single(crn, crnProtocol); //  出库
                                    break;
                                default:
                                    this.locToCrnStn1(crn, crnProtocol); //  出库
                            }
                            crnProtocol.setLastIo("I");
                        } else if (basCrnp.getInEnable().equals("Y")) {
                            this.crnStnToLoc1(crn, crnProtocol); //  入库
                            switch (crn.getId()){
                                case 1:
                                case 2:
                                    this.crnStnToLoc1Single(crn, crnProtocol); //  入库
                                    break;
                                default:
                                    this.crnStnToLoc1(crn, crnProtocol); //  入库
                            }
                            crnProtocol.setLastIo("O");
                        }
                    }
@@ -705,607 +1509,6 @@
            log.error("搜索RGV车。通过目标站搜索哪台车可用"+e);
            return null;
        }
    }
//    /**
//     * 绑定小车方法
//     */
//    public synchronized void rgvBindSte() {
//        //获取等待绑定RGV的任务
//        List<WrkMast> wrkMasts = wrkMastMapper.selectWaitBindRGV();
//        for (WrkMast wrkMast : wrkMasts) {
//            //目标站
//            Integer staNo = wrkMast.getStaNo();
//            //源站
//            Integer sourceStaNo = wrkMast.getSourceStaNo();
//            //通过目标站搜索rgv号
//            Integer rgvNo=0;
//            if (wrkMast.getCrnNo()==1){
//                rgvNo=1;
//            }else if (wrkMast.getCrnNo()==6){
//                rgvNo=2;
//            }else {
//                rgvNo = this.searchRgvNo(staNo);
//            }
//            if (rgvNo == null || rgvNo==0) {//未找到可用的rgv
//                continue;
//            }
//
//            wrkMast.setRgvNo(rgvNo);//绑定rgv号
//            wrkMast.setRgvDstaNo(wrkMast.getSourceStaNo());//设置RGV前往工作档源站取货
//            if (wrkMastMapper.updateById(wrkMast)==0){
//                log.error("绑定小车更新工作档失败!!! [工作号:{}]", wrkMast.getWrkNo());
//            }
//        }
//    }
    /**
     * 绑定小车方法
     */
    public synchronized void rgvBindSte() {
        try {
            // 根据输送线plc遍历
            for (DevpSlave devp : slaveProperties.getDevp()) {
                if (devp.getId()==2){
                    continue;
                }
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                //入库绑小车
                for (DevpSlave.Sta Sta : devp.getInRgvSta()) {
                    StaProtocol staProtocol = devpThread.getStation().get(Sta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() != 0 && staProtocol.getWorkNo() < 9990){
                        List<WrkMast> wrkMasts = wrkMastMapper.selectList(new EntityWrapper<WrkMast>().eq("wrk_no", staProtocol.getWorkNo()).eq("wrk_sts", 2L));
                        if (Cools.isEmpty(wrkMasts) || wrkMasts.size()!=1){
                            continue;
                        }
                        WrkMast wrkMast = wrkMasts.get(0);
                                    //目标站
                        Integer staNo = wrkMast.getStaNo();
                        //通过目标站搜索rgv号
                        Integer rgvNo=0;
                        if (wrkMast.getCrnNo()==1){
                            rgvNo=1;
                        }else if (wrkMast.getCrnNo()==6){
                            rgvNo=2;
                        }else {
                            rgvNo = this.searchRgvNo(staNo);
                        }
                        if (rgvNo == null || rgvNo==0) {//未找到可用的rgv
                            continue;
                        }
                        wrkMast.setRgvNo(rgvNo);//绑定rgv号
                        if (wrkMastMapper.updateById(wrkMast)==0){
                            log.error("绑定小车更新工作档失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                    }
                }
                //出库绑小车
                for (DevpSlave.Sta Sta : devp.getOutRgvSta()) {
                    StaProtocol staProtocol = devpThread.getStation().get(Sta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() != 0 && staProtocol.getWorkNo() < 9990){
                        List<WrkMast> wrkMasts = wrkMastMapper.selectList(new EntityWrapper<WrkMast>().eq("wrk_no", staProtocol.getWorkNo()).eq("wrk_sts", 14L));
                        if (Cools.isEmpty(wrkMasts) || wrkMasts.size()!=1){
                            continue;
                        }
                        WrkMast wrkMast = wrkMasts.get(0);
                        //目标站
                        Integer staNo = wrkMast.getStaNo();
                        //通过目标站搜索rgv号
                        Integer rgvNo=0;
                        if (wrkMast.getCrnNo()==1){
                            rgvNo=1;
                        }else if (wrkMast.getCrnNo()==6){
                            rgvNo=2;
                        }else {
                            rgvNo = this.searchRgvNo(staNo);
                        }
                        if (rgvNo == null || rgvNo==0) {//未找到可用的rgv
                            continue;
                        }
                        wrkMast.setRgvNo(rgvNo);//绑定rgv号
                        if (wrkMastMapper.updateById(wrkMast)==0){
                            log.error("绑定小车更新工作档失败!!! [工作号:{}]", wrkMast.getWrkNo());
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("绑定小车异常:{}", e.getMessage());
        }
    }
    /**
     * 绑定小车方法
     */
    public synchronized void rgvBindSte2() {
        try{
            for (RgvSlave rgv : slaveProperties.getRgv()) {
                List<WrkMast> wrkMasts = wrkMastMapper.selectWaitBindRGVRgvNo(rgv.getId());
                if (!Cools.isEmpty(wrkMasts) && wrkMasts.size()!=0){
                    continue;
                }
                List<WrkMast> wrkMasts2 = wrkMastMapper.selectWaitBindRgvNo2(rgv.getId());
                for (WrkMast wrkMast : wrkMasts2) {
                    if (wrkMastMapper.selectWaitBindRgvNoOneWrkNo(wrkMast.getWrkNo())!=null){
                        continue;
                    }
                    //目标站
                    BasDevp basDevp = basDevpService.selectById(wrkMast.getRgvDstaNo());
                    if (Cools.isEmpty(basDevp) || !basDevp.getAutoing().equals("Y") || !basDevp.getLoading().equals("N") || basDevp.getWrkNo()!=0){
                        continue;
                    }
                    wrkMastMapper.insertRgvMast(wrkMast.getWrkNo());
                    wrkMastMapper.updateRgvMast(wrkMast.getWrkNo());
                    break;
                }
            }
        }catch (Exception e){
            log.error("小车搬运任务异常:{}", e.getMessage());
        }
    }
    /**
     * 入出库  ===>>  RGV入出库作业下发
     */
    public synchronized void rgvIoExecuteOld() {
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            // 获取RGV信息
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                continue;
            }
            BasRgv basRgv = basRgvService.selectById(rgv.getId());
            if (basRgv == null) {
                log.error("{}号RGV尚未在数据库进行维护!", rgv.getId());
                continue;
            }
            // 只有当RGV空闲、自动,
            if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                    && rgvProtocol.getModeType() == RgvModeType.AUTO
//                    && rgvProtocol.getTaskNo1() == 0 && rgvProtocol.getTaskNo2() == 0
//                    && rgvProtocol.getLoaded1() == 0 && rgvProtocol.getLoaded2() == 0
            ) {
                //查找是否存在入出库工作中等待RGV搬运的任务
                List<WrkMast> wrkMasts = wrkMastMapper.selectIoRgvNo(rgv.getId());
                for (WrkMast wrkMast : wrkMasts) {
                    if (wrkMast.getWrkSts() == 2) {//2.设备上走1 => 3.RGV取货中
                        if (rgvProtocol.getTaskNo1() != 0 || rgvProtocol.getLoaded1() != 0) {//RGV是否无任务、RGV是否无货
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getSourceStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
//                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.FETCH); // 工位1任务模式:  取货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 2.设备上走1 => 3.RGV取货中
                            Date now = new Date();
                            wrkMast.setWrkSts(3L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 2.设备上走1 => 3.RGV取货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    } else if (wrkMast.getWrkSts() == 14) {//4.RGV取货完成 => 5.RGV放货中   14出库完成
                        if (rgvProtocol.getTaskNo1() == 0 || !rgvProtocol.getTaskNo1().equals(wrkMast.getWrkNo().shortValue())) {//RGV必须有任务且任务和当前工作档一致
                            continue;
                        }
                        if (rgvProtocol.getLoaded1() == 0) {//RGV必须有物
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.PUT); // 工位1任务模式:  放货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 4.RGV取货完成 => 5.RGV放货中
                            Date now = new Date();
                            wrkMast.setWrkSts(5L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 4.RGV取货完成 => 5.RGV放货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    } else if (wrkMast.getWrkSts() == 23) {//23.设备上走1 => 24.RGV取货中
                        if (rgvProtocol.getTaskNo1() != 0 || rgvProtocol.getLoaded1() != 0) {//RGV是否无任务、RGV是否无货
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getSourceStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.FETCH); // 工位1任务模式:  取货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 23.设备上走1 => 24.RGV取货中
                            Date now = new Date();
                            wrkMast.setWrkSts(24L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 23.设备上走1 => 24.RGV取货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    } else if (wrkMast.getWrkSts() == 25) {//25.RGV取货完成 => 26.RGV放货中
                        if (rgvProtocol.getTaskNo1() == 0 || !rgvProtocol.getTaskNo1().equals(wrkMast.getWrkNo().shortValue())) {//RGV必须有任务且任务和当前工作档一致
                            continue;
                        }
                        if (rgvProtocol.getLoaded1() == 0) {//RGV必须有物
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.PUT); // 工位1任务模式:  放货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 25.RGV取货完成 => 26.RGV放货中
                            Date now = new Date();
                            wrkMast.setWrkSts(26L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 25.RGV取货完成 => 26.RGV放货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * 入出库  ===>>  RGV入出库作业下发
     */
    public synchronized void rgvIoExecute() {
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            RgvSlave rgvSlave=null;
            if (rgv.getId()==1){
                rgvSlave = slaveProperties.getRgv().get(1);
            }else {
                rgvSlave = slaveProperties.getRgv().get(0);
            }
            // 获取RGV信息
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                continue;
            }
            RgvThread rgvThreadSlave = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
            RgvProtocol rgvProtocolSlave = rgvThreadSlave.getRgvProtocol();
            BasRgv basRgvSlave = null;
            if (rgvProtocolSlave == null) {
                rgvSlave=null;
            }else {
                basRgvSlave = basRgvService.selectById(rgv.getId());
                if (basRgvSlave == null) {
                    rgvSlave=null;
                }
            }
            BasRgv basRgv = basRgvService.selectById(rgv.getId());
            if (basRgv == null) {
                log.error("{}号RGV尚未在数据库进行维护!", rgv.getId());
                continue;
            }
            boolean signSlave=false;//此处判断RgvSlave是否已经规避
            boolean signSlaveState=false;//此处判断RgvSlave是否空闲
            Integer staSlave = 0;//此处记录RgvSlave当前位置
            // 只有当RGV空闲、自动,
            if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                    && rgvProtocol.getModeType() == RgvModeType.AUTO
//                    && rgvProtocol.getTaskNo1() == 0 && rgvProtocol.getTaskNo2() == 0
//                    && rgvProtocol.getLoaded1() == 0 && rgvProtocol.getLoaded2() == 0
                    ) {
                //查找是否存在入出库工作中等待RGV搬运的任务
                List<WrkMast> wrkMasts = wrkMastMapper.selectIoRgvNo(rgv.getId());
                for (WrkMast wrkMast : wrkMasts) {
                    if (wrkMast.getWrkSts() == 2) {//2.设备上走1 => 3.RGV取货中
                        if (rgvProtocol.getTaskNo1() != 0 || rgvProtocol.getLoaded1() != 0) {//RGV是否无任务、RGV是否无货
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getSourceStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
//                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.FETCH); // 工位1任务模式:  取货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 2.设备上走1 => 3.RGV取货中
                            Date now = new Date();
                            wrkMast.setWrkSts(3L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 2.设备上走1 => 3.RGV取货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    } else if (wrkMast.getWrkSts() == 14) {//4.RGV取货完成 => 5.RGV放货中   14出库完成
                        if (rgvProtocol.getTaskNo1() == 0 || !rgvProtocol.getTaskNo1().equals(wrkMast.getWrkNo().shortValue())) {//RGV必须有任务且任务和当前工作档一致
                            continue;
                        }
                        if (rgvProtocol.getLoaded1() == 0) {//RGV必须有物
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.PUT); // 工位1任务模式:  放货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 4.RGV取货完成 => 5.RGV放货中
                            Date now = new Date();
                            wrkMast.setWrkSts(5L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 4.RGV取货完成 => 5.RGV放货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    } else if (wrkMast.getWrkSts() == 23) {//23.设备上走1 => 24.RGV取货中
                        if (rgvProtocol.getTaskNo1() != 0 || rgvProtocol.getLoaded1() != 0) {//RGV是否无任务、RGV是否无货
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getSourceStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.FETCH); // 工位1任务模式:  取货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 23.设备上走1 => 24.RGV取货中
                            Date now = new Date();
                            wrkMast.setWrkSts(24L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 23.设备上走1 => 24.RGV取货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    } else if (wrkMast.getWrkSts() == 25) {//25.RGV取货完成 => 26.RGV放货中
                        if (rgvProtocol.getTaskNo1() == 0 || !rgvProtocol.getTaskNo1().equals(wrkMast.getWrkNo().shortValue())) {//RGV必须有任务且任务和当前工作档一致
                            continue;
                        }
                        if (rgvProtocol.getLoaded1() == 0) {//RGV必须有物
                            continue;
                        }
                        //判断行走路径是否被占用
                        Integer staNo = wrkMast.getStaNo();
                        BasDevp basDevp = basDevpService.selectById(staNo);
                        if (basDevp == null) {
                            continue;//目标站不存在
                        }
                        //起始路径
                        int startPath = rgvProtocol.getRgvPos().intValue();
                        //目标路径值
                        int endPath = basDevp.getLocType3().intValue();
                        boolean pathUsed = RgvUtils.isPathUsed(startPath, endPath);//判断行走路径是否被占用
                        if (pathUsed) {
                            //行走路径被占用,禁止下发命令
                            continue;
                        }
                        //行走路径空闲,锁定路径
                        RgvUtils.lockPath(startPath, endPath, rgvProtocol.getRgvNo(), wrkMast.getWrkNo(), true);
                        //  命令下发区 --------------------------------------------------------------------------
                        RgvCommand rgvCommand = new RgvCommand();
                        rgvCommand.setRgvNo(wrkMast.getRgvNo()); // RGV编号
                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
                        rgvCommand.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工位1工作号
                        rgvCommand.setTaskMode1(RgvTaskModeType.PUT); // 工位1任务模式:  放货
                        rgvCommand.setDestinationStaNo1(wrkMast.getRgvDstaNo().shortValue());   //工位1目标站点
                        rgvCommand.setCommand((short) 1);   //工位1任务确认
                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getRgvNo(), new Task(4, rgvCommand))) {
                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                            log.error("RGV命令下发失败,RGV号={},任务数据={}", wrkMast.getRgvNo(), JSON.toJSON(rgvCommand));
                        } else {
                            // 修改工作档状态 25.RGV取货完成 => 26.RGV放货中
                            Date now = new Date();
                            wrkMast.setWrkSts(26L);
                            wrkMast.setModiTime(now);
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                log.error("修改工作档状态 25.RGV取货完成 => 26.RGV放货中 失败!!,工作号={}", wrkMast.getWrkNo());
                            }
                        }
                    }
                }
            }
        }
    }
    private boolean rgvIoExecuteWrk2To3() {
        return false;
    }
    /**
@@ -1629,6 +1832,140 @@
    }
    /**
     * 入库  ===>>  堆垛机站到库位
     * 2022-12-03 TQS修改,先遍历查询同台堆垛机工作档所有站点入库任务LIST,根据工作档任务排序优先级高于 根据堆垛机入库站点排序
     */
    public synchronized void crnStnToLoc1Single(CrnSlave slave, CrnProtocol crnProtocol) {
        List<WrkMast> wrkMasts = wrkMastMapper.selectPakInStep12(slave.getId());
        for(WrkMast wrkMast : wrkMasts){
            if (wrkMast == null) {
                continue;
            }
            CrnSlave.CrnStn crnStn = null;
            for (CrnSlave.CrnStn crnStn1 : slave.getCrnInStn()){
                if(crnStn1.getStaNo().equals(wrkMast.getStaNo())){
                    crnStn = crnStn1;
                    break;
                }
            }
            if(Cools.isEmpty(crnStn)){
                continue;
            }
            boolean flag = false;
            boolean flagOther = false;
            // 获取堆垛机入库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            StaProtocol staProtocolOther = devpThread.getStation().get(crnStn.getStaNoOther());
            if (staProtocolOther == null) {
                continue;
            } else {
                staProtocolOther = staProtocolOther.clone();
            }
            // 查询站点详细信息
            BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
            if (staDetl == null) {
                log.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
                continue;
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staProtocol.isInEnable()
                    && staDetl.getCanining() != null && staDetl.getCanining().equals("Y")) {
                flag = true;
            }
            // 查询站点详细信息
            BasDevp staDetlOther = basDevpService.selectById(crnStn.getStaNoOther());
            if (staDetlOther == null) {
                log.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNoOther());
                continue;
            }
            if (staProtocolOther.isAutoing() && staProtocolOther.isLoading() && staProtocolOther.getWorkNo() > 0 && staProtocolOther.isInEnable()
                    && staDetlOther.getCanining() != null && staDetlOther.getCanining().equals("Y")) {
                flagOther = true;
            }
            if (!flag || !flagOther) {
                continue;
            }
            //查询堆垛机任务
            WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(wrkMast.getWrkNo());
            if (Cools.isEmpty(wrkMastCrn)){
                continue;
            }
            WrkMast wrkMastOther = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoTwo().intValue());
            // 获取库位信息
            LocMast locMast = locMastService.selectById(Utils.getRow(wrkMastCrn.getLocNo())%4>2? wrkMastCrn.getLocNoTwo():wrkMastCrn.getLocNoOne());
            if (locMast == null) {
                log.error("查询库存无数据--库位号{}", wrkMastCrn.getLocNo());
                continue;
            }
            if (!locMast.getLocSts().equals("S") && !locMast.getLocSts().equals("Q")) {
                log.error("入库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), locMast.getLocSts());
                continue;
            }
            // 堆垛机控制过滤
            if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
                continue;
            }
            // 已经存在吊车执行任务时,则过滤
            if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                continue;
            }
            // 命令下发区 --------------------------------------------------------------------------
            CrnCommand crnCommand = new CrnCommand();
            crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
            crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号
            crnCommand.setAckFinish((short) 0);  // 任务完成确认位
            crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
            crnCommand.setSourcePosX(crnStn.getRow().shortValue());     // 源库位排
            crnCommand.setSourcePosY(crnStn.getBay().shortValue());     // 源库位列
            crnCommand.setSourcePosZ(crnStn.getLev().shortValue());     // 源库位层
            crnCommand.setDestinationPosX(locMast.getRow1().shortValue());     // 目标库位排
            crnCommand.setDestinationPosY(locMast.getBay1().shortValue());     // 目标库位列
            crnCommand.setDestinationPosZ(locMast.getLev1().shortValue());     // 目标库位层
            if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
            } else {
                // 修改工作档状态 2.设备上走 => 3.吊车入库中
                Date now = new Date();
                wrkMast.setWrkSts(3L);
                wrkMast.setCrnStrTime(now);
                wrkMast.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast) == 0) {
                    log.error("修改工作档状态 2.设备上走 => 3.吊车入库中 失败!!,工作号={}", wrkMast.getWrkNo());
                }
                // 修改工作档状态 2.设备上走 => 3.吊车入库中
                wrkMastOther.setWrkSts(3L);
                wrkMastOther.setCrnStrTime(now);
                wrkMastOther.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMastOther) == 0) {
                    log.error("修改工作档状态 2.设备上走 => 3.吊车入库中 失败!!,工作号={}", wrkMastOther.getWrkNo());
                }
                wrkMastCrn.setWrkSts(3L);
                wrkMastCrn.setModiTime(now);
                if (wrkMastCrnMapper.updateById(wrkMastCrn) == 0) {
                    log.error("修改堆垛机工作档状态 2.设备上走 => 3.吊车入库中 失败!!,工作号={}", wrkMastCrn.getWrkNo());
                }
            }
        }
    }
    /**
     * 出库  ===>>  库位到堆垛机站
     * 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库
     */
@@ -1793,6 +2130,13 @@
                log.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getIoType());
                continue;
            }
            //退库模式跳过118、119出库任务
            if (wrkMast.getStaNo()==118 || wrkMast.getStaNo()==119){
                RgvOneSign rgvOneSign = rgvOneSignMapper.selectOneSign();
                if (Cools.isEmpty(rgvOneSign) || rgvOneSign.getRgvOneSign()==1){
                    continue;
                }
            }
            // 获取源库位信息
            LocMast sourceSta = locMastService.selectById(wrkMast.getSourceLocNo());
            if (!sourceSta.getLocSts().equals("R") && !sourceSta.getLocSts().equals("P")) {
@@ -1914,6 +2258,142 @@
    }
    /**
     * 出库  ===>>  库位到堆垛机站
     * 2022-12-03 TQS修改,先遍历查询工作档所有站点出库任务LIST,根据工作档任务排序优先级高于 根据堆垛机入库站点排序
     */
    public synchronized void locToCrnStn1Single(CrnSlave slave, CrnProtocol crnProtocol) {
        List<WrkMastCrn> wrkMastCrnList = wrkMastCrnMapper.selectList(new EntityWrapper<WrkMastCrn>()
                .eq("crn_no", crnProtocol.getCrnNo()).eq("wrk_sts", 11L));
        for (WrkMastCrn wrkMastCrn : wrkMastCrnList) {
            if (wrkMastCrn == null) {
                continue;
            }
            CrnSlave.CrnStn crnStn = null;
            for (CrnSlave.CrnStn crnStn1 : slave.getCrnOutStn()){
                if(crnStn1.getStaNo().equals(wrkMastCrn.getSourceStaNo())){
                    crnStn = crnStn1;
                    break;
                }
            }
            if(Cools.isEmpty(crnStn)){
                continue;
            }
            // 工作档状态判断
            if (wrkMastCrn.getIoType() < 100 || wrkMastCrn.getSourceStaNo() == null) {
                log.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", wrkMastCrn.getWrkNo(), wrkMastCrn.getSourceLocNo(), wrkMastCrn.getIoType());
                continue;
            }
            // 获取源库位信息
            LocMast sourceSta = locMastService.selectById(wrkMastCrn.getSourceLocNo());
            if (!sourceSta.getLocSts().equals("R") && !sourceSta.getLocSts().equals("P")) {
                log.error("出库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMastCrn.getLocNo(), sourceSta.getLocSts());
                continue;
            }
            // 获取堆垛机出库站信息
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                break;
//                    continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            StaProtocol staProtocolOther = devpThread.getStation().get(crnStn.getStaNoOther());
            if (staProtocolOther == null) {
                continue;
            } else {
                staProtocolOther = staProtocolOther.clone();
            }
//            // 入出库模式判断
//            if (devpThread.ioMode != IoModeType.PAKOUT_MODE) { continue; }
//            if (wrkMast.getStaNo() == 204 && devpThread.ioModeOf2F != IoModeType.PAKOUT_MODE) {
//                continue;
//            }
            // 查询站点详细信息
            BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
            if (staDetl == null) {
                log.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
                break;
//                    continue;
            }
            // 查询站点详细信息
            BasDevp staDetlOther = basDevpService.selectById(crnStn.getStaNoOther());
            if (staDetlOther == null) {
                log.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNoOther());
                break;
//                    continue;
            }
            // 判断堆垛机出库站状态
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")
                    && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                if (staProtocolOther.isAutoing() && !staProtocolOther.isLoading() && staDetlOther.getCanouting() != null && staDetlOther.getCanouting().equals("Y")
                        && staProtocolOther.getWorkNo() == 0 && staProtocolOther.isOutEnable()){
                    // 命令下发区 --------------------------------------------------------------------------
                    // 堆垛机控制过滤
                    if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
//                        continue;
                        break;
                    }
                    // 已经存在吊车执行任务时,则过滤
                    if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                        break;
//                        return;
                    }
                    // 1.堆垛机开始移动
                    CrnCommand crnCommand = new CrnCommand();
                    crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                    crnCommand.setTaskNo(wrkMastCrn.getWrkNo().shortValue()); // 工作号
                    crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                    crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                    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());     // 目标库位层
                    if (!MessageQueue.offer(SlaveType.Crn, wrkMastCrn.getCrnNo(), new Task(2, crnCommand))) {
                        log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMastCrn.getCrnNo(), JSON.toJSON(crnCommand));
                    } else {
                        // 修改工作档状态 11.生成出库ID => 12.吊车出库中
                        Date now = new Date();
                        wrkMastCrn.setWrkSts(12L);
                        wrkMastCrn.setModiTime(now);
                        if (wrkMastCrnMapper.updateById(wrkMastCrn) == 0) {
                            log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMastCrn.getWrkNo());
                        }
                        WrkMast wrkMastOne = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoOne().intValue());
                        wrkMastOne.setWrkSts(12L);
                        wrkMastOne.setCrnStrTime(now);
                        wrkMastOne.setModiTime(now);
                        if (wrkMastMapper.updateById(wrkMastOne) == 0) {
                            log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMastOne.getWrkNo());
                        }
                        WrkMast wrkMastTwo = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoTwo().intValue());
                        wrkMastTwo.setWrkSts(12L);
                        wrkMastTwo.setCrnStrTime(now);
                        wrkMastTwo.setModiTime(now);
                        if (wrkMastMapper.updateById(wrkMastTwo) == 0) {
                            log.error("修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMastTwo.getWrkNo());
                        }
                        break;
                    }
                }
            }
        }
    }
    /**
     * 查找工作状态为2(设备上走),且RGV入库接驳站符合的的入库工作档,提取出最多2笔
     * @param slave
     * @return
@@ -1985,201 +2465,6 @@
    }
    /**
     * 入库  ===>>  RGV入库站到站
     */
    public synchronized void rgvInStn(RgvSlave slave, RgvProtocol rgvProtocol) {
        WrkMast wrkMast = wrkMastMapper.selectRgvInSteNo(slave.getId());
        //查找工作状态为2(设备上走),且RGV入库接驳站符合的的入库工作档,提取出最多2笔
        List<WrkMast> wrkMastTask = getRgvInTask(slave);
        if(wrkMastTask.size() <= 0){
            return;
        }
        // RGV控制过滤, 必须满足自动、空闲,没有任务号
        if (!rgvProtocol.getStatusType().equals(CrnStatusType.IDLE)
                || rgvProtocol.getModeType() != RgvModeType.AUTO
                || rgvProtocol.getTaskNo1() != 0 || rgvProtocol.getTaskNo2() != 0) {
            return;
        }
        // 已经存在RGV执行任务时,则过滤
        if(wrkMastMapper.selectRgvInWorking(slave.getId()).size() > 0){
            return;
        }
        if(wrkMastTask.size() == 2){
            //有2笔RGV待入库任务,2个工位,取货、放货任务同时下发
            WrkMast wrkMast1 = wrkMastTask.get(0);
            WrkMast wrkMast2 = wrkMastTask.get(1);
            if(Cools.isEmpty(wrkMast1) || Cools.isEmpty(wrkMast2)){
                log.error("工作档RGV入库数据为空");
                return;
            }
            //  命令下发区 --------------------------------------------------------------------------
            RgvCommand rgvCommand = new RgvCommand();
            rgvCommand.setRgvNo(slave.getId()); // RGV编号
            rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
            rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
            rgvCommand.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 工位1任务模式:  取放货
            rgvCommand.setSourceStaNo1(wrkMast1.getRgvSstaNo().shortValue());   //工位1源站点
            rgvCommand.setDestinationStaNo1(wrkMast1.getRgvDstaNo().shortValue());   //工位1目标站点
            rgvCommand.setAckFinish2((short) 0);  // 工位2任务完成确认位
            rgvCommand.setTaskNo2(wrkMast2.getWrkNo().shortValue()); // 工位2工作号
            rgvCommand.setTaskMode2(RgvTaskModeType.FETCH_PUT); // 工位2任务模式:  取放货
            rgvCommand.setSourceStaNo2(wrkMast2.getRgvSstaNo().shortValue());   //工位2源站点
            rgvCommand.setDestinationStaNo2(wrkMast2.getRgvDstaNo().shortValue());   //工位2目标站点
            rgvCommand.setCommand((short) 0);   //工位1、2任务确认
            if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(2, rgvCommand))) {
                //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                log.error("RGV命令下发失败,RGV号={},任务数据={}", slave.getId(), JSON.toJSON(rgvCommand));
            } else {
                // 修改工作档状态 2.设备上走 => 6.RGV入库取货中
                Date now = new Date();
                wrkMast1.setWrkSts(6L);
                wrkMast1.setCrnStrTime(now);
                wrkMast1.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast1) == 0) {
                    log.error("修改工作档状态 2.设备上走 => 6.RGV入库取货中 失败!!,工作号={}", wrkMast1.getWrkNo());
                }
                wrkMast2.setWrkSts(6L);
                wrkMast2.setCrnStrTime(now);
                wrkMast2.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast2) == 0) {
                    log.error("修改工作档状态 2.设备上走 => 6.RGV入库取货中 失败!!,工作号={}", wrkMast2.getWrkNo());
                }
            }
        } else if(wrkMastTask.size() == 1){
            //只有1笔RGV待入库任务,先下发取货任务,取货后再判断是否有下一笔待入库任务
            WrkMast wrkMast1 = wrkMastTask.get(0);
            if(Cools.isEmpty(wrkMast1)){
                log.error("工作档RGV入库数据为空");
                return;
            }
            //  命令下发区 --------------------------------------------------------------------------
            RgvCommand rgvCommand = new RgvCommand();
            rgvCommand.setRgvNo(slave.getId()); // RGV编号
            rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
            rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
            rgvCommand.setTaskMode1(RgvTaskModeType.FETCH); // 工位1任务模式:  取货
            rgvCommand.setSourceStaNo1(wrkMast1.getRgvSstaNo().shortValue());   //工位1源站点
            rgvCommand.setDestinationStaNo1(wrkMast1.getRgvDstaNo().shortValue());   //工位1目标站点
            rgvCommand.setCommand((short) 0);   //工位1、2任务确认
            if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(4, rgvCommand))) {
                //step=2,工位1、2任务确认;   step=4,工位1确认;     step=5,工位2任务确认
                log.error("RGV命令下发失败,RGV号={},任务数据={}", slave.getId(), JSON.toJSON(rgvCommand));
            } else {
                // 修改工作档状态 2.设备上走 => 6.RGV入库取货中
                Date now = new Date();
                wrkMast1.setWrkSts(6L);
                wrkMast1.setCrnStrTime(now);
                wrkMast1.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast1) == 0) {
                    log.error("修改工作档状态 2.设备上走 => 6.RGV入库取货中 失败!!,工作号={}", wrkMast1.getWrkNo());
                }
            }
        }
    }
    /**
     * 出库  ===>>  RGV出库站到站
     */
    public synchronized void rgvOutStn(RgvSlave slave, RgvProtocol rgvProtocol) {
        //查找工作状态为14(出库完成),且RGV出库接驳站符合的的出库工作档,提取出最多2笔
        List<WrkMast> wrkMastTask = getRgvOutTask(slave);
        if(wrkMastTask.size() <= 0){
            return;
        }
        // RGV控制过滤, 必须满足自动、空闲,没有任务号
        if (!rgvProtocol.getStatusType().equals(CrnStatusType.IDLE)
                || rgvProtocol.getModeType() != RgvModeType.AUTO
                || rgvProtocol.getTaskNo1() != 0 || rgvProtocol.getTaskNo2() != 0) {
            return;
        }
        // 已经存在RGV执行任务时,则过滤
        if(wrkMastMapper.selectRgvOutWorking(slave.getId()).size() > 0){
            return;
        }
        if(wrkMastTask.size() == 2){
            //有2笔RGV待入库任务,2个工位,取货、放货任务同时下发
            WrkMast wrkMast1 = wrkMastTask.get(0);
            WrkMast wrkMast2 = wrkMastTask.get(1);
            if(Cools.isEmpty(wrkMast1) || Cools.isEmpty(wrkMast2)){
                log.error("工作档RGV入库数据为空");
                return;
            }
            //  命令下发区 --------------------------------------------------------------------------
            RgvCommand rgvCommand = new RgvCommand();
            rgvCommand.setRgvNo(slave.getId()); // RGV编号
            rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
            rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
            rgvCommand.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 工位1任务模式:  取放货
            rgvCommand.setSourceStaNo1(wrkMast1.getRgvSstaNo().shortValue());   //工位1源站点
            rgvCommand.setDestinationStaNo1(wrkMast1.getRgvDstaNo().shortValue());   //工位1目标站点
            rgvCommand.setAckFinish2((short) 0);  // 工位2任务完成确认位
            rgvCommand.setTaskNo2(wrkMast2.getWrkNo().shortValue()); // 工位2工作号
            rgvCommand.setTaskMode2(RgvTaskModeType.FETCH_PUT); // 工位2任务模式:  取放货
            rgvCommand.setSourceStaNo2(wrkMast2.getRgvSstaNo().shortValue());   //工位2源站点
            rgvCommand.setDestinationStaNo2(wrkMast2.getRgvDstaNo().shortValue());   //工位2目标站点
            rgvCommand.setCommand((short) 0);   //工位1、2任务确认
            if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(2, rgvCommand))) {
                //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
                log.error("RGV命令下发失败,RGV号={},任务数据={}", slave.getId(), JSON.toJSON(rgvCommand));
            } else {
                // 修改工作档状态 14.出库完成 => 16.RGV出库取货中
                Date now = new Date();
                wrkMast1.setWrkSts(16L);
                wrkMast1.setCrnStrTime(now);
                wrkMast1.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast1) == 0) {
                    log.error("修改工作档状态 14.出库完成 => 16.RGV出库取货中 失败!!,工作号={}", wrkMast1.getWrkNo());
                }
                wrkMast2.setWrkSts(16L);
                wrkMast2.setCrnStrTime(now);
                wrkMast2.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast2) == 0) {
                    log.error("修改工作档状态 14.出库完成 => 16.RGV出库取货中 失败!!,工作号={}", wrkMast2.getWrkNo());
                }
            }
        } else if(wrkMastTask.size() == 1){
            //只有1笔RGV待入库任务,先下发取货任务,取货后再判断是否有下一笔待入库任务
            WrkMast wrkMast1 = wrkMastTask.get(0);
            if(Cools.isEmpty(wrkMast1)){
                log.error("工作档RGV入库数据为空");
                return;
            }
            //  命令下发区 --------------------------------------------------------------------------
            RgvCommand rgvCommand = new RgvCommand();
            rgvCommand.setRgvNo(slave.getId()); // RGV编号
            rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
            rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
            rgvCommand.setTaskMode1(RgvTaskModeType.FETCH); // 工位1任务模式:  取货
            rgvCommand.setSourceStaNo1(wrkMast1.getRgvSstaNo().shortValue());   //工位1源站点
            rgvCommand.setDestinationStaNo1(wrkMast1.getRgvDstaNo().shortValue());   //工位1目标站点
            rgvCommand.setCommand((short) 0);   //工位1、2任务确认
            if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(4, rgvCommand))) {
                //step=2,工位1、2任务确认;   step=4,工位1确认;     step=5,工位2任务确认
                log.error("RGV命令下发失败,RGV号={},任务数据={}", slave.getId(), JSON.toJSON(rgvCommand));
            } else {
                // 修改工作档状态 14.出库完成 => 16.RGV出库取货中
                Date now = new Date();
                wrkMast1.setWrkSts(16L);
                wrkMast1.setCrnStrTime(now);
                wrkMast1.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast1) == 0) {
                    log.error("修改工作档状态 14.出库完成 => 16.RGV出库取货中 失败!!,工作号={}", wrkMast1.getWrkNo());
                }
            }
        }
    }
    /**
     * 查找工作状态为14(出库完成),且RGV出库接驳站符合的的出库工作档,提取出最多2笔
     * @param slave
     * @return
@@ -2248,347 +2533,6 @@
            }
        }
        return wrkMastTask;
    }
    /**
     * 根据RGV完成信号,执行对工作档的完成操作,和RGV的任务下发
     */
    public synchronized void rgvFinished() {
        Date now = new Date();
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            // 获取RGV信息
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                continue;
            }
            //判断RGV是否空闲,工位1是否空闲,工位1是否有物,是否为电脑模式,工位1是否有工作号
            if (rgvProtocol.statusType1 == RgvStatusType.FETCHWAITING
                    && rgvProtocol.getModeType() == RgvModeType.AUTO
                    && rgvProtocol.getTaskNo1() != 0
                    && rgvProtocol.getStatus() != 0
                    && rgvProtocol.getStatus1() != 0
            ) {
                WrkMast wrkMast1 = wrkMastMapper.selectPakInStep3(rgvProtocol.getTaskNo1().intValue());
                if (wrkMast1 == null) {
                    log.error("RGV工位1处于等待确认且取货任务完成状态,但未找到工作档。RGV号={},工作号={}", rgv.getId(), rgvProtocol.getTaskNo1());
                    continue;
                }
                if (wrkMast1.getWrkSts() == 3) {//3.RGV取货中 => 4.RGV取货完成
                    wrkMast1.setWrkSts(4L);
                }else if(wrkMast1.getWrkSts() == 5){//5.RGV放货中 => 6.RGV放货完成
                    rgvProtocol.setTaskNo1((short) 0);//入库任务完成,清空任务号
                    wrkMast1.setWrkSts(6L);
                } else if (wrkMast1.getWrkSts() == 24) {//24.RGV取货中 => 25.RGV取货完成
                    wrkMast1.setWrkSts(25L);//
                } else if (wrkMast1.getWrkSts() == 26) {//26.RGV放货中 => 27.RGV放货完成
                    rgvProtocol.setTaskNo1((short) 0);//出库任务完成,清空任务号
                    wrkMast1.setWrkSts(27L);//27.RGV放货完成
                }
                //解锁路径
                RgvUtils.unLockPath(wrkMast1.getRgvNo());
                wrkMast1.setModiTime(now);
                if (wrkMastMapper.updateById(wrkMast1) == 0) {
                    log.error("工位1修改工作档状态失败!!,工作号={}", wrkMast1.getWrkNo());
                }
                //  命令下发区 --------------------------------------------------------------------------
                RgvCommand rgvCommand = new RgvCommand();
                rgvCommand.setRgvNo(rgv.getId()); // RGV编号
                rgvCommand.setAckFinish1((short) 1);  // 工位1任务完成确认位
                rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
                rgvCommand.setTaskMode1(RgvTaskModeType.NONE); // 工位1任务模式:  无
                rgvCommand.setCommand((short) 1);   //工位1任务确认
                if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(4, rgvCommand))) {
                    //step=2,工位1、2任务确认;   step=4,工位1确认;     step=5,工位2任务确认
                    log.error("RGV命令下发失败,RGV号={},任务数据={}", rgv.getId(), JSON.toJSON(rgvCommand));
                }
//                //工位1取货完成后,工位2是无货空闲状态时,准备给工位2发任务,确认是否有待执行RGV任务
//                if (rgvProtocol.getModeType() == RgvModeType.AUTO
//                        && rgvProtocol.getTaskNo1() > 0 && rgvProtocol.getTaskNo2() == 0
//                        && rgvProtocol.getLoaded1() > 0 && rgvProtocol.getLoaded2() == 0
//                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
//                ) {
//                    WrkMast wrkMast1 = wrkMastMapper.selectPakInStep3(rgvProtocol.getTaskNo1().intValue());
//                    if (wrkMast1 == null) {
//                        log.error("RGV工位1处于等待确认且取货任务完成状态,但未找到工作档。RGV号={},工作号={}", rgv.getId(), rgvProtocol.getTaskNo1());
//                        continue;
//                    }
//                    List<WrkMast> wrkMastTask = new ArrayList<>();
//                    List<WrkMast> list = new ArrayList<>();
//                    Integer type = 0;//1入库,2出库
//                    if(wrkMast1.getWrkSts()==6L){
//                        wrkMastTask = getRgvInTask(rgv);
//                        list = wrkMastMapper.selectRgvInWorking(rgv.getId());
//                        type = 1;
//                    } else if(wrkMast1.getWrkSts()==16L){
//                        wrkMastTask = getRgvOutTask(rgv);
//                        list = wrkMastMapper.selectRgvOutWorking(rgv.getId());
//                        type = 2;
//                    }
//                    if(wrkMastTask.size() > 0){//有继续执行任务,下发取货任务给工位2
//                        // 已经存在RGV执行任务时,则过滤
//                        if (list.size() > 1) {
//                            continue;
//                        }
//                        WrkMast wrkMast2 = wrkMastTask.get(0);
//                        //  命令下发区 --------------------------------------------------------------------------
//                        RgvCommand rgvCommand = new RgvCommand();
//                        rgvCommand.setRgvNo(rgv.getId()); // RGV编号
//                        rgvCommand.setAckFinish2((short) 0);  // 工位2任务完成确认位
//                        rgvCommand.setTaskNo2(wrkMast2.getWrkNo().shortValue()); // 工位2工作号
//                        rgvCommand.setTaskMode2(RgvTaskModeType.FETCH); // 工位2任务模式:  取货
//                        rgvCommand.setSourceStaNo2(wrkMast2.getRgvSstaNo().shortValue());   //工位2源站点
//                        rgvCommand.setDestinationStaNo2(wrkMast2.getRgvDstaNo().shortValue());   //工位2目标站点
//                        rgvCommand.setCommand((short) 0);   //工位1、2任务确认
//                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast2.getRgvNo(), new Task(5, rgvCommand))) {
//                            //step=2,工位1、2写任务;   step=4,工位1写任务;     step=5,工位2写任务
//                            log.error("RGV命令下发失败,RGV号={},任务数据={}", rgv.getId(), JSON.toJSON(rgvCommand));
//                        } else {
//                            // 修改工作档状态 2.设备上走 => 6.RGV入库取货中
//                            Date now = new Date();
//                            wrkMast2.setWrkSts(type==1 ? 6L : 16L);
//                            wrkMast2.setCrnStrTime(now);
//                            wrkMast2.setModiTime(now);
//                            if (wrkMastMapper.updateById(wrkMast2) == 0) {
//                                log.error("工位2修改工作档状态 2/14.设备上走 => 6/16.RGV入库取货中 失败!!,工作号={}", wrkMast2.getWrkNo());
//                            }
//                        }
//                    } else {//没有继续执行任务,下发放货任务给工位1
//                        if(type == 1 && wrkMast1.getWrkSts() != 6L){//RGV入库取货中
//                            continue;
//                        }
//                        if(type == 2 && wrkMast1.getWrkSts() != 16L){//RGV出库取货中
//                            continue;
//                        }
//
//                        //  命令下发区 --------------------------------------------------------------------------
//                        RgvCommand rgvCommand = new RgvCommand();
//                        rgvCommand.setRgvNo(rgv.getId()); // RGV编号
//                        rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
//                        rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
//                        rgvCommand.setTaskMode1(RgvTaskModeType.PUT); // 工位1任务模式:  放货
//                        rgvCommand.setSourceStaNo1(wrkMast1.getRgvSstaNo().shortValue());   //工位1源站点
//                        rgvCommand.setDestinationStaNo1(wrkMast1.getRgvDstaNo().shortValue());   //工位1目标站点
//                        rgvCommand.setCommand((short) 0);   //工位1、2任务确认
//                        if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(4, rgvCommand))) {
//                            //step=2,工位1、2任务确认;   step=4,工位1确认;     step=5,工位2任务确认
//                            log.error("RGV命令下发失败,RGV号={},任务数据={}", rgv.getId(), JSON.toJSON(rgvCommand));
//                        } else {
//                            // 修改工作档状态 6.RGV入库取货中 => 7.RGV入库放货中
//                            Date now = new Date();
//                            wrkMast1.setWrkSts(type==1 ? 7L : 17L);
//                            wrkMast1.setCrnEndTime(now);
//                            wrkMast1.setModiTime(now);
//                            if (wrkMastMapper.updateById(wrkMast1) == 0) {
//                                log.error("修改工作档状态 6/16.RGV入库取货中 => 7/17.RGV入库放货中 失败!!,工作号={}", wrkMast1.getWrkNo());
//                            }
//                            log.error("RGV命令下发成功,RGV号={},任务数据={}", rgv.getId(), JSON.toJSON(rgvCommand));
//                        }
//                    }
//                } else if (rgvProtocol.getModeType() == RgvModeType.AUTO
//                        && rgvProtocol.getTaskNo1() > 0 && rgvProtocol.getTaskNo2() > 0
//                        && rgvProtocol.getLoaded1() > 0 && rgvProtocol.getLoaded2() > 0
//                        && rgvProtocol.statusType2 == RgvStatusType.FETCHWAITING){
//                    //  工位2状态:也是取货完成等待确认91 并且  任务完成位 = 1,  工位1、2同时下发放货任务
//                    WrkMast wrkMast1 = wrkMastMapper.selectPakInStep3(rgvProtocol.getTaskNo1().intValue());
//                    WrkMast wrkMast2 = wrkMastMapper.selectPakInStep3(rgvProtocol.getTaskNo2().intValue());
//                    //  命令下发区 --------------------------------------------------------------------------
//                    RgvCommand rgvCommand = new RgvCommand();
//                    rgvCommand.setRgvNo(rgv.getId()); // RGV编号
//                    rgvCommand.setAckFinish1((short) 0);  // 工位1任务完成确认位
//                    rgvCommand.setTaskNo1(wrkMast1.getWrkNo().shortValue()); // 工位1工作号
//                    rgvCommand.setTaskMode1(RgvTaskModeType.PUT); // 工位1任务模式:  放货
//                    rgvCommand.setSourceStaNo1(wrkMast1.getRgvSstaNo().shortValue());   //工位1源站点
//                    rgvCommand.setDestinationStaNo1(wrkMast1.getRgvDstaNo().shortValue());   //工位1目标站点
//                    rgvCommand.setAckFinish2((short) 0);  // 工位2任务完成确认位
//                    rgvCommand.setTaskNo2(wrkMast2.getWrkNo().shortValue()); // 工位2工作号
//                    rgvCommand.setTaskMode2(RgvTaskModeType.PUT); // 工位2任务模式:  放货
//                    rgvCommand.setSourceStaNo2(wrkMast2.getRgvSstaNo().shortValue());   //工位2源站点
//                    rgvCommand.setDestinationStaNo2(wrkMast2.getRgvDstaNo().shortValue());   //工位2目标站点
//                    rgvCommand.setCommand((short) 0);   //工位1、2任务确认
//                    if (!MessageQueue.offer(SlaveType.Crn, wrkMast1.getRgvNo(), new Task(2, rgvCommand))) {
//                        //step=2,工位1、2任务确认;   step=4,工位1确认;     step=5,工位2任务确认
//                        log.error("RGV命令下发失败,RGV号={},任务数据={}", rgv.getId(), JSON.toJSON(rgvCommand));
//                    } else {
//                        // 修改工作档状态 2.设备上走 => 6.RGV入库取货中
//                        Date now = new Date();
//                        wrkMast1.setWrkSts(wrkMast1.getWrkSts()==6L ? 7L : 17L);
//                        wrkMast1.setCrnStrTime(now);
//                        wrkMast1.setModiTime(now);
//                        if (wrkMastMapper.updateById(wrkMast1) == 0) {
//                            log.error("修改工作档状态 6/16.RGV入库取货中 => 7/17.RGV入库放货中 失败!!,工作号={}", wrkMast1.getWrkNo());
//                        }
//
//                        wrkMast2.setWrkSts(wrkMast2.getWrkSts()==6L ? 7L : 17L);
//                        wrkMast2.setCrnStrTime(now);
//                        wrkMast2.setModiTime(now);
//                        if (wrkMastMapper.updateById(wrkMast2) == 0) {
//                            log.error("修改工作档状态 6/16.RGV入库取货中 => 7/17.RGV入库放货中 失败!!,工作号={}", wrkMast2.getWrkNo());
//                        }
//                    }
//                }
            }
        }
    }
    /**
     * 入出库  ===>>  RGV出库站到堆垛机入库站/系统入库站
     * rgvInDStnToCrnStn
     */
    public synchronized void rgvDestStnToCrnStn() {
        for (RgvSlave rgvSlave : slaveProperties.getRgv()) {
            // 遍历入库任务的RGV出库站
            for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvDestStn()) {
                // 获取RGV出库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, rgvStn.getDevpPlcId());
                StaProtocol staProtocol = devpThread.getStation().get(rgvStn.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                    // 查询工作档List
//                    List<WrkMast> wrkMasts = wrkMastMapper.selectRgvInStep2(staProtocol.getSiteId());
                    List<WrkMast> wrkMasts = wrkMastMapper.selectRgvDestStep2(staProtocol.getSiteId());
                    for(WrkMast wrkMast : wrkMasts){
                        // 判断工作档条件
                        if (wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null
                            || wrkMast.getRgvSstaNo() == null || wrkMast.getRgvDstaNo() == null) {
                            continue;
                        }
                        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, wrkMast.getRgvNo());
                        RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                        //  判断RGV状态等待确认,工位1
                        if (rgvProtocol.modeType == RgvModeType.AUTO && rgvProtocol.getTaskNo1().equals(wrkMast.getWrkNo().shortValue())
                                && rgvProtocol.statusType1 == RgvStatusType.WAITING) {
                            // 命令下发区 --------------------------------------------------------------------------
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(wrkMast.getStaNo());
                            if (!MessageQueue.offer(SlaveType.Devp, rgvStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                continue;
                            }
                            // 更新工作档状态为2,14
                            wrkMast.setWrkSts(wrkMast.getWrkSts()==7L ? 2L : 14L);
                            wrkMast.setOnlineYn("Y");
                            wrkMast.setCrnEndTime(new Date());
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                // 复位RGV工位1
                                rgvThread.setResetFlag1(true);
                            } else {
                                log.error("RGV工位1接驳,更新工作档的工作状态为{}失败!!! [工作号:{}]", wrkMast.getWrkSts()==7L ? 2L : 14L, wrkMast.getWrkNo());
                            }
                        }
                        //  判断RGV状态等待确认,工位2
                        if (rgvProtocol.modeType == RgvModeType.AUTO && rgvProtocol.getTaskNo2().equals(wrkMast.getWrkNo().shortValue())
                                && rgvProtocol.statusType2 == RgvStatusType.WAITING) {
                            // 命令下发区 --------------------------------------------------------------------------
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(wrkMast.getStaNo());
                            if (!MessageQueue.offer(SlaveType.Devp, rgvStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                continue;
                            }
                            // 更新工作档状态为2,14
                            wrkMast.setWrkSts(wrkMast.getWrkSts()==7L ? 2L : 14L);
                            wrkMast.setOnlineYn("Y");
                            wrkMast.setCrnEndTime(new Date());
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                // 复位RGV工位2
                                rgvThread.setResetFlag2(true);
                            } else {
                                log.error("RGV工位2接驳,更新工作档的工作状态为{}失败!!! [工作号:{}]", wrkMast.getWrkSts()==7L ? 2L : 14L, wrkMast.getWrkNo());
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * 出库  ===>>  RGV出库站到系统出库站
     */
    public synchronized void rgvOutDStnToOutStn() {
        for (RgvSlave rgvSlave : slaveProperties.getRgv()) {
            // 遍历出库任务的RGV出库站
            for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvDestStn()) {
                // 获取RGV出库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, rgvStn.getDevpPlcId());
                StaProtocol staProtocol = devpThread.getStation().get(rgvStn.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                    // 查询工作档List
                    List<WrkMast> wrkMasts = wrkMastMapper.selectRgvOutStep2(staProtocol.getSiteId());
                    for(WrkMast wrkMast : wrkMasts){
                        // 判断工作档条件
                        if (wrkMast.getIoType() < 100 || wrkMast.getStaNo() == null || wrkMast.getSourceStaNo() == null
                                || wrkMast.getRgvSstaNo() == null || wrkMast.getRgvDstaNo() == null) {
                            continue;
                        }
                        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, wrkMast.getRgvNo());
                        RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                        //  判断RGV状态等待确认,工位1
                        if (rgvProtocol.modeType == RgvModeType.AUTO && rgvProtocol.getTaskNo1().equals(wrkMast.getWrkNo().shortValue())
                                && rgvProtocol.statusType1 == RgvStatusType.WAITING) {
                            // 命令下发区 --------------------------------------------------------------------------
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(wrkMast.getStaNo());
                            if (!MessageQueue.offer(SlaveType.Devp, rgvStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                continue;
                            }
                            // 更新工作档状态为14
                            wrkMast.setWrkSts(14L);
                            wrkMast.setOnlineYn("Y");   //控制WMS将工作状态14转15的时机,只有RGV运搬完成后才可以转
                            wrkMast.setCrnEndTime(new Date());
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                // 复位RGV工位1
                                rgvThread.setResetFlag1(true);
                            } else {
                                log.error("RGV工位1接驳,更新工作档的工作状态为2失败!!! [工作号:{}]", wrkMast.getWrkNo());
                            }
                        }
                        //  判断RGV状态等待确认,工位2
                        if (rgvProtocol.modeType == RgvModeType.AUTO && rgvProtocol.getTaskNo2().equals(wrkMast.getWrkNo().shortValue())
                                && rgvProtocol.statusType2 == RgvStatusType.WAITING) {
                            // 命令下发区 --------------------------------------------------------------------------
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(wrkMast.getStaNo());
                            if (!MessageQueue.offer(SlaveType.Devp, rgvStn.getDevpPlcId(), new Task(2, staProtocol))) {
                                continue;
                            }
                            // 更新工作档状态为14
                            wrkMast.setWrkSts(14L);
                            wrkMast.setOnlineYn("Y");   //控制WMS将工作状态14转15的时机,只有RGV运搬完成后才可以转
                            wrkMast.setCrnEndTime(new Date());
                            if (wrkMastMapper.updateById(wrkMast) != 0) {
                                // 复位RGV工位2
                                rgvThread.setResetFlag2(true);
                            } else {
                                log.error("RGV工位2接驳,更新工作档的工作状态为2失败!!! [工作号:{}]", wrkMast.getWrkNo());
                            }
                        }
                    }
                }
            }
        }
    }
    /**
@@ -2675,6 +2619,47 @@
                if (crnProtocol.getTaskNo() == 32222) {
                    // 堆垛机复位
                    crnThread.setResetFlag(true);
                } else if (crnProtocol.getCrnNo()<3) {
                    // 获取入库待确认工作档
                    WrkMastCrn wrkMastCrn = wrkMastCrnMapper.selectWrkNoOneAndTwo(crnProtocol.getTaskNo().intValue());
                    if (wrkMastCrn == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                    }
                    // 获取入库待确认工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNo().intValue());
                    if (wrkMast == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                    }
                    // 获取入库待确认工作档
                    WrkMast wrkMastOther = wrkMastMapper.selectPakInStep3(wrkMastCrn.getWrkNoTwo().intValue());
                    if (wrkMastOther == null) {
                        log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                        continue;
                    }
                    // 入库 + 库位转移  ==> 4.入库完成
                    if (wrkMastCrn.getWrkSts() == 3 || (wrkMastCrn.getWrkSts() == 12 && wrkMastCrn.getIoType() == 11)) {
                        wrkMastCrn.setWrkSts(4L);
                    } else {
                        continue;
                    }
                    Date now = new Date();
                    wrkMastCrn.setModiTime(now);
                    wrkMast.setCrnEndTime(now);
                    wrkMast.setWrkSts(4L);
                    wrkMast.setModiTime(now);
                    wrkMastOther.setCrnEndTime(now);
                    wrkMastOther.setWrkSts(4L);
                    wrkMastOther.setModiTime(now);
                    // 修改成功后复位堆垛机
                    if (wrkMastCrnMapper.updateById(wrkMastCrn) > 0 && wrkMastMapper.updateById(wrkMast) > 0 && wrkMastMapper.updateById(wrkMastOther) > 0 ) {
                        // 堆垛机复位
                        crnThread.setResetFlag(true);
                    }
                } else {
                    // 获取入库待确认工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(crnProtocol.getTaskNo().intValue());
@@ -3013,6 +2998,63 @@
    }
    /**
     * 空栈板初始化入库,叉车入库站放货
     */
    public synchronized void storeEmptyPltSingle() {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历空板入库口
            for (DevpSlave.Sta emptyInSta : devp.getEmptyInSingleSta()) {
                // 获取空板入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(emptyInSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                // 站点条件判断
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable()
                        && staProtocol.isEmptyMk() && ((staProtocol.getWorkNo() > 32222 && staProtocol.getWorkNo() <= 63333) || staProtocol.getWorkNo()==0)  && staProtocol.isPakMk()) {
                    try {
                        LocTypeDto locTypeDto = new LocTypeDto(staProtocol);
                        SearchLocParam param = new SearchLocParam();
                        param.setIoType(10);
                        param.setSourceStaNo(emptyInSta.getStaNo());
                        param.setLocType1(locTypeDto.getLocType1());
                        String response = new HttpHandler.Builder()
                                .setUri(wmsUrl)
                                .setPath("/rpc/pakin/pair/station/single/loc/v1")
                                .setJson(JSON.toJSONString(param))
                                .build()
                                .doPost();
                        JSONObject jsonObject = JSON.parseObject(response);
                        if (jsonObject.getInteger("code").equals(200)) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            // 更新站点信息 且 下发plc命令
                            staProtocol.setWorkNo(dto.getWorkNo());
                            staProtocol.setStaNo(dto.getStaNo());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            if (!result) {
                                throw new CoolException("更新plc站点信息失败");
                            }
                        } else {
                            log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/pair/station/single/loc/v1", JSON.toJSONString(param), response);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }
                }
            }
        }
    }
    /**
     * 入库  ===>> 空栈板初始化入库,1楼叠盘机叠盘
     */
    public synchronized void storeEmptyPlt2() {
@@ -3054,6 +3096,10 @@
     */
    public synchronized void storeEmptyPlt3() {
        try{
            RgvOneSign rgvOneSign = rgvOneSignMapper.selectOneSign();
            if (Cools.isEmpty(rgvOneSign) || rgvOneSign.getRgvOneSign()==1){
                return;
            }
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
@@ -3069,9 +3115,17 @@
                // 只有当RGV空闲、自动,工位二有物//rgv可用
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        &&  (rgvProtocol.getLoaded2()==2  || rgvProtocol.getLoaded2()==3 ) ////0 无物;1 一层无物二层有物  ;2一层有物二层无物 (只能满放);3  1、2层都有物
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
//                        &&  (rgvProtocol.getLoaded2()==2  || rgvProtocol.getLoaded2()==3 ) ////0 无物;1 一层无物二层有物  ;2一层有物二层无物 (只能满放);3  1、2层都有物  4:()只允许拆盘
                        &&  rgvProtocol.getLoaded2()==3 ////0 无物;1 一层无物二层有物  ;2一层有物二层无物 (只能满放);3  1、2层都有物  4:()只允许拆盘
                ) {
                    try {
                        WrkMast wrkMast1 = wrkMastMapper.selectPakOutStep3(122);
                        if (!Cools.isEmpty(wrkMast1)){
                            continue;
                        }
                        // 获取空板入库站信息
                        SearchLocParam param = new SearchLocParam();
@@ -3092,7 +3146,7 @@
                            if (!Cools.isEmpty(wrkMast) && wrkMast.getIoType()==10 && wrkMast.getWrkSts()==2){
                                WrkMastSta wrkMastSta = wrkMastStaMapper.selectByWrkNo(wrkMast.getWrkNo().longValue());
                                if (Cools.isEmpty(wrkMastSta)){
                                    WrkMastSta wrkMastSta1 = new WrkMastSta(new Date(),0);
                                    WrkMastSta wrkMastSta1 = new WrkMastSta(new Date(),wrkMast.getStaNo());
                                    wrkMastSta1.setWrkNo(wrkMast.getWrkNo().longValue());
                                    wrkMastSta1.setType(2);
                                    wrkMastSta1.setWrkType(6);//工作类型  1:取(叠盘)  2:拆盘  3:取放 5:满取  6:满放
@@ -3147,6 +3201,7 @@
                // 出库模式
                switch (wrkMast.getIoType()) {
                    case 1:
                    case 202:
                        ledCommand.setTitle("全板入库");
                        break;
                    case 10:
@@ -3168,6 +3223,10 @@
                        ledCommand.setTitle("空板出库");
                        ledCommand.setEmptyMk(true);
                        break;
                    case 212:
                        ledCommand.setTitle("空板出库");
                        ledCommand.setEmptyMk(true);
                        break;
                    default:
                        log.error("任务入出库类型错误!!![工作号:{}] [入出库类型:{}]", wrkMast.getWrkNo(), wrkMast.getIoType());
                        break;
@@ -3178,7 +3237,7 @@
//                ledCommand.setSourceStaNo(wrkMast.getSourceStaNo());
                if (wrkMast.getIoType() != 110 && wrkMast.getIoType() != 10) {
                    List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo());
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getAnfme())));
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl)));
                }
                commands.add(ledCommand);
            }
@@ -3191,21 +3250,22 @@
            }
            // 命令下发 -------------------------------------------------------------------------------
            if (!commands.isEmpty()) {
                if (led.getId() == 7) {
//                if (led.getId() == 7) {
                    if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(3, commands))) {
                        log.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort());
                        continue;
                    } else {
                        ledThread.setLedMk(false);
                    }
                } else {
                    if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(1, commands))) {
                        log.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort());
                        continue;
                    } else {
                        ledThread.setLedMk(false);
                    }
                }
//                }
//                else {
//                    if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(1, commands))) {
//                        log.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort());
//                        continue;
//                    } else {
//                        ledThread.setLedMk(false);
//                    }
//                }
            }
@@ -3467,26 +3527,26 @@
        }
    }
    /**
     * 初始化RGV地图
     */
    public synchronized void initRgvMap() {
        Object data = redisUtil.get("rgv_map");
        if (data == null) {
            //重新获取全路径地图
            BasRgvPath basRgvPath = basRgvPathService.selectByRgvNo(0);//获取默认路径
            if (basRgvPath != null) {
                ArrayList<RgvNode> rgvNodes = new ArrayList<>();
                List<Integer> rgvPath = JSON.parseArray(basRgvPath.getPath(), Integer.class);
                for (Integer integer : rgvPath) {
                    RgvNode rgvNode = new RgvNode(integer);
                    rgvNodes.add(rgvNode);
                }
                //将数据库地图数据存入redis
                redisUtil.set("rgv_map", JSON.toJSONString(rgvNodes));
            }
        }
    }
//    /**
//     * 初始化RGV地图
//     */
//    public synchronized void initRgvMap() {
//        Object data = redisUtil.get("rgv_map");
//        if (data == null) {
//            //重新获取全路径地图
//            BasRgvPath basRgvPath = basRgvPathService.selectByRgvNo(0);//获取默认路径
//            if (basRgvPath != null) {
//                ArrayList<RgvNode> rgvNodes = new ArrayList<>();
//                List<Integer> rgvPath = JSON.parseArray(basRgvPath.getPath(), Integer.class);
//                for (Integer integer : rgvPath) {
//                    RgvNode rgvNode = new RgvNode(integer);
//                    rgvNodes.add(rgvNode);
//                }
//                //将数据库地图数据存入redis
//                redisUtil.set("rgv_map", JSON.toJSONString(rgvNodes));
//            }
//        }
//    }
    /**
     * 堆垛机演示  ===>> 库位移转
@@ -3702,97 +3762,6 @@
    }
    public synchronized void outOfDevp() {
        List<WrkMast> wrkMasts = wrkMastMapper.selectPick();
        for (WrkMast wrkMast : wrkMasts) {
            if (basDevpService.selectCount(new EntityWrapper<BasDevp>().eq("wrk_no", wrkMast.getWrkNo())) == 0) {
                wrkMast.setCtnNo("Y");
                if (wrkMastMapper.updateById(wrkMast) == 0) {
                    log.error("修改{}工作档失败,ctn_no", wrkMast.getWrkNo());
                }
            }
        }
    }
    public synchronized void autoEmptyOut() {
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        Integer autoOutSite = 12;
        //如果站点可出禁用,则不生成空盘出库任务
        StaProtocol staProtocol = devpThread.getStation().get(autoOutSite);
        if (staProtocol == null) {
            return;
        } else {
            staProtocol = staProtocol.clone();
        }
        if (staProtocol.isAutoing()  //自动
                && !staProtocol.isLoading()  //无物
                && staProtocol.isOutEnable()  //可出信号
                && staProtocol.getWorkNo() == 0
        ) {
            WrkMast pakoutEmpty = wrkMastMapper.selectPakoutEmpty(autoOutSite);
            if (null != pakoutEmpty) {
                return;
            }
            try {
                String response = new HttpHandler.Builder()
                        .setUri(wmsUrl)
                        .setPath("/rpc/auto/emptyOut/v1")
                        .build()
                        .doPost();
                JSONObject jsonObject = JSON.parseObject(response);
                if (jsonObject.getInteger("code").equals(200)) {
                    JSONObject data = (JSONObject) jsonObject.get("data");
                    log.info((String) data.get("msg"));
                } else {
                    log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/auto/emptyOut/v1","", response);
                }
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
    }
    public synchronized void autoEmptyIn() {
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        Integer autoInSite = 12;
        StaProtocol staProtocol = devpThread.getStation().get(autoInSite);
        if (staProtocol == null) {
            return;
        } else {
            staProtocol = staProtocol.clone();
        }
        if (staProtocol.isAutoing()  //自动
                && staProtocol.isLoading()  //有物
                && staProtocol.isInEnable()  //可入信号
                && (staProtocol.getWorkNo() == 0 || staProtocol.getWorkNo() > 9990) //工作号为0或者工作号是9991~9999(输送机留用)
        ) {
            try {
                LocTypeDto locTypeDto = new LocTypeDto((short) 1, (short) 1, (short) 1);
                String response = new HttpHandler.Builder()
                        .setUri(wmsUrl)
                        .setPath("/rpc/auto/emptyIn/v1")
                        .setJson(JSON.toJSONString(locTypeDto))
                        .build()
                        .doPost();
                JSONObject jsonObject = JSON.parseObject(response);
                if (jsonObject.getInteger("code").equals(200)) {
                    log.info((String) jsonObject.get("msg"));
                } else {
                    log.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/auto/emptyIn/v1", JSON.toJSONString(locTypeDto), response);
                }
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
    }
//    /**
//     * 其他  ===>> 码垛位自动补充空板:驱动拆盘机输出托盘
//     */
@@ -3863,10 +3832,10 @@
     */
    public synchronized void stackingCompletionDriveTray() {
        try {
            int[] staNos=new int[]{216,220,123};//(3个入库站点,1楼1个退货码垛站,2楼两个入库码垛站)
            int[] staNos=new int[]{215,219};//(2楼两个入库码垛站)
            for (int staNo : staNos){
                BasDevp basDevp = basDevpService.selectById(staNo);
                if (basDevp.getWrkNo()!=9992 || Cools.isEmpty(basDevp.getBarcode())){
                if ((basDevp.getWrkNo()!=0 && (basDevp.getWrkNo()<9900 || basDevp.getWrkNo()>9999)) || Cools.isEmpty(basDevp.getBarcode())){
                    continue;
                }
                Integer zpallet = waitPakinMapper.selectCount(new EntityWrapper<WaitPakin>().eq("zpallet", basDevp.getBarcode()).eq("status","N"));
@@ -3897,11 +3866,11 @@
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && !staProtocol.isEmptyMk()
                        && staProtocol.getWorkNo() == 9992
                        && (basDevp.getWrkNo()==0 || (basDevp.getWrkNo()>=9900 && basDevp.getWrkNo()<=9999))
                ) {//&& staProtocol.isPakMk() && !Cools.isEmpty(barcode)) {
                    staProtocol.setWorkNo(9999);
                    staProtocol.setStaNo(staNo + 1);
                    int workNo = commonService.getWorkNo(5);
                    staProtocol.setWorkNo(workNo);
                    staProtocol.setStaNo(staNo + 2);
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devpThread.getSlave().getId(), new Task(2, staProtocol));
                    if (!result) {
@@ -3924,7 +3893,10 @@
            int[] staNos=new int[]{131,135};//(2个入库站点,1楼2个出库码垛站,根据现场修改)
            for (int staNo : staNos){
                BasDevp basDevp = basDevpService.selectById(staNo);
                if (basDevp.getWrkNo()!=0){
                if (Cools.isEmpty(basDevp) || basDevp.getReportSign()!=1){
                    continue;
                }
                if (basDevp.getWrkNo()!=0 && (basDevp.getWrkNo()<9900 || basDevp.getWrkNo()>9999)){
                    continue;
                }
                WrkMast wrkMast = wrkMastMapper.selectWrkMastUnstackingOne202(staNo);
@@ -3954,7 +3926,7 @@
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && staProtocol.getWorkNo() == 0
                        && (staProtocol.getWorkNo() == 0 || (staProtocol.getWorkNo()>9899 && staProtocol.getWorkNo()<10000))
                ) {//&& staProtocol.isPakMk() && !Cools.isEmpty(barcode)) {
                    //任务完成
@@ -4009,7 +3981,7 @@
                        // 无拣料数据
                        continue;
                    }
                    if (!wrkMast.getSheetNo().equals("2") || wrkMast.getIoType()<100 || wrkMast.getWrkSts()!=14){
                    if (Cools.isEmpty(wrkMast.getSheetNo()) || !wrkMast.getSheetNo().equals("2") || wrkMast.getIoType()<100 || wrkMast.getWrkSts()!=14){
                        continue;
                    }
                    if (wrkMast.getIoType()==101){
@@ -4048,7 +4020,7 @@
            int[] staNos=new int[]{144};//(1楼1个贴标位,根据现场修改)
            for (int staNo : staNos){
                BasDevp basDevp = basDevpService.selectById(staNo);
                if ((basDevp.getWrkNo()<9900 || basDevp.getWrkNo()>19999) && basDevp.getWrkNo()!=32222){
                if ((basDevp.getWrkNo()<9900 || basDevp.getWrkNo()>9999) && basDevp.getWrkNo()!=32222){
                    continue;
                }
                WrkMast wrkMast = wrkMastMapper.selectWrkMastUnstackingOne202(staNo);
@@ -4102,6 +4074,155 @@
    }
    /**
     * 其他  ===>> 退货码垛完成托盘继续下一步
     */
    public synchronized void stackingCompletionDriveTrayOk3() {
        try {
            int[] staNos=new int[]{118};
            for (int staNo : staNos){
                BasDevp basDevp = basDevpService.selectById(staNo);
                if (Cools.isEmpty(basDevp) || basDevp.getWrkNo()!=0 || basDevp.getReportSign()!=3){
                    continue;
                }
                WrkMast wrkMast = wrkMastMapper.selectWrkMastUnstackingOne145(145);
                if (Cools.isEmpty(wrkMast)){
                    continue;
                }
                // 获取站点信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                StaProtocol staProtocol = devpThread.getStation().get(staNo);
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                StaProtocol staProtocol147 = devpThread.getStation().get(147);
                if (staProtocol147 == null) {
                    continue;
                } else {
                    staProtocol147 = staProtocol147.clone();
                }
                if (!staProtocol.isLoading()){
                    log.info("{}站点无物,异常!",staNo);
                    continue;
                }
                if (staProtocol147.isLoading()){
                    log.info("{}站点有物!",staProtocol147.getSiteId());
                    continue;
                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && !staProtocol.isEmptyMk()
                ) {
                    boolean result3 = MessageQueue.offer(SlaveType.Devp, 1, new Task(3, staProtocol147));
                    staProtocol.setWorkNo(wrkMast.getWrkNo());
                    staProtocol.setStaNo(wrkMast.getStaNo());
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devpThread.getSlave().getId(), new Task(2, staProtocol));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败==>驱动码垛位托盘前进失败!");
                    }
                    wrkMast.setSheetNo("5");
                    wrkMastMapper.updateById(wrkMast);
                    boolean result4 = MessageQueue.offer(SlaveType.Devp, 1, new Task(3, staProtocol147));
                }
            }
        }catch (Exception e){
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("其他  ===>> 退货码垛完成托盘继续下一步"+e);
        }
    }
    /**
     * 其他  ===>> 拆垛完成继续下一步  运行途中自动避让空板
     */
    public synchronized void stackingCompletionDriveTray4() {
        try {
            int[] staNos=new int[]{134};//(134有任务,135空闲,则避让)
            for (int staNo : staNos){
                BasDevp basDevp = basDevpService.selectById(staNo);
                BasDevp basDevp135 = basDevpService.selectById(135);
                if (basDevp.getWrkNo()==0 || (basDevp.getWrkNo()<10000 && basDevp.getWrkNo()>9899) ){
                    continue;
                }
                if (basDevp135.getReportSign()!=0){
                    continue;
                }
                WrkMast wrkMast131 = wrkMastMapper.selectWrkMastUnstackingOne202Two(131);
                if (Cools.isEmpty(wrkMast131)){
                    continue;
                }
                // 获取站点信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                StaProtocol staProtocol135 = devpThread.getStation().get(135);
                if (staProtocol135 == null) {
                    continue;
                } else {
                    staProtocol135 = staProtocol135.clone();
                }
                if (staProtocol135.getWorkNo()<9900 || staProtocol135.getWorkNo()>9999 || staProtocol135.getWorkNo()==0
                        || !staProtocol135.isLoading() || !staProtocol135.isAutoing()){
                    continue;
                }
                StaProtocol staProtocol = devpThread.getStation().get(staNo);
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                if (!staProtocol.isLoading()){
                    continue;
                }
//                if (!staProtocol.getWorkNo().equals(wrkMast131.getWrkNo())){
//                    log.info("站点工作号={} 与贴标工作号={} 不一致,异常!",staProtocol.getWorkNo(),wrkMast131.getWrkNo().shortValue());
//                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && basDevp.getReportSign()==0
                ) {//&& staProtocol.isPakMk() && !Cools.isEmpty(barcode)) {
//                    if (true){
//                        return;
//                    }
                    //任务完成
                    boolean result1 = MessageQueue.offer(SlaveType.Devp, devpThread.getSlave().getId(), new Task(3, staProtocol135));
                    try{
                        Thread.sleep(100);
                    }catch (Exception e){ }
                    basDevp135.setReportSign(2);
                    basDevpService.updateById(basDevp135);
                    int workNo = commonService.getWorkNo(5);
                    staProtocol135.setWorkNo(workNo);
                    staProtocol135.setStaNo(144);
                    devpThread.setPakMk(staProtocol135.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devpThread.getSlave().getId(), new Task(2, staProtocol135));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败==>驱动码垛位托盘前进失败!");
                    }
                    boolean result2 = MessageQueue.offer(SlaveType.Devp, devpThread.getSlave().getId(), new Task(4, staProtocol135));
                }
            }
        }catch (Exception e){
//            e.printStackTrace();
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("其他  ===>> 贴标完成驱动托盘进入下一步"+e);
        }
    }
    /**
     *  完成小车任务
     */
    public synchronized void rgvCompleteWrkMastSta() {
@@ -4141,22 +4262,47 @@
                            log.error("未查到小车执行任务或者执行任务状态不符合!"+wrkMastSta);
                            continue;
                        }
                        boolean rgvComplete = rgvComplete(rgvProtocol.getRgvNo());
                        if (!rgvComplete){
                            log.error("小车复位失败,小车号{}!",rgvProtocol.getRgvNo());
                            break;
                        }
                        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                        StaProtocol staProtocol = devpThread.getStation().get(wrkMastSta.getStaEnd());
                        WrkMast wrkMast = wrkMastMapper.selectPakInStep3(wrkMastSta.getWrkNo().intValue());
                        if (!Cools.isEmpty(wrkMast)){
                        if (!Cools.isEmpty(wrkMast) && wrkMastSta.getWrkType()!=5){
                            Thread.sleep(200);
                            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                            StaProtocol staProtocol = devpThread.getStation().get(wrkMastSta.getStaEnd());
                            if (staProtocol == null) {
                                continue;
                            } else {
                                staProtocol = staProtocol.clone();
                            }
                            if (!staProtocol.isAutoing() || !staProtocol.isLoading()){
                                continue;
                            }
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(wrkMast.getStaNo());
                            if (!MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol))) {
                                continue;
                            }
                            log.error("小车任务完成下发输送线任务:"+staProtocol);
//                            try{
//                                Thread.sleep(1000);
//                                DevpThread devpThreadEnd = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
//                                StaProtocol staProtocolEnd = devpThreadEnd.getStation().get(wrkMastSta.getStaEnd());
//                                log.error("小车任务完成读取输送线任务:"+staProtocolEnd);
//                                if (staProtocolEnd.getWorkNo()==0 ){ //|| !staProtocolEnd.getWorkNo().equals(wrkMast.getWrkNo())
//                                    staProtocolEnd.setWorkNo(wrkMast.getWrkNo());
//                                    staProtocolEnd.setStaNo(wrkMast.getStaNo());
//                                    if (!MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocolEnd))) {
//                                        continue;
//                                    }
//                                    log.error("小车任务完成下发输送线任务第二次:"+staProtocolEnd);
//                                }
//                            }catch (Exception e){
//
//                            }
                        }
                        boolean rgvComplete = rgvComplete(rgvProtocol.getRgvNo());
                        if (!rgvComplete){
                            log.error("小车复位失败,小车号{}!",rgvProtocol.getRgvNo());
                            break;
                        }
                        wrkMastSta.setWrkSts(3);
                        wrkMastStaMapper.updateById(wrkMastSta);
@@ -4179,21 +4325,42 @@
                            log.error("未查到小车执行任务或者执行任务状态不符合!"+wrkMastSta);
                            continue;
                        }
                        boolean rgvComplete = rgvComplete(rgvProtocol.getRgvNo());
                        if (!rgvComplete){
                            log.error("小车复位失败,小车号{}!",rgvProtocol.getRgvNo());
                            break;
                        }
                        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                        StaProtocol staProtocol = devpThread.getStation().get(wrkMastSta.getStaEnd());
                        WrkMast wrkMast = wrkMastMapper.selectPakInStep3(wrkMastSta.getWrkNo().intValue());
                        if (!Cools.isEmpty(wrkMast)){
                        if (!Cools.isEmpty(wrkMast)  && wrkMastSta.getWrkType()!=5){
                            Thread.sleep(200);
                            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
                            StaProtocol staProtocol = devpThread.getStation().get(wrkMastSta.getStaEnd());
                            if (!staProtocol.isAutoing() || !staProtocol.isLoading()){
                                continue;
                            }
                            // 下发站点信息
                            staProtocol.setWorkNo(wrkMast.getWrkNo());
                            staProtocol.setStaNo(wrkMast.getStaNo());
                            if (!MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol))) {
                                continue;
                            }
                            log.error("小车任务完成下发输送线任务:"+staProtocol);
//                            try{
//                                Thread.sleep(1000);
//                                DevpThread devpThreadEnd = (DevpThread) SlaveConnection.get(SlaveType.Devp, 1);
//                                StaProtocol staProtocolEnd = devpThreadEnd.getStation().get(wrkMastSta.getStaEnd());
//                                log.error("小车任务完成读取输送线任务:"+staProtocolEnd);
//                                if (staProtocolEnd.getWorkNo()==0 ){ //|| !staProtocolEnd.getWorkNo().equals(wrkMast.getWrkNo())
//                                    staProtocolEnd.setWorkNo(wrkMast.getWrkNo());
//                                    staProtocolEnd.setStaNo(wrkMast.getStaNo());
//                                    if (!MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocolEnd))) {
//                                        continue;
//                                    }
//                                    log.error("小车任务完成下发输送线任务第二次:"+staProtocolEnd);
//                                }
//                            }catch (Exception e){
//
//                            }
                        }
                        boolean rgvComplete = rgvComplete(rgvProtocol.getRgvNo());
                        if (!rgvComplete){
                            log.error("小车复位失败,小车号{}!",rgvProtocol.getRgvNo());
                            break;
                        }
                        wrkMastSta.setWrkSts(3);
                        wrkMastStaMapper.updateById(wrkMastSta);
@@ -4210,11 +4377,14 @@
        }
    }
    /**
     * 执行小车搬运任务
     * 入出库  ===>>  小车作业下发
     */
    public synchronized void rgvRunWrkMastFullSta() {
    public synchronized boolean rgvIoExecute(Integer sign) {
        boolean rgvIoExecuteSign = false;
        try{
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                // 获取小车信息
                boolean signWork = false;
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
@@ -4228,6 +4398,98 @@
                // 只有当RGV空闲、自动,工位一无物//rgv可用
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        && rgvProtocol.getLoaded1()==0
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
                ) {
                    switch (sign){
                        //执行小车货物搬运任务
                        case 1:
                            signWork = rgvRunWrkMastFullSta(rgvSlave);
                            break;
                        //执行小车空板搬运任务
                        case 2://放//拆盘
                            signWork = rgvRunWrkMastEmptyStaPut(rgvSlave);
                            break;
                        case 3://满放
                            signWork = rgvRunWrkMastEmptyStaPutFull(rgvSlave);
                            break;
                        case 4://取叠盘
                            signWork = rgvRunWrkMastEmptyStaTake(rgvSlave);
                            break;
                        case 5:////满取
                            signWork = rgvRunWrkMastEmptyStaTakeFull(rgvSlave);
                            break;
                        case 6:////提升
//                            signWork = qwe();
                            break;
                        default:
                            break;
                    }
                    for (int signCount = 1;!signWork && signCount<7;signCount++){
                        switch (signCount){
                            case 1://执行小车货物搬运任务
                                signWork = rgvRunWrkMastFullSta(rgvSlave);
                                break;
                            case 2://放//拆盘
                                signWork = rgvRunWrkMastEmptyStaPut(rgvSlave);
                                break;
                            case 3://满放
                                signWork = rgvRunWrkMastEmptyStaPutFull(rgvSlave);
                                break;
                            case 4://取叠盘
                                signWork = rgvRunWrkMastEmptyStaTake(rgvSlave);
                                break;
                            case 5:////满取
                                signWork = rgvRunWrkMastEmptyStaTakeFull(rgvSlave);
                                break;
                            case 6:////提升
//                            signWork = rgvRunWrkMastEmptyStaPut();
                                break;
                            default:
                                break;
                        }
                    }
                }else {
                    continue;
                }
                if (!rgvIoExecuteSign){
                    rgvIoExecuteSign = signWork;
                }
            }
//            if (!rgvIoExecuteSign){
//                if (sign>6){
//
//                }
//            }
        }catch (Exception e){
            log.error("RGV小车任务下发报错"+e);
        }
        return rgvIoExecuteSign;
    }
    /**
     * 执行小车搬运任务
     */
    public synchronized boolean rgvRunWrkMastFullSta(RgvSlave rgvSlave) {
        try{
//            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    return false;
                }
                BasRgv basRgv = basRgvService.selectById(rgvSlave.getId());
                if (basRgv == null) {
                    log.error("{}号RGV尚未在数据库进行维护!", rgvSlave.getId());
                    return false;
                }
                // 只有当RGV空闲、自动,工位一无物//rgv可用
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        && rgvProtocol.getLoaded1()==0
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
@@ -4235,13 +4497,17 @@
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(basRgv.getRgvNo());
                    if (basRgvMap == null) {
                        log.error("{}号RGV尚未在数据库地图中进行维护!", rgvProtocol.getRgvNo());
                        continue;
                        return false;
                    }
                    List<Integer> route = RouteUtils.getRoute(basRgvMap.getStartRoute(), basRgvMap.getEndRoute());
                    basRgvMap.setNowRoute(rgvProtocol.getRgvPosI()); //更新小车当前位置站点号
                    List<WrkMastSta> wrkMastStaList = wrkMastStaMapper.selectNoInterfereList(route, route);
                    for (WrkMastSta wrkMastSta : wrkMastStaList){
                        if (wrkMastSta.getType()!=1 || wrkMastSta.getWrkType()!=3){//1:满版   3:取放
                            continue;
                        }
                        BasDevp basDevp = basDevpService.selectById(wrkMastSta.getStaEnd());
                        if (!basDevp.getAutoing().equals("Y") || basDevp.getLoading().equals("Y")){
                            continue;
                        }
                        boolean sign = rgvTakeFullAll(basRgvMap.getRgvNo(), wrkMastSta);
@@ -4254,7 +4520,7 @@
                                }catch (Exception e){
                                    log.error("更新小车任务失败");
                                }
                                return;
                                return true;
                            }else {
                                log.error("3864行,货物搬运任务:工作号{}所属任务下发后地图同步失败",wrkMastSta.getWrkNo());
                            }
@@ -4264,39 +4530,42 @@
                        break;
                    }
                }
            }
//            }
        }catch (Exception e){
            log.error("3875行执行小车搬运任务下发失败");
            log.error("3875行"+e);
        }
        return false;
    }
    /**
     * 执行小车搬运任务//拆盘
     */
    public synchronized void rgvRunWrkMastEmptyStaPut() {//拆盘
    public synchronized boolean rgvRunWrkMastEmptyStaPut(RgvSlave rgvSlave) {//拆盘
        try{
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
//            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    continue;
                    return false;
                }
                BasRgv basRgv = basRgvService.selectById(rgvSlave.getId());
                if (basRgv == null) {
                    log.error("{}号RGV尚未在数据库进行维护!", rgvSlave.getId());
                    continue;
                    return false;
                }
                // 只有当RGV空闲、自动,工位二有物//rgv可用//拆盘
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
                        && (rgvProtocol.getLoaded2()==3  || rgvProtocol.getLoaded2()==1 )////0 无物;1 一层无物二层有物 (只能拆叠) ;2一层有物二层无物 ;3  1、2层都有物
                        && (rgvProtocol.getLoaded2()==3  || rgvProtocol.getLoaded2()==1 || rgvProtocol.getLoaded2()==4)////0 无物;1 一层无物二层有物 (只能拆叠) ;2一层有物二层无物() ;3  1、2层都有物  4:()只允许拆盘
                ) {
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
                    if (basRgvMap == null) {
                        log.error("{}号RGV尚未在数据库地图中进行维护!", rgvProtocol.getRgvNo());
                        continue;
                        return false;
                    }
                    basRgvMap.setNowRoute(rgvProtocol.getRgvPosI()); //更新小车当前位置站点号
                    List<Integer> route = RouteUtils.getRoute(basRgvMap.getStartRoute(), basRgvMap.getEndRoute());//获取活动范围
@@ -4307,6 +4576,10 @@
                        }
                        boolean sign = false;
                        if ( wrkMastSta.getStaEnd()!=0){//放
                            BasDevp basDevp = basDevpService.selectById(wrkMastSta.getStaEnd());
                            if (!basDevp.getAutoing().equals("Y") || basDevp.getLoading().equals("Y")){
                                continue;
                            }
                            sign = rgvPutEmpty(rgvProtocol.getRgvNo(),wrkMastSta);//拆盘
                        }else {
                            continue;
@@ -4320,7 +4593,7 @@
                                }catch (Exception e){
                                    log.error("更新小车任务失败");
                                }
                                return;
                                return true;
                            }else {
                                log.error("3857行,货物搬运任务:工作号{}所属任务下发后地图同步失败",wrkMastSta.getWrkNo());
                            }
@@ -4330,49 +4603,57 @@
                        break;
                    }
                }
            }
//            }
        }catch (Exception e){
            log.error("3933行执行小车放空板任务下发失败");
            log.error("3933行"+e);
        }
        return false;
    }
    /**
     * 执行小车搬运任务
     */
    public synchronized void rgvRunWrkMastEmptyStaPutFull() {//满放
    public synchronized boolean rgvRunWrkMastEmptyStaPutFull(RgvSlave rgvSlave) {//满放
        try{
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
//            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    continue;
                    return false;
                }
                BasRgv basRgv = basRgvService.selectById(rgvSlave.getId());
                if (basRgv == null) {
                    log.error("{}号RGV尚未在数据库进行维护!", rgvSlave.getId());
                    continue;
                    return false;
                }
                // 只有当RGV空闲、自动,工位二有物//rgv可用
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        &&  (rgvProtocol.getLoaded2()==2  || rgvProtocol.getLoaded2()==3 ) ////0 无物;1 一层无物二层有物  ;2一层有物二层无物 (只能满放);3  1、2层都有物
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
                        &&  (rgvProtocol.getLoaded2()==2  || rgvProtocol.getLoaded2()==3 ) ////0 无物;1 一层无物二层有物  ;2一层有物二层无物 (只能满放);3  1、2层都有物  4:()只允许拆盘
                ) {
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
                    if (basRgvMap == null) {
                        log.error("{}号RGV尚未在数据库地图中进行维护!", rgvProtocol.getRgvNo());
                        continue;
                        return false;
                    }
                    basRgvMap.setNowRoute(rgvProtocol.getRgvPosI()); //更新小车当前位置站点号
                    List<Integer> route = RouteUtils.getRoute(basRgvMap.getStartRoute(), basRgvMap.getEndRoute());//获取活动范围
                    List<WrkMastSta> wrkMastStaList = wrkMastStaMapper.selectNoInterfereList(route, route);//查询可执行任务
                    for (WrkMastSta wrkMastSta : wrkMastStaList){
                        if (wrkMastSta.getType()!=2 || wrkMastSta.getWrkType()!=6){// 2:空板  || 工作类型  1:取(叠盘)  2:拆盘  5:满取  6:满放
                        if (wrkMastSta.getType()!=2 || wrkMastSta.getWrkType()!=6){// 2:空板  || 工作类型  1:取(叠盘)  2:拆盘  5:满取  6:满放  7:提升
                            continue;
                        }
                        boolean sign = false;
                        if (wrkMastSta.getStaStart()==0 && wrkMastSta.getStaEnd()!=0){//满放
                        if ( wrkMastSta.getStaEnd()!=0){//满放
                            BasDevp basDevp = basDevpService.selectById(wrkMastSta.getStaEnd());
                            if (!basDevp.getAutoing().equals("Y") || basDevp.getLoading().equals("Y")){
                                continue;
                            }
                            sign = rgvPutEmptyFull(rgvProtocol.getRgvNo(),wrkMastSta);
                        }else {
                            continue;
@@ -4386,7 +4667,7 @@
                                }catch (Exception e){
                                    log.error("更新小车任务失败");
                                }
                                return;
                                return true;
                            }else {
                                log.error("3857行,货物搬运任务:工作号{}所属任务下发后地图同步失败",wrkMastSta.getWrkNo());
                            }
@@ -4396,37 +4677,40 @@
                        break;
                    }
                }
            }
//            }
        }catch (Exception e){
            log.error("3933行执行小车放空板任务下发失败");
            log.error("3933行"+e);
        }
        return false;
    }
    public synchronized void rgvRunWrkMastEmptyStaTake() {//叠盘
    public synchronized boolean rgvRunWrkMastEmptyStaTake(RgvSlave rgvSlave) {//叠盘
        try{
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
//            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    continue;
                    return false;
                }
                BasRgv basRgv = basRgvService.selectById(rgvSlave.getId());
                if (basRgv == null) {
                    log.error("{}号RGV尚未在数据库进行维护!", rgvSlave.getId());
                    continue;
                    return false;
                }
                // 只有当RGV空闲、自动,工位二无物//rgv可用
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
                        &&  (rgvProtocol.getLoaded2()==0  || rgvProtocol.getLoaded2()==1 ) //现场修改:叠盘机,////0 无物;1 一层无物二层有物(只能拆叠)   ;2一层有物二层无物 (只能满放);3  1、2层都有物
                        &&  (rgvProtocol.getLoaded2()==0  || rgvProtocol.getLoaded2()==1 ) //现场修改:叠盘机,////0 无物;1 一层无物二层有物(只能拆叠)   ;2一层有物二层无物 (只能满放);3  1、2层都有物  4:()只允许拆盘
                ) {
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
                    if (basRgvMap == null) {
                        log.error("{}号RGV尚未在数据库地图中进行维护!", rgvProtocol.getRgvNo());
                        continue;
                        return false;
                    }
                    List<Integer> route = RouteUtils.getRoute(basRgvMap.getStartRoute(), basRgvMap.getEndRoute());
                    basRgvMap.setNowRoute(rgvProtocol.getRgvPosI()); //更新小车当前位置站点号
@@ -4437,6 +4721,10 @@
                        }
                        boolean sign = false;
                        if ( wrkMastSta.getStaStart()!=0){//取
                            BasDevp basDevp = basDevpService.selectById(wrkMastSta.getStaStart());
                            if (!basDevp.getAutoing().equals("Y") || !basDevp.getLoading().equals("Y")){
                                continue;
                            }
                            sign = rgvTakeEmpty(rgvProtocol.getRgvNo(),wrkMastSta);//叠盘
                        }else {
                            continue;
@@ -4450,7 +4738,7 @@
                                }catch (Exception e){
                                    log.error("更新小车任务失败");
                                }
                                return;
                                return true;
                            }else {
                                log.error("3879行,货物搬运任务:工作号{}所属任务下发后地图同步失败",wrkMastSta.getWrkNo());
                            }
@@ -4460,36 +4748,40 @@
                        break;
                    }
                }
            }
//            }
        }catch (Exception e){
            log.error("3989行执行小车取空板任务下发失败");
            log.error("3989行"+e);
        }
        return false;
    }
    public synchronized void rgvRunWrkMastEmptyStaTakeFull() {//满取
    public synchronized boolean rgvRunWrkMastEmptyStaTakeFull(RgvSlave rgvSlave) {//满取
        try{
            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
//            for (RgvSlave rgvSlave:slaveProperties.getRgv()) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    continue;
                    return false;
                }
                BasRgv basRgv = basRgvService.selectById(rgvSlave.getId());
                if (basRgv == null) {
                    log.error("{}号RGV尚未在数据库进行维护!", rgvSlave.getId());
                    continue;
                    return false;
                }
                // 只有当RGV空闲、自动,工位二无物//rgv可用
                if (rgvProtocol.getStatusType() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                        && rgvProtocol.getModeType() == RgvModeType.AUTO
                        &&  rgvProtocol.getLoaded2()==0  //现场修改:叠盘机,////0 无物;1 一层无物二层有物(只能拆叠)   ;2一层有物二层无物 (只能满放);3  1、2层都有物
                        && rgvProtocol.getTaskNo1()==0 && rgvProtocol.getTaskNo2()==0
                        &&  rgvProtocol.getLoaded2()==0  //现场修改:叠盘机,////0 无物;1 一层无物二层有物(只能拆叠)   ;2一层有物二层无物 (只能满放);3  1、2层都有物  4:()只允许拆盘
                ) {
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
                    if (basRgvMap == null) {
                        log.error("{}号RGV尚未在数据库地图中进行维护!", rgvProtocol.getRgvNo());
                        continue;
                        return false;
                    }
                    List<Integer> route = RouteUtils.getRoute(basRgvMap.getStartRoute(), basRgvMap.getEndRoute());
                    basRgvMap.setNowRoute(rgvProtocol.getRgvPosI()); //更新小车当前位置站点号
@@ -4499,7 +4791,11 @@
                            continue;
                        }
                        boolean sign = false;
                        if (wrkMastSta.getStaEnd()==0 && wrkMastSta.getStaStart()!=0){//满取
                        if (wrkMastSta.getStaStart()!=0){//满取
                            BasDevp basDevp = basDevpService.selectById(wrkMastSta.getStaStart());
                            if (!basDevp.getAutoing().equals("Y") || !basDevp.getLoading().equals("Y")){
                                continue;
                            }
                            sign = rgvTakeEmptyFull(rgvProtocol.getRgvNo(),wrkMastSta);
                        }else {
                            continue;
@@ -4513,7 +4809,7 @@
                                }catch (Exception e){
                                    log.error("更新小车任务失败");
                                }
                                return;
                                return true;
                            }else {
                                log.error("3879行,货物搬运任务:工作号{}所属任务下发后地图同步失败",wrkMastSta.getWrkNo());
                            }
@@ -4523,11 +4819,12 @@
                        break;
                    }
                }
            }
//            }
        }catch (Exception e){
            log.error("3989行执行小车取空板任务下发失败");
            log.error("3989行"+e);
        }
        return false;
    }
    /*
@@ -4557,6 +4854,8 @@
                        && rgvProtocol.getLoaded1()==0  //现场修改:叠盘机,不满都算无物,怎么判断需要跟电控对接
                        && rgvProtocol.getTaskNo1()==0
                        && rgvProtocol.getTaskNo2()==0
                        && rgvProtocol.getStatusType1() == RgvStatusType.IDLE
                        && rgvProtocol.getStatusType2() == RgvStatusType.IDLE
                ) {
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
                    if (rgvProtocol.getRgvPosI().equals(basRgvMap.getStartRoute())){
@@ -4601,7 +4900,7 @@
                        && rgvProtocol.getTaskNo1()==0
                        && rgvProtocol.getTaskNo2()==0
                ) {
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
                    BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvSlave.getId());
                    basRgvMap.setNowRoute(rgvProtocol.getRgvPosI());
                    rgvMapUpdate(basRgvMap,basRgvMap.getStartRoute(),basRgvMap.getStartRoute());
                }