#
Junjie
4 天以前 7620bd47ec7dc59ea1f4c00e35d238d9d6e4ab53
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -14,6 +14,7 @@
import com.zy.asrs.service.*;
import com.zy.asrs.utils.Utils;
import com.zy.asrs.utils.VersionUtils;
import com.zy.common.constant.RedisConstantType;
import com.zy.common.model.LocTypeDto;
import com.zy.common.model.MatDto;
import com.zy.common.model.SearchLocParam;
@@ -22,23 +23,26 @@
import com.zy.common.utils.CollectionUtils;
import com.zy.common.utils.HttpHandler;
import com.zy.common.utils.News;
import com.zy.common.utils.RedisUtil;
import com.zy.core.CrnThread;
import com.zy.core.DevpThread;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.*;
import com.zy.core.model.CrnSlave;
import com.zy.core.model.DevpSlave;
import com.zy.core.model.LedSlave;
import com.zy.core.model.Task;
import com.zy.core.model.*;
import com.zy.core.model.command.CrnCommand;
import com.zy.core.model.command.LedCommand;
import com.zy.core.model.command.RgvCommand;
import com.zy.core.model.protocol.CrnProtocol;
import com.zy.core.model.protocol.RgvProtocol;
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.BarcodeThread;
import com.zy.core.thread.LedThread;
import com.zy.core.thread.RgvThread;
import com.zy.core.thread.SiemensDevpThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -87,6 +91,14 @@
    private BasErrLogService basErrLogService;
    @Autowired
    private BasCrnErrorMapper basCrnErrorMapper;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private WrkMastLogService wrkMastLogService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private RedisUtil redisUtil;
    @Value("${wms.url}")
    private String wmsUrl;
@@ -188,6 +200,18 @@
                        continue;
                    }
                    if (inSta.getStaNo() == 1005) {
                        //检测是否有出库任务
                        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                                .in("io_type", 101, 103, 107)
                                .in("sta_no", 1003, 1007)
                        );
                        if (!wrkMasts.isEmpty()) {
                            News.error(""+mark+" - 4"+" - 1003站入库,检测存在出库任务,等待出库任务执行完成,托盘码={}", barcode);
                            continue;
                        }
                    }
                    try {
                        LocTypeDto locTypeDto = new LocTypeDto(staProtocol);
@@ -209,9 +233,14 @@
                            LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                                    .eq("loc_no", dto.getLocNo()));
                            short staNo = dto.getStaNo().shortValue();
                            if (inSta.getStaNo() == 1002) {
                                staNo = 2002;
                            }
                            barcodeThread.setBarcode("");
                            staProtocol.setWorkNo(dto.getWorkNo().shortValue());
                            staProtocol.setStaNo(dto.getStaNo().shortValue());
                            staProtocol.setStaNo(staNo);
                            staProtocol.setPalletSize(locMast.getLocType2());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
@@ -219,21 +248,21 @@
                                throw new CoolException("更新plc站点信息失败");
                            }
                            // led 入库信息显示
                            if (ledThread != null) {
                                // 命令集合
                                List<LedCommand> commands = new ArrayList<>();
                                // 组装命令
                                LedCommand ledCommand = new LedCommand();
                                ledCommand.setWorkNo(dto.getWorkNo());
                                ledCommand.setIoType(1);
                                ledCommand.setTitle("全板入库");
                                ledCommand.setLocNo(dto.getLocNo());
                                ledCommand.setStaNo(dto.getStaNo());
                                commands.add(ledCommand);
                                MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, commands));
//                                ledThread.errorReset();
                            }
//                            // led 入库信息显示
//                            if (ledThread != null) {
//                                // 命令集合
//                                List<LedCommand> commands = new ArrayList<>();
//                                // 组装命令
//                                LedCommand ledCommand = new LedCommand();
//                                ledCommand.setWorkNo(dto.getWorkNo());
//                                ledCommand.setIoType(1);
//                                ledCommand.setTitle("全板入库");
//                                ledCommand.setLocNo(dto.getLocNo());
//                                ledCommand.setStaNo(dto.getStaNo());
//                                commands.add(ledCommand);
//                                MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, commands));
////                                ledThread.errorReset();
//                            }
                        } else {
                            News.error(""+mark+" - 5"+" - 请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/loc/v1", JSON.toJSONString(param), response);
//                            staProtocol.setWorkNo((short)9992);
@@ -348,26 +377,30 @@
                    staProtocol = staProtocol.clone();
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && staProtocol.isPakMk()) {
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && staProtocol.isInEnable()
                        && staProtocol.getWorkNo() > 0
                        && staProtocol.isPakMk()) {
                    News.warnNoLog(""+mark+" - 0"+" - 开始执行");
                    // 获取条码扫描仪信息
                    BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, pickSta.getBarcode());
                    if (barcodeThread == null) {
                        continue;
                    }
                    String barcode = barcodeThread.getBarcode();
                    if(!Cools.isEmpty(barcode)) {
                        News.info(""+mark+" - 1"+" - {}号条码扫描器检测条码信息:{}", pickSta.getBarcode(), barcode);
                        if("NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                            continue;
                        }
                    } else {
                        continue;
                    }
//                    // 获取条码扫描仪信息
//                    BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, pickSta.getBarcode());
//                    if (barcodeThread == null) {
//                        continue;
//                    }
//                    String barcode = barcodeThread.getBarcode();
//                    if(!Cools.isEmpty(barcode)) {
//                        News.info(""+mark+" - 1"+" - {}号条码扫描器检测条码信息:{}", pickSta.getBarcode(), barcode);
//                        if("NG".endsWith(barcode) || "NoRead".equals(barcode)) {
//                            continue;
//                        }
//                    } else {
//                        continue;
//                    }
                    WrkMast wrkMast = wrkMastMapper.selectPickStep(barcode);
//                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(staProtocol.getWorkNo().intValue());
//                    WrkMast wrkMast = wrkMastMapper.selectPickStep(barcode);
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep3(staProtocol.getWorkNo().intValue());
                    if (wrkMast == null) {
                        // 无拣料数据
                        continue;
@@ -393,11 +426,11 @@
                            .eq("crn_no", wrkMast.getCrnNo()); // 堆垛机号
                    StaDesc staDesc = staDescService.selectOne(wrapper);
                    if (Cools.isEmpty(staDesc)) {
                        News.error(""+mark+" - 2"+" - 入库路径不存在!type_no={},stn_no={},crn_no={}", wrkMast.getIoType(), pickSta.getStaNo(), wrkMast.getCrnNo());
                        staProtocol.setWorkNo((short) 9989);
                        staProtocol.setStaNo((short) (pickSta.getStaNo().shortValue()-(short)1));
                        devpThread.setPakMk(staProtocol.getSiteId(), false);
                        MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                        News.error(""+mark+" - 2"+" - 入库路径不存在!type_no={},stn_no={},crn_no={}", wrkMast.getIoType(), pickSta.getStaNo(), wrkMast.getCrnNo());
//                        staProtocol.setWorkNo((short) 9989);
//                        staProtocol.setStaNo((short) (pickSta.getStaNo().shortValue()-(short)1));
//                        devpThread.setPakMk(staProtocol.getSiteId(), false);
//                        MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                        //LED
                        LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, pickSta.getLed());
                        // led 异常显示
@@ -448,9 +481,11 @@
                        continue;
                    }
                    LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                    staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                    staProtocol.setPalletSize(locMast.getLocType2());
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
@@ -509,9 +544,13 @@
                        // 命令下发区 --------------------------------------------------------------------------
                        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                                .eq("loc_no", wrkMast.getSourceLocNo()));
                        // 下发站点信息
                        staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                        staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                        staProtocol.setPalletSize(locMast.getLocType2());
                        if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                            continue;
                        }
@@ -601,59 +640,71 @@
    }
    /**
     * 回原点,堆垛机没有执行中任务,设备存在入库任务时叫回原点
     * 堆垛机无任务两分钟,回入库口待机
     */
    public synchronized void crnRebackHp(CrnProtocol crnProtocol, CrnThread crnThread) {
//        for (CrnSlave crn : slaveProperties.getCrn()) {
//            // 获取堆垛机信息
//            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
//            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
//            if (crnProtocol == null) {
//                continue;
//            }
//            BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
//            if (basCrnp == null) {
//                log.error("{}号堆垛机尚未在数据库进行维护!", crn.getId());
//                continue;
//            }
        if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO) {
            if (crnProtocol.getBay() == 1 && crnProtocol.getLevel() == 1) {
                return;
    public synchronized void crnMove() {
        for (CrnSlave crn : slaveProperties.getCrn()) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                continue;
            }
            BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
            if (basCrnp == null) {
                log.error("{}号堆垛机尚未在数据库进行维护!", crn.getId());
                continue;
            }
            // 已经存在吊车执行任务时,则过滤3,12
            if (wrkMastMapper.selectWorking(crnProtocol.getCrnNo()) != null) {
                return;
            }
            if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO) {
                if (crnProtocol.getBay() == 1 && crnProtocol.getLevel() == 1) {
                    continue;
                }
            //堆垛机有执行中任务,过滤3,4,11,12
            if (wrkMastMapper.selectCrnWorking(crnProtocol.getCrnNo()) != null) {
                return;
            }
                if (System.currentTimeMillis() - crnProtocol.getLastCommandTime() < 1000 * 60 * 2) {
                    continue;
                }
            //输送线没有入库任务,过滤2
            if (wrkMastMapper.selectDevWorking(crnProtocol.getCrnNo()) == null) {
                return;
                Object object = redisUtil.get(RedisConstantType.CRN_MOVE_LOCK);
                if (object != null) {
                    continue;
                }
                List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                        .eq("crn_no", crn.getId())
                        .notIn("wrk_sts", 5, 14, 15)
                );
                if (!wrkMasts.isEmpty()) {
                    continue;
                }
                CrnSlave.CrnStn crnStn = crn.getCrnInStn().get(0);
                News.info("堆垛机无任务自动回入库口待机==>>" + crnProtocol.getCrnNo() + "号堆垛机");
                // 命令下发区 --------------------------------------------------------------------------
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setCrnNo(crnProtocol.getCrnNo()); // 堆垛机编号
                crnCommand.setTaskNo((short) 9999); // 工作号
                crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                crnCommand.setTaskMode(CrnTaskModeType.CRN_MOVE); // 任务模式:  堆垛机移动
                crnCommand.setSourcePosX(crnStn.getRow().shortValue());     // 源库位排
                crnCommand.setSourcePosY((short) 1);     // 源库位列
                crnCommand.setSourcePosZ((short) 1);     // 源库位层
                crnCommand.setDestinationPosX((short) 0);     // 目标库位排
                crnCommand.setDestinationPosY((short) 0);     // 目标库位列
                crnCommand.setDestinationPosZ((short) 0);     // 目标库位层
                if (!MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, crnCommand))) {
                    News.error("堆垛机移动命令下发失败,堆垛机号={},任务数据={}", crnProtocol.getCrnNo(), JSON.toJSON(crnCommand));
                }
                crnThread.setBackHpFlag(true);
                redisUtil.set(RedisConstantType.CRN_MOVE_LOCK + crn.getId(), "lock", 60);
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            News.info("堆垛机召回原点==>>" + crnProtocol.getCrnNo() + "号堆垛机有入库任务,召回原点");
            // 命令下发区 --------------------------------------------------------------------------
            CrnCommand crnCommand = new CrnCommand();
            crnCommand.setCrnNo(crnProtocol.getCrnNo()); // 堆垛机编号
            crnCommand.setTaskNo((short) 9999); // 工作号
            crnCommand.setAckFinish((short) 0);  // 任务完成确认位
            crnCommand.setTaskMode(CrnTaskModeType.GO_ORIGIN); // 任务模式:  回原点
            crnCommand.setSourcePosX((short) 0);     // 源库位排
            crnCommand.setSourcePosY((short) 0);     // 源库位列
            crnCommand.setSourcePosZ((short) 0);     // 源库位层
            crnCommand.setDestinationPosX((short) 0);     // 目标库位排
            crnCommand.setDestinationPosY((short) 0);     // 目标库位列
            crnCommand.setDestinationPosZ((short) 0);     // 目标库位层
            if (!MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, crnCommand))) {
                News.error("堆垛机回原点命令下发失败,堆垛机号={},任务数据={}", crnProtocol.getCrnNo(), JSON.toJSON(crnCommand));
            }
            crnThread.setBackHpFlag(true);
        }
//        }
    }
    /**
@@ -716,6 +767,17 @@
            // 已经存在吊车执行任务时,则过滤
            if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                continue;
            }
            if (crnProtocol.getCrnNo() == 1) {
                //判断堆垛机和当前任务是否处于一个巷道
                if (Utils.getLaneByLocNo(wrkMast.getLocNo()) != crnProtocol.getCrnLane()) {
                    //判断堆垛机所在巷道是否存在其他任务,如存在则优先执行
                    List<WrkMast> currentWrkMasts = wrkMastService.selectLaneWrkMast(crnProtocol.getCrnLane(), false);
                    if (!currentWrkMasts.isEmpty()) {
                        continue;//当前堆垛机所在巷道存在任务
                    }
                }
            }
            // 双深库位且浅库位有货,则需先对浅库位进行库位移转
@@ -846,6 +908,18 @@
                    staProtocol = staProtocol.clone();
                }
                if (wrkMast.getStaNo() == 1003 || wrkMast.getStaNo() == 1007) {
                    //检测是否有入库任务
                    List<WrkMast> inWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                            .in("io_type", 1, 53, 57)
                            .in("source_sta_no", 1005)
                    );
                    if (!inWrkMasts.isEmpty()) {
                        News.error("" + mark + " - 2" + " - 检测存在入库任务,等待入库任务执行完成再出库,工作号={}" + wrkMast.getWrkNo());
                        continue;
                    }
                }
//            // 入出库模式判断
//            if (devpThread.ioMode != IoModeType.PAKOUT_MODE) { continue; }
//                if (wrkMast.getStaNo() == 204 && devpThread.ioModeOf2F != IoModeType.PAKOUT_MODE) {
@@ -862,13 +936,40 @@
                }
                // 判断堆垛机出库站状态
                if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")
                        && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                        && staProtocol.getWorkNo() == 0) {
                    //根据参数判断是否校验可出信号
                    String crnOutVerifyOut = "Y";
                    Config crnOutVerifyOutEnableConfig = configService.selectOne(new EntityWrapper<Config>()
                            .eq("code", "crnOutVerifyOutEnable"));
                    if(crnOutVerifyOutEnableConfig != null) {
                        crnOutVerifyOut = crnOutVerifyOutEnableConfig.getValue();
                    }
                    if (crnOutVerifyOut.equals("Y")) {
                        if (!staProtocol.isOutEnable()) {
                            continue;
                        }
                    }
                    // 命令下发区 --------------------------------------------------------------------------
                    // 堆垛机控制过滤
                    if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
//                        continue;
                        break;
                    }
                    if (crnProtocol.getCrnNo() == 1) {
                        //判断堆垛机和当前任务是否处于一个巷道
                        if (Utils.getLaneByLocNo(wrkMast.getLocNo()) != crnProtocol.getCrnLane()) {
                            //判断堆垛机所在巷道是否存在其他任务,如存在则优先执行
                            List<WrkMast> currentWrkMasts = wrkMastService.selectLaneWrkMast(crnProtocol.getCrnLane(), false);
                            if (!currentWrkMasts.isEmpty()) {
                                continue;//当前堆垛机所在巷道存在任务
                            }
                        }
                    }
                    // 双深库位且浅库位有货,则需先对浅库位进行库位移转
@@ -1244,7 +1345,6 @@
     * 执行对工作档的完成操作
     */
    public synchronized void storeFinished(Integer mark) {
        for (CrnSlave crn : slaveProperties.getCrn()) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
@@ -1592,24 +1692,39 @@
                ledCommand.setSourceLocNo(wrkMast.getSourceLocNo());
                ledCommand.setLocNo(wrkMast.getLocNo());
                ledCommand.setStaNo(wrkMast.getStaNo());
                ledCommand.setBarcode(wrkMast.getBarcode());
//                ledCommand.setSourceStaNo(wrkMast.getSourceStaNo());
                if (wrkMast.getIoType() != 110 && wrkMast.getIoType() != 10) {
                    List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo());
                    try{
                        if (wrkMast.getIoType()>100){
                            for (WrkDetl wrkDetl : wrkDetls){
                                LocDetl locDetl = locDetlService.selectMatnrSpecs(wrkDetl.getMatnr(), wrkDetl.getSpecs(), wrkMast.getSourceLocNo());
                                wrkDetl.setWeight(locDetl.getAnfme());
                            }
                        }else {
                            for (WrkDetl wrkDetl : wrkDetls){
                                wrkDetl.setWeight(wrkDetl.getAnfme());
                            }
                        }
                    }catch (Exception e){
                        log.error("工作档案明细输入电视机失败1:异常信息==》"+e);
                    }
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMaktx(), wrkDetl.getAnfme(),wrkDetl.getWeight(),wrkDetl.getSpecs(),wrkDetl.getSku())));
//                    try{
//                        if (wrkMast.getIoType()>100){
//                            for (WrkDetl wrkDetl : wrkDetls){
//                                LocDetl locDetl = locDetlService.selectMatnrSpecs(wrkDetl.getMatnr(), wrkDetl.getSpecs(), wrkMast.getSourceLocNo());
//                                wrkDetl.setWeight(locDetl.getAnfme());
//                            }
//                        }else {
//                            for (WrkDetl wrkDetl : wrkDetls){
//                                wrkDetl.setWeight(wrkDetl.getAnfme());
//                            }
//                        }
//                    }catch (Exception e){
//                        log.error("工作档案明细输入电视机失败1:异常信息==》"+e);
//                    }
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(
                            wrkDetl.getMatnr()
                            , wrkDetl.getMaktx()
                            , wrkDetl.getAnfme()
                            , wrkDetl.getWeight()
                            , wrkDetl.getStockNum()
                            , wrkDetl.getStockNum2()
                            , wrkDetl.getSpecs()
                            , wrkDetl.getSku()
                            , wrkDetl.getZpallet()
                            , wrkDetl.getModel()
                            , wrkDetl.getSupp()
                            , wrkDetl.getKpCstmrName()
                            , wrkDetl.getOrderNo()
                    )));
                }
                commands.add(ledCommand);
            }
@@ -1749,10 +1864,11 @@
            List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", shallowLoc.getLocNo()));
            for (LocDetl locDetl : locDetls) {
                WrkDetl wrkDetl = new WrkDetl();
                wrkDetl.sync(locDetl);
                wrkDetl.setWrkNo(workNo);
                wrkDetl.setIoTime(now);
                wrkDetl.setAnfme(locDetl.getAnfme());
                VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制
//                VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制
                wrkDetl.setAppeTime(now);
                wrkDetl.setModiTime(now);
                if (!wrkDetlService.insert(wrkDetl)) {
@@ -1873,10 +1989,11 @@
                        for (LocDetl locDetl : locDetls) {
                            WrkDetl wrkDetl = new WrkDetl();
                            wrkDetl.sync(locDetl);
                            wrkDetl.setWrkNo(workNo);
                            wrkDetl.setIoTime(new Date());
                            wrkDetl.setAnfme(locDetl.getAnfme());
                            VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制
//                            VersionUtils.setWrkDetl(wrkDetl, locDetl); // 版本控制
                            wrkDetl.setAppeTime(new Date());
                            wrkDetl.setModiTime(new Date());
                            if (!wrkDetlService.insert(wrkDetl)) {
@@ -1958,6 +2075,11 @@
                        continue;
                    }
                    Integer ctnType = 1;
                    if (ctnType.equals(loc.getCtnType())) {
                        continue;
                    }
                    String sourceLocNo = sourceLoc.getLocNo();
                    String locNo = loc.getLocNo();
@@ -2012,6 +2134,7 @@
                    // 修改目标库位状态
                    if (loc.getLocSts().equals("O")) {
                        loc.setLocSts("S"); // S.入库预约
                        loc.setCtnType(1);
                        loc.setModiTime(new Date());
                        if (!locMastService.updateById(loc)) {
                            throw new CoolException("更新目标库位状态失败");
@@ -2079,143 +2202,181 @@
        }
    }
    /**
     * 入出库模式切换函数
     */
    public synchronized void ioConvert() {
        try {
            // 根据输送线plc遍历
            for (DevpSlave devp : slaveProperties.getDevp()) {
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
    // RGV  ===>> 执行对RGV操作
    public synchronized void rgvExecute(Integer mark) {
        ArrayList<Integer> list = new ArrayList<Integer>(){{add(2003);add(2002);}};
        for (Integer staNo : list) {
            Integer devpId = null;
            Integer rgvStaNo = null;
            if (staNo == 2003) {
                devpId = 1;
                rgvStaNo = 2002;
            }else {
                devpId = 2;
                rgvStaNo = 2003;
            }
                for (DevpSlave.Sta inSta : devp.getInSta()) {
                    if (inSta.getStaNo() == 2) {
                        continue;
                    }
                    WrkMast pakout = wrkMastMapper.selectWorkingPakout(inSta.getStaNo());
                    switch (inSta.getStaNo()) {
                        case 101://1F
                            if (pakout != null) {
                                if (devpThread.ioModeOf2F != IoModeType.PAKOUT_MODE) {
                                    // 出库切换中
                                    devpThread.ioModeOf2F = IoModeType.PAKOUT_BOOTING;
                                    WrkMast pakin = wrkMastMapper.selectWorkingPakin(inSta.getStaNo());
                                    if (pakin == null && !devpThread.getStation().get(inSta.getStaNo()).isLoading()
                                            && !devpThread.getStation().get(inSta.getStaNo() + 1).isLoading()
                                            && devpThread.getStation().get(inSta.getStaNo() + 1).getWorkNo() == 0) {
                                        // 出库模式
                                        devpThread.ioModeOf2F = IoModeType.PAKOUT_MODE;
                                    }
                                }
                            } else {
                                // 入库模式
                                devpThread.ioModeOf2F = IoModeType.PAKIN_MODE;
                            }
                            break;
                    }
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devpId);
            if (devpThread == null) {
                continue;
            }
            StaProtocol staProtocol = devpThread.getStation().get(staNo);
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            if (staProtocol.isAutoing()
                    && staProtocol.isLoading()
//                    && staProtocol.isInEnable()
                    && staProtocol.getWorkNo() > 0
            ) {
                WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>()
                        .eq("wrk_no", staProtocol.getWorkNo()));
                if (wrkMast.getWrkSts() == 201) {
                    continue;
                }
            }
                RgvCommand command = new RgvCommand();
                command.setRgvNo(1); // RGV编号
                command.setAckFinish1((short) 0);  // 任务完成确认位
                command.setTaskNo1(wrkMast.getWrkNo().shortValue()); // 工作号
                command.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
                command.setSourceStaNo1(staNo.shortValue()); // 源站
                command.setDestinationStaNo1(rgvStaNo.shortValue());  // 目标站
                command.setCommand((short) 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public synchronized void outOfDevp(Integer mark) {
        List<WrkMast> wrkMasts = wrkMastMapper.selectPick();
        if (wrkMasts.size()!=0){
            News.warnNoLog(""+mark+" - 0"+" - 开始执行outOfDevp");
        }
        for (WrkMast wrkMast : wrkMasts) {
            if (basDevpService.selectCount(new EntityWrapper<BasDevp>().eq("wrk_no", wrkMast.getWrkNo())) == 0) {
                wrkMast.setCtnNo("Y");
                if (wrkMastMapper.updateById(wrkMast) == 0) {
                    News.error(""+mark+" - 1"+" - 修改{}工作档失败,ctn_no", wrkMast.getWrkNo());
                boolean result = MessageQueue.offer(SlaveType.Rgv, 1, new Task(4, command));
                if (!result) {
                    throw new CoolException("RGV指令下发失败");
                }
                wrkMast.setWrkSts(201L);//201.RGV搬运中
                wrkMast.setModiTime(new Date());
                wrkMastService.updateById(wrkMast);
            }
        }
        News.infoNoLog(""+mark+" - 0"+" - outOfDevp执行完成");
    }
    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;
    // RGV  ===>> 执行对RGV工作档的完成操作
    public synchronized void rgvFinished(Integer mark) {
        for (RgvSlave rgvSlave : slaveProperties.getRgv()) {
            // 获取RGV信息
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgvSlave.getId());
            if (rgvThread == null) {
                continue;
            }
            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");
                    News.info((String) data.get("msg"));
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                continue;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (rgvProtocol.statusType1 == RgvStatusType.WAITING && rgvProtocol.getTaskNo1() != 0) {
                News.warnNoLog(""+mark+" - 0"+" - 开始执行对RGV工作档的完成操作");
                // 获取入库待确认工作档
                WrkMast wrkMast = wrkMastMapper.selectPakInStep3(rgvProtocol.getTaskNo1().intValue());
                if (wrkMast == null) {
                    News.error(""+mark+" - 1"+" - RGV处于等待确认且任务完成状态,但未找到工作档。RGV号={},工作号={}", rgvSlave.getId(), rgvProtocol.getTaskNo1());
                    continue;
                }
                Integer devpId = null;
                Integer devpStaNo = null;
                String locNo = null;
                if (wrkMast.getIoType() < 100) {
                    //入库
                    wrkMast.setWrkSts(2L);
                    devpId = 1;
                    devpStaNo = 2003;
                    locNo = wrkMast.getLocNo();
                }else {
                    //出库
                    wrkMast.setWrkSts(15L);
                    devpId = 2;
                    devpStaNo = 2002;
                    locNo = wrkMast.getSourceLocNo();
                }
                // 获取入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devpId);
                StaProtocol staProtocol = devpThread.getStation().get(devpStaNo);
                if (staProtocol == null) {
                    continue;
                } else {
                    News.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/auto/emptyOut/v1","", response);
                    staProtocol = staProtocol.clone();
                }
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && staProtocol.getWorkNo() == 0
                ) {
                    LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                            .eq("loc_no", locNo));
                    staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                    staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                    staProtocol.setPalletSize(locMast.getLocType2());
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devpId, new Task(2, staProtocol));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败");
                    }
                    Date now = new Date();
                    wrkMast.setModiTime(now);
                    wrkMastMapper.updateById(wrkMast);
                    rgvThread.setResetFlag1(true);
                }
            }
        }
        News.infoNoLog(""+mark+" - 0"+" - 对工作档的完成操作执行完成");
    }
    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)) {
                    News.info((String) jsonObject.get("msg"));
                } else {
                    News.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/auto/emptyIn/v1", JSON.toJSONString(locTypeDto), response);
                }
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
    }
//    /**
//     * 入出库模式切换函数
//     */
//    public synchronized void ioConvert() {
//        try {
//            // 根据输送线plc遍历
//            for (DevpSlave devp : slaveProperties.getDevp()) {
//                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
//
//                for (DevpSlave.Sta inSta : devp.getInSta()) {
//                    if (inSta.getStaNo() == 2) {
//                        continue;
//                    }
//                    WrkMast pakout = wrkMastMapper.selectWorkingPakout(inSta.getStaNo());
//                    switch (inSta.getStaNo()) {
//                        case 101://1F
//                            if (pakout != null) {
//                                if (devpThread.ioModeOf2F != IoModeType.PAKOUT_MODE) {
//                                    // 出库切换中
//                                    devpThread.ioModeOf2F = IoModeType.PAKOUT_BOOTING;
//                                    WrkMast pakin = wrkMastMapper.selectWorkingPakin(inSta.getStaNo());
//                                    if (pakin == null && !devpThread.getStation().get(inSta.getStaNo()).isLoading()
//                                            && !devpThread.getStation().get(inSta.getStaNo() + 1).isLoading()
//                                            && devpThread.getStation().get(inSta.getStaNo() + 1).getWorkNo() == 0) {
//                                        // 出库模式
//                                        devpThread.ioModeOf2F = IoModeType.PAKOUT_MODE;
//                                    }
//                                }
//                            } else {
//                                // 入库模式
//                                devpThread.ioModeOf2F = IoModeType.PAKIN_MODE;
//                            }
//                            break;
//                    }
//                }
//
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//
//    }
}