*
lsh
2025-11-24 a775cccf69b395cff784ea50164b89a6ef00341a
*
15个文件已添加
14个文件已修改
4128 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/RgvController.java 574 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/DeviceError.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/DeviceErrorMapper.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/DeviceErrorService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/DeviceErrorServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/TrackRangeUtils.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ThreadHandler.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/RgvErrCache.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/RgvRunCache.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/RgvStatusCache.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/RgvTaskCache.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/TaskProtocolCache.java 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/RgvStatusType.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/RgvSlave.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/RgvErrProtocol.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/RgvProtocol.java 488 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/RgvRunProtocol.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/RgvTaskProtocol.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/TaskProtocol.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/BarcodeThread.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/LedThread.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/MelsecCrnThread.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/RgvThread.java 1671 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/RoboticArmThread.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/ScaleThread.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensCrnThread.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensDevpThread.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/DeviceErrorMapper.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/RgvController.java
@@ -66,113 +66,113 @@
    private LocMastService locMastService;
    @Autowired
    private BasRgvMapMapper basRgvMapMapper;
    @ManagerAuth(memo = "解锁小车")
    @PostMapping("/lock")
    public R lock(CrnOperatorParam param){
        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, param.getRgvNo());
        rgvThread.setPakMk(true);
        return R.ok();
    }
    @PostMapping("/table/rgv/state")
    @ManagerAuth(memo = "RGV信息表")
    public R rgvStateTable() {
        List<RgvStateTableVo> list = new ArrayList<>();
        List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no"));
        for (BasRgv basRgv : rgvs) {
            RgvStateTableVo vo = new RgvStateTableVo();
            vo.setRgvNo(basRgv.getRgvNo());   //  RGV号
            list.add(vo);
            // 获取RGV信息
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo());
            if (rgvThread == null) continue;
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) continue;
            BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
            vo.setStatusType(rgvProtocol.modeType.desc);   // 模式状态
            vo.setStatus(String.valueOf(rgvProtocol.getMode())); // 状态
            vo.setWorkNo1(rgvProtocol.getTaskNo1());      // 工位1任务号
            vo.setStatus1(rgvProtocol.getStatusType1().desc); // 工位1状态
            vo.setLoading1(rgvProtocol.getLoaded1() ? "有物" : "无物"); // 工位1有物
            vo.setRgvPos(basRgvMap != null?basRgvMap.getNowRoute():0);
            vo.setRgvPos1(rgvProtocol.getRgvPosI2());
            vo.setWalkPos(Objects.equals(rgvProtocol.getWalkPos(), 1) ? "在定位" : "不在定位");
            vo.setPakMk(rgvThread.isPakMk() ? "无锁" : "锁定");
//            vo.setPakIn(rgvThread.isPakIn() ? "可入" : "不可入");
//            vo.setPakOut(rgvThread.isPakOut() ? "可出" : "不可出");
//            vo.setPakRgv(rgvThread.isPakRgv() ? "无锁" : "锁定");
            vo.setPaking(rgvThread.isPaking()? "无锁" : "锁定");
//            vo.setPakAll(rgvThread.isPakAll() ? "无锁" : "锁定");
//            vo.setPakToCrn(rgvThread.isPakToCrn() ? "无锁" : "锁定");
//    @ManagerAuth(memo = "解锁小车")
//    @PostMapping("/lock")
//    public R lock(CrnOperatorParam param){
//        RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, param.getRgvNo());
//        rgvThread.setPakMk(true);
//        return R.ok();
//    }
//
//    @PostMapping("/table/rgv/state")
//    @ManagerAuth(memo = "RGV信息表")
//    public R rgvStateTable() {
//        List<RgvStateTableVo> list = new ArrayList<>();
//        List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no"));
//
//        for (BasRgv basRgv : rgvs) {
//            RgvStateTableVo vo = new RgvStateTableVo();
//            vo.setRgvNo(basRgv.getRgvNo());   //  RGV号
//            list.add(vo);
//
//            // 获取RGV信息
//            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo());
//            if (rgvThread == null) continue;
//
//            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//            if (rgvProtocol == null) continue;
//            BasRgvMap basRgvMap = basRgvMapMapper.selectById(rgvProtocol.getRgvNo());
//
//            vo.setStatusType(rgvProtocol.modeType.desc);   // 模式状态
//            vo.setStatus(String.valueOf(rgvProtocol.getMode())); // 状态
//            vo.setWorkNo1(rgvProtocol.getTaskNo1());      // 工位1任务号
//            vo.setStatus1(rgvProtocol.getStatusType1().desc); // 工位1状态
//            vo.setLoading1(rgvProtocol.getLoaded1() ? "有物" : "无物"); // 工位1有物
//            vo.setRgvPos(basRgvMap != null?basRgvMap.getNowRoute():0);
//            vo.setRgvPos1(rgvProtocol.getRgvPosI2());
//            vo.setWalkPos(Objects.equals(rgvProtocol.getWalkPos(), 1) ? "在定位" : "不在定位");
//            vo.setPakMk(rgvThread.isPakMk() ? "无锁" : "锁定");
////            vo.setPakIn(rgvThread.isPakIn() ? "可入" : "不可入");
////            vo.setPakOut(rgvThread.isPakOut() ? "可出" : "不可出");
////            vo.setPakRgv(rgvThread.isPakRgv() ? "无锁" : "锁定");
//            vo.setPaking(rgvThread.isPaking()? "无锁" : "锁定");
////            vo.setPakAll(rgvThread.isPakAll() ? "无锁" : "锁定");
////            vo.setPakToCrn(rgvThread.isPakToCrn() ? "无锁" : "锁定");
//
//
//            vo.setWorkNo2(rgvProtocol.getTaskNo2());      // 工位2任务号
////            vo.setStatus2(rgvProtocol.getStatusType2().desc); // 工位2状态
//            vo.setLoading2(rgvProtocol.getLoaded2() ? "有物" : "无物"); // 工位2有物
//
//            // --- 遍历 errX 字段生成 warnCode 和 alarm ---
//            List<String> alarms = new ArrayList<>();
//            List<String> warnCodes = new ArrayList<>();
//            Field[] fields = rgvProtocol.getClass().getDeclaredFields();
//            for (Field field : fields) {
//                if (field.getName().startsWith("err") && field.getType().equals(Boolean.class)) {
//                    field.setAccessible(true);
//                    try {
//                        Boolean value = (Boolean) field.get(rgvProtocol);
//                        if (Boolean.TRUE.equals(value)) {
//                            String numPart = field.getName().substring(3);
//                            int errId = Integer.parseInt(numPart);
//                            warnCodes.add(String.valueOf(errId));
//
//                            BasRgvErr rgvErr = basRgvErrMapper.selectById(errId);
//                            alarms.add(rgvErr == null ? "未知异常(" + errId + ")" : rgvErr.getErrName());
//                        }
//                    } catch (IllegalAccessException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//
//            vo.setWarnCode(String.join(",", warnCodes));
//            vo.setAlarm(alarms.isEmpty() ? "" : String.join(",", alarms));
//        }
//
//        return R.ok().add(list);
//    }
            vo.setWorkNo2(rgvProtocol.getTaskNo2());      // 工位2任务号
//            vo.setStatus2(rgvProtocol.getStatusType2().desc); // 工位2状态
            vo.setLoading2(rgvProtocol.getLoaded2() ? "有物" : "无物"); // 工位2有物
            // --- 遍历 errX 字段生成 warnCode 和 alarm ---
            List<String> alarms = new ArrayList<>();
            List<String> warnCodes = new ArrayList<>();
            Field[] fields = rgvProtocol.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field.getName().startsWith("err") && field.getType().equals(Boolean.class)) {
                    field.setAccessible(true);
                    try {
                        Boolean value = (Boolean) field.get(rgvProtocol);
                        if (Boolean.TRUE.equals(value)) {
                            String numPart = field.getName().substring(3);
                            int errId = Integer.parseInt(numPart);
                            warnCodes.add(String.valueOf(errId));
                            BasRgvErr rgvErr = basRgvErrMapper.selectById(errId);
                            alarms.add(rgvErr == null ? "未知异常(" + errId + ")" : rgvErr.getErrName());
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
            vo.setWarnCode(String.join(",", warnCodes));
            vo.setAlarm(alarms.isEmpty() ? "" : String.join(",", alarms));
        }
        return R.ok().add(list);
    }
    @PostMapping("/table/rgv/msg")
    @ManagerAuth(memo = "RGV数据表")
    public R rgvMsgTable(){
        List<RgvMsgTableVo> list = new ArrayList<>();
        List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no"));
        for (BasRgv basRgv : rgvs) {
            // 表格行
            RgvMsgTableVo vo = new RgvMsgTableVo();
            vo.setRgvNo(basRgv.getRgvNo());   //  RGV号
            list.add(vo);
            // 获取RGV信息
            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo());
            if (rgvThread == null) {
                continue;
            }
            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
            if (rgvProtocol == null) {
                continue;
            }
            vo.setWorkNo1(rgvProtocol.getTaskNo1());  //  工位1工作号
            vo.setWorkNo2(rgvProtocol.getTaskNo2()); //工位2 工作号
            vo.setStaNo(String.valueOf(rgvProtocol.getRgvPosDestination())); //小车目标站
            vo.setStatus(rgvProtocol.modeType.equals(RgvModeType.AUTO)? rgvProtocol.modeType.desc: RgvModeType.HAND.desc);   //  模式状态
        }
        return R.ok().add(list);
    }
//    @PostMapping("/table/rgv/msg")
//    @ManagerAuth(memo = "RGV数据表")
//    public R rgvMsgTable(){
//        List<RgvMsgTableVo> list = new ArrayList<>();
//        List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no"));
//        for (BasRgv basRgv : rgvs) {
//            // 表格行
//            RgvMsgTableVo vo = new RgvMsgTableVo();
//            vo.setRgvNo(basRgv.getRgvNo());   //  RGV号
//            list.add(vo);
//            // 获取RGV信息
//            RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo());
//            if (rgvThread == null) {
//                continue;
//            }
//            RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//            if (rgvProtocol == null) {
//                continue;
//            }
//
//            vo.setWorkNo1(rgvProtocol.getTaskNo1());  //  工位1工作号
//            vo.setWorkNo2(rgvProtocol.getTaskNo2()); //工位2 工作号
//            vo.setStaNo(String.valueOf(rgvProtocol.getRgvPosDestination())); //小车目标站
//            vo.setStatus(rgvProtocol.modeType.equals(RgvModeType.AUTO)? rgvProtocol.modeType.desc: RgvModeType.HAND.desc);   //  模式状态
//
//        }
//        return R.ok().add(list);
//    }
    @PostMapping("/output/site")
    @ManagerAuth(memo = "RGV报文日志输出")
@@ -187,196 +187,196 @@
        return R.ok().add(str.toString());
    }
    /****************************************************************/
    /************************** 手动操作 ******************************/
    /****************************************************************/
    @ManagerAuth(memo = "取放货")
    @PostMapping("/operator/put")
    public R rgvFetchPut(RgvOperatorParam param){
        RgvCommand command = new RgvCommand();
        command.setRgvNo(param.getRgvNo()); // RGV编号
        command.setAckFinish1(false);  // 任务完成确认位
        command.setTaskNo(0); // 工作号
        command.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
//        command.setDestinationStaNo1(param.getStaNo1());  // 目标站
        command.setAckFinish2(false);  // 任务完成确认位
        command.setTaskNo2(0); // 工作号
        command.setTaskMode2(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
//        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
        command.setCommand(true);
        return rgvControl(command)? R.ok(): R.error();
    }
    @ManagerAuth(memo = "取货")
    @PostMapping("/operator/take")
    public R rgvFetch(RgvOperatorParam param){
        RgvCommand command = new RgvCommand();
        command.setRgvNo(param.getRgvNo()); // RGV编号
        command.setWrkTaskPri(param.getWorkSta());  //执行工位
        command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号
        command.setTaskStatus(RgvTaskStatusType.FETCH); // 任务模式: 取货
        command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站
//        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货
//    /****************************************************************/
//    /************************** 手动操作 ******************************/
//    /****************************************************************/
//
//    @ManagerAuth(memo = "取放货")
//    @PostMapping("/operator/put")
//    public R rgvFetchPut(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setAckFinish1(false);  // 任务完成确认位
//        command.setTaskNo(0); // 工作号
//        command.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
//        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
////        command.setDestinationStaNo1(param.getStaNo1());  // 目标站
//        command.setAckFinish2(false);  // 任务完成确认位
//        command.setTaskNo2( 0); // 工作号
//        command.setTaskNo2(0); // 工作号
//        command.setTaskMode2(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货
//        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
//        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
        command.setCommand(true);
////        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
        return rgvControl(command)? R.ok(): R.error();
    }
//    @ManagerAuth(memo = "取货")
//    @PostMapping("/operator/take")
//    public R rgvFetch(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setWrkTaskPri(param.getWorkSta());  //执行工位
//        command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号
//        command.setTaskStatus(RgvTaskStatusType.FETCH); // 任务模式: 取货
//        command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站
////        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货
////        command.setAckFinish1(false);  // 任务完成确认位
////        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
////        command.setAckFinish2(false);  // 任务完成确认位
////        command.setTaskNo2( 0); // 工作号
////        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
////        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
    @ManagerAuth(memo = "放货")
    @PostMapping("/operator/stockMove")
    public R rgvPut(RgvOperatorParam param){
        RgvCommand command = new RgvCommand();
        command.setRgvNo(param.getRgvNo()); // RGV编号
        command.setWrkTaskPri(param.getWorkSta());  //执行工位
        command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号
        command.setTaskStatus(RgvTaskStatusType.PUT); // 任务模式: 取货
        command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站
//        command.setAckFinish1(false);  // 任务完成确认位
//        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
//        command.setAckFinish2(false);  // 任务完成确认位
//    @ManagerAuth(memo = "放货")
//    @PostMapping("/operator/stockMove")
//    public R rgvPut(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setWrkTaskPri(param.getWorkSta());  //执行工位
//        command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号
//        command.setTaskStatus(RgvTaskStatusType.PUT); // 任务模式: 取货
//        command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站
////        command.setAckFinish1(false);  // 任务完成确认位
////        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站
////        command.setAckFinish2(false);  // 任务完成确认位
////        command.setTaskNo2( 0); // 工作号
////        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货
////        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
////        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
//    @ManagerAuth(memo = "任务完成")
//    @PostMapping("/operator/taskComplete")
//    public R rgvTaskComplete(RgvOperatorParam param){
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setAckFinish1(true);  // 任务完成确认位
////        command.setTaskNo1(0); // 工作号
//        command.setTaskMode1(RgvTaskModeType.NONE); // 任务模式
//        command.setSourceStaNo1((short) 0); // 源站
//        command.setDestinationStaNo1((short) 0);  // 目标站
//        command.setAckFinish2(true);  // 任务完成确认位
//        command.setTaskNo2( 0); // 工作号
//        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货
//        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站
//        command.setDestinationStaNo2(param.getStaNo2());  // 目标站
        command.setCommand(true);
//        command.setTaskMode2(RgvTaskModeType.NONE); // 任务模式
//        command.setSourceStaNo2((short) 0); // 源站
//        command.setDestinationStaNo2((short) 0);  // 目标站
//        command.setCommand(true);
//
//        return rgvControl(command)? R.ok(): R.error();
//    }
        return rgvControl(command)? R.ok(): R.error();
    }
//    @ManagerAuth(memo = "清除命令")
//    @PostMapping("/operator/clearCommand")
//    public R rgvClearCommand(RgvOperatorParam param){
//        if (param.getRgvNo() == null) {
//            throw new CoolException("请选择RGV号");
//        }
//        RgvCommand command = new RgvCommand();
//        command.setRgvNo(param.getRgvNo()); // RGV编号
//        command.setWrkTaskPri(0);  //执行工位
//        command.setTaskNo(Math.toIntExact(0)); // 工作号
//        command.setTaskStatus((short)0); // 任务模式: 取货
//        command.setTargetPosition(0);  // 目标站
//
//        return rgvClear(command)? R.ok(): R.error();
//    }
    @ManagerAuth(memo = "任务完成")
    @PostMapping("/operator/taskComplete")
    public R rgvTaskComplete(RgvOperatorParam param){
        RgvCommand command = new RgvCommand();
        command.setRgvNo(param.getRgvNo()); // RGV编号
        command.setAckFinish1(true);  // 任务完成确认位
//        command.setTaskNo1(0); // 工作号
        command.setTaskMode1(RgvTaskModeType.NONE); // 任务模式
        command.setSourceStaNo1((short) 0); // 源站
        command.setDestinationStaNo1((short) 0);  // 目标站
        command.setAckFinish2(true);  // 任务完成确认位
        command.setTaskNo2( 0); // 工作号
        command.setTaskMode2(RgvTaskModeType.NONE); // 任务模式
        command.setSourceStaNo2((short) 0); // 源站
        command.setDestinationStaNo2((short) 0);  // 目标站
        command.setCommand(true);
        return rgvControl(command)? R.ok(): R.error();
    }
    @ManagerAuth(memo = "清除命令")
    @PostMapping("/operator/clearCommand")
    public R rgvClearCommand(RgvOperatorParam param){
        if (param.getRgvNo() == null) {
            throw new CoolException("请选择RGV号");
        }
        RgvCommand command = new RgvCommand();
        command.setRgvNo(param.getRgvNo()); // RGV编号
        command.setWrkTaskPri(0);  //执行工位
        command.setTaskNo(Math.toIntExact(0)); // 工作号
        command.setTaskStatus((short)0); // 任务模式: 取货
        command.setTargetPosition(0);  // 目标站
        return rgvClear(command)? R.ok(): R.error();
    }
    @ManagerAuth(memo = "手动复位")
    @PostMapping("/operator/handleReset")
    public R handleReset(RgvOperatorParam param) throws Exception {
        if (param.getRgvNo() == null) {
            throw new CoolException("请选择RGV");
        }
        // 获取RGV缓存
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            // 获取RGV信息
            if (param.getRgvNo().equals(rgv.getId())) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
                if (rgvThread == null) {
                    throw new CoolException("RGV不在线");
                }
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    throw new CoolException("RGV不在线");
                }
                RgvCommand Command = new RgvCommand();
                Command.setRgvNo(rgv.getId()); // RGV编号
                Command.setTaskMode1(RgvTaskModeType.NONE);
                Command.setAckFinish1(true);  // 任务完成确认位
                Command.setAckFinish2(true);  // 任务完成确认位
                Command.setCommand(true);  // 任务完成确认位
                // 延时发送
                Thread.sleep(1000L);
                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(4, Command))) {
                    return R.ok();
                } else {
                    throw new CoolException("命令下发失败");
                }
            }
        }
        return R.error();
    }
    private boolean rgvControl(RgvCommand command){
        if (command.getRgvNo() == null) {
            throw new CoolException("请选择RGV");
        }
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            // 获取RGV信息
            if (command.getRgvNo().equals(rgv.getId())) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
                if (rgvThread == null) {
                    throw new CoolException("RGV不在线");
                }
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    throw new CoolException("RGV不在线");
                }
                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(2, command))) {
                    return true;
                } else {
                    throw new CoolException("命令下发失败");
                }
            }
        }
        return false;
    }
    private boolean rgvClear(RgvCommand command){
        if (command.getRgvNo() == null) {
            throw new CoolException("请选择RGV");
        }
        for (RgvSlave rgv : slaveProperties.getRgv()) {
            // 获取RGV信息
            if (command.getRgvNo().equals(rgv.getId())) {
                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
                if (rgvThread == null) {
                    throw new CoolException("RGV不在线");
                }
                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
                if (rgvProtocol == null) {
                    throw new CoolException("RGV不在线");
                }
                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(3, command))) {
                    return true;
                } else {
                    throw new CoolException("命令下发失败");
                }
            }
        }
        return false;
    }
//    @ManagerAuth(memo = "手动复位")
//    @PostMapping("/operator/handleReset")
//    public R handleReset(RgvOperatorParam param) throws Exception {
//        if (param.getRgvNo() == null) {
//            throw new CoolException("请选择RGV");
//        }
//        // 获取RGV缓存
//        for (RgvSlave rgv : slaveProperties.getRgv()) {
//            // 获取RGV信息
//            if (param.getRgvNo().equals(rgv.getId())) {
//                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
//                if (rgvThread == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//                if (rgvProtocol == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvCommand Command = new RgvCommand();
//                Command.setRgvNo(rgv.getId()); // RGV编号
//                Command.setTaskMode1(RgvTaskModeType.NONE);
//                Command.setAckFinish1(true);  // 任务完成确认位
//                Command.setAckFinish2(true);  // 任务完成确认位
//                Command.setCommand(true);  // 任务完成确认位
//                // 延时发送
//                Thread.sleep(1000L);
//                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(4, Command))) {
//                    return R.ok();
//                } else {
//                    throw new CoolException("命令下发失败");
//                }
//
//            }
//        }
//        return R.error();
//    }
//
//    private boolean rgvControl(RgvCommand command){
//        if (command.getRgvNo() == null) {
//            throw new CoolException("请选择RGV");
//        }
//        for (RgvSlave rgv : slaveProperties.getRgv()) {
//            // 获取RGV信息
//            if (command.getRgvNo().equals(rgv.getId())) {
//                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
//                if (rgvThread == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//                if (rgvProtocol == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(2, command))) {
//                    return true;
//                } else {
//                    throw new CoolException("命令下发失败");
//                }
//            }
//        }
//        return false;
//    }
//
//    private boolean rgvClear(RgvCommand command){
//        if (command.getRgvNo() == null) {
//            throw new CoolException("请选择RGV");
//        }
//        for (RgvSlave rgv : slaveProperties.getRgv()) {
//            // 获取RGV信息
//            if (command.getRgvNo().equals(rgv.getId())) {
//                RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId());
//                if (rgvThread == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                RgvProtocol rgvProtocol = rgvThread.getRgvProtocol();
//                if (rgvProtocol == null) {
//                    throw new CoolException("RGV不在线");
//                }
//                if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(3, command))) {
//                    return true;
//                } else {
//                    throw new CoolException("命令下发失败");
//                }
//            }
//        }
//        return false;
//
//    }
}
src/main/java/com/zy/asrs/entity/DeviceError.java
New file
@@ -0,0 +1,96 @@
package com.zy.asrs.entity;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import com.core.common.Cools;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
@Data
@TableName("wcs_device_error")
public class DeviceError implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Long id;
    /**
     * 设备
     */
    @ApiModelProperty(value= "设备")
    @TableField("device")
    private String device;
    /**
     * 异常信息
     */
    @ApiModelProperty(value= "异常信息")
    @TableField("msg")
    private String msg;
    /**
     * 设备ID
     */
    @ApiModelProperty(value= "设备ID")
    @TableField("device_id")
    private Integer deviceId;
    /**
     * 设备ID
     */
    @ApiModelProperty(value= "设备plcID")
    @TableField("device_plc_id")
    private Integer devicePlcId;
    /**
     * 创建时间
     */
    @ApiModelProperty(value= "创建时间")
    @TableField("create_time")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 创建时间
     */
    @ApiModelProperty(value= "创建时间")
    @TableField("appe_time")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date appeTime;
    public DeviceError() {}
    public DeviceError(Long id, String device, String msg, Integer deviceId, Date createTime) {
        this.id = id;
        this.device = device;
        this.msg = msg;
        this.deviceId = deviceId;
        this.createTime = createTime;
    }
    //    DeviceError deviceError = new DeviceError(
//            null,    // 设备
//            null,    // 设备ID
//            null,    // 创建时间
//            null    // 异常信息
//    );
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
}
src/main/java/com/zy/asrs/mapper/DeviceErrorMapper.java
New file
@@ -0,0 +1,33 @@
package com.zy.asrs.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.zy.asrs.entity.DeviceError;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface DeviceErrorMapper extends BaseMapper<DeviceError> {
    DeviceError selectByDeviceAndDeviceId(String device, Integer deviceId);
    Integer deleteByDeviceAndDeviceId(String device, Integer deviceId);
    List<DeviceError> selectDeviceErrorList(
            @Param("id")Long id,
            @Param("device")String device,
            @Param("deviceId")Integer deviceId,
            @Param("pageNumber")Integer curr,
            @Param("pageSize")Integer limit
    ) ;
    Long selectDeviceErrorListTotal(
            @Param("id")Long id,
            @Param("device")String device,
            @Param("deviceId")Integer deviceId
    ) ;
}
src/main/java/com/zy/asrs/service/DeviceErrorService.java
New file
@@ -0,0 +1,19 @@
package com.zy.asrs.service;
import com.baomidou.mybatisplus.service.IService;
import com.zy.asrs.entity.DeviceError;
import java.util.List;
public interface DeviceErrorService extends IService<DeviceError> {
    DeviceError selectByDeviceAndDeviceId(String device, Integer deviceId);
    Boolean addDeviceError(String device, Integer deviceId, String msg);
    Integer deleteDeviceError(String device, Integer deviceId);
    List<DeviceError> selectDeviceErrorList(Long id, String device, Integer deviceId, Integer curr, Integer limit) ;
    Long selectDeviceErrorListTotal(Long id,String device, Integer deviceId) ;
}
src/main/java/com/zy/asrs/service/impl/DeviceErrorServiceImpl.java
New file
@@ -0,0 +1,55 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.entity.DeviceError;
import com.zy.asrs.mapper.DeviceErrorMapper;
import com.zy.asrs.service.DeviceErrorService;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service("deviceErrorService")
public class DeviceErrorServiceImpl extends ServiceImpl<DeviceErrorMapper, DeviceError> implements DeviceErrorService {
    @Override
    public DeviceError selectByDeviceAndDeviceId(String device, Integer deviceId) {
        return this.baseMapper.selectByDeviceAndDeviceId(device, deviceId);
    }
    @Override
    public Boolean addDeviceError(String device, Integer deviceId, String msg) {
//        DeviceError error = this.selectByDeviceAndDeviceId(device, deviceId);
//        if (error == null) {
            DeviceError deviceError = new DeviceError();
            deviceError.setDevice(device);
            deviceError.setDeviceId(deviceId);
            deviceError.setMsg(msg);
            deviceError.setCreateTime(new Date());
            Integer insert = 0;
            try{
                insert = this.baseMapper.insert(deviceError);
            } catch (Exception e){
            }
            return  insert> 0;
//        }
//        return true;
    }
    @Override
    public Integer deleteDeviceError(String device, Integer deviceId) {
        return this.baseMapper.deleteByDeviceAndDeviceId(device, deviceId);
    }
    @Override
    public List<DeviceError> selectDeviceErrorList(Long id, String device, Integer deviceId, Integer curr, Integer limit) {
        return this.baseMapper.selectDeviceErrorList(id,device, deviceId,curr,limit);
    }
    @Override
    public Long selectDeviceErrorListTotal(Long id,String device, Integer deviceId) {
        return this.baseMapper.selectDeviceErrorListTotal(id,device, deviceId);
    }
}
src/main/java/com/zy/asrs/utils/TrackRangeUtils.java
New file
@@ -0,0 +1,81 @@
package com.zy.asrs.utils;
import com.zy.core.cache.RgvStatusCache;
import com.zy.core.model.RgvSlave;
import com.zy.core.model.protocol.RgvProtocol;
/**
 * Created by Monkey D. Luffy on 2023/7/18
 */
public class TrackRangeUtils {
    public boolean IsItSmall(RgvSlave slave) {
        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        if (rgvProtocol.getRgvPos() < rgvProtocolOther.getRgvPos()) {
            return true;
        }
        return false;
    }
    public Long[][] avoidRange(RgvSlave slave, Long trackEntireLength, Long trackBenchmark, Long avoidDistance) {
        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        RgvProtocol rgvProtocolE, rgvProtocolB;
        if (IsItSmall(slave)) {
            rgvProtocolE = rgvProtocolOther;
            rgvProtocolB = rgvProtocol;
        } else {
            rgvProtocolE = rgvProtocol;
            rgvProtocolB = rgvProtocolOther;
        }
        long entireLengthE = trackEntireLength - rgvProtocolE.getCarBodyKunPeng();
        long benchmarkE = trackBenchmark + rgvProtocolB.getCarBodyJiaoMing() + rgvProtocolB.getCarBodyKunPeng() + avoidDistance + rgvProtocolE.getCarBodyJiaoMing();
        long entireLengthB = trackEntireLength - rgvProtocolE.getCarBodyKunPeng() - rgvProtocolE.getCarBodyJiaoMing() - avoidDistance - rgvProtocolB.getCarBodyKunPeng();
        long benchmarkB = trackBenchmark + rgvProtocolB.getCarBodyJiaoMing();
        return new Long[][]{new Long[]{entireLengthE, benchmarkE}, new Long[]{entireLengthB, benchmarkB}};
    }
    public Long[][] avoidRangeArr(RgvSlave slave, Long trackEntireLength, Long trackBenchmark, Long avoidDistance) {
        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        RgvProtocol rgvProtocolE, rgvProtocolB;
        if (IsItSmall(slave)) {
            rgvProtocolE = rgvProtocolOther;
            rgvProtocolB = rgvProtocol;
            long entireLength = rgvProtocolE.getRgvPosDestination() - rgvProtocolE.getCarBodyJiaoMing() - avoidDistance - rgvProtocolB.getCarBodyKunPeng();
            long benchmark = trackBenchmark + rgvProtocolB.getCarBodyJiaoMing();
            long entireLengthOther = trackEntireLength - rgvProtocolE.getCarBodyKunPeng();
            long benchmarkOther = rgvProtocolB.getRgvPosDestination() + rgvProtocolB.getCarBodyKunPeng() + avoidDistance + rgvProtocolE.getCarBodyJiaoMing();
            return new Long[][]{new Long[]{entireLength, benchmark}, new Long[]{entireLengthOther, benchmarkOther}};
        } else {
            rgvProtocolE = rgvProtocol;
            rgvProtocolB = rgvProtocolOther;
            long entireLength = trackEntireLength - rgvProtocolE.getCarBodyKunPeng();
            long benchmark = rgvProtocolB.getRgvPosDestination() + rgvProtocolB.getCarBodyKunPeng() + avoidDistance + rgvProtocolE.getCarBodyJiaoMing();
            long entireLengthOther = rgvProtocolE.getRgvPosDestination() - rgvProtocolE.getCarBodyJiaoMing() - avoidDistance - rgvProtocolB.getCarBodyKunPeng();
            long benchmarkOther = trackBenchmark + rgvProtocolB.getCarBodyJiaoMing();
            return new Long[][]{new Long[]{entireLength, benchmark}, new Long[]{entireLengthOther, benchmarkOther}};
        }
    }
    public boolean avoidRange(Long avoid, Long[] range) {
        return avoid < range[0] && avoid > range[1];
    }
}
src/main/java/com/zy/core/ThreadHandler.java
@@ -6,4 +6,6 @@
    void close();
    void setWrkSign();
}
src/main/java/com/zy/core/cache/RgvErrCache.java
New file
@@ -0,0 +1,100 @@
package com.zy.core.cache;
import com.zy.core.model.protocol.RgvErrProtocol;
import java.util.concurrent.ConcurrentHashMap;
/**
 * Created by IX on 2025/02/21
 */
public class RgvErrCache {
    // 本地缓存,键为 currentPosition,值为 DeviceStatus
    private static final ConcurrentHashMap<Integer, RgvErrProtocol> cache = new ConcurrentHashMap<>();
    /**
     * 更新设备状态
     */
    public static void updateRgvStatus(RgvErrProtocol status) {
        try {
            cache.put(status.getRgvNo(), status);
        } finally {
        }
    }
    /**
     * 更新设备状态
     */
    public static void updateRgvErr(Integer rgvNo,String error) {
        try {
            RgvErrProtocol rgvErrProtocol = cache.get(rgvNo);
            if (rgvErrProtocol == null){
                rgvErrProtocol = new RgvErrProtocol();
                rgvErrProtocol.setRgvNo(rgvNo);
            }
            if (!rgvErrProtocol.getError().equals(error)){
                rgvErrProtocol.setError(error);
                cache.put(rgvErrProtocol.getRgvNo(), rgvErrProtocol);
            }
        } finally {
        }
    }
    /**
     * 更新设备状态
     */
    public static void updateRgvErr(Integer rgvNo) {
        try {
            RgvErrProtocol rgvErrProtocol = cache.get(rgvNo);
            if (rgvErrProtocol == null){
                rgvErrProtocol = new RgvErrProtocol();
                rgvErrProtocol.setRgvNo(rgvNo);
            }
            if (!rgvErrProtocol.getError().equals("-")){
                rgvErrProtocol.setError("-");
                cache.put(rgvErrProtocol.getRgvNo(), rgvErrProtocol);
            }
        } finally {
        }
    }
    /**
     * 更新设备状态
     */
    public static String getErrorDev(Integer rgvNo) {
        try {
            RgvErrProtocol rgvErrProtocol = cache.get(rgvNo);
            if (rgvErrProtocol == null){
                rgvErrProtocol = new RgvErrProtocol();
                rgvErrProtocol.setRgvNo(rgvNo);
            }
            return rgvErrProtocol.getError();
        } finally {
        }
    }
    /**
     * 获取设备状态
     */
    public static RgvErrProtocol getRgvStatus(Integer rgvNo) {
        try {
            return cache.get(rgvNo);
        } finally {
        }
    }
    /**
     * 获取所有设备状态
     */
    public static ConcurrentHashMap<Integer, RgvErrProtocol> getAllRgvStatus() {
        try {
            return new ConcurrentHashMap<>(cache); // 返回副本
        } finally {
        }
    }
}
src/main/java/com/zy/core/cache/RgvRunCache.java
New file
@@ -0,0 +1,59 @@
package com.zy.core.cache;
import com.core.common.Cools;
import com.zy.core.model.protocol.RgvRunProtocol;
import java.util.concurrent.ConcurrentHashMap;
/**
 * Created by IX on 2025/02/21
 */
public class RgvRunCache {
    // 本地缓存,键为 currentPosition,值为 DeviceStatus
    private static final ConcurrentHashMap<String, RgvRunProtocol> cache = new ConcurrentHashMap<>();
    /**
     * 更新设备状态
     */
    public static void updateRgvStatus(RgvRunProtocol status) {
        try {
            cache.put(status.getDev(), status);
        } finally {
        }
    }
    /**
     * 获取设备状态
     */
    public static RgvRunProtocol getRgvRun() {
        try {
            RgvRunProtocol rgv = cache.get("RGV");
            if (Cools.isEmpty(rgv)){
                rgv = new RgvRunProtocol();
            }
            return rgv;
        } finally {
        }
    }
    /**
     * 获取设备状态
     */
    public static RgvRunProtocol getRgvStatus(String dev) {
        try {
            return cache.get(dev);
        } finally {
        }
    }
    /**
     * 获取所有设备状态
     */
    public static ConcurrentHashMap<String, RgvRunProtocol> getAllRgvStatus() {
        try {
            return new ConcurrentHashMap<>(cache); // 返回副本
        } finally {
        }
    }
}
src/main/java/com/zy/core/cache/RgvStatusCache.java
New file
@@ -0,0 +1,62 @@
package com.zy.core.cache;
import com.zy.core.model.protocol.RgvProtocol;
import java.util.concurrent.ConcurrentHashMap;
/**
 * Created by IX on 2025/02/21
 */
public class RgvStatusCache {
    // 本地缓存,键为 currentPosition,值为 DeviceStatus
    private static final ConcurrentHashMap<Integer, RgvProtocol> cache = new ConcurrentHashMap<>();
    /**
     * 更新设备状态
     */
    public static void updateRgvStatus(RgvProtocol status) {
        try {
            if (status.getRgvNo()!=1 && status.getRgvNo() != 2){
                return;
            }
            cache.put(status.getRgvNo(), status);
        } finally {
        }
    }
    /**
     * 获取设备状态
     */
    public static RgvProtocol getRgvStatus(Integer RgvNo) {
        try {
            return cache.get(RgvNo);
        } finally {
        }
    }
    /**
     * 获取所有设备状态
     */
    public static ConcurrentHashMap<Integer, RgvProtocol> getAllRgvStatus() {
        try {
            return new ConcurrentHashMap<>(cache); // 返回副本
        } finally {
        }
    }
    /**
     * 获取所有设备状态
     */
    public static void removeAll() {
        try {
            ConcurrentHashMap<Integer, RgvProtocol> integerRgvProtocolConcurrentHashMap = new ConcurrentHashMap<>(cache);
            if (integerRgvProtocolConcurrentHashMap.values().size()>2){
                for (RgvProtocol rgvProtocol : integerRgvProtocolConcurrentHashMap.values()){
                    cache.remove(rgvProtocol.getRgvNo());
                }
            }
        } finally {
        }
    }
}
src/main/java/com/zy/core/cache/RgvTaskCache.java
New file
@@ -0,0 +1,44 @@
package com.zy.core.cache;
import com.zy.core.model.protocol.RgvTaskProtocol;
import java.util.concurrent.ConcurrentHashMap;
/**
 * Created by IX on 2025/02/21
 */
public class RgvTaskCache {
    // 本地缓存,键为 currentPosition,值为 DeviceStatus
    private static final ConcurrentHashMap<Integer, RgvTaskProtocol> cache = new ConcurrentHashMap<>();
    /**
     * 更新设备状态
     */
    public static void updateRgvStatus(RgvTaskProtocol status) {
        try {
            cache.put(status.getRgvNo(), status);
        } finally {
        }
    }
    /**
     * 获取设备状态
     */
    public static RgvTaskProtocol getRgvStatus(Integer RgvNo) {
        try {
            return cache.get(RgvNo);
        } finally {
        }
    }
    /**
     * 获取所有设备状态
     */
    public static ConcurrentHashMap<Integer, RgvTaskProtocol> getAllRgvStatus() {
        try {
            return new ConcurrentHashMap<>(cache); // 返回副本
        } finally {
        }
    }
}
src/main/java/com/zy/core/cache/TaskProtocolCache.java
New file
@@ -0,0 +1,184 @@
package com.zy.core.cache;
import com.zy.core.model.protocol.TaskProtocol;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
 * Created by IX on 2025/02/21
 */
@Slf4j
public class TaskProtocolCache {
    // 本地缓存,键为 taskNo,值为 TaskProtocol
    private final ConcurrentHashMap<String, TaskProtocol> cache = new ConcurrentHashMap<>();
    // 读写锁,确保线程安全
//    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    /**
     * 更新设备状态
     */
    public void updateTaskProtocol(TaskProtocol status) {
        cache.put(status.getTaskNoDirection(), status);
    }
    /**
     * 删除任务缓存
     */
    public TaskProtocol removeTaskProtocol(String taskNoDirection) {
//        lock.readLock().lock(); // 加读锁
        try {
            return cache.remove(taskNoDirection);
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 获取所有任务
     */
    public ConcurrentHashMap<String, TaskProtocol> getAllTaskProtocol() {
//        lock.readLock().lock(); // 加读锁
        try {
            return new ConcurrentHashMap<>(cache); // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 获取所有取任务
     */
    public List<TaskProtocol> getTakeOrPutTaskProtocol(short loaded) {
        if (loaded == 0){
            return getAllTakeTaskProtocol();
        } else if (loaded == 1){
            return getAllPutTaskProtocol();
        }
        return new ArrayList<>();
    }
    /**
     * 获取所有取任务
     */
    public List<TaskProtocol> getAllTakeTaskProtocol() {
//        lock.readLock().lock(); // 加读锁
        try {
            List<TaskProtocol> allTakeTaskProtocol = new ArrayList<>();
            for (TaskProtocol task : cache.values()) {
                if (task.getTaskStatus()==2) {
                    allTakeTaskProtocol.add(task);
                }
            }
            return allTakeTaskProtocol; // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 获取所有放任务
     */
    public List<TaskProtocol> getAllPutTaskProtocol() {
//        lock.readLock().lock(); // 加读锁
        try {
            List<TaskProtocol> allPutTaskProtocol = new ArrayList<>();
            for (TaskProtocol task : cache.values()) {
                if (task.getTaskStatus()==3) {
                    allPutTaskProtocol.add(task);
                }
            }
            return allPutTaskProtocol; // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 获取所有行走任务
     */
    public List<TaskProtocol> getAllWalkTaskProtocol() {
//        lock.readLock().lock(); // 加读锁
        try {
            List<TaskProtocol> allWalkTaskProtocol = new ArrayList<>();
            for (TaskProtocol task : cache.values()) {
                if (task.getTaskStatus()==1) {
                    allWalkTaskProtocol.add(task);
                }
            }
            return allWalkTaskProtocol; // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 查询是否有可执行任务
     */
    public boolean isNowPosRun(Long targetPosition) {
//        lock.readLock().lock(); // 加读锁
        try {
            List<TaskProtocol> allWalkTaskProtocol = new ArrayList<>();
            for (TaskProtocol task : cache.values()) {
                long runPos = Math.abs(task.getTargetPosition() - targetPosition);
                if (runPos<50) {
                    return true;
                }
            }
            return false; // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 查询是否有可执行任务
     */
    public TaskProtocol getNowPosRunTask(Long targetPosition) {
//        lock.readLock().lock(); // 加读锁
        try {
            for (TaskProtocol task : cache.values()) {
                long runPos = Math.abs(task.getTargetPosition() - targetPosition);
                if (runPos<50) {
                    return task;
                }
            }
            return null; // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
    /**
     * 查询是否有可执行任务
     */
    public TaskProtocol getNowPosRunTask2() {
//        lock.readLock().lock(); // 加读锁
        try {
            for (TaskProtocol task : cache.values()) {
                if (task.getTaskStatus()==1) {
                    return task;
                }
            }
            for (TaskProtocol task : cache.values()) {
                if (task.getTaskStatus()==2) {
                    return task;
                }
            }
            for (TaskProtocol task : cache.values()) {
                if (task.getTaskStatus()==3) {
                    return task;
                }
            }
            return null; // 返回副本
        } finally {
//            lock.readLock().unlock(); // 释放读锁
        }
    }
}
src/main/java/com/zy/core/enums/RgvStatusType.java
@@ -2,45 +2,51 @@
public enum RgvStatusType {
    NONE(-1, "离线"),
    IDLE(0, "空闲"),
    WORKING(1, "作业中"),
    SOS(2, "报警"),
    WORKING1(3, "作业中"),
    FETCHING(11, "取货中"),
    PUTTING(12, "放货中"),
    WAITING(90, "任务完成等待WCS确认"),
    FETCHWAITING(91, "取货任务完成等待WCS确认"),
    NONE(-1, "离线","ffffff"),
    NONE0(0, "离线","ffffff"),
    IDLE(1, "空闲","ffffff"),
    WORKING(2, "作业中","ffffff"),// 1:行走  2:取  3:放
    SOS(3, "报警","ffffff"),
    FETCHING(11, "取货中","ffffff"),
    PUTTING(12, "放货中","ffffff"),
    WAITING(90, "任务完成等待WCS确认","ffffff"),
    FETCHWAITING(91, "取货任务完成等待WCS确认","ffffff"),
    SOS99(99, "报警99","ffffff"),
    OTHER(100, "其它100","ffffff"),
    MAN(110, "作业启动中","ffffff"),
    ROAM(100000, "漫游","ffffff")
    ;
    public Integer id;
    public String desc;
    RgvStatusType(Integer id, String desc) {
    public String color;
    RgvStatusType(Integer id, String desc, String color) {
        this.id = id;
        this.desc = desc;
        this.color = color;
    }
    public static RgvStatusType get(Short id) {
        if (null == id) {
            return null;
            return OTHER;
        }
        for (RgvStatusType type : RgvStatusType.values()) {
            if (type.id.equals(id.intValue())) {
                return type;
            }
        }
        return NONE;
        return OTHER;
    }
    public static RgvStatusType get(RgvStatusType type) {
        if (null == type) {
            return null;
            return OTHER;
        }
        for (RgvStatusType rgvStatusType : RgvStatusType.values()) {
            if (rgvStatusType == type) {
                return rgvStatusType;
            }
        }
        return null;
        return OTHER;
    }
}
src/main/java/com/zy/core/model/RgvSlave.java
@@ -22,29 +22,16 @@
    private Boolean demo;
    private Integer otherId;
    private Long carBodyJiaoMing;
    private Long carBodyKunPeng;
    // RGV入库源站点
    private List<RgvStn> rgvInSStn = new ArrayList<>();
    // RGV出库源站点
    private List<RgvStn> rgvOutSStn = new ArrayList<>();
    // RGV叠盘
    private List<RgvStn> rgvEmptyInSStn = new ArrayList<>();
    // RGV空板入库
    private List<RgvStn> rgvEmptyOutSStn = new ArrayList<>();
    // RGV出库目标站点
    private List<RgvStn> rgvDestStn = new ArrayList<>();
    // RGV入库取货站点
    private List<RgvStn> rgvInTStn = new ArrayList<>();
    // RGV入库放货站点
    private List<RgvStn> rgvInPStn = new ArrayList<>();
    // RGV出库取货站点
    private List<RgvStn> rgvOutTStn = new ArrayList<>();
    //RGV出库放货站点
    private List<RgvStn> rgvOutPStn = new ArrayList<>();
    private List<RgvStn> rgvInSta = new ArrayList<>();
    private List<RgvStn> rgvOutSta = new ArrayList<>();
    private List<RgvStn> rgvSuperSta = new ArrayList<>();
    @Data
    public static class RgvStn {
@@ -54,17 +41,15 @@
        // RGV站点编号
        private Integer staNo;
        // RGV二站点编号
        private Integer staNo2;
//        // 排
//        private Integer row;
//
//        // 列
//        private Integer bay;
//
//        // 层
//        private Integer lev;
        // RGV站点编号
        private boolean direction;
        // RGV站点编号
        private Integer staNoOther;
        // RGV站点编号
        private boolean directionOther;
    }
src/main/java/com/zy/core/model/protocol/RgvErrProtocol.java
New file
@@ -0,0 +1,16 @@
package com.zy.core.model.protocol;
import lombok.Data;
/**
 * Created by IX on 2025/02/21
 */
@Data
public class RgvErrProtocol {
    private Integer rgvNo;
    public String error = "-";
    public RgvErrProtocol(){}
}
src/main/java/com/zy/core/model/protocol/RgvProtocol.java
@@ -1,99 +1,59 @@
package com.zy.core.model.protocol;
import com.zy.asrs.entity.BasRgv;
import com.zy.asrs.entity.BasRgvErrorLog;
import com.zy.core.enums.RgvModeType;
import com.zy.core.enums.RgvStatusType;
import lombok.Data;
import javax.swing.*;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by vincent on 2020/8/7
 */
@Data
public class RgvProtocol implements Cloneable{
public class RgvProtocol {
    private short RgvNo;
    private Integer RgvNo;
    /**
     * 1 = 手动模式
     * 2 = 自动模式
     * 3 = 电脑模式
     */
    public Short mode;
    public Short mode = -1;
    public RgvModeType modeType;
    private transient Long loadingStartTime;
    public RgvModeType modeType = RgvModeType.NONE;
    /**
     * 执行优先级
     * 0:不判断
     * 1:工位1先执行
     * 2:工位2先执行
     */
    public Short wrkTaskPri;
    public Short wrkTaskMove1;
    public Short wrkTaskMove2;
    /**
     * RGV当前状态工位1
     * RGV当前状态
     * 0:空闲,无任务
     * 1:作业中
     * 2:报警
     */
    public Short status;
    public Short status = -1;
    /**
     * 状态枚举
     */
    public RgvStatusType statusType;
    public RgvStatusType statusType = RgvStatusType.NONE;
    /**
     * 工位1任务号
     * 任务号
     */
    public Integer taskNo1 = 0;
    /**
     * 工位1目标站
     */
    public Integer staNo1 = 0;
    public Long taskNo = 0L;
    /**
     * RGV工位1当前状态
     * 0:空闲,无任务
     * 11:取货中
     * 12:放货中
     * 10:任务完成等待WCS确认
     * 有物
     */
    public Short status1;
    /**
     * 状态枚举
     */
    public RgvStatusType statusType1;
    /**
     * 工位1有物
     */
    public Boolean loaded1;
    public Short loaded = -1;//0 无物;1 有物
    /**
     * RGV当前位置
     */
    public Integer RgvPos;
    public Long RgvPos = 0L;
    /**
     * RGV当前目的位置
     * RGV目的位置
     */
    public Integer RgvPosDestination;
    public Long RgvPosDestination = 0L;
    /**
     * 走行在定位
@@ -103,176 +63,9 @@
    public Short walkPos;
    /**
     * 急停触发
     */
    public Boolean err1;
    /**
     *
     */
    public Boolean err2;
    /**
     * 有资料无物
     */
    public Boolean err3;
    /**
     * 命令错误走行联调冲突
     */
    public Boolean err4;
    /**
     * 目标为超过行走极限
     */
    public Boolean err5;
    /**
     *  变频器异常
     */
    public Boolean err6;
    /**
     * 光电异常
     */
    public Boolean err7;
    public Boolean err8;
    public Boolean err9;
    public Boolean err10;
    public Boolean err11;
    public Boolean err12;
    //////////////////////     工位2定义   //////////////////////////////////////////////////
    /**
     * 工位2任务号
     */
    public Integer taskNo2 = 0;
    /**
     * 工位1目标站
     */
    public Integer staNo2 = 0;
    /**
     * RGV工位2当前状态
     * 0:空闲,无任务
     * 11:取货中
     * 12:放货中
     * 10:任务完成等待WCS确认
     */
    public Short status2;
    /**
     * 状态枚举
     */
    public RgvStatusType statusType2;
    /**
     * 工位2有物
     */
    public Boolean loaded2;
//    /**
//     * 急停
//     */
//    public Boolean err21;
//
//    /**
//     * 有物无资料
//     */
//    public Boolean err22;
//
//    /**
//     * 有资料无物
//     */
//    public Boolean err23;
//
//    /**
//     * 命令错误走行联调冲突
//     */
//    public Boolean err24;
//
//    /**
//     * 目标为超过行走极限
//     */
//    public Boolean err25;
//
//    /**
//     *  变频器异常
//     */
//    public Boolean err26;
//
//    /**
//     * 光电异常
//     */
//    public Boolean err27;
    ///////////////////////////////////////////////////////////////////////////////////////
    //配置信号-----------------------------------------------------------------------------
    // 故障读取锁定标记
    private boolean errorMk = false;
    //写入标记
    private boolean writeMk = true;
    private Boolean chainForward1 = false;       // 链条前进 1
    private Boolean chainReverse1 = false;       // 链条后退 1
    private Boolean inverterAlarm = false;       // 变频器报警
    private Boolean leftOverlimit2 = false;      // 左超限 2
    private Boolean rightOverlimit2 = false;     // 右超限 2
    private Boolean leftAtPosition2 = false;     // 左到位 2
    private Boolean rightAtPosition2 = false;    // 右到位 2
    private Boolean cargoSpeedReduction = false; // 货物减速
    private Boolean conveyorInverterAlarm2 = false; // 输送变频器报警 2
    private Boolean emergencyStop = false;       // 急停触发
    private Boolean slot1EmptyNoData = false;    // 1号位有物无资料
    private Boolean slot2EmptyNoData = false;    // 2号位有物无资料
    private Boolean commandErrorChainConflict = false; // 命令错误走链条冲突
    private Boolean targetPositionIssue = false; // 目标位下发错误
    private Boolean travelInverterError = false; // 走行变频器异常
    private Boolean photoelectric1Error = false; // 1号光电异常
    private Boolean photoelectric2Error = false; // 2号光电异常
    private Boolean timeoutConnectionWithLine = false; // 与输线时接超时
    private Boolean leftRollerTimeout = false;    // 左侧滚筒运行超时
    private Boolean rightRollerTimeout = false;   // 右侧滚筒运行超时
    private Boolean rgvRunTimeout = false;        // rgv运行超时
    private Boolean position1ChainInverterError = false; // 1号工位链条变频器异常
    private Boolean position2ChainInverterError = false; // 2号工位链条变频器异常
    private Boolean frontRearLimit = false;      // 前后极限位
    private Boolean emergencyButton = false;     // 急停按钮
    private Boolean forwardButton = false;       // 前进按钮
    private Boolean reverseButton = false;       // 后退按钮
    private Boolean localRemote = false;         // 本地/远程
    private Boolean reset = false;               // 复位
    private Boolean travelBrakeSwitch = false;   // 走行抱闸开关钮
    private Boolean travelSpeedLimitPhotoelectric = false; // 走行强制减速光电
    private Boolean leftOverlimit1 = false;      // 左超限 1
    private Boolean rightOverlimit1 = false;     // 右超限 1
    private Boolean leftAtPosition1 = false;     // 左到位 1
    private Boolean rightAtPosition1 = false;    // 右到位 1
    private Boolean rightConveyor2 = false;      // 右输送 2
    private Boolean leftConveyor2 = false;       // 左输送 2
    //---------------------------------------------------------------------
    /**
     * 异常码
     */
    public Short alarm;
    /**
     * 心跳指令 1-2每秒切换一次
     */
    public Short heart;
    private Short temp1;
    private Short temp2;
    private Short temp3;
    private Short temp4;
    private Short temp5;
    /**
     * X行走行速度m/min
@@ -280,59 +73,54 @@
    private Float xSpeed;
    /**
     * 堆垛机累计走行距离km
     * 累计走行距离km
     */
    public Float xDistance;
    /**
     * 堆垛机累计走行时长h
     * 累计走行时长h
     */
    public Float xDuration;
    /**
     * 车身
     */
    public Long carBodyJiaoMing = 2000L;
    public BasRgvErrorLog toSqlModelError(){
        BasRgvErrorLog basRgvErrorLog = new BasRgvErrorLog();
        basRgvErrorLog.setRgvNo((int) RgvNo);// 设备号(假设有定义 siteId)
        basRgvErrorLog.setChainForward1(chainForward1 ? "Y" : "N");       // 链条前进 1
        basRgvErrorLog.setChainReverse1(chainReverse1 ? "Y" : "N");       // 链条后退 1
        basRgvErrorLog.setInverterAlarm(inverterAlarm ? "Y" : "N");       // 变频器报警
        basRgvErrorLog.setLeftOverlimit2(leftOverlimit2 ? "Y" : "N");      // 左超限 2
        basRgvErrorLog.setRightOverlimit2(rightOverlimit2 ? "Y" : "N");     // 右超限 2
        basRgvErrorLog.setLeftAtPosition2(leftAtPosition2 ? "Y" : "N");     // 左到位 2
        basRgvErrorLog.setRightAtPosition2(rightAtPosition2 ? "Y" : "N");    // 右到位 2
        basRgvErrorLog.setCargoSpeedReduction(cargoSpeedReduction ? "Y" : "N"); // 货物减速
        basRgvErrorLog.setConveyorInverterAlarm2(conveyorInverterAlarm2 ? "Y" : "N"); // 输送变频器报警 2
        basRgvErrorLog.setEmergencyStop(emergencyStop ? "Y" : "N");       // 急停触发
        basRgvErrorLog.setSlot1EmptyNoData(slot1EmptyNoData ? "Y" : "N");    // 1号位有物无资料
        basRgvErrorLog.setSlot2EmptyNoData(slot2EmptyNoData ? "Y" : "N");    // 2号位有物无资料
        basRgvErrorLog.setCommandErrorChainConflict(commandErrorChainConflict ? "Y" : "N"); // 命令错误走链条冲突
        basRgvErrorLog.setTargetPositionIssue(targetPositionIssue ? "Y" : "N"); // 目标位下发错误
        basRgvErrorLog.setTravelInverterError(travelInverterError ? "Y" : "N"); // 走行变频器异常
        basRgvErrorLog.setPhotoelectric1Error(photoelectric1Error ? "Y" : "N"); // 1号光电异常
        basRgvErrorLog.setPhotoelectric2Error(photoelectric2Error ? "Y" : "N"); // 2号光电异常
        basRgvErrorLog.setTimeoutConnectionWithLine(timeoutConnectionWithLine ? "Y" : "N"); // 与输线时接超时
        basRgvErrorLog.setLeftRollerTimeout(leftRollerTimeout ? "Y" : "N");    // 左侧滚筒运行超时
        basRgvErrorLog.setRightRollerTimeout(rightRollerTimeout ? "Y" : "N");   // 右侧滚筒运行超时
        basRgvErrorLog.setRgvRunTimeout(rgvRunTimeout ? "Y" : "N");        // rgv运行超时
        basRgvErrorLog.setPosition1ChainInverterError(position1ChainInverterError ? "Y" : "N"); // 1号工位链条变频器异常
        basRgvErrorLog.setPosition2ChainInverterError(position2ChainInverterError ? "Y" : "N"); // 2号工位链条变频器异常
        basRgvErrorLog.setFrontRearLimit(frontRearLimit ? "Y" : "N");      // 前后极限位
        basRgvErrorLog.setEmergencyButton(emergencyButton ? "Y" : "N");     // 急停按钮
        basRgvErrorLog.setForwardButton(forwardButton ? "Y" : "N");       // 前进按钮
        basRgvErrorLog.setReverseButton(reverseButton ? "Y" : "N");       // 后退按钮
        basRgvErrorLog.setLocalRemote(localRemote ? "Y" : "N");         // 本地/远程
        basRgvErrorLog.setReset(reset ? "Y" : "N");               // 复位
        basRgvErrorLog.setTravelBrakeSwitch(travelBrakeSwitch ? "Y" : "N");   // 走行抱闸开关钮
        basRgvErrorLog.setTravelSpeedLimitPhotoelectric(travelSpeedLimitPhotoelectric ? "Y" : "N"); // 走行强制减速光电
        basRgvErrorLog.setLeftOverlimit1(leftOverlimit1 ? "Y" : "N");      // 左超限 1
        basRgvErrorLog.setRightOverlimit1(rightOverlimit1 ? "Y" : "N");     // 右超限 1
        basRgvErrorLog.setLeftAtPosition1(leftAtPosition1 ? "Y" : "N");     // 左到位 1
        basRgvErrorLog.setRightAtPosition1(rightAtPosition1 ? "Y" : "N");    // 右到位 1
        basRgvErrorLog.setRightConveyor2(rightConveyor2 ? "Y" : "N");      // 右输送 2
        basRgvErrorLog.setLeftConveyor2(leftConveyor2 ? "Y" : "N");       // 左输送 2
    /**
     * 车身
     */
    public Long carBodyKunPeng = 15000L;
        return basRgvErrorLog;
    }
    /**
     * 是否启用
     */
    public boolean statusEnable;//0\1\2
    // 急停
    private boolean err1;
    // 有物无资料
    private boolean err2;
    // 命令错误走行链条冲突
    private boolean err3;
    // 目标为超过走行极限
    private boolean err4;
    // 变频器异常
    private boolean err5;
    // 光电异常
    private boolean err6;
    //小车模式切换错误
    private boolean err7;
    //其他未知异常
    private boolean err8;
    private String errorRgv;
    public void setMode(Short mode) {
        this.mode = mode;
@@ -354,50 +142,20 @@
        this.status = RgvStatusType.get(type).id.shortValue();
    }
    public void setStatus1(Short status1){
        this.status1 = status1;
        this.statusType1 = RgvStatusType.get(status1);
    }
    public void setStatus1(RgvStatusType type1){
        this.statusType1 = type1;
        this.status1 = RgvStatusType.get(type1).id.shortValue();
    }
    public void setStatus2(Short status2){
        this.status2 = status2;
        this.statusType2 = RgvStatusType.get(status2);
    }
    public void setStatus2(RgvStatusType type2){
        this.statusType2 = type2;
        this.status2 = RgvStatusType.get(type2).id.shortValue();
    }
    public boolean isLoaded1ing() {
        return Boolean.TRUE.equals(this.loaded1);
    }
    public boolean isLoaded2ing() {
        return Boolean.TRUE.equals(this.loaded2);
    }
    /**
     * 最近一次入出库类型
     *       I:入库
     *       O:出库
     */
    private String lastIo = "I";
    public BasRgv toSqlModel(BasRgv basRgv){
        if (alarm!=null) {
            basRgv.setRgvErr(alarm.longValue());
        }
        basRgv.setWrkNo1(taskNo1.intValue());
        basRgv.setWrkNo2(taskNo2.intValue());
        basRgv.setWrkNo1(taskNo.intValue());
        return basRgv;
    }
    public long getRgvPosDestinationOrPos(boolean sign){
        if (!sign){
            return RgvPosDestination>RgvPos? RgvPosDestination:RgvPos;
        } else {
            return RgvPosDestination<RgvPos? RgvPosDestination:RgvPos;
        }
    }
    public void setxSpeed(Short xSpeed) {
@@ -412,87 +170,53 @@
        this.xDuration = Float.valueOf(xDuration);
    }
    public Integer getRgvPosI(){
        //需要根据现场改造  根据读到的值获取对应站点位置
        Map<Short,Integer> map = new HashMap<>();
        map.put((short) 1,1004);map.put((short) 2,1007);
        map.put((short) 3,1010);map.put((short) 4,1014);
        map.put((short) 5,1018);map.put((short) 6,1021);
       map.put((short) 7,1024); map.put((short) 8,1028);
        map.put((short) 9,1031);map.put((short) 10,1035);
        map.put((short) 11,2003);map.put((short) 12,2006);
        map.put((short) 13,2009);map.put((short) 14,2012);
        map.put((short) 15,2015);map.put((short) 16,2018);
        map.put((short) 17,2021);map.put((short) 18,2024);
        map.put((short) 19,2027);map.put((short) 20,2030);
        if (RgvPos==null) return 0;
        return map.get(RgvPos);
    }
    public Integer getRgvPosI1() {
        // key: 站点号  value: 基准物理位置
        Map<Integer, Integer> posMap = new HashMap<>();
        posMap.put(1004, 6534);
        posMap.put(1007, 33634);
        posMap.put(1010, 75174);
        posMap.put(1014, 102124);
        posMap.put(1018, 138224);
        posMap.put(1021, 178034);
        posMap.put(1024, 219684);
        posMap.put(1028, 246724);
        posMap.put(1031, 288194);
        posMap.put(1035, 314954);
        int tolerance = 200; // 允许误差范围
        for (Map.Entry<Integer, Integer> entry : posMap.entrySet()) {
            int site = entry.getKey();
            int basePos = entry.getValue();
            if (Math.abs(RgvPos - basePos) <= tolerance) {
                return site;
            }
    public int getAlarm$(){
        if (err1){
            return 1;
        }
        return 0; // 没匹配到站点
    }
    public Integer getRgvPosI2() {
        // key: 站点号  value: 基准物理位置
        Map<Integer, Integer> posMap = new HashMap<>();
        posMap.put(2030, 314954);
        posMap.put(2027, 288094);
        posMap.put(2024, 246574);
        posMap.put(2021, 219584);
        posMap.put(2018, 177934);
        posMap.put(2015, 138126);
        posMap.put(2012, 102124);
        posMap.put(2009, 75174);
        posMap.put(2006, 33748);
        posMap.put(2003, 6449);
        int tolerance = 500; // 允许误差范围
        for (Map.Entry<Integer, Integer> entry : posMap.entrySet()) {
            int site = entry.getKey();
            int basePos = entry.getValue();
            if (Math.abs(RgvPos - basePos) <= tolerance) {
                return site;
            }
        if (err2){
            return 2;
        }
        return 0; // 没匹配到站点
    }
    @Override
    public RgvProtocol clone() {
        try {
            return (RgvProtocol) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        if (err3){
            return 3;
        }
        return null;
        if (err4){
            return 4;
        }
        if (err5){
            return 5;
        }
        if (err6){
            return 6;
        }
        if (err7){
            return 7;
        }
        if (err8){
            return 8;
        }
        return 0;
    }
    public String getAlarmM(){
        switch (getAlarm$()){
            case 1:
                return "急停";
            case 2:
                return "有物无资料";
            case 3:
                return "命令错误走行链条冲突";
            case 4:
                return "目标为超过走行极限";
            case 5:
                return "变频器异常";
            case 6:
                return "光电异常";
            case 7:
                return "小车模式切换错误";
            case 8:
                return "其它未知异常";
        }
        return "正常";
    }
}
src/main/java/com/zy/core/model/protocol/RgvRunProtocol.java
New file
@@ -0,0 +1,18 @@
package com.zy.core.model.protocol;
import lombok.Data;
/**
 * Created by IX on 2025/02/21
 */
@Data
public class RgvRunProtocol {
    private String dev = "RGV";
    private Integer RgvNo = 1;
    public Long currentTimeMilliOld = 0L;
    public RgvRunProtocol(){}
}
src/main/java/com/zy/core/model/protocol/RgvTaskProtocol.java
New file
@@ -0,0 +1,25 @@
package com.zy.core.model.protocol;
import lombok.Data;
/**
 * Created by IX on 2025/02/21
 */
@Data
public class RgvTaskProtocol {
    private Integer RgvNo;
    /**
     * 是否避让
     */
    public Integer Avoid;//0\1\2
    /**
     * 避让目的地
     */
    public Long AvoidingTheDestination;
    public RgvTaskProtocol(){}
}
src/main/java/com/zy/core/model/protocol/TaskProtocol.java
New file
@@ -0,0 +1,61 @@
package com.zy.core.model.protocol;
import lombok.Data;
/**
 * Created by IX on 2025/02/21
 */
@Data
public class TaskProtocol {
    private volatile String taskNoDirection; // 任务号(主属性)
    private volatile Long taskNo; // 任务号(主属性)
    private volatile Long targetPosition = 0L; // 目标位置
    private volatile Integer targetPositionStaNo = 0; // 目标位置
    private volatile Integer targetPositionStaNoPlcId = 1; // 目标位置
    private volatile int isRunning = 0; // 运行状态  0:初始  1:等待执行  2:执行中 3:执行中断 4:完结
    private volatile int taskStatus = 0; //作业模式  1:行走  2:取  3:放  0:无
    private volatile boolean direction; // 执行方向(面朝轨道 定位值左小右大)  true:左   false:右  执行方向(面朝轨道  1:自己  2 轨道   true:自己   false:轨道
    public TaskProtocol(){}
    public TaskProtocol(Long taskNo, Long targetPosition, int isRunning, int taskStatus, boolean direction) {
        this.taskNo = taskNo;
        this.targetPosition = targetPosition;
        this.isRunning = isRunning;
        this.taskStatus = taskStatus;
        this.direction = direction;
    }
    public TaskProtocol(TaskProtocol taskProtocol) {
        this.taskNo = taskProtocol.getTaskNo();
        this.targetPosition = taskProtocol.getTargetPosition();
        this.taskStatus = taskProtocol.getTaskStatus();
        this.direction = taskProtocol.direction;
    }
    public TaskProtocol(TaskProtocol taskProtocol, boolean direction) {
        this.taskNo = taskProtocol.getTaskNo();
        this.targetPosition = taskProtocol.getTargetPosition();
        this.taskStatus = 1;
        this.direction = taskProtocol.direction;
    }
    public String gettaskNoDirection$(Long taskNo,int taskStatus){
        String taskStatusStr = "Walk";
        switch (taskStatus){
            case 2:
                taskStatusStr = "Tack";
                break;
            case 3:
                taskStatusStr = "Put";
                break;
        }
        return taskNo+"_"+taskStatusStr;
    }
}
src/main/java/com/zy/core/thread/BarcodeThread.java
@@ -61,4 +61,11 @@
    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/java/com/zy/core/thread/LedThread.java
@@ -128,4 +128,11 @@
    public void close() {
    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/java/com/zy/core/thread/MelsecCrnThread.java
@@ -473,4 +473,11 @@
    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/java/com/zy/core/thread/RgvThread.java
@@ -5,34 +5,34 @@
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
import com.zy.common.utils.News;
import com.zy.core.RgvThread2;
import com.zy.asrs.entity.BasRgv;
import com.zy.asrs.entity.BasRgvOpt;
import com.zy.asrs.service.BasRgvOptService;
import com.zy.asrs.service.BasRgvService;
import com.zy.asrs.service.DeviceErrorService;
import com.zy.asrs.utils.RouteUtils;
import com.zy.asrs.utils.TrackRangeUtils;
import com.zy.core.DevpThread;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.*;
import com.zy.core.enums.RgvModeType;
import com.zy.core.enums.RgvStatusType;
import com.zy.core.enums.RgvTaskModeType;
import com.zy.core.enums.RgvTaskStatusType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.RgvSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.CrnCommand;
import com.zy.core.model.command.RgvCommand;
import com.zy.core.model.protocol.RgvProtocol;
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.model.protocol.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import java.sql.Wrapper;
import java.text.MessageFormat;
import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -41,12 +41,19 @@
 */
@Data
@Slf4j
public class RgvThread implements Runnable, RgvThread2 {
public class RgvThread implements Runnable, ThreadHandler {
    private SiemensS7Net siemensNet;
    private RgvSlave slave;
    private RgvProtocol rgvProtocol;
    private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
    //    private RgvProtocol rgvProtocol;
    private TaskProtocolCache taskProtocolCache = new TaskProtocolCache();
    // # 轨道总长
    private Long trackEntireLength = 224000L;
    //# 轨道基准点
    private Long trackBenchmark = 1L;
    //  # 避让距离
    private Long avoidDistance = 5000L;
    private String errorRgv = "-";
    /**
     * 工位1复位信号
@@ -57,20 +64,11 @@
     */
    private boolean resetFlag2 = false;
    //锁定标记
    private boolean PakMk = true;
    //入库标记
//    private boolean PakIn = true;
//    //出库标记
//    private boolean PakOut = true;
//    //根据距离跳过取货
//    private boolean PakRgv  = true;
//    //接驳标记
//    private boolean PakToCrn = true;
    // 任务锁定
    private boolean Paking  = true;
//    //连续任务下发
//    private boolean PakAll = true;
    private boolean connectRgv = false;
    public Long currentTimeMilliConnectRgv= 0L;
    private boolean delRgvTask = false;
    private short wrkSign = 0;
    public RgvThread(RgvSlave slave) {
        this.slave = slave;
@@ -79,133 +77,900 @@
    @Override
    @SuppressWarnings("InfiniteLoopStatement")
    public void run() {
        this.connect();
        initRgv();
        // 启动线程自动重连
        new Thread(this::rgvConnect).start();
        // 启动读数据线程
        new Thread(this::readStatusRgv).start();
        // 启动任务下发线程
        new Thread(this::taskIssued).start();
        // 启动漫游线程
        new Thread(this::taskWalkIssued).start();
//        new Thread(this::taskWalkIssued2).start();
        // 启动任务完成线程
        new Thread(this::taskComplete).start();
    }
    private void rgvConnect() {
        while (true) {
            try {
                int step = 1;
                Task task = MessageQueue.poll(SlaveType.Rgv, slave.getId());
                if (task != null) {
                    step = task.getStep();
                Thread.sleep(1000);
                if(!connectRgv){
                    try {
                        connectRgv = this.connect();
                        Thread.sleep(100);
                    } catch (Exception e){
                    }
                }
                switch (step) {
                    // 读数据
                    case 1:
                        readStatus();
                        break;
                    // 小车工位写入数据
                    case 2:
                        write((RgvCommand) task.getData());
                        break;
                    // 复位
                    case 3:
                        RgvCommand command = (RgvCommand) task.getData();
                        if (null == command) {
                            command = new RgvCommand();
                        }
                        command.setRgvNo(slave.getId()); // RGV编号
                        command.setTaskNo(0); // 工作号
                        command.setTaskStatus(RgvTaskStatusType.NONE); // 任务模式
                        command.setTargetPosition(0);     // 源站
                        command.setWrkTaskPri(0);     // 目标站
                        command.setCommand(false);
                        write2(command);
                        break;
                    default:
                        break;
                }
                Thread.sleep(500);
            } catch (Exception e) {
                log.error("rgv连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                try{
                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "rgv连接失败"+e.getMessage());
                } catch (Exception e2){
//                    log.error("e2:"+e2.getMessage());
                }
                initRgv();
//                e.printStackTrace();
            }
        }
    }
    private void readStatusRgv() {
        while (true) {
            try {
                if(!connectRgv){
                    try {
                        Thread.sleep(1000L);
                    } catch (Exception e){
                    }
                    initRgv();
                    continue;
                }
                Thread.sleep(20);
//                System.out.println("读线程,小车号"+ slave.getId()+"时间戳:"+System.currentTimeMillis());
                readStatus();
            } catch (Exception e) {
                log.error("RGV数据读取线程异常!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                try{
                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV数据读取线程异常"+e.getMessage());
                } catch (Exception e2){
//                    log.error("e2:"+e2.getMessage());
                }
                initRgv();
//                e.printStackTrace();
            }
        }
    }
    private static final Set<Integer> specialSites = new HashSet<>(
            Arrays.asList(1004,1014,1018,1028,1035,2006,2012,2018,2024,2030));
    public static final Map<Integer, Integer> StaPosition = new HashMap<Integer, Integer>() {{
        put(1004, 1001);put(1014, 1011);put(1018, 1015);put(1028, 1025);put(1035, 1032);
        put(2006, 2004);put(2012, 2010);put(2018, 2016);put(2024, 2022);put(2030, 2028);
    }};
    public static final ArrayList<Integer> staNos1 = new ArrayList<Integer>() {{
        add(1);add(2);
    }};
    public static final ArrayList<Integer> staNos2 = new ArrayList<Integer>() {{
        add(3);add(4);
    }};
    /**
     * 初始化站点状态
     * 完成
     */
    private void initSite() {
        ArrayList<Integer> staNos = getStaNo();
    private void taskComplete() {
        while (true) {
            try {
                if(!connectRgv){
                    try {
                        Thread.sleep(1000L);
                    } catch (Exception e){
            // 站点编号
            for (Integer siteId : staNos) {
                StaProtocol staProtocol = station.get(siteId);
                if (null == staProtocol) {
                    staProtocol = new StaProtocol();
                    staProtocol.setSiteId(siteId);
                    station.put(siteId, staProtocol);
                    }
                    continue;
                }
                staProtocol.setWorkNo(0);    // ID
                staProtocol.setAutoing(false);      // 自动
                staProtocol.setLoading(false);      // 有物
                staProtocol.setInEnable(false);     // 可入
                staProtocol.setOutEnable(false);    // 可出
                staProtocol.setEmptyMk(false);      // 空板信号
                staProtocol.setStaNo((short) 0);     // 目标站
                if (delRgvTask){
                    writeDelRgvTask();
                    delRgvTask = false;
                    continue;
                }
                Thread.sleep(50L);
                OperateResultExOne<byte[]> result = siemensNet.Read("DB100.12", (short) 1);
                boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, 0, 1);
                if (status[0]){
                    Thread.sleep(500L);
                    OperateResult result4 = siemensNet.Write("DB100.12.0", false);
                }
            } catch (Exception e) {
                log.error("RGV数据任务下发复位线程异常!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                try{
                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV数据任务下发复位线程异常"+e.getMessage());
                } catch (Exception e2){
//                    log.error("e2:"+e2.getMessage());
                }
                initRgv();
//                e.printStackTrace();
            }
        }
    }
    /**
     * 漫游
     */
    private void taskWalkIssued() {
        while (true) {
            try {
                if(!connectRgv){
                    try {
                        Thread.sleep(1000L);
                    } catch (Exception e){
                    }
                    continue;
                }
                // 休眠 1 秒
                Thread.sleep(100);
                if (!deviceDetection()) {
                    continue;
                }
                RgvTaskProtocol rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
                if (rgvTaskProtocol == null) {
                    initRgv();
                    rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
                }
                if (rgvTaskProtocol.getAvoid() != 1) {
                    continue;
                }
                TaskProtocol issued = new TaskProtocol();
                issued.setTaskNo(32222L);
                issued.setTargetPosition(rgvTaskProtocol.getAvoidingTheDestination());
                issued.setTaskStatus(1);
                issued.setDirection(true);
                write(issued);
                rgvTaskProtocol.setAvoid(0);
//                Thread.sleep(200);
                RgvTaskCache.updateRgvStatus(rgvTaskProtocol);
            } catch (Exception e) {
                log.error("RGV行走任务下发线程异常!!!" + e.getMessage());
//                e.printStackTrace();
            }
        }
    }
    /**
     * 任务下发
     */
    private void taskIssued() {
        while (true) {
            if(!connectRgv){
                try {
                    Thread.sleep(1000L);
                } catch (Exception e){
                }
                continue;
            }
            RgvRunProtocol rgvRun = RgvRunCache.getRgvRun();
            if (!rgvRun.getRgvNo().equals(slave.getId())){
                continue;
            }
            try {
                Thread.sleep(100);
                rgvRun = RgvRunCache.getRgvRun();
//                System.out.println(JSON.toJSON(rgvRun));
                // 休眠 1 秒
                if (System.currentTimeMillis() - rgvRun.currentTimeMilliOld > 500L) {
                    rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                } else {
                    continue;
                }
                if (!deviceDetection()) {
                    rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                    rgvRun.setRgvNo(slave.getOtherId());
                    RgvRunCache.updateRgvStatus(rgvRun);
                    if (!errorRgv.equals("无")){
                        RgvErrCache.updateRgvErr(slave.getId(),errorRgv);
                    }
                    continue;
                }
                RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
                RgvTaskProtocol rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
                if (rgvProtocol == null || rgvTaskProtocol == null) {
                    initRgv();
                    rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
                    rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
                }
                if (!rgvProtocol.getStatusType().equals(RgvStatusType.IDLE) || (Math.abs(rgvProtocol.getRgvPos() - rgvProtocol.getRgvPosDestination())>100)){
                    rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                    rgvRun.setRgvNo(slave.getOtherId());
                    RgvRunCache.updateRgvStatus(rgvRun);
                    continue;
                }
                if (rgvProtocol.getLoaded() == -1){
                    rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                    rgvRun.setRgvNo(slave.getOtherId());
                    RgvRunCache.updateRgvStatus(rgvRun);
                    RgvErrCache.updateRgvErr(slave.getId(),"小车探物物状态异常");
                    continue;
                }
                if (rgvTaskProtocol.getAvoid() != 0) {
                    rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                    rgvRun.setRgvNo(slave.getOtherId());
                    RgvRunCache.updateRgvStatus(rgvRun);
                    continue;
                }
                List<TaskProtocol> allTakeTaskProtocol = taskProtocolCache.getTakeOrPutTaskProtocol(rgvProtocol.getLoaded());
                if (allTakeTaskProtocol.isEmpty()){
                    allTakeTaskProtocol = taskProtocolCache.getAllWalkTaskProtocol();
                    for (TaskProtocol taskProtocol : allTakeTaskProtocol) {
                        if (taskProtocol.getIsRunning() == 1) {//准备下发
                            // 双车
                            if (rgvOtherStatusEnable()) {
                                //另一台车是否允许此台车执行
                                if (!otherRgvAvoid(taskProtocol.getTargetPosition())) {
                                    RgvErrCache.updateRgvErr(slave.getId(),errorRgv);
                                    break;
                                }
                            }
                            if (taskProtocol.getTargetPosition()<=rgvProtocol.getRgvPos()+50
                                    && taskProtocol.getTargetPosition()>=rgvProtocol.getRgvPos()-50){
                                taskProtocolCache.removeTaskProtocol(taskProtocol.getTaskNoDirection());
                                RgvErrCache.updateRgvErr(slave.getId());
                                break;
                            } else {
                                TaskProtocol issued = new TaskProtocol(taskProtocol,true);
                                write(issued);
                                RgvErrCache.updateRgvErr(slave.getId());
                                taskProtocolCache.removeTaskProtocol(taskProtocol.getTaskNoDirection());
                                break;
                            }
                        }
                    }
                    RgvErrCache.updateRgvErr(slave.getId());
                } else {
                    for (TaskProtocol taskProtocol : allTakeTaskProtocol) {
                        if (taskProtocol.getIsRunning() == 1) {//准备下发
                            //双车
                            if (rgvOtherStatusEnable()) {
                                //另一台车是否允许此台车执行
                                if (!otherRgvAvoid(taskProtocol.getTargetPosition())) {
                                    RgvErrCache.updateRgvErr(slave.getId(),errorRgv);
                                    break;
                                }
                            }
                            if (taskProtocol.getTargetPosition()<=rgvProtocol.getRgvPos()+50
                                    && taskProtocol.getTargetPosition()>=rgvProtocol.getRgvPos()-50){
                                if (taskProtocol.getTaskStatus()==3){
                                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, taskProtocol.getTargetPositionStaNoPlcId());
                                    StaProtocol staProtocol = devpThread.getStation().get(taskProtocol.getTargetPositionStaNo());
                                    if (staProtocol == null ) {
                                        RgvErrCache.updateRgvErr(slave.getId(),"未查到小车作业站"+staProtocol.getStaNo()+"站点");
                                        break;
                                    }
                                    // 判断是否满足入库条件
                                    if (!staProtocol.isAutoing() || staProtocol.isLoading()
                                    ){
                                        RgvErrCache.updateRgvErr(slave.getId(),"小车等待"+staProtocol.getStaNo()+"站点就绪");
                                        break;
                                    }
                                } else if (taskProtocol.getTaskStatus()==2){
                                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, taskProtocol.getTargetPositionStaNoPlcId());
                                    StaProtocol staProtocol = devpThread.getStation().get(taskProtocol.getTargetPositionStaNo());
                                    if (staProtocol == null ) {
                                        RgvErrCache.updateRgvErr(slave.getId(),"未查到小车作业站"+staProtocol.getStaNo()+"站点");
                                        break;
                                    }
                                    // 判断是否满足入库条件
                                    if (!staProtocol.isAutoing() || !staProtocol.isLoading() || staProtocol.getWorkNo()==0
                                    ){
                                        RgvErrCache.updateRgvErr(slave.getId(),"小车等待"+staProtocol.getStaNo()+"站点就绪");
                                        break;
                                    }
                                }
                                TaskProtocol issued = new TaskProtocol(taskProtocol);
                                write(issued);
                                RgvErrCache.updateRgvErr(slave.getId());
                                taskProtocolCache.removeTaskProtocol(taskProtocol.getTaskNoDirection());
                                break;
                            } else {
                                TaskProtocol issued = new TaskProtocol(taskProtocol,true);
                                write(issued);
                                RgvErrCache.updateRgvErr(slave.getId());
                                break;
                            }
                        }
                    }
                }
                rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                rgvRun.setRgvNo(slave.getOtherId());
                RgvRunCache.updateRgvStatus(rgvRun);
            } catch (Exception e) {
                log.error("RGV任务下发线程异常!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                try{
                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV任务下发线程异常"+e.getMessage());
                } catch (Exception e2){
//                    log.error("e2:"+e2.getMessage());
                }
                rgvRun = RgvRunCache.getRgvRun();
                rgvRun.currentTimeMilliOld = System.currentTimeMillis()+50;
                rgvRun.setRgvNo(slave.getOtherId());
                RgvRunCache.updateRgvStatus(rgvRun);
                continue;
//                e.printStackTrace();
            }
        }
    }
    public boolean isSignRgvTaskProtocol() {
        RgvTaskProtocol rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
        if (rgvTaskProtocol == null) {
            return false;
        }
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        RgvTaskProtocol rgvTaskProtocolOther = RgvTaskCache.getRgvStatus(slave.getOtherId());
        if (rgvProtocolOther == null) {
            return false;
        }
        if (rgvProtocolOther.statusEnable) {
            if (rgvTaskProtocolOther == null) {
                return false;
            }
        }
        return true;
    }
    public boolean deviceDetection() {
        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
        RgvTaskProtocol rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
        if (rgvProtocol == null || rgvTaskProtocol == null) {
            errorRgv = slave.getId()+"号小车连接失败";
            return false;
        }
        if (!rgvProtocol.getModeType().equals(RgvModeType.AUTO)) {
            errorRgv = slave.getId()+"号小车非自动";
            return false;
        }
        if (rgvProtocol.getRgvPos().equals(0L)
                || rgvTaskProtocol.getAvoid() == -1
                || rgvProtocol.getRgvPosDestination() == 0L) {
            errorRgv = slave.getId()+"号小车状态异常";
            return false;
        }
        if (!rgvProtocol.getStatusType().equals(RgvStatusType.IDLE) && !rgvProtocol.getStatusType().equals(RgvStatusType.ROAM)) {
            errorRgv = "无";
            return false;
        }
        if ( (Math.abs(rgvProtocol.getRgvPos() - rgvProtocol.getRgvPosDestination())>100) && !rgvProtocol.getStatusType().equals(RgvStatusType.ROAM)) {
            errorRgv = slave.getId()+"号小车存在运行目标值,需要复位!!!";
            return false;
        }
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        RgvTaskProtocol rgvTaskProtocolOther = RgvTaskCache.getRgvStatus(slave.getOtherId());
//        System.out.println("rgvTaskProtocol:"+slave.getId()+"sign:"+rgvTaskProtocol.isSignRun()+"/n"+
//                "rgvTaskProtocolOther:"+slave.getOtherId()+"sign:"+rgvTaskProtocolOther.isSignRun()+"/n");
        if (rgvProtocolOther == null) {
            errorRgv = slave.getOtherId()+"号小车连接失败";
            return false;
        }
        if (rgvProtocolOther.statusEnable) {
            if (!rgvProtocolOther.getModeType().equals(RgvModeType.AUTO) || rgvProtocolOther.getRgvPos().equals(0L) || rgvTaskProtocolOther.getAvoid() == -1 || rgvProtocolOther.getRgvPosDestination() == 0L) {
                errorRgv = slave.getOtherId()+"号小车状态异常";
                return false;
            }
        }
        return true;
    }
    public boolean rgvOtherStatusEnable() {
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        if (rgvProtocolOther == null) {
            return true;
        }
        if (rgvProtocolOther.statusEnable) {
//            if (!rgvProtocolOther.getModeType().equals(RgvModeType.AUTO) || rgvProtocolOther.getRgvPos().equals(0L)) {
            return true;
//            }
        }
        return false;
    }
    public boolean otherRgvAvoid(Long targetPosition) {
        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
        long onePos = Math.abs(targetPosition - rgvProtocol.getRgvPos());
        if (onePos<50){
            return true;
        }
        RgvTaskProtocol rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
        RgvProtocol rgvProtocolOther = RgvStatusCache.getRgvStatus(slave.getOtherId());
        RgvTaskProtocol rgvTaskProtocolOther = RgvTaskCache.getRgvStatus(slave.getOtherId());
        Long[][] avoidRange = new TrackRangeUtils().avoidRange(slave, trackEntireLength, trackBenchmark, avoidDistance);
        if (new TrackRangeUtils().IsItSmall(slave)) {
            if (rgvProtocolOther.getStatusType().equals(RgvStatusType.IDLE) && (Math.abs(rgvProtocolOther.getRgvPos() - rgvProtocolOther.getRgvPosDestination())<50)) {
                if ((rgvProtocolOther.getRgvPos() - rgvProtocolOther.getCarBodyJiaoMing())
                        - (targetPosition + rgvProtocol.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                } else {
                    RgvThread rgvThreadOther = (RgvThread) SlaveConnection.get(SlaveType.Rgv, slave.getOtherId());
                    TaskProtocolCache taskProtocolCacheOther = rgvThreadOther.getTaskProtocolCache();
                    TaskProtocol nowPosRunTask = taskProtocolCacheOther.getNowPosRunTask(rgvProtocolOther.getRgvPos());
                    if (!Cools.isEmpty(nowPosRunTask)){
                        boolean signNowPosRun = true;
                        if (nowPosRunTask.getTaskStatus()==3){
                            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, nowPosRunTask.getTargetPositionStaNoPlcId());
                            StaProtocol staProtocol = devpThread.getStation().get(nowPosRunTask.getTargetPositionStaNo());
                            if (staProtocol == null ) {
                                signNowPosRun =false;
                            }
                            if (signNowPosRun){
                                // 判断是否满足入库条件
                                if (!staProtocol.isAutoing() || staProtocol.isLoading()
                                ){
                                    if (targetPosition.equals(nowPosRunTask.getTargetPosition())){
                                        if (rgvProtocolOther.getRgvPosDestination() >= rgvProtocolOther.getRgvPos()-50) {
                                            long avoid = rgvProtocolOther.getRgvPos() - rgvProtocolOther.getCarBodyJiaoMing() - avoidDistance - rgvProtocol.getCarBodyKunPeng();
                                            if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[1])) {
                                                log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                                                errorRgv = "RGV行走目标超出范围";
                                                try{
                                                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                                                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                                                } catch (Exception e2){
//                                                    log.error("e2:"+e2.getMessage());
                                                }
                                                return false;
                                            }
                                            long avoidAbs = Math.abs(avoid - rgvProtocol.getRgvPos());
                                            if (avoidAbs<51){
                                                return false;
                                            }
                                            rgvTaskProtocol.setAvoid(1);
                                            rgvTaskProtocol.setAvoidingTheDestination(avoid);
                                            RgvTaskCache.updateRgvStatus(rgvTaskProtocol);
                                        }
                                        return false;
                                    }
                                    signNowPosRun =false;
                                }
                            }
                        }
                        if (signNowPosRun){
                            errorRgv = slave.getOtherId()+"号RGV等待作业...";
                            return false;
                        }
                    }
                    TaskProtocol nowPosRunTask2 = taskProtocolCacheOther.getNowPosRunTask2();
                    if (!Cools.isEmpty(nowPosRunTask2)){
                        boolean signNowPosRun = true;
                        boolean signNowPosA = true;
                        if (targetPosition - rgvProtocol.getRgvPos()>0){
                            if (nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos()>0){
                                if (rgvProtocol.getRgvPos()>rgvProtocolOther.getRgvPos()){
                                    signNowPosA = false;
                                    signNowPosRun = false;
                                }
                            }
                        } else if (targetPosition - rgvProtocol.getRgvPos()<0){
                            if (nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos()<0){
                                if (rgvProtocol.getRgvPos()<rgvProtocolOther.getRgvPos()){
                                    signNowPosA = false;
                                    signNowPosRun = false;
                                }
                            }
                        }
                        if (signNowPosA){
                            if (nowPosRunTask2.getTaskStatus()==3){
                                long twoPos = Math.abs(nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos());
                                if (Math.abs(onePos - twoPos)>100){
                                    if (onePos-50>twoPos+50){
                                        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, nowPosRunTask2.getTargetPositionStaNoPlcId());
                                        StaProtocol staProtocol = devpThread.getStation().get(nowPosRunTask2.getTargetPositionStaNo());
                                        if (staProtocol == null ) {
                                            signNowPosRun =false;
                                        }
                                        if (signNowPosRun){
                                            // 判断是否满足入库条件
                                            if (staProtocol.isAutoing() && !staProtocol.isLoading()
                                            ){
                                                errorRgv = slave.getOtherId()+"号RGV等待作业...";
                                                return false;
                                            }
                                        }
                                        signNowPosRun =false;
                                    }
                                }
                            } else {
                                long twoPos = Math.abs(nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos());
                                if (twoPos<100){
                                    errorRgv = slave.getOtherId()+"号RGV等待作业...";
                                    return false;
                                }
                                if (Math.abs(onePos - twoPos)>100){
                                    if (onePos-50>twoPos+50){
                                        signNowPosRun =false;
                                    }
                                }
                            }
                        }
                        if (signNowPosRun){
                            errorRgv = slave.getOtherId()+"号RGV等待作业...";
                            return false;
                        }
                    }
                    long avoid = targetPosition + rgvProtocol.getCarBodyKunPeng() + avoidDistance + rgvProtocolOther.getCarBodyJiaoMing();
                    if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[0])) {
                        log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                        errorRgv = "RGV行走目标超出范围";
                        try{
                            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                            deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                        } catch (Exception e2){
//                            log.error("e2:"+e2.getMessage());
                        }
                        return false;
                    }
                    long avoidAbs = Math.abs(avoid - rgvProtocolOther.getRgvPos());
                    if (avoidAbs<51){
                        return true;
                    }
                    rgvTaskProtocolOther.setAvoid(1);
                    rgvTaskProtocolOther.setAvoidingTheDestination(avoid);
                    RgvTaskCache.updateRgvStatus(rgvTaskProtocolOther);
                    return false;
                }
            } else if (rgvProtocolOther.getStatusType().equals(RgvStatusType.ROAM)) {
                if ((rgvProtocolOther.getRgvPosDestination() - rgvProtocolOther.getCarBodyJiaoMing())
                        - (targetPosition + rgvProtocol.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                } else {
                    long avoid = targetPosition + rgvProtocol.getCarBodyKunPeng() + avoidDistance + rgvProtocolOther.getCarBodyJiaoMing();
                    if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[0])) {
                        log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                        errorRgv = "RGV行走目标超出范围";
                        try{
                            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                            deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                        } catch (Exception e2){
//                            log.error("e2:"+e2.getMessage());
                        }
                        return false;
                    }
                    long avoidAbs = Math.abs(avoid - rgvProtocolOther.getRgvPos());
                    if (avoidAbs<51){
                        return true;
                    }
                    rgvTaskProtocolOther.setAvoid(1);
                    rgvTaskProtocolOther.setAvoidingTheDestination(avoid);
                    RgvTaskCache.updateRgvStatus(rgvTaskProtocolOther);
                    return false;
                }
            } else if (rgvProtocolOther.getStatusType().equals(RgvStatusType.WORKING)) {
                if ((rgvProtocolOther.getRgvPosDestination() - rgvProtocolOther.getCarBodyJiaoMing())
                        - (targetPosition + rgvProtocol.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                } else {
                    if (rgvProtocolOther.getRgvPosDestination() >= rgvProtocolOther.getRgvPos()-50) {
                        long avoid = rgvProtocolOther.getRgvPos() - rgvProtocolOther.getCarBodyJiaoMing() - avoidDistance - rgvProtocol.getCarBodyKunPeng();
                        if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[1])) {
                            log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                            errorRgv = "RGV行走目标超出范围";
                            try{
                                DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                                deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                            } catch (Exception e2){
//                                log.error("e2:"+e2.getMessage());
                            }
                            return false;
                        }
                        long avoidAbs = Math.abs(avoid - rgvProtocol.getRgvPos());
                        if (avoidAbs<51){
                            return false;
                        }
                        rgvTaskProtocol.setAvoid(1);
                        rgvTaskProtocol.setAvoidingTheDestination(avoid);
                        RgvTaskCache.updateRgvStatus(rgvTaskProtocol);
                        return false;
                    }
                    errorRgv = slave.getOtherId()+"号RGV影响,等待中...";
                    return false;
                }
            } else {
                if ((rgvProtocolOther.getRgvPosDestinationOrPos(true) - rgvProtocolOther.getCarBodyJiaoMing())
                        - (targetPosition + rgvProtocol.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                }
            }
        } else {
            if (rgvProtocolOther.getStatusType().equals(RgvStatusType.IDLE)  && (Math.abs(rgvProtocolOther.getRgvPos() - rgvProtocolOther.getRgvPosDestination())<50)) {
                if ((targetPosition - rgvProtocol.getCarBodyJiaoMing())
                        - (rgvProtocolOther.getRgvPos() + rgvProtocolOther.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                } else {
                    RgvThread rgvThreadOther = (RgvThread) SlaveConnection.get(SlaveType.Rgv, slave.getOtherId());
                    TaskProtocolCache taskProtocolCacheOther = rgvThreadOther.getTaskProtocolCache();
                    TaskProtocol nowPosRunTask = taskProtocolCacheOther.getNowPosRunTask(rgvProtocolOther.getRgvPos());
                    if (!Cools.isEmpty(nowPosRunTask)){
                        boolean signNowPosRun = true;
                        if (nowPosRunTask.getTaskStatus()==3){
                            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, nowPosRunTask.getTargetPositionStaNoPlcId());
                            StaProtocol staProtocol = devpThread.getStation().get(nowPosRunTask.getTargetPositionStaNo());
                            if (staProtocol == null ) {
                                signNowPosRun =false;
                            }
                            if (signNowPosRun){
                                // 判断是否满足入库条件
                                if (!staProtocol.isAutoing() || staProtocol.isLoading()
                                ){
                                    if (targetPosition.equals(nowPosRunTask.getTargetPosition())){
                                        if (rgvProtocolOther.getRgvPosDestination() <= rgvProtocolOther.getRgvPos() + 50) {
                                            long avoid = rgvProtocolOther.getRgvPos() + rgvProtocolOther.getCarBodyKunPeng() + avoidDistance + rgvProtocol.getCarBodyJiaoMing();
                                            if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[0])) {
                                                log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                                                errorRgv = "RGV行走目标超出范围";
                                                try{
                                                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                                                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                                                } catch (Exception e2){
//                                                    log.error("e2:"+e2.getMessage());
                                                }
                                                return false;
                                            }
                                            long avoidAbs = Math.abs(avoid - rgvProtocol.getRgvPos());
                                            if (avoidAbs<51){
                                                return false;
                                            }
                                            rgvTaskProtocol.setAvoid(1);
                                            rgvTaskProtocol.setAvoidingTheDestination(avoid);
                                            RgvTaskCache.updateRgvStatus(rgvTaskProtocol);
                                        }
                                        return false;
                                    }
                                    signNowPosRun =false;
                                }
                            }
                        }
                        if (signNowPosRun){
                            errorRgv = slave.getOtherId()+"号RGV等待作业...";
                            return false;
                        }
                    }
                    TaskProtocol nowPosRunTask2 = taskProtocolCacheOther.getNowPosRunTask2();
                    if (!Cools.isEmpty(nowPosRunTask2)){
                        boolean signNowPosRun = true;
                        boolean signNowPosA = true;
                        if (targetPosition - rgvProtocol.getRgvPos()>0){
                            if (nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos()>0){
                                if (rgvProtocol.getRgvPos()>rgvProtocolOther.getRgvPos()){
                                    signNowPosA = false;
                                    signNowPosRun = false;
                                }
                            }
                        } else if (targetPosition - rgvProtocol.getRgvPos()<0){
                            if (nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos()<0){
                                if (rgvProtocol.getRgvPos()<rgvProtocolOther.getRgvPos()){
                                    signNowPosA = false;
                                    signNowPosRun = false;
                                }
                            }
                        }
                        if (signNowPosA){
                            if (nowPosRunTask2.getTaskStatus()==3){
                                long twoPos = Math.abs(nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos());
                                if (Math.abs(onePos - twoPos)>100){
                                    if (onePos-50>twoPos+50){
                                        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, nowPosRunTask2.getTargetPositionStaNoPlcId());
                                        StaProtocol staProtocol = devpThread.getStation().get(nowPosRunTask2.getTargetPositionStaNo());
                                        if (staProtocol == null ) {
                                            signNowPosRun =false;
                                        }
                                        if (signNowPosRun){
                                            // 判断是否满足入库条件
                                            if (staProtocol.isAutoing() && !staProtocol.isLoading()
                                            ){
                                                errorRgv = slave.getOtherId()+"号RGV等待作业...";
                                                return false;
                                            }
                                        }
                                        signNowPosRun =false;
                                    }
                                }
                            } else {
                                long twoPos = Math.abs(nowPosRunTask2.getTargetPosition() - rgvProtocolOther.getRgvPos());
                                if (twoPos<100){
                                    errorRgv = slave.getOtherId()+"号RGV等待作业...";
                                    return false;
                                }
                                if (Math.abs(onePos - twoPos)>100){
                                    if (onePos-50>twoPos+50){
                                        signNowPosRun =false;
                                    }
                                }
                            }
                        }
                        if (signNowPosRun){
                            errorRgv = slave.getOtherId()+"号RGV等待作业...";
                            return false;
                        }
                    }
                    long avoid = targetPosition - rgvProtocol.getCarBodyJiaoMing() - avoidDistance - rgvProtocolOther.getCarBodyKunPeng();
                    if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[1])) {
                        log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                        errorRgv = "RGV行走目标超出范围";
                        try{
                            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                            deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                        } catch (Exception e2){
//                            log.error("e2:"+e2.getMessage());
                        }
                        return false;
                    }
                    long avoidAbs = Math.abs(avoid - rgvProtocolOther.getRgvPos());
                    if (avoidAbs<51){
                        return true;
                    }
                    rgvTaskProtocolOther.setAvoid(1);
                    rgvTaskProtocolOther.setAvoidingTheDestination(avoid);
                    RgvTaskCache.updateRgvStatus(rgvTaskProtocolOther);
                    return false;
                }
            } else if (rgvProtocolOther.getStatusType().equals(RgvStatusType.ROAM)) {
                if ((targetPosition - rgvProtocol.getCarBodyJiaoMing())
                        - (rgvProtocolOther.getRgvPosDestination() + rgvProtocolOther.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                } else {
                    long avoid = targetPosition - rgvProtocol.getCarBodyJiaoMing() - avoidDistance - rgvProtocolOther.getCarBodyKunPeng();
                    if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[1])) {
                        log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                        errorRgv = "RGV行走目标超出范围";
                        try{
                            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                            deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                        } catch (Exception e2){
//                            log.error("e2:"+e2.getMessage());
                        }
                        return false;
                    }
                    long avoidAbs = Math.abs(avoid - rgvProtocolOther.getRgvPos());
                    if (avoidAbs<51){
                        return true;
                    }
                    rgvTaskProtocolOther.setAvoid(1);
                    rgvTaskProtocolOther.setAvoidingTheDestination(avoid);
                    RgvTaskCache.updateRgvStatus(rgvTaskProtocolOther);
                    return false;
                }
            } else if (rgvProtocolOther.getStatusType().equals(RgvStatusType.WORKING)) {
                if ((targetPosition - rgvProtocol.getCarBodyJiaoMing())
                        - (rgvProtocolOther.getRgvPosDestination() + rgvProtocolOther.getCarBodyKunPeng())
                        > avoidDistance-50) {//无需避让
                    return true;
                } else {
                    if (rgvProtocolOther.getRgvPosDestination() <= rgvProtocolOther.getRgvPos() + 50) {
                        long avoid = rgvProtocolOther.getRgvPos() + rgvProtocolOther.getCarBodyKunPeng() + avoidDistance + rgvProtocol.getCarBodyJiaoMing();
                        if (!new TrackRangeUtils().avoidRange(avoid, avoidRange[0])) {
                            log.error("RGV行走超出范围!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                            errorRgv = "RGV行走目标超出范围";
                            try{
                                DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                                deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV行走超出范围");
                            } catch (Exception e2){
//                                log.error("e2:"+e2.getMessage());
                            }
                            return false;
                        }
                        long avoidAbs = Math.abs(avoid - rgvProtocol.getRgvPos());
                        if (avoidAbs<51){
                            return false;
                        }
                        rgvTaskProtocol.setAvoid(1);
                        rgvTaskProtocol.setAvoidingTheDestination(avoid);
                        RgvTaskCache.updateRgvStatus(rgvTaskProtocol);
                        return false;
                    }
                    errorRgv = slave.getOtherId()+"号RGV等待中...";
                    return false;
                }
            } else {
                if ((rgvProtocolOther.getRgvPosDestinationOrPos(false) - rgvProtocolOther.getCarBodyJiaoMing())
                        - (targetPosition + rgvProtocol.getCarBodyKunPeng())
                        > avoidDistance - 50) {//无需避让
                    return true;
                }
            }
        }
        errorRgv = slave.getOtherId()+"号RGV影响,等待中...";
        return false;
    }
    /**
     * 初始化RGV状态
     */
    private void initRgv() {
        if (null == rgvProtocol) {
        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
        if (rgvProtocol == null) {
            rgvProtocol = new RgvProtocol();
            rgvProtocol.setRgvNo(slave.getId());
        }
        //小车状态
        rgvProtocol.setStatus((short)-1);
        rgvProtocol.setRgvPosDestination(0);
        rgvProtocol.setMode((short) -1);
        rgvProtocol.setRgvPos(0);
        rgvProtocol.setErr1(false);
        rgvProtocol.setErr2(false);
        rgvProtocol.setErr3(false);
        rgvProtocol.setErr4(false);
        rgvProtocol.setErr5(false);
        rgvProtocol.setErr6(false);
        rgvProtocol.setErr7(false);
        rgvProtocol.setWrkTaskPri((short)0);
        //工位1状态
        rgvProtocol.setTaskNo1(0);
        rgvProtocol.setStatus1((short)-1);
        rgvProtocol.setLoaded1(false);
        rgvProtocol.setWrkTaskMove1((short)0);
        //工位2状态
        rgvProtocol.setTaskNo2(0);
        rgvProtocol.setStatus2((short)-1);
        rgvProtocol.setLoaded2(false);
        rgvProtocol.setWrkTaskMove2((short)0);
//        rgvProtocol.setAlarm((short)0);
//        rgvProtocol.setxSpeed((short) 0);
//        rgvProtocol.setxDistance((short) 0);
//        rgvProtocol.setxDuration((short) 0);
    }
    private ArrayList<Integer> getStaNo() {
        switch (slave.getId()) {
            case 1:
                return staNos1;
            case 2:
                return staNos2;
            default:
                throw new CoolException("服务器异常");
        rgvProtocol.setStatus((short) -1);
        rgvProtocol.setWalkPos((short) 0);
        rgvProtocol.setRgvPos(0L);
        rgvProtocol.setAlarm((short) 0);
        rgvProtocol.setxSpeed((short) 0);
        rgvProtocol.setxDistance((short) 0);
        rgvProtocol.setxDuration((short) 0);
        rgvProtocol.setCarBodyJiaoMing(0L);
        rgvProtocol.setCarBodyKunPeng(0L);
        try {
            BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
            BasRgv rgv = basRgvService.selectById(slave.getId());
            if (!Cools.isEmpty(rgv)) {
                rgvProtocol.setStatusEnable(rgv.getStatus() == 1);
            } else {
                rgvProtocol.setStatusEnable(false);
            }
        } catch (Exception e) {
            log.error("RGV异常!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            try{
                DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV异常"+e.getMessage());
            } catch (Exception e2){
//                log.error("e2:"+e2.getMessage());
            }
            rgvProtocol.setStatusEnable(true);
        }
        RgvTaskProtocol rgvTaskProtocol = RgvTaskCache.getRgvStatus(slave.getId());
        if (rgvTaskProtocol == null) {
            rgvTaskProtocol = new RgvTaskProtocol();
            rgvTaskProtocol.setRgvNo(slave.getId());
        }
        rgvTaskProtocol.setAvoid(0);
        rgvTaskProtocol.setAvoidingTheDestination(0L);
        RgvStatusCache.updateRgvStatus(rgvProtocol);
        RgvTaskCache.updateRgvStatus(rgvTaskProtocol);
    }
    @Override
    public boolean connect() {
        boolean result = false;
@@ -213,515 +978,307 @@
        siemensNet.setRack(slave.getRack().byteValue());
        siemensNet.setSlot(slave.getSlot().byteValue());
        OperateResult connect = siemensNet.ConnectServer();
        if(connect.IsSuccess){
        if (connect.IsSuccess) {
            result = true;
            OutputQueue.RGV.offer(MessageFormat.format( "【{0}】RGV plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
//            OutputQueue.RGV.offer(MessageFormat.format( "【{0}】RGV plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.info("RGV plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
        } else {
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】RGV plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
//            OutputQueue.RGV.offer(MessageFormat.format("【{0}】RGV plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("RGV plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            initRgv();
            if (System.currentTimeMillis()-currentTimeMilliConnectRgv>1000*60*10){
                try{
                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGVplc连接失败");
                } catch (Exception e2){
//                log.error("e2:"+e2.getMessage());
                }
                if (currentTimeMilliConnectRgv == 0){
                    currentTimeMilliConnectRgv = System.currentTimeMillis()-1000*60*10-1;
                } else {
                    currentTimeMilliConnectRgv = System.currentTimeMillis();
                }
            }
        }
        initRgv();
//        siemensNet.ConnectClose();
        return result;
    }
    private void setBool(byte[] buffer, int byteIndex, int bitIndex, boolean value) {
        if (value) {
            buffer[byteIndex] |= (1 << bitIndex); // 置位
        } else {
            buffer[byteIndex] &= ~(1 << bitIndex); // 清零
        }
    }
    private void updateFlagInDb(String field, boolean value) {
        try {
            BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
            EntityWrapper<BasRgv> wrapper = new EntityWrapper<>();
            wrapper.eq("rgv_no", slave.getId());
            BasRgv entity = new BasRgv();
            switch (field) {
                case "pak_mk":    entity.setPakMk(value ? "1" : "0"); break;
                case "pak_in":    entity.setPakIn(value ? "1" : "0"); break;
                case "pak_out":   entity.setPakOut(value ? "1" : "0"); break;
                case "pak_rgv":   entity.setPakRgv(value ? "1" : "0"); break;
                case "pak_to_crn":entity.setPakToCrn(value ? "1" : "0"); break;
                case "paking":entity.setPaking(value ? "1" : "0"); break;
                case "pak_all":entity.setPakAll(value ? "1" : "0"); break;
                default:
                    log.warn("未知标志位字段: {}", field);
                    return;
            }
            basRgvService.update(entity, wrapper);
//            log.info("RGV标志位更新成功 [rgv_no:{}] {}={}", slave.getId(), field, value ? "1" : "0");
        } catch (Exception e) {
            log.error("更新RGV标志位异常 [rgv_no:{}] {}={} 错误:{}", slave.getId(), field, value, e.getMessage());
        }
    }
    public void setPakMk(boolean pakMk) {
        this.PakMk = pakMk;
        updateFlagInDb("pak_mk", pakMk);
    }
    /**
     * 读取状态
     */
    private void readStatus(){
    private void readStatus() {
        try {
            OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 41);
            OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 20);
            if (result.IsSuccess) {
                if (null == rgvProtocol) {
                // 构建设备状态对象
                RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(slave.getId());
                if (rgvProtocol == null) {
                    rgvProtocol = new RgvProtocol();
                    rgvProtocol.setRgvNo(siemensNet.getByteTransform().TransInt16(result.Content, 0));
                }
                rgvProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 2));
                rgvProtocol.setRgvPos(siemensNet.getByteTransform().TransInt32(result.Content, 4));
                rgvProtocol.setRgvPosDestination( siemensNet.getByteTransform().TransInt32(result.Content, 8));
                rgvProtocol.setStatus1(siemensNet.getByteTransform().TransInt16(result.Content, 12));
                rgvProtocol.setTaskNo1(siemensNet.getByteTransform().TransInt32(result.Content, 16));
                rgvProtocol.setTaskNo2(siemensNet.getByteTransform().TransInt32(result.Content, 20));
                rgvProtocol.setStaNo1(siemensNet.getByteTransform().TransInt32(result.Content, 28));
                rgvProtocol.setStaNo2(siemensNet.getByteTransform().TransInt32(result.Content, 32));
                boolean[] status1 = siemensNet.getByteTransform().TransBool(result.Content, 24, 1);
                rgvProtocol.setLoaded1(status1[0]);
                rgvProtocol.setLoaded2(status1[1]);
                boolean[] status2 = siemensNet.getByteTransform().TransBool(result.Content, 36,1);
                rgvProtocol.setErr1(status2[0]);
                rgvProtocol.setErr2(status2[1]);
                rgvProtocol.setErr3(status2[2]);
                rgvProtocol.setErr4(status2[3]);
                rgvProtocol.setErr5(status2[4]);
                rgvProtocol.setErr6(status2[5]);
                rgvProtocol.setErr7(status2[6]);
                rgvProtocol.setErr8(status2[7]);
                boolean[] status3 = siemensNet.getByteTransform().TransBool(result.Content, 37, 1);
                rgvProtocol.setErr9(status3[0]);
                rgvProtocol.setErr10(status3[1]);
                rgvProtocol.setErr11(status3[2]);
                rgvProtocol.setErr12(status3[3]);
                boolean[] statusErr = siemensNet.getByteTransform().TransBool(result.Content, 36, 5);
                rgvProtocol.setEmergencyStop(statusErr[0]);       // 急停触发
                rgvProtocol.setSlot1EmptyNoData(statusErr[1]);   // 1号位有物无资料
                rgvProtocol.setSlot2EmptyNoData(statusErr[2]);   // 2号位有物无资料
                rgvProtocol.setCommandErrorChainConflict(statusErr[3]); // 命令错误走链条冲突
                rgvProtocol.setTargetPositionIssue(statusErr[4]); // 目标位下发错误
                rgvProtocol.setTravelInverterError(statusErr[5]); // 走行变频器异常
                rgvProtocol.setPhotoelectric1Error(statusErr[6]); // 1号光电异常
                rgvProtocol.setPhotoelectric2Error(statusErr[7]); // 2号光电异常
                rgvProtocol.setTimeoutConnectionWithLine(statusErr[8]); // 与输线时接超时
                rgvProtocol.setLeftRollerTimeout(statusErr[9]);    // 左侧滚筒运行超时
                rgvProtocol.setRightRollerTimeout(statusErr[10]);   // 右侧滚筒运行超时
                rgvProtocol.setRgvRunTimeout(statusErr[11]);        // rgv运行超时
                rgvProtocol.setPosition1ChainInverterError(statusErr[12]); // 1号工位链条变频器异常
                rgvProtocol.setPosition2ChainInverterError(statusErr[13]); // 2号工位链条变频器异常
                rgvProtocol.setFrontRearLimit(statusErr[14]);      // 前后极限位
                rgvProtocol.setEmergencyButton(statusErr[15]);     // 急停按钮
                rgvProtocol.setForwardButton(statusErr[16]);       // 前进按钮
                rgvProtocol.setReverseButton(statusErr[17]);       // 后退按钮
                rgvProtocol.setLocalRemote(statusErr[18]);         // 本地/远程
                rgvProtocol.setReset(statusErr[19]);               // 复位
                rgvProtocol.setTravelBrakeSwitch(statusErr[20]);   // 走行抱闸开关钮
                rgvProtocol.setTravelSpeedLimitPhotoelectric(statusErr[21]); // 走行强制减速光电
                rgvProtocol.setLeftOverlimit1(statusErr[22]);      // 左超限 1
                rgvProtocol.setRightOverlimit1(statusErr[23]);     // 右超限 1
                rgvProtocol.setLeftAtPosition1(statusErr[24]);     // 左到位 1
                rgvProtocol.setRightAtPosition1(statusErr[25]);    // 右到位 1
                rgvProtocol.setChainForward1(statusErr[26]);       // 链条前进 1
                rgvProtocol.setChainReverse1(statusErr[27]);       // 链条后退 1
                rgvProtocol.setInverterAlarm(statusErr[28]);       // 变频器报警
                rgvProtocol.setLeftOverlimit2(statusErr[29]);      // 左超限 2
                rgvProtocol.setRightOverlimit2(statusErr[30]);     // 右超限 2
                rgvProtocol.setLeftAtPosition2(statusErr[31]);     // 左到位 2
                rgvProtocol.setRightAtPosition2(statusErr[32]);    // 右到位 2
                rgvProtocol.setCargoSpeedReduction(statusErr[33]); // 货物减速
                rgvProtocol.setConveyorInverterAlarm2(statusErr[34]); // 输送变频器报警 2
                rgvProtocol.setRightConveyor2(statusErr[35]);      // 右输送 2
                rgvProtocol.setLeftConveyor2(statusErr[36]);       // 左输送 2
                if(rgvProtocol.getStatus1() == 99){
                    rgvProtocol.setErrorMk(true);//若存在异常触发写入
                }else{
                    rgvProtocol.setWriteMk(true);//无异常后才能继续写入
                    rgvProtocol.setErrorMk(false);
                rgvProtocol.setRgvNo(slave.getId());
                rgvProtocol.setCarBodyJiaoMing(slave.getCarBodyJiaoMing());
                rgvProtocol.setCarBodyKunPeng(slave.getCarBodyKunPeng());
                rgvProtocol.setRgvPos((long)siemensNet.getByteTransform().TransInt32(result.Content, 0));
                rgvProtocol.setRgvPosDestination((long)siemensNet.getByteTransform().TransInt32(result.Content, 4));
                if (rgvProtocol.getRgvPosDestination()==0L){
                    rgvProtocol.setRgvPosDestination(rgvProtocol.getRgvPos());
                }
                rgvProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 8));
//                rgvProtocol.setStatus((short)1);
                //作业启动中  解决任务下发后小车状态未更新,小车状态不及时
                if (this.wrkSign == 1 && rgvProtocol.getStatus()!=(short)1){
                    this.wrkSign = 0;
                }
                if (this.wrkSign == 1){
                    rgvProtocol.setStatus((short)110);
                }
//                BasRgvMapService basRgvMapService = SpringUtils.getBean(BasRgvMapService.class);
                rgvProtocol.setTaskNo((long)siemensNet.getByteTransform().TransInt32(result.Content, 10));
                rgvProtocol.setRgvNo((int)siemensNet.getByteTransform().TransInt16(result.Content, 14));
                rgvProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 16));
//                rgvProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 20));
//                rgvProtocol.setxSpeed(siemensNet.getByteTransform().TransInt16(result.Content, 28));
//                rgvProtocol.setxDistance(siemensNet.getByteTransform().TransInt16(result.Content, 40));
//                rgvProtocol.setxDuration(siemensNet.getByteTransform().TransInt16(result.Content, 48));
//                OperateResultExOne<byte[]> result11 = siemensNet.Read("DB100.12", (short) 1);
                boolean[] status = siemensNet.getByteTransform().TransBool(result.Content, 18, 2);
                rgvProtocol.setLoaded(status[0]? (short)1:(short)0);
                rgvProtocol.setErr1(status[8]);
                rgvProtocol.setErr2(status[9]);
                rgvProtocol.setErr3(status[10]);
                rgvProtocol.setErr4(status[11]);
                rgvProtocol.setErr5(status[12]);
                rgvProtocol.setErr6(status[13]);
                rgvProtocol.setErr7(status[14]);
                rgvProtocol.setErr8(status[15]);
//                System.out.println("读线程"+ slave.getId()+"---"+JSON.toJSONString(rgvProtocol));
//                System.out.println("读线程,小车号"+ slave.getId()+"时间戳:"+System.currentTimeMillis()+"小车数据:"+JSON.toJSONString(rgvProtocol));
                OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId()));
//                // 工位1复位信号
//                if (rgvProtocol.getStatusType().equals(RgvStatusType.WAITING)
//                        || rgvProtocol.getStatusType().equals(RgvStatusType.FETCHWAITING)) {
//                    if (resetFlag1) {
//                        RgvCommand rgvCommand = new RgvCommand();
//                        rgvCommand.setAckFinish1((short)1);
//                        if (write(rgvCommand)) {
//                            resetFlag1 = false;
//                        }
//                    }
//                }
                if (rgvProtocol.getAlarm$()!=0){
                    RgvErrCache.updateRgvErr(slave.getId(),rgvProtocol.getAlarmM());
                }
                try {
                    // 根据实时信息更新数据库
                    BasRgvService basRgvService = SpringUtils.getBean(BasRgvService.class);
                    BasRgv basRgv = new BasRgv();
                    BasRgv basRgv = basRgvService.selectById(slave.getId());
                    if (!Cools.isEmpty(basRgv)) {
                        rgvProtocol.setStatusEnable(basRgv.getStatus() == 1);
                    } else {
                        rgvProtocol.setStatusEnable(false);
                    }
//                    BasRgv basRgv = new BasRgv();
                    basRgv.setRgvNo(slave.getId());
                    basRgv.setRgvSts((int)rgvProtocol.getMode());
                    if(rgvProtocol.isWriteMk() && rgvProtocol.isErrorMk()){
                        try {
                            // 日志记录异常情况
                            BasRgvErrorLog basRgvErrorLogs;
                            basRgvErrorLogs = rgvProtocol.toSqlModelError();
                            BasRgvErrorLogService basRgvErrorLogService = SpringUtils.getBean(BasRgvErrorLogService.class);
                            basRgvErrorLogService.insert(basRgvErrorLogs);
                            rgvProtocol.setWriteMk(false);
                        } catch (Exception ignore) {
                            log.error(ignore.getMessage());
                    basRgv.setRgvSts((int) rgvProtocol.getMode());
                    if (!basRgvService.updateById(rgvProtocol.toSqlModel(basRgv))) {
                        log.error("RGV plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                        try{
                            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                            deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV plc数据库更新失败");
                        } catch (Exception e2){
//                            log.error("e2:"+e2.getMessage());
                        }
                    }
                    if (!basRgvService.updateById(rgvProtocol.toSqlModel(basRgv))){
                        log.error("RGV plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                    }
                } catch (Exception ignore){
                    System.out.println(ignore);
                } catch (Exception ignore) {
                }
                // 更新缓存
                RgvStatusCache.updateRgvStatus(rgvProtocol);
            } else {
                initRgv();
                OutputQueue.RGV.offer(MessageFormat.format("【{0}】读取RGV plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
//                log.error("读取RGV plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                connectRgv = false;
//                OutputQueue.RGV.offer(MessageFormat.format("【{0}】读取RGV plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
                log.error("读取RGV plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                try{
                    DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                    deviceErrorService.addDeviceError("rgvErr", slave.getId(), "读取RGV plc状态信息失败");
                } catch (Exception e2){
//                    log.error("e2:"+e2.getMessage());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】读取RGV plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
//            log.error("读取RGV plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
//            e.printStackTrace();
//            OutputQueue.RGV.offer(MessageFormat.format("【{0}】读取RGV plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("读取RGV plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            try{
                DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                deviceErrorService.addDeviceError("rgvErr", slave.getId(), "读取RGV plc状态信息失败");
            } catch (Exception e2){
//                log.error("e2:"+e2.getMessage());
            }
            initRgv();
        }
    }
    /**
     * 小车工位写入写入数据
     * 写入数据
     */
    private boolean write(RgvCommand command) throws InterruptedException {
        if (null == command) {
            log.error("RGV写入命令为空");
            return false;
        }
        OperateResultExOne<byte[]> result1 = siemensNet.Read("DB100.0", (short) 39);
        if (result1.IsSuccess){
            RgvCommand one = new RgvCommand();
            one.setWrkTaskPri(siemensNet.getByteTransform().TransInt32(result1.Content, 0));//执行工位
            one.setTargetPosition(siemensNet.getByteTransform().TransInt32(result1.Content, 4));//行走目标站
            one.setTaskStatus(siemensNet.getByteTransform().TransInt16(result1.Content, 8));//小车状态
            one.setTaskNo(siemensNet.getByteTransform().TransInt32(result1.Content, 10));//下发工作号
            News.info("RGV命令下发前读取状态[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
        }
        byte[] writeBytes = new byte[14];
        command.setRgvNo(slave.getId());
        if(specialSites.contains(command.getTargetPosition())){
            command.setTargetPosition(StaPosition.get(command.getTargetPosition()));
        }
        writeInt32(writeBytes, 0, command.getWrkTaskPri());
        writeInt32(writeBytes, 4, command.getTargetPosition());
        writeInt16(writeBytes, 8, (short)command.getTaskStatus());
        writeInt32(writeBytes, 10, command.getTaskNo());
        OperateResult result = siemensNet.Write("DB100.0", writeBytes);
    private boolean write(TaskProtocol taskProtocol) throws InterruptedException {
        if (null == taskProtocol) {
            log.error("RGV写入命令为空 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        if (!result.IsSuccess){
            News.error("写入RGVplc数据失败,重新添加任务到队列 ===> [id:{}],{}",slave.getId(),JSON.toJSON(command));
            MessageQueue.offer(SlaveType.Rgv,slave.getId(),new Task(2,command));
            Thread.sleep(100);
            readStatus();
            return false;
        }
        //RGV任务写入后,回读一次,看是否成功
        Thread.sleep(400);
        try {
            OperateResultExOne<byte[]> resultRead = siemensNet.Read("DB100.0", (short) 14);
            if (resultRead.IsSuccess){
                RgvCommand one = new RgvCommand();
                one.setWrkTaskPri(siemensNet.getByteTransform().TransInt32(resultRead.Content, 0));//执行工位
                one.setTargetPosition(siemensNet.getByteTransform().TransInt32(resultRead.Content, 4));//行走目标站
                one.setTaskStatus(siemensNet.getByteTransform().TransInt16(resultRead.Content, 8));//小车状态
                one.setTaskNo(siemensNet.getByteTransform().TransInt32(resultRead.Content, 10));//下发工作号
                if (
                        !command.getTaskNo().equals(one.getTaskNo()) ||
                        !command.getTaskStatus().equals(one.getTaskStatus()) ||
                        !command.getWrkTaskPri().equals(one.getWrkTaskPri()) ||
                        !command.getTargetPosition().equals(one.getTargetPosition())
                ) {
                    try{
                        News.error("RGV命令地址写入后回读失败[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
                    }catch (Exception e){
                        try{
                            News.error("日志打印失败:===>>参数one报错 [id:{}],{}", slave.getId(), JSON.toJSON(command),JSON.toJSON(resultRead));
                        }catch (Exception e1){
                            News.error("日志打印失败:===>> [id:{}],{}", slave.getId(), JSON.toJSON(command));
                        }
                    }
                    News.error("Rgv命令回读失败后,重新添加任务到队列 ===>> [id:{}],{}", slave.getId(), JSON.toJSON(command));
                    MessageQueue.offer(SlaveType.Rgv, slave.getId(), new Task(2, command));
                    Thread.sleep(100);
                    readStatus();
                    return false;
                }else {
                    News.info("RGV命令地址写入后回读成功[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
                }
            try{
                DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                deviceErrorService.addDeviceError("rgvErr", slave.getId(), "RGV写入命令为空");
            } catch (Exception e2){
//                log.error("e2:"+e2.getMessage());
            }
        }catch (Exception e){
            News.error("RGV命令地址写入后回读出错");
            return false;
        }
//        convertRow(command);
//        taskProtocol.setRgvNo(slave.getId());
//        Long[] array = new Long[11];
        OperateResult result41 = siemensNet.Write("DB100.12.0", false);
//        array[0] = taskProtocol.getAckFinish1();
//        array[1] = taskProtocol.getTaskNo();
//        array[2] = taskProtocol.getTaskMode();
//        array[4] = command.getDestinationStaNo();
//        array[10] = taskProtocol.getCommand();
        int taskStatus = taskProtocol.getTaskStatus();
        if (result.IsSuccess) {  //任务下发确认
            Thread.sleep(300);
            //任务下发次数
            int writeCount2 = 0;
            do {
                writeCount2++;
                Short commandFinish = 1;
                result = siemensNet.Write("DB100.34.0", commandFinish);
                if(result.IsSuccess){
                    //RGV任务写入后,回读一次,看是否成功
                    Thread.sleep(200);
                    OperateResultExOne<byte[]> resultRead = siemensNet.Read("DB100.34", (short) 2);
                    if (resultRead.IsSuccess) {
                        commandFinish=siemensNet.getByteTransform().TransInt16(resultRead.Content, 0);
                        if (commandFinish !=1){
                            News.error("RGV任务确认位"+commandFinish+"写入数据与回读数据不一致!"+"循环执行次数:"+writeCount2+"次");
                        }else{
                            //任务命令写入成功
                            News.info("RGV任务确认位"+commandFinish+"回读成功!"+"循环执行次数:"+writeCount2+"次");
                            break;
                        }
                    }else {
                        News.error("RGV任务确认位"+commandFinish+"回读失败!"+"循环执行次数:"+writeCount2+"次");
                    }
                } else {
                    News.error("RGV任务确认位"+commandFinish+"写入失败!"+"循环执行次数:"+writeCount2+"次");
                }
            }while (writeCount2<5);
        }
        OperateResult result = siemensNet.Write("DB100.0", taskProtocol.getTargetPosition().intValue());
        OperateResult result1 = siemensNet.Write("DB100.4", (short) taskStatus);
        OperateResult result2 = siemensNet.Write("DB100.6", taskProtocol.getTaskNo().intValue());
        OperateResult result3 = siemensNet.Write("DB100.10", taskProtocol.isDirection()? (short) 1 :  (short) 2); // 执行方向(面朝轨道 定位值左小右大)    true:左   false:右
        Thread.sleep(20L);
        OperateResult result4 = siemensNet.Write("DB100.12.0", true);
        this.wrkSign = 1;
//        log.info("任务下发线程,小车号"+ slave.getId()+"时间戳:"+System.currentTimeMillis());
//        if (taskProtocol.getAckFinish1() == 0) {
//            short commandFinish = 3;  //工位1、2任务同时写入
//            Thread.sleep(100L);
//            result = siemensNet.Write("DB100.20", commandFinish);
//        }
        try {
            // 日志记录
            BasRgvOptService bean = SpringUtils.getBean(BasRgvOptService.class);
            BasRgvOpt basRgvOpt = new BasRgvOpt(
                    command.getTaskNo(),
                    command.getRgvNo(),
                    taskProtocol.getTaskNo().intValue(),
                    taskProtocol.getTaskNo().intValue(),
                    slave.getId(),
                    new Date(),
                    command.getTaskStatus().toString(),
                    command.getTargetPosition(),
                    command.getWrkTaskPri(),
                    new Date()
                    String.valueOf(taskProtocol.getTaskStatus()),
                    null,
                    null,
                    null,
                    result.IsSuccess ? 1 : 0,
                    null,
                    new Date(),
                    null
            );
            bean.insert(basRgvOpt);
        } catch (Exception ignore) {
            log.error(ignore.getMessage());
        }
        readStatus();
        if (result != null && result.IsSuccess) {
            Thread.sleep(200);
            this.readStatus();
            log.info("RGV 工位命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 工位命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
//            Thread.sleep(50);
//            this.readStatus();
            log.info("RGV 命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(taskProtocol));
            log.error("RGV 命令下发 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            try{
                DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
                deviceErrorService.addDeviceError("rgvWrite", slave.getId(), "RGV 命令下发"+JSON.toJSON(taskProtocol));
            } catch (Exception e2){
//                log.error("e2:"+e2.getMessage());
            }
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(taskProtocol)));
            return true;
        } else {
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】写入RGV plc工位数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("写入RGV plc工位数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】写入RGV plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("写入RGV plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            return false;
        }
    }
    private boolean write2(RgvCommand command) throws InterruptedException {
        if (null == command) {
            log.error("RGV写入命令为空");
            return false;
        }
        OperateResultExOne<byte[]> result1 = siemensNet.Read("DB100.0", (short) 39);
        if (result1.IsSuccess){
            RgvCommand one = new RgvCommand();
            one.setWrkTaskPri(siemensNet.getByteTransform().TransInt32(result1.Content, 0));//执行工位
            one.setTargetPosition(siemensNet.getByteTransform().TransInt32(result1.Content, 4));//行走目标站
            one.setTaskStatus(siemensNet.getByteTransform().TransInt16(result1.Content, 8));//小车状态
            one.setTaskNo(siemensNet.getByteTransform().TransInt32(result1.Content, 10));//下发工作号
            News.info("RGV命令下发前读取状态[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
        }
        byte[] writeBytes = new byte[36];
        command.setRgvNo(slave.getId());
        if(specialSites.contains(command.getTargetPosition())){
            command.setTargetPosition(StaPosition.get(command.getTargetPosition()));
        }
        writeInt32(writeBytes, 0, command.getWrkTaskPri());
        writeInt32(writeBytes, 4, command.getTargetPosition());
        writeInt16(writeBytes, 8, (short)command.getTaskStatus());
        writeInt32(writeBytes, 10, command.getTaskNo());
        writeBool(writeBytes, 34, 0, command.getCommand());
        OperateResult result = siemensNet.Write("DB100.0", writeBytes);
        if (!result.IsSuccess){
            News.error("写入RGVplc数据失败,重新添加任务到队列 ===> [id:{}],{}",slave.getId(),JSON.toJSON(command));
            MessageQueue.offer(SlaveType.Rgv,slave.getId(),new Task(2,command));
            Thread.sleep(100);
            readStatus();
            return false;
        }
    private boolean writeDelRgvTask() throws InterruptedException {
//
        OperateResult result = siemensNet.Write("DB100.12.0", false);
        OperateResult result0 = siemensNet.Write("DB100.0", (int) 0);
        OperateResult result1 = siemensNet.Write("DB100.4", (short) 0);
        OperateResult result2 = siemensNet.Write("DB100.6", (int) 0);
        OperateResult result3 = siemensNet.Write("DB100.10", (short) 0); // 执行方向(面朝轨道 定位值左小右大)    true:左   false:右
        log.info("任务完成下发线程,小车号"+ slave.getId()+"时间戳:"+System.currentTimeMillis());
        //RGV任务写入后,回读一次,看是否成功
        Thread.sleep(400);
        try {
            OperateResultExOne<byte[]> resultRead = siemensNet.Read("DB100.0", (short) 14);
            if (resultRead.IsSuccess){
                RgvCommand one = new RgvCommand();
                one.setWrkTaskPri(siemensNet.getByteTransform().TransInt32(resultRead.Content, 0));//执行工位
                one.setTargetPosition(siemensNet.getByteTransform().TransInt32(resultRead.Content, 4));//行走目标站
                one.setTaskStatus(siemensNet.getByteTransform().TransInt16(resultRead.Content, 8));//小车状态
                one.setTaskNo(siemensNet.getByteTransform().TransInt32(resultRead.Content, 10));//下发工作号
                if (
                        !command.getTaskNo().equals(one.getTaskNo()) ||
                                !command.getTaskStatus().equals(one.getTaskStatus()) ||
                                !command.getWrkTaskPri().equals(one.getWrkTaskPri()) ||
                                !command.getTargetPosition().equals(one.getTargetPosition())
                ) {
                    try{
                        News.error("RGV命令地址写入后回读失败[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
                    }catch (Exception e){
                        try{
                            News.error("日志打印失败:===>>参数one报错 [id:{}],{}", slave.getId(), JSON.toJSON(command),JSON.toJSON(resultRead));
                        }catch (Exception e1){
                            News.error("日志打印失败:===>> [id:{}],{}", slave.getId(), JSON.toJSON(command));
                        }
                    }
                    News.error("Rgv命令回读失败后,重新添加任务到队列 ===>> [id:{}],{}", slave.getId(), JSON.toJSON(command));
                    MessageQueue.offer(SlaveType.Rgv, slave.getId(), new Task(2, command));
                    Thread.sleep(100);
                    readStatus();
                    return false;
                }else {
                    News.info("RGV命令地址写入后回读成功[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
                }
            }
        }catch (Exception e){
            News.error("RGV命令地址写入后回读出错");
        }
        if (result.IsSuccess) {  //任务下发确认
            Thread.sleep(300);
            //任务下发次数
            int writeCount2 = 0;
            do {
                writeCount2++;
                Short commandFinish = 1;
                result = siemensNet.Write("DB100.34.0", commandFinish);
                if(result.IsSuccess){
                    //RGV任务写入后,回读一次,看是否成功
                    Thread.sleep(200);
                    OperateResultExOne<byte[]> resultRead = siemensNet.Read("DB100.34", (short) 2);
                    if (resultRead.IsSuccess) {
                        commandFinish=siemensNet.getByteTransform().TransInt16(resultRead.Content, 0);
                        if (commandFinish !=1){
                            News.error("RGV任务确认位"+commandFinish+"写入数据与回读数据不一致!"+"循环执行次数:"+writeCount2+"次");
                        }else{
                            //任务命令写入成功
                            News.info("RGV任务确认位"+commandFinish+"回读成功!"+"循环执行次数:"+writeCount2+"次");
                            break;
                        }
                    }else {
                        News.error("RGV任务确认位"+commandFinish+"回读失败!"+"循环执行次数:"+writeCount2+"次");
                    }
                } else {
                    News.error("RGV任务确认位"+commandFinish+"写入失败!"+"循环执行次数:"+writeCount2+"次");
                }
            }while (writeCount2<5);
        }
        try {
            // 日志记录
            BasRgvOptService bean = SpringUtils.getBean(BasRgvOptService.class);
            BasRgvOpt basRgvOpt = new BasRgvOpt(
                    command.getTaskNo(),
                    command.getRgvNo(),
                    0,
                    0,
                    slave.getId(),
                    new Date(),
                    command.getTaskStatus().toString(),
                    command.getTargetPosition(),
                    command.getWrkTaskPri(),
                    new Date()
                    String.valueOf(0),
                    null,
                    null,
                    null,
                    result.IsSuccess ? 1 : 0,
                    null,
                    new Date(),
                    null
            );
            bean.insert(basRgvOpt);
        } catch (Exception ignore) {
            log.error(ignore.getMessage());
        }
        if (result != null && result.IsSuccess) {
            Thread.sleep(200);
            this.readStatus();
            log.info("RGV 工位命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 工位命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
//            Thread.sleep(200);
//            this.readStatus();
            log.info("RGV 命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON("null"));
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON("null")));
            return true;
        } else {
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】写入RGV plc工位数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("写入RGV plc工位数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            OutputQueue.RGV.offer(MessageFormat.format("【{0}】写入RGV plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error("写入RGV plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            return false;
        }
    }
    public static void writeInt32(byte[] buffer, int index, int value) {
        buffer[index]     = (byte)((value >> 24) & 0xFF);
        buffer[index + 1] = (byte)((value >> 16) & 0xFF);
        buffer[index + 2] = (byte)((value >> 8) & 0xFF);
        buffer[index + 3] = (byte)(value & 0xFF);
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
        this.wrkSign = 0;
    }
    public static void writeInt16(byte[] buffer, int index, short value) {
        buffer[index]     = (byte)((value >> 8) & 0xFF); // 高字节
        buffer[index + 1] = (byte)(value & 0xFF);        // 低字节
    }
    public static void writeBool(byte[] buffer, int byteIndex, int bitIndex, boolean value) {
        if (value) {
            buffer[byteIndex] |= (1 << bitIndex);
        } else {
            buffer[byteIndex] &= ~(1 << bitIndex);
        }
    }
    public Integer getRgvPosI(Integer pos) {
        if (pos == null) return 0;
        // key: 站点号  value: 基准物理位置
        Map<Integer, Integer> posMap = new HashMap<>();
        posMap.put(1004, 6534);
        posMap.put(1007, 33634);
        posMap.put(1010, 75174);
        posMap.put(1014, 102124);
        posMap.put(1018, 138224);
        posMap.put(1021, 178034);
        posMap.put(1024, 219684);
        posMap.put(1028, 246724);
        posMap.put(1031, 288194);
        posMap.put(1035, 315204);
        int tolerance = 50; // 允许误差范围
        for (Map.Entry<Integer, Integer> entry : posMap.entrySet()) {
            int site = entry.getKey();
            int basePos = entry.getValue();
            if (Math.abs(pos - basePos) <= tolerance) {
                return site;
            }
        }
        return 0; // 没匹配到站点
    public void setDelRgvTask() {
        delRgvTask = true;
    }
    @Override
    public void close() {
        siemensNet.ConnectClose();
    }
    /******************************************************************************************/
    /**************************************** 测试专用 *****************************************/
    /*****************************************************************************************/
    public static void main(String[] args) throws InterruptedException {
        RgvSlave slave = new RgvSlave();
        slave.setId(1);
        slave.setIp("192.168.6.9");
        slave.setRack(0);
        slave.setSlot(0);
        RgvThread rgvThread = new RgvThread(slave);
        rgvThread.connect();
        rgvThread.readStatus();
        System.out.println(JSON.toJSONString(rgvThread.rgvProtocol));
        Thread.sleep(3000L);
    }
}
src/main/java/com/zy/core/thread/RoboticArmThread.java
@@ -154,4 +154,11 @@
    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/java/com/zy/core/thread/ScaleThread.java
@@ -134,4 +134,12 @@
        return true;
    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/java/com/zy/core/thread/SiemensCrnThread.java
@@ -831,4 +831,11 @@
    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -1021,4 +1021,11 @@
//
//    }
    /**
     * 清除作业启动中
     */
    @Override
    public void setWrkSign() {
    }
}
src/main/resources/application.yml
@@ -253,133 +253,239 @@
      row: 18
      bay: 52
      lev: 2
  # RGV穿梭车1
  rgv[0]:
    id: 1
    ip: 10.10.10.190
    port: 502
    rack: 0
    slot: 0
    #RGV入库取货站点
    rgvInTStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1042
      staNo2: 1043
    rgvInTStn[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1105
      staNo2: 1104
    rgvInTStn[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1038
    rgvInTStn[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1036
    #RGV入库放货站点
    rgvInPStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1004
    rgvInPStn[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1014
    rgvInPStn[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1018
    rgvInPStn[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1028
    rgvInPStn[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1035
    #RGV出库取货站点
    rgvOutTStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1007
      staNo2: 1005
    rgvOutTStn[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1010
      staNo2: 1008
    rgvOutTStn[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1021
      staNo2: 1019
    rgvOutTStn[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1024
      staNo2: 1022
    rgvOutTStn[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1031
      staNo2: 1029
    #RGV出库放货站点
    rgvOutPStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1106
    rgvOutPStn[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1041
    rgvOutPStn[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1036
  # RGV穿梭车2
  rgv[1]:
    id: 2
    ip: 10.10.10.193
    ip: 27.172.2.70
    port: 502
    rack: 0
    slot: 0
    #RGV入库取货站点
    rgvInTStn[0]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2037
    #RGV入库放货站点
    rgvInPStn[0]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2006
    rgvInPStn[1]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2012
    rgvInPStn[2]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2018
    rgvInPStn[3]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2024
    rgvInPStn[4]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2030
    #RGV出库取货站点
    rgvOutTStn[0]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2003
      staNo2: 2001
    rgvOutTStn[1]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2009
      staNo2: 2007
    rgvOutTStn[2]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2015
      staNo2: 2013
    rgvOutTStn[3]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2021
      staNo2: 2019
    rgvOutTStn[4]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2027
      staNo2: 2025
    #RGV出库放货站点
    rgvOutPStn[0]:
      devpPlcId: ${wcs-slave.devp[1].id}
      staNo: 2031
    otherId: 1
    carBodyJiaoMing: 2800
    carBodyKunPeng: 13500
    #RGV源站点
    rgvInSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1004
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1005
      directionOther: false
    rgvInSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1014
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1016
      directionOther: true
    rgvInSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1020
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1021
      directionOther: false
    rgvInSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1003
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1003
      directionOther: false
    rgvInSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1007
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1007
      directionOther: false
    rgvInSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1013
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1013
      directionOther: false
    rgvInSta[6]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1018
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1018
      directionOther: false
    rgvInSta[7]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1019
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1019
      directionOther: false
    #RGV目标站点
    rgvOutSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1002
      direction: true
      staNoOther: 1002
      directionOther: false
    rgvOutSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1009
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1009
      directionOther: false
    rgvOutSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1001
      direction: false
      staNoOther: 1001
      directionOther: false
    rgvOutSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1006
      direction: false
      staNoOther: 1006
      directionOther: false
    rgvOutSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1008
      direction: false
      staNoOther: 1008
      directionOther: false
    rgvOutSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1017
      direction: false
      staNoOther: 1017
      directionOther: false
    rgvSuperSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1001
      direction: false
      staNoOther: 1001
      directionOther: false
    rgvSuperSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1002
      direction: false
      staNoOther: 1002
      directionOther: false
  # RGV穿梭车2
  rgv[0]:
    id: 1
    ip: 27.172.2.71
    port: 502
    rack: 0
    slot: 0
    otherId: 2
    carBodyJiaoMing: 2800
    carBodyKunPeng: 13500
    #RGV源站点
    rgvInSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1004
      direction: true
      staNoOther: 1005
      directionOther: false
    rgvInSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1014
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1016
      directionOther: true
    rgvInSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1020
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1021
      directionOther: false
    rgvInSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1003
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1003
      directionOther: false
    rgvInSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1007
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1007
      directionOther: false
    rgvInSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1013
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1013
      directionOther: false
    rgvInSta[6]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1018
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1018
      directionOther: false
    rgvInSta[7]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1019
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: false
      staNoOther: 1019
      directionOther: false
    #RGV目标站点
    rgvOutSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1023
      direction: true
      staNoOther: 1023
      directionOther: false
    rgvOutSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1009
      #执行方向(面朝轨道 定位值左小右大)  true:左   false:右
      direction: true
      staNoOther: 1009
      directionOther: false
    rgvOutSta[2]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1022
      direction: false
      staNoOther: 1022
      directionOther: false
    rgvOutSta[3]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1006
      direction: false
      staNoOther: 1006
      directionOther: false
    rgvOutSta[4]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1008
      direction: false
      staNoOther: 1008
      directionOther: false
    rgvOutSta[5]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1017
      direction: false
      staNoOther: 1017
      directionOther: false
    rgvSuperSta[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1023
      direction: false
      staNoOther: 1023
      directionOther: false
    rgvSuperSta[1]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 1022
      direction: false
      staNoOther: 1022
      directionOther: false
  # 输送线1
  devp[0]:
    id: 1
src/main/resources/mapper/DeviceErrorMapper.xml
New file
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.DeviceErrorMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.DeviceError">
        <id column="id" property="id" />
        <result column="device" property="device" />
        <result column="msg" property="msg" />
        <result column="device_id" property="deviceId" />
        <result column="create_time" property="createTime" />
        <result column="appe_time" property="appeTime" />
        <result column="device_plc_id" property="devicePlcId" />
    </resultMap>
    <sql id="batchSeq">
        <if test="id != null and id != 0">
            and id = #{id}
        </if>
        <if test="device != null and device != ''">
            and device = #{device}
        </if>
        <if test="deviceId != null and deviceId != 0">
            and device_id = #{deviceId}
        </if>
        <if test="devicePlcId != null and devicePlcId != 0">
            and device_plc_id = #{devicePlcId}
        </if>
    </sql>
    <select id="selectByDeviceAndDeviceId" resultMap="BaseResultMap">
        select top 1 * from wcs_device_error
        where "device" = #{device}
        and "device_id" = #{deviceId}
    </select>
    <delete id="deleteByDeviceAndDeviceId">
        delete from wcs_device_error
        where "device" = #{device}
        and "device_id" = #{deviceId}
    </delete>
    <select id="selectDeviceErrorList" resultMap="BaseResultMap">
        SELECT * FROM (
            SELECT ROW_NUMBER() over(order by create_time DESC) as row,*
            FROM ( SELECT * FROM wcs_device_error ) t
            WHERE 1=1
            <include refid="batchSeq"></include>
        ) a
        WHERE a.row BETWEEN ((#{pageNumber}-1)*#{pageSize}+1) and (#{pageNumber}*#{pageSize})
    </select>
    <select id="selectDeviceErrorListTotal" resultType="Long">
        SELECT count(1) FROM wcs_device_error
        WHERE 1=1
        <include refid="batchSeq"></include>
    </select>
</mapper>