huang
2025-10-22 78d73df2f8e0c6855d65eb1f2c6df08e0f99bab1
hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/job/RawGlassTask.java
@@ -67,17 +67,27 @@
    private static final String LOAD_GLASS_DEVICE_TWO_TASK = "load_glass_device_two_task";
    private static final List<Integer> LOAD_STATION_01 = Arrays.asList(101, 102);
    private static final List<Integer> LOAD_STATION_02 = Arrays.asList(103, 104);
    private static final List<Integer> LOAD_STATION_ALL = Arrays.asList(101, 102, 103, 104);
    private static final Integer LEFTING_01 = 98;
    private static final Integer LEFTING_02 = 99;
    private static final List<Integer> LOAD_STATION_01 = Collections.singletonList(101);
//    private static final List<Integer> LOAD_STATION_02 = Arrays.asList(103, 104);
//    private static final List<Integer> LOAD_STATION_ALL = Arrays.asList(101, 102, 103, 104);
    private static final Integer LEFTING_01 = 99;
//    private static final Integer LEFTING_02 = 99;
    private static final Integer LOAD_GLASS_ONE_DEVICE = 5;
    private static final Integer LOAD_GLASS_TWO_DEVICE = 6;
    @Scheduled(fixedDelay = 1000)
    public void rawStorageTask() throws Exception {
        S7Data S7DataWL1 = s7Serializer.read(S7Data.class);
//        S7Data S7DataWL1 = new S7Data();
//        S7DataWL1.setRequest((short) 1);
//        S7DataWL1.setConfirmation((short) 0);
//        S7DataWL1.setReportWord((short) 0);
//        S7DataWL1.setTaskWord((short) 0);
//        String requestWord = S7DataWL1.getRequest().toString();
//        String confireWord = S7DataWL1.getConfirmation().toString();
//        String reportWord = S7DataWL1.getReportWord().toString();
//        String taskWord = S7DataWL1.getTaskWord().toString();
        String requestWord = S7DataWL1.getRequest().toString();
        String confireWord = S7DataWL1.getConfirmation().toString();
        String reportWord = S7DataWL1.getReportWord().toString();
@@ -129,19 +139,19 @@
            log.info("执行调度任务,结束");
            return;
        }
        flag = outboundTask();
        flag = inboundRequestTask();
        if (flag) {
            log.info("执行出库任务,结束");
            log.info("执行吊装位请求任务");
            return;
        }
        flag = warehouseTask();
        if (flag) {
            log.info("执行入库任务");
            log.info("执行回库任务");
            return;
        }
        flag = shelfResetTask();
        flag = outboundTask();
        if (flag) {
            log.info("执行复位任务");
            log.info("执行出库任务,结束");
            return;
        }
        log.info("无任务执行,结束");
@@ -150,6 +160,8 @@
    @Scheduled(fixedDelay = 1000)
    public void rawStorageInCar() throws Exception {
        S7Data S7DataWL1 = s7Serializer.read(S7Data.class);
//        S7Data S7DataWL1 = new S7Data();
//        S7DataWL1.setInCar((short) 1);
        String value = S7DataWL1.getInCar().toString();
//        ReadWriteEntity entity = miloService.readFromOpcUa("CC.CC.inCar");
//        String value = entity.getValue() + "";
@@ -171,6 +183,8 @@
    @Scheduled(fixedDelay = 1000)
    public void rawStorageFinish() throws Exception {
        S7Data S7DataWL1 = s7Serializer.read(S7Data.class);
//        S7Data S7DataWL1 = new S7Data();
//        S7DataWL1.setReportWord((short) 1);
        String value = S7DataWL1.getReportWord().toString();
//        ReadWriteEntity entity = miloService.readFromOpcUa("CC.CC.reportWord");
//        String value = entity.getValue() + "";
@@ -185,7 +199,7 @@
            return;
        }
        RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>()
                .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW));
                .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING, Const.RAW_GLASS_TASK_NEW));
        RawGlassStorageDetails targetDetails = rawGlassStorageDetailsService.generateDetails(details, task.getEndSlot());
        int deviceId = details.getDeviceId();
        Integer taskType = task.getTaskType();
@@ -196,7 +210,7 @@
                    .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_CAR));
            log.info("任务状态已更改为:已完成");
            rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                    .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                    .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)
                    .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_SUCCESS));
            switch (taskType) {
                case 1:
@@ -208,7 +222,7 @@
                    break;
                case 2:
                case 4:
                    log.info("2、出片,4、入库请求。{}", taskType);
                    log.info("2、出片,4、吊装位请求。{}", taskType);
                    targetDetails = new RawGlassStorageDetails();
                    targetDetails.setSlot(task.getEndSlot());
                    targetDetails.setDeviceId(deviceId);
@@ -232,21 +246,18 @@
                        .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING, Const.RAW_GLASS_STATE_CAR));
            }
            rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                    .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                    .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING)
                    .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_FAILURE));
        }
        S7Data s7Data = new S7Data();
        s7Data.setConfirmation((short) 1);
        s7Serializer.write(s7Data);
//        List<ReadWriteEntity> list = new ArrayList<>();
//        list.add(generateReadWriteEntity("CC.CC.confirmation", 1));
//        miloService.writeToOpcWord(list);
    }
    private boolean isHasRunningTask() {
        RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>()
                .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW));
                .in(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING));
        return task == null ? Boolean.FALSE : Boolean.TRUE;
    }
@@ -269,55 +280,127 @@
        }
        return Boolean.FALSE;
    }
    /**
     * 处理空架子吊装位请求任务:将仓库的空架子送到吊装位99,等待入库
     *
     * @return
     */
    public boolean inboundRequestTask() throws Exception {
        // 步骤1:查询“未执行的空架子到吊装位请求任务”(类型IN_REQUEST,状态NEW)
        RawGlassStorageTask inRequestTask = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>()
                .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_IN_REQUEST) // 空架子入库请求类型
                .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .last("limit 1")); // 每次处理一个任务,避免冲突
        if (inRequestTask == null) {
            log.info("无待执行的空架子吊装位请求任务");
            return Boolean.FALSE;
        }
        // 步骤2:检查任务关联的空架子状态(需为“待入库”,且确实是空架子)
        RawGlassStorageDetails emptyShelf = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, inRequestTask.getStartSlot()) // 起始位:仓库空架子位
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); // 待入库状态);
        if (emptyShelf == null) {
            log.info("空架子到吊装位请求任务关联的架子异常(非空架子或状态错误),跳过执行");
            return Boolean.FALSE;
        }
        // 步骤3:检查目标吊装位99是否空闲
        List<RawGlassStorageDetails> liftingShelfList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, inRequestTask.getEndSlot()) // 目标位:吊装位99
                .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN_ALL));
        if (CollectionUtil.isNotEmpty(liftingShelfList)) {
            log.info("吊装位{}已有关联架子,无法执行空架子到吊装位请求", inRequestTask.getEndSlot());
            return Boolean.FALSE;
        }
        // 步骤4:更新空架子状态为“执行中”
        rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, emptyShelf.getSlot())
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
                .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
        // 步骤5:更新任务状态为“执行中”,避免重复执行
        rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                .eq(RawGlassStorageTask::getId, inRequestTask.getId())
                .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING));
        // 步骤6:发送PLC指令,驱动空架子从仓库→吊装位
        S7Data s7Data = new S7Data();
        s7Data.setTaskWord((short) 1); // 任务触发信号
        s7Data.setStartSlot((short) inRequestTask.getStartSlot().intValue()); // 起始位:仓库空架子位
        s7Data.setEndSlot((short) inRequestTask.getEndSlot().intValue());     // 目标位:吊装位99
        s7Serializer.write(s7Data);
        log.info("执行空架子到吊装位请求任务:从仓库{}到吊装位{}", inRequestTask.getStartSlot(), inRequestTask.getEndSlot());
        return Boolean.TRUE;
    }
    /**
     * 出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务
     */
    public boolean outboundTask() throws Exception {
        List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT)
                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1"));
        if (CollectionUtil.isEmpty(rawGlassList)) {
            log.info("系统没有需要出库的原片信息");
        // 步骤1:查询已生成的“未执行出库任务”(状态为NEW,类型为OUT)
        RawGlassStorageTask outboundTask = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>()
                .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_OUT)
                .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .last("limit 1")); // 每次处理一个任务
        if (outboundTask == null) {
            log.info("无待执行的出库任务");
            return Boolean.FALSE;
        }
        //获取工位上是否有架子,
        // 步骤2:获取任务关联的架子详情,检查状态是否合法(待出库)
        RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, outboundTask.getStartSlot()) // 任务起始位(仓库位)
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT)); // 待出库状态
        if (details == null) {
            log.info("出库任务关联的架子状态异常,跳过执行");
            return Boolean.FALSE;
        }
        // 步骤3:检查吊装位99是否空闲(无架子)
        List<RawGlassStorageDetails> emptyLeftingList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN_ALL)
                .in(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4"));
        if (CollectionUtil.isNotEmpty(emptyLeftingList) && emptyLeftingList.size() > 1) {
            log.info("吊装位当前都有架子,结束出片任务");
        if (CollectionUtil.isNotEmpty(emptyLeftingList)) {
            log.info("吊装位99当前有架子,无法执行出库任务");
            return Boolean.FALSE;
        }
        //获取需要落架的
        List<Integer> leftingList = emptyLeftingList.stream().map(RawGlassStorageDetails::getSlot).collect(Collectors.toList());
        int lefting = CollectionUtil.isEmpty(leftingList) ? LEFTING_01 : leftingList.get(0).equals(LEFTING_01) ? LEFTING_02 : LEFTING_01;
        Integer startSlot = rawGlassList.get(0).getSlot();
        //生成出库任务
        rawGlassStorageDetailsService.generateTask(startSlot, lefting, startSlot, rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_OUT);
//        List<ReadWriteEntity> list = new ArrayList<>();
//        list.add(generateReadWriteEntity("CC.CC.taskWord", 1));
//        list.add(generateReadWriteEntity("CC.CC.taskSending", 1));
//        list.add(generateReadWriteEntity("CC.CC.startSlot", startSlot));
//        list.add(generateReadWriteEntity("CC.CC.endSlot", lefting));
//        miloService.writeToOpcWord(list);
        //修改出片任务状态
        // 步骤4:更新架子状态为“执行中”
        rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot())
                .eq(RawGlassStorageDetails::getSlot, details.getSlot())
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT)
                .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
        // 步骤5:更新任务状态为“执行中”(避免重复执行)
        rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                .eq(RawGlassStorageTask::getId, outboundTask.getId())
                .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING));
        S7Data s7Data = new S7Data();
        s7Data.setTaskWord((short) 1);
        s7Data.setStartSlot((short) outboundTask.getStartSlot().intValue()); // 仓库存储位(起始位)
        s7Data.setEndSlot((short) outboundTask.getEndSlot().intValue());     // 吊装位99(目标位)
        s7Serializer.write(s7Data);
        return Boolean.TRUE;
    }
    /**
     * 复位任务:1、点复位,立马生成复位任务 2、点出库修改工位详情内的状态为架子复位,定时任务扫描生成复位任务
     */
    public boolean shelfResetTask() throws Exception {
        // 1. 查询“待复位”的架子(状态为RESET,且工位启用)
        List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RESET)
                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1"));
@@ -325,22 +408,35 @@
            log.info("系统没有需要复位的原片信息");
            return Boolean.FALSE;
        }
        //生成复位任务
//        rawGlassStorageDetailsService.generatask(rawGlassList.get(0).getSlot(), rawGlassList.get(0).getShelf(), rawGlassList.get(0).getShelf(), rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
        // 2. 取第一条待复位的架子(每次处理一个)
        RawGlassStorageDetails details = rawGlassList.get(0);
        Integer startSlot = details.getSlot();       // 复位起始位(当前架子所在位)
        Integer targetSlot = details.getShelf();     // 复位目标位(初始仓库存储位)
//        List<ReadWriteEntity> list = new ArrayList<>();
//        list.add(generateReadWriteEntity("CC.CC.taskWord", 1));
//        list.add(generateReadWriteEntity("CC.CC.taskSending", 1));
//        list.add(generateReadWriteEntity("CC.CC.startSlot", startSlot));
//        list.add(generateReadWriteEntity("CC.CC.endSlot", lefting));
//        miloService.writeToOpcWord(list);
        // 3. 生成复位任务(类型建议单独定义:如Const.RAW_GLASS_TASK_TYPE_RESET,避免与调度任务混淆)
        rawGlassStorageDetailsService.generateTask(
                startSlot,
                targetSlot,
                targetSlot,
                details.getRemainQuantity(),
                Const.RAW_GLASS_TASK_TYPE_DISPATCH
        );
        //修改复位任务状态
        // 4. 更新架子状态为“执行中”
        rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot())
                .eq(RawGlassStorageDetails::getSlot, startSlot)
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RESET)
                .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
        // 5. 补充PLC交互:发送复位指令
        S7Data s7Data = new S7Data();
        s7Data.setTaskWord((short) 1); // 任务触发信号
        s7Data.setStartSlot((short) startSlot.intValue()); // 起始位:当前架子位
        s7Data.setEndSlot((short) targetSlot.intValue());   // 目标位:初始仓库位
        s7Serializer.write(s7Data);
        log.info("执行架子复位任务:从{}到{}", startSlot, targetSlot);
        return Boolean.TRUE;
    }
@@ -350,32 +446,49 @@
     * @throws Exception
     */
    public boolean warehouseTask() throws Exception {
        List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
                .gt(RawGlassStorageDetails::getRemainQuantity, 0)
                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4")
                .inSql(RawGlassStorageDetails::getShelf, "select slot from raw_glass_storage_station where enable_state = 1 "));
        if (CollectionUtil.isEmpty(rawGlassList)) {
            log.info("吊装位被禁用/架子所在工位被禁用/无原片信息");
            return Boolean.FALSE;
//        List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
//                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
//                .gt(RawGlassStorageDetails::getRemainQuantity, 0)
//                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4")
//                .inSql(RawGlassStorageDetails::getShelf, "select slot from raw_glass_storage_station where enable_state = 1 "));
//        if (CollectionUtil.isEmpty(rawGlassList)) {
//            log.info("吊装位被禁用/架子所在工位被禁用/无原片信息");
//            return Boolean.FALSE;
//        }
        // 查询回库任务
        RawGlassStorageTask task = rawGlassStorageTaskService.getOne(new LambdaQueryWrapper<RawGlassStorageTask>()
                .in(RawGlassStorageTask::getTaskType,  Const.RAW_GLASS_TASK_TYPE_IN)
                .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .last("limit 1"));
        if (task == null) {
            log.info("无待执行的回库任务");
            return false;
        }
        //生成进笼任务
        RawGlassStorageDetails details = rawGlassList.get(0);
        rawGlassStorageDetailsService.generateTask(details.getSlot(), details.getShelf(), details.getShelf(),
                details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_IN);
        RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, task.getStartSlot()) // 任务起始位(吊装位)
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING)); // 已标记为执行中
        if (details == null) {
            log.info("任务关联的架子状态异常,跳过执行");
            return false;
        }
        rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                .eq(RawGlassStorageTask::getId, task.getId())
                .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING));
        log.info("执行回库任务:从{}到{}", task.getStartSlot(), task.getEndSlot());
//        List<ReadWriteEntity> list = new ArrayList<>();
//        list.add(generateReadWriteEntity("CC.CC.taskWord", 1));
//        list.add(generateReadWriteEntity("CC.CC.taskSending", 1));
//        list.add(generateReadWriteEntity("CC.CC.startSlot", details.getSlot()));
//        list.add(generateReadWriteEntity("CC.CC.endSlot", details.getShelf()));
//        miloService.writeToOpcWord(list);
        //生成工位任务,将吊装位的玻璃状态改位进笼中
        //修改吊装位的原片状态为103 出片中
        //修改出片任务状态
        rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot())
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
                .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
        S7Data s7Data = new S7Data();
        s7Data.setTaskWord((short) 1);
        s7Data.setStartSlot((short) details.getSlot().intValue());
        s7Data.setEndSlot((short) details.getShelf().intValue());
        s7Serializer.write(s7Data);
        return Boolean.TRUE;
    }
@@ -397,12 +510,13 @@
                .collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber));
        List<UpPattenUsageVO> usageVOS = upListMap.get("1");
        //获取当前上片位1号架子信息
        List<Integer> loadStation = LOAD_GLASS_ONE_DEVICE.equals(stationCell) ? LOAD_STATION_01 : LOAD_STATION_02;
        List<Integer> loadStation = LOAD_STATION_01;
        List<RawGlassStorageStation> stations = rawGlassStorageStationService.list(new LambdaQueryWrapper<RawGlassStorageStation>()
                .in(RawGlassStorageStation::getSlot, loadStation)
                .eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON).orderByAsc(RawGlassStorageStation::getSlot));
                .eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON)
                .orderByAsc(RawGlassStorageStation::getSlot));
        if (CollectionUtils.isEmpty(stations)) {
            log.info("没有可用的上片位");
            log.info("101的上片位不可用");
            return Boolean.FALSE;
        }
@@ -410,160 +524,77 @@
                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1")
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                .eq(RawGlassStorageDetails::getDeviceId, stationCell));
        if (stations.size() == 1) {
            if (CollectionUtils.isEmpty(loadStationList)) {
                RawGlassStorageDetails rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size());
                rawGlassStorageDetailsService.generateTask(rawDetails.getSlot(), stations.get(0).getSlot(), rawDetails.getShelf(), rawDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101  目标位新增一条数据,架子号为(起始位)
                rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                        .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                        .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                return Boolean.TRUE;
            }
            RawGlassStorageDetails oneLoadStation = loadStationList.get(0);
            if (oneLoadStation.getRemainQuantity() <= 0 || !compareRawSize(usageVOS.get(0), oneLoadStation)) {
                rawGlassStorageDetailsService.generateTask(stations.get(0).getSlot(), oneLoadStation.getShelf(), oneLoadStation.getShelf(), oneLoadStation.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                        .eq(RawGlassStorageDetails::getSlot, oneLoadStation.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                        .set(RawGlassStorageDetails::getDeviceId, Const.RAW_GLASS_STATE_RUNNING));
                return Boolean.FALSE;
            }
        }
        log.info("获取{}上片线的工位信息{}", stationCell, loadStationList);
        if (CollectionUtils.isEmpty(loadStationList)) {
            log.info("1号上片位生成调度任务");
            RawGlassStorageDetails rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size());
            if (CollectionUtils.isEmpty(loadStationList)) {
                log.info("仓库内无匹配的玻璃");
            if (rawDetails == null) {
                log.info("仓库无匹配规格的原片,无法调度到101工位");
                return Boolean.FALSE;
            }
            rawGlassStorageDetailsService.generateTask(rawDetails.getSlot(), loadStation.get(0), rawDetails.getShelf(), rawDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
            //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101  目标位新增一条数据,架子号为(起始位)
            // 生成调度任务:仓库原片位 → 101上片位
            rawGlassStorageDetailsService.generateTask(
                    rawDetails.getSlot(),
                    stations.get(0).getSlot(),
                    rawDetails.getShelf(),
                    rawDetails.getRemainQuantity(),
                    Const.RAW_GLASS_TASK_TYPE_DISPATCH);
            rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                    .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_DISPATCH)
                    .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                    .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING));
            rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                    .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                    .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot())
                    .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                    .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
            S7Data s7Data = new S7Data();
            s7Data.setTaskWord((short) 1);
            s7Data.setStartSlot((short) rawDetails.getSlot().intValue()); // 起始位:仓库
            s7Data.setEndSlot((short) LOAD_STATION_01.get(0).intValue()); // 目标位:上片位101
            s7Serializer.write(s7Data); // 发送到PLC
            log.info("调度任务已发送PLC:从仓库{}到上片位{}", rawDetails.getSlot(), LOAD_STATION_01);
            return Boolean.TRUE;
        }
        RawGlassStorageDetails oneLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(0))).findFirst().orElse(null);
        if (null == oneLoadStation) {
            RawGlassStorageDetails twoLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(1))).findFirst().orElse(null);
            if (twoLoadStation.getRemainQuantity() > 0) {
                if (compareRawSize(usageVOS.get(0), twoLoadStation)) {
//                    2号上片位的原片信息源工程信息一致,可上片操作,结束本次任务
                    return Boolean.FALSE;
                } else {
//                    生成1号位入库任务
                    log.info("2号上片位玻璃尺寸不一致,1号上片位生成调度任务");
                    //按照尺寸及数量获取数量最接近的格子信息
                    RawGlassStorageDetails rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size());
                    if (null == rawDetails) {
                        log.info("仓库内无需要上架的玻璃");
                        return Boolean.FALSE;
                    }
                    rawGlassStorageDetailsService.generateTask(rawDetails.getSlot(), loadStation.get(0), rawDetails.getShelf(), rawDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                    //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101  目标位新增一条数据,架子号为(起始位)
                    rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                            .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                            .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                    return Boolean.TRUE;
                }
            } else {
//                生成1号位入库任务
                log.info("2号上片位仅剩空架子,1号上片位生成调度任务");
                RawGlassStorageDetails rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size());
                rawGlassStorageDetailsService.generateTask(rawDetails.getSlot(), loadStation.get(0), rawDetails.getShelf(), rawDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                        .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                        .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                return Boolean.TRUE;
            }
        } else {
            String tableName = stationCell == 5 ? LOAD_GLASS_DEVICE_ONE_TASK : LOAD_GLASS_DEVICE_TWO_TASK;
            if (oneLoadStation.getRemainQuantity() > 0) {
                if (compareRawSize(usageVOS.get(0), oneLoadStation)) {
                    //结束仓储调度,等待上片任务
                    //在上片任务执行空闲过程中,可执行二号位出入库任务  二号架子的信息是否需要调度,不需要调度直接放回false
                    log.info("获取二号位原片信息");
                    RawGlassStorageDetails twoLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(1))).findFirst().orElse(null);
                    if (null == twoLoadStation) {
                        //按照尺寸生成二号位上片任务信息
                        LoadGlassDeviceTask loadTask = loadGlassDeviceTaskService.queryTaskMessage(tableName);
                        RawGlassStorageDetails rawDetails = null;
                        if (oneLoadStation.getRemainQuantity() > (loadTask.getTotalCount() + loadTask.getDamageCount())) {
                            usageVOS = upListMap.get("2");
                            if (CollectionUtils.isEmpty(usageVOS)) {
                                log.info("当前工程的原片即将用完,结束本次调度");
                                return Boolean.FALSE;
                            }
                            rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size());
                        } else {
                            rawDetails = getRawGlassStorageDetailsBySize(usageVOS.get(0), usageVOS.size());
        // 上片位101有玻璃 → 判断尺寸是否匹配
        RawGlassStorageDetails oneLoadStation = loadStationList.get(0);
        if (oneLoadStation.getRemainQuantity() <= 0 || !compareRawSize(usageVOS.get(0), oneLoadStation)) {
                        }
                        if (null == rawDetails) {
                            log.info("原片仓储没有相同尺寸的玻璃");
                            return Boolean.FALSE;
                        }
                        rawGlassStorageDetailsService.generateTask(rawDetails.getSlot(), loadStation.get(1), rawDetails.getShelf(), rawDetails.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                        //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101  目标位新增一条数据,架子号为(起始位)
                        rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                                .eq(RawGlassStorageDetails::getSlot, rawDetails.getSlot()).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                                .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                        return Boolean.TRUE;
                    } else {
                        //todo:当二号为的尺寸大于0时,是否执行调度任务,更换当前原片的尺寸,等待下一次任务的直接执行;还是继续等待,当尺寸不一样,等待一号工位的进出库调度任务。
                        if (twoLoadStation.getRemainQuantity() > 0) {
                            LoadGlassDeviceTask loadTask = loadGlassDeviceTaskService.queryTaskMessage(tableName);
                            if (oneLoadStation.getRemainQuantity() > (loadTask.getTotalCount() + loadTask.getDamageCount())) {
                                usageVOS = upListMap.get("2");
                                if (CollectionUtils.isEmpty(usageVOS)) {
                                    log.info("当前工程的原片即将用完,结束本次调度");
                                    return Boolean.FALSE;
                                }
                            }
                            if (compareRawSize(usageVOS.get(0), twoLoadStation)) {
//                              //2号上片位的原片信息源工程信息一致,可上片操作,结束本次任务
                                return Boolean.FALSE;
                            } else {
//                    生成1号位入库任务
                                log.info("2号上片位玻璃尺寸不一致,2号上片位生成出片调度任务");
                                //按照尺寸及数量获取数量最接近的格子信息
                                rawGlassStorageDetailsService.generateTask(loadStation.get(1), twoLoadStation.getShelf(), twoLoadStation.getShelf(), twoLoadStation.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                                //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101  目标位新增一条数据,架子号为(起始位)
                                rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                                        .eq(RawGlassStorageDetails::getSlot, loadStation.get(1)).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                                        .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                                return Boolean.TRUE;
                            }
                        } else {
                            //todo:生成出库任务
                            rawGlassStorageDetailsService.generateTask(loadStation.get(1), twoLoadStation.getShelf(), twoLoadStation.getShelf(), twoLoadStation.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                            //结束调度任务 修改工位状态(起始位)状态为103 RAW_GLASS_STATE_RUNNING 任务完成后将状态改为101  目标位新增一条数据,架子号为(起始位)
                            rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                                    .eq(RawGlassStorageDetails::getSlot, loadStation.get(1)).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                                    .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                            return Boolean.TRUE;
                        }
                    }
//                    return Boolean.FALSE;
                } else {
                    log.info("2号上片位仅剩空架子,1号上片位生成出库调度任务");
                    rawGlassStorageDetailsService.generateTask(loadStation.get(0), oneLoadStation.getShelf(), oneLoadStation.getShelf(), oneLoadStation.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                    rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                            .eq(RawGlassStorageDetails::getSlot, loadStation.get(0)).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                            .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                    return Boolean.TRUE;
                }
            } else {
                log.info("1号上片位玻璃尺寸不一致,1号上片位生成出库调度任务");
                rawGlassStorageDetailsService.generateTask(loadStation.get(0), oneLoadStation.getSlot(), oneLoadStation.getShelf(), oneLoadStation.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                        .eq(RawGlassStorageDetails::getSlot, loadStation.get(0)).eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                        .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
                return Boolean.TRUE;
            // 检查上片机是否正在工作,若正在工作则不生成退回任务
            if (pattenUsageList.stream().allMatch(vo -> vo.getState() == 101)) {
                log.warn("上片机{}正在工作,无法执行退回任务", stationCell);
                return Boolean.FALSE;
            }
            // 生成退回任务:101上片位 → 原仓库存储位
            rawGlassStorageDetailsService.generateTask(
                    stations.get(0).getSlot(),
                    oneLoadStation.getShelf(),
                    oneLoadStation.getShelf(),
                    oneLoadStation.getRemainQuantity(),
                    Const.RAW_GLASS_TASK_TYPE_DISPATCH);
            rawGlassStorageTaskService.update(new LambdaUpdateWrapper<RawGlassStorageTask>()
                    .eq(RawGlassStorageTask::getTaskType, Const.RAW_GLASS_TASK_TYPE_DISPATCH)
                    .eq(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_NEW)
                    .set(RawGlassStorageTask::getTaskState, Const.RAW_GLASS_TASK_RUNNING));
            rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
                    .eq(RawGlassStorageDetails::getSlot, oneLoadStation.getSlot())
                    .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                    .set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
            S7Data s7Data = new S7Data();
            s7Data.setTaskWord((short) 1); // 任务触发信号
            s7Data.setStartSlot((short) LOAD_STATION_01.get(0).intValue()); // 起始位:上片位101
            s7Data.setEndSlot((short) oneLoadStation.getShelf().intValue()); // 目标位:仓库
            s7Serializer.write(s7Data); // 发送到PLC
            log.info("退回任务已发送PLC:从上片位{}到仓库{}", LOAD_STATION_01, oneLoadStation.getShelf());
            return Boolean.FALSE;
        }
        // 上片位101玻璃尺寸匹配且数量充足 → 无需调度
        log.info("101工位玻璃尺寸匹配且数量充足,无需调度");
        return Boolean.FALSE;
    }
    private ReadWriteEntity generateReadWriteEntity(String identifier, int value) {
@@ -579,7 +610,7 @@
                .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth())
                .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight())
                .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness())
                .notIn(RawGlassStorageDetails::getSlot, LOAD_STATION_ALL)
                .notIn(RawGlassStorageDetails::getSlot, LOAD_STATION_01)
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
                .orderByAsc(RawGlassStorageDetails::getRemainQuantity)
                .last("order by abs(t.remain_quantity - " + remainQuantity + ")  asc")