#
Administrator
2026-04-25 faaf77b2ed6609e1ec159f163cb97c79f37df532
src/main/java/com/zy/core/thread/impl/ZySiemensDualCrnThread.java
@@ -9,6 +9,7 @@
import com.zy.asrs.entity.*;
import com.zy.asrs.service.BasDualCrnpOptService;
import com.zy.asrs.service.BasDualCrnpService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
@@ -20,6 +21,7 @@
import com.zy.core.model.StationObjModel;
import com.zy.core.model.Task;
import com.zy.core.model.command.DualCrnCommand;
import com.zy.core.model.param.SendDualCrnCommandParam;
import com.zy.core.model.protocol.DualCrnProtocol;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.network.DeviceConnectPool;
@@ -31,10 +33,8 @@
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import com.zy.asrs.entity.BasDualCrnpErrLog;
import com.zy.asrs.service.BasDualCrnpErrLogService;
@@ -49,7 +49,7 @@
    private RedisUtil redisUtil;
    private ZyDualCrnConnectDriver zyDualCrnConnectDriver;
    private DualCrnProtocol crnProtocol;
    private int deviceLogCollectTime = 200;
    private volatile int deviceLogCollectTime = 200;
    public ZySiemensDualCrnThread(DeviceConfig deviceConfig, RedisUtil redisUtil) {
        this.deviceConfig = deviceConfig;
@@ -85,14 +85,17 @@
                    }
                    if (step == 2) {
                        List<DualCrnCommand> commandList = (List<DualCrnCommand>) task.getData();
                        DualCrnCommand command = commandList.get(0);
                        HashMap<String, Object> map = new HashMap<>();
                        map.put("commands", commandList);
                        map.put("idx", 1);
                        redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_.key + command.getTaskNo(), JSON.toJSONString(map, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24);
                        sendCommand(command);
                        List<SendDualCrnCommandParam> commandList = (List<SendDualCrnCommandParam>) task.getData();
                        for (SendDualCrnCommandParam sendDualCrnCommandParam : commandList) {
                            DualCrnCommand dualCrnCommand = sendDualCrnCommandParam.getCommands().get(0);
                            redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_IDX.key + dualCrnCommand.getTaskNo(), 0, 60 * 60 * 24);
                            redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_.key + dualCrnCommand.getTaskNo(), JSON.toJSONString(sendDualCrnCommandParam, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24);
                            if (sendDualCrnCommandParam.getStation() == 1) {
                                redisUtil.set(RedisKeyType.DUAL_CRN_STATION1_FLAG.key + crnProtocol.getCrnNo(), dualCrnCommand.getTaskNo(), 60 * 60 * 24);
                            } else {
                                redisUtil.set(RedisKeyType.DUAL_CRN_STATION2_FLAG.key + crnProtocol.getCrnNo(), dualCrnCommand.getTaskNo(), 60 * 60 * 24);
                            }
                        }
                    } else if (step == 3) {
                        sendCommand((DualCrnCommand) task.getData());
                    }
@@ -108,116 +111,229 @@
        Thread commandThread = new Thread(() -> {
            while (true) {
                try {
                    if(crnProtocol.getMode() != DualCrnModeType.AUTO.id) {
                        continue;
                    }
                    if(crnProtocol.getAlarm() != 0) {
                        continue;
                    }
                    if (crnProtocol.getLoaded() == 1 && crnProtocol.getLoadedTwo() == 1) {
                        Object wait = redisUtil.get(RedisKeyType.DUAL_CRN_PICK_WAIT_NEXT_TASK.key + crnProtocol.getCrnNo());
                        if (wait != null) {
                            redisUtil.del(RedisKeyType.DUAL_CRN_PICK_WAIT_NEXT_TASK.key + crnProtocol.getCrnNo());
                        }
                    }
                    if(crnProtocol.getTaskNo() > 0 && crnProtocol.getStatus().equals(DualCrnStatusType.FETCH_COMPLETE.id)) {
                        Integer taskNo = crnProtocol.getTaskNo();
                        Object commandObj = redisUtil.get(RedisKeyType.DUAL_CRN_COMMAND_.key + taskNo);
                        if (commandObj == null) {
                            News.error("双工位堆垛机,工位1空闲等待下发命令,但未找到命令。堆垛机号={},工作号={}", crnProtocol.getCrnNo(), taskNo);
                            continue;
                        }
                        JSONObject commandMap = JSON.parseObject(commandObj.toString());
                        Integer idx = commandMap.getInteger("idx");
                        List<DualCrnCommand> commandList = commandMap.getJSONArray("commands").toJavaList(DualCrnCommand.class);
                        if (idx >= commandList.size()) {
                            continue;
                        }
                        DualCrnCommand dualCommand = commandList.get(idx);
                        if (dualCommand.getTaskMode() == DualCrnTaskModeType.PUT.id.shortValue()) {
                            //等待下一个任务
                            Object wait = redisUtil.get(RedisKeyType.DUAL_CRN_PICK_WAIT_NEXT_TASK.key + crnProtocol.getCrnNo());
                            if (wait != null) {
                                continue;
                            }
                            Object outTaskStationInfoObj = redisUtil.get(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + taskNo);
                            if (outTaskStationInfoObj != null) {
                                //检测出口站是否可执行放货动作
                                StationObjModel stationObjModel = JSON.parseObject(outTaskStationInfoObj.toString(), StationObjModel.class);
                                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                                if (stationThread == null) {
                                    continue;
                                }
                                Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
                                StationProtocol stationProtocol = statusMap.get(stationObjModel.getStationId());
                                if (stationProtocol == null) {
                                    continue;
                                }
                                if (!stationProtocol.isAutoing()) {
                                    continue;
                                }
                                if (stationProtocol.isLoading()) {
                                    continue;
                                }
                                if (stationProtocol.getTaskNo() > 0) {
                                    continue;
                                }
                            }
                        }
                        idx++;
                        commandMap.put("idx", idx);
                        sendCommand(dualCommand);
                        redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_.key + taskNo, commandMap.toJSONString(), 60 * 60 * 24);
                    }
                    if(crnProtocol.getTaskNoTwo() > 0 && crnProtocol.getStatusTwo() == DualCrnStatusType.IDLE.id) {
                        Integer taskNo = crnProtocol.getTaskNoTwo();
                        Object commandObj = redisUtil.get(RedisKeyType.DUAL_CRN_COMMAND_.key + taskNo);
                        if (commandObj == null) {
                            News.error("双工位堆垛机,工位2空闲等待下发命令,但未找到命令。堆垛机号={},工作号={}", crnProtocol.getCrnNo(), taskNo);
                            continue;
                        }
                        JSONObject commandMap = JSON.parseObject(commandObj.toString());
                        Integer idx = commandMap.getInteger("idx");
                        List<DualCrnCommand> commandList = commandMap.getJSONArray("commands").toJavaList(DualCrnCommand.class);
                        if (idx >= commandList.size()) {
                            continue;
                        }
                        DualCrnCommand dualCommand = commandList.get(idx);
                        if (dualCommand.getTaskMode() == DualCrnTaskModeType.PUT.id.shortValue()) {
                            //等待下一个任务
                            Object wait = redisUtil.get(RedisKeyType.DUAL_CRN_PICK_WAIT_NEXT_TASK.key + crnProtocol.getCrnNo());
                            if (wait != null) {
                                continue;
                            }
                        }
                        idx++;
                        commandMap.put("idx", idx);
                        sendCommand(dualCommand);
                        redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_.key + taskNo, commandMap.toJSONString(), 60 * 60 * 24);
                    }
                    Thread.sleep(100);
                    if (crnProtocol.getMode() != DualCrnModeType.AUTO.id) {
                        continue;
                    }
                    if (crnProtocol.getAlarm() != 0) {
                        continue;
                    }
                    if (!((crnProtocol.getStatusType().equals(DualCrnStatusType.IDLE) || crnProtocol.getStatusType().equals(DualCrnStatusType.FETCH_COMPLETE))
                            && (crnProtocol.getStatusTypeTwo().equals(DualCrnStatusType.IDLE) || crnProtocol.getStatusTypeTwo().equals(DualCrnStatusType.FETCH_COMPLETE)))
                    ) {
                        continue;
                    }
                    List<SendDualCrnCommandParam> commandList = getDualCrnCommandList();
                    for (SendDualCrnCommandParam commandParam : commandList) {
                        processStation(commandParam);
                    }
                } catch (Exception e) {
                    log.error("DualCrnCommand Fail", e);
                }
            }
        });
        commandThread.start();
    }
    private void processStation(SendDualCrnCommandParam commandParam) {
        Integer station = commandParam.getStation();
        List<DualCrnCommand> commandList = commandParam.getCommands();
        DualCrnCommand firstCommand = commandList.get(0);
        Object idxObj = redisUtil.get(RedisKeyType.DUAL_CRN_COMMAND_IDX.key + firstCommand.getTaskNo());
        if (idxObj == null) {
            return;
        }
        Integer idx = (Integer) idxObj;
        if (idx >= commandList.size()) {
            return;
        }
        DualCrnCommand dualCommand = commandList.get(idx);
        boolean send = false;
        //TODO 判断站点1,2任务类型是否一致
        if (station == 1) {
            log.info("工位2任务==========>{}, 任务模式---->{}", crnProtocol.getTaskNoTwo(), crnProtocol.getMode());
            log.info("工位1任务==========>{}, 任务模式---->{}", crnProtocol.getTaskNo(), crnProtocol.getMode());
            Integer taskNo = crnProtocol.getTaskNoTwo();
            if (crnProtocol.getTaskSend() == 0) {
                //两个工位只允许放相同类型任务
//                if (taskNo != null && taskNo > 0) {
//                    WrkMastService mastService = SpringUtils.getBean(WrkMastService.class);
//                    WrkMast wrkMast = mastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", taskNo));
//                    WrkMast wrkMast1 = mastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", dualCommand.getTaskNo()));
//                    if (!Objects.isNull(wrkMast) && !Objects.isNull(wrkMast1)) {
//                        if (wrkMast1.getIoType() != wrkMast.getIoType()) {
////                            return;
//                        }
//                    }
//                }
                // && sendComm(taskNo, dualCommand.getTaskNo())
                if (dualCommand.getTaskMode().intValue() == DualCrnTaskModeType.PICK.id) {
                    if (crnProtocol.getStatus().equals(DualCrnStatusType.IDLE.id)) {
                        send = true;
                    } else {
                        logDualCrnWaitLimited("pick_station1_" + crnProtocol.getCrnNo(), 3,
                                "[WCS Trace][双工位入库] 工位1取货命令等待发送。crnNo={}, idx={}, taskNo1={}, taskNo2={}, status1={}({}), status2={}({}), taskSend1={}, taskSend2={}, nextTaskMode={}",
                                crnProtocol.getCrnNo(), idx, crnProtocol.getTaskNo(), crnProtocol.getTaskNoTwo(),
                                crnProtocol.getStatus(), crnProtocol.getStatusType(),
                                crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(),
                                crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo(), dualCommand.getTaskMode());
                    }
                } else if (dualCommand.getTaskMode().intValue() == DualCrnTaskModeType.PUT.id) {
                    if (crnProtocol.getStatus().equals(DualCrnStatusType.FETCH_COMPLETE.id)) {
                        send = true;
                    } else {
                        logDualCrnWaitLimited("put_station1_status_" + crnProtocol.getCrnNo(), 3,
                                "[WCS Trace][双工位入库] 工位1放货命令等待FETCH_COMPLETE。crnNo={}, idx={}, currentTaskNo={}, status1={}({}), status2={}({}), taskSend1={}, taskSend2={}, taskReceive1={}, taskReceive2={}, loaded1={}, loaded2={}",
                                crnProtocol.getCrnNo(), idx, dualCommand.getTaskNo(),
                                crnProtocol.getStatus(), crnProtocol.getStatusType(),
                                crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(),
                                crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo(),
                                crnProtocol.getTaskReceive(), crnProtocol.getTaskReceiveTwo(),
                                crnProtocol.getLoaded(), crnProtocol.getLoadedTwo());
                    }
                }
            } else {
                logDualCrnWaitLimited("station1_tasksend_" + crnProtocol.getCrnNo(), 3,
                        "[WCS Trace][双工位入库] 工位1命令等待taskSend清零。crnNo={}, idx={}, taskSend1={}, taskSend2={}, status1={}({}), status2={}({}), nextTaskMode={}",
                        crnProtocol.getCrnNo(), idx, crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo(),
                        crnProtocol.getStatus(), crnProtocol.getStatusType(),
                        crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(), dualCommand.getTaskMode());
            }
        } else {
            log.info("工位1任务==========>{}, 任务模式---->{}", crnProtocol.getTaskNo(), crnProtocol.getMode());
            log.info("工位2任务==========>{}, 任务模式---->{}", crnProtocol.getTaskNoTwo(), crnProtocol.getMode());
            Integer taskNo = crnProtocol.getTaskNo();
            // && sendComm(taskNo, dualCommand.getTaskNo())
            if (crnProtocol.getTaskSendTwo() == 0) {
                if (dualCommand.getTaskMode().intValue() == DualCrnTaskModeType.PICK.id) {
                    if (crnProtocol.getStatusTwo().equals(DualCrnStatusType.IDLE.id)) {
                        send = true;
                    } else {
                        logDualCrnWaitLimited("pick_station2_" + crnProtocol.getCrnNo(), 3,
                                "[WCS Trace][双工位入库] 工位2取货命令等待发送。crnNo={}, idx={}, taskNo1={}, taskNo2={}, status1={}({}), status2={}({}), taskSend1={}, taskSend2={}, nextTaskMode={}",
                                crnProtocol.getCrnNo(), idx, crnProtocol.getTaskNo(), crnProtocol.getTaskNoTwo(),
                                crnProtocol.getStatus(), crnProtocol.getStatusType(),
                                crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(),
                                crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo(), dualCommand.getTaskMode());
                    }
                } else if (dualCommand.getTaskMode().intValue() == DualCrnTaskModeType.PUT.id) {
                    if (crnProtocol.getStatusTwo().equals(DualCrnStatusType.FETCH_COMPLETE.id)) {
                        send = true;
                    } else {
                        logDualCrnWaitLimited("put_station2_status_" + crnProtocol.getCrnNo(), 3,
                                "[WCS Trace][双工位入库] 工位2放货命令等待FETCH_COMPLETE。crnNo={}, idx={}, currentTaskNo={}, status1={}({}), status2={}({}), taskSend1={}, taskSend2={}, taskReceive1={}, taskReceive2={}, loaded1={}, loaded2={}",
                                crnProtocol.getCrnNo(), idx, dualCommand.getTaskNo(),
                                crnProtocol.getStatus(), crnProtocol.getStatusType(),
                                crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(),
                                crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo(),
                                crnProtocol.getTaskReceive(), crnProtocol.getTaskReceiveTwo(),
                                crnProtocol.getLoaded(), crnProtocol.getLoadedTwo());
                    }
                }
            } else {
                logDualCrnWaitLimited("station2_tasksend_" + crnProtocol.getCrnNo(), 3,
                        "[WCS Trace][双工位入库] 工位2命令等待taskSend清零。crnNo={}, idx={}, taskSend1={}, taskSend2={}, status1={}({}), status2={}({}), nextTaskMode={}",
                        crnProtocol.getCrnNo(), idx, crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo(),
                        crnProtocol.getStatus(), crnProtocol.getStatusType(),
                        crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(), dualCommand.getTaskMode());
            }
        }
        if (idx == 0) {
            if (send) {
                idx++;
                redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_IDX.key + firstCommand.getTaskNo(), idx, 60 * 60 * 24);
                sendCommand(dualCommand);
                redisUtil.set(RedisKeyType.DUAL_CRN_PICK_WAIT_NEXT_TASK.key + crnProtocol.getCrnNo(), "lock", 3);
            }
            return;
        } else {
            if (dualCommand.getTaskMode() == DualCrnTaskModeType.PUT.id.shortValue()) {
                //等待下一个任务
                Object wait = redisUtil.get(RedisKeyType.DUAL_CRN_PICK_WAIT_NEXT_TASK.key + crnProtocol.getCrnNo());
                if (wait != null) {
                    logDualCrnWaitLimited("put_wait_lock_" + crnProtocol.getCrnNo(), 2,
                            "[WCS Trace][双工位入库] 放货命令被取货等待锁拦住。crnNo={}, idx={}, station={}, currentTaskNo={}, status1={}({}), status2={}({}), taskSend1={}, taskSend2={}",
                            crnProtocol.getCrnNo(), idx, station, dualCommand.getTaskNo(),
                            crnProtocol.getStatus(), crnProtocol.getStatusType(),
                            crnProtocol.getStatusTwo(), crnProtocol.getStatusTypeTwo(),
                            crnProtocol.getTaskSend(), crnProtocol.getTaskSendTwo());
                    return;
                }
                Integer taskNo = dualCommand.getTaskNo();
                Object outTaskStationInfoObj = redisUtil.get(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + taskNo);
                if (outTaskStationInfoObj != null) {
                    //检测出口站是否可执行放货动作
                    StationObjModel stationObjModel = JSON.parseObject(outTaskStationInfoObj.toString(), StationObjModel.class);
                    StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                    if (stationThread == null) {
                        return;
                    }
                    Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
                    StationProtocol stationProtocol = statusMap.get(stationObjModel.getStationId());
                    if (stationProtocol == null) {
                        return;
                    }
                    if (!stationProtocol.isAutoing()) {
                        return;
                    }
                    if (stationProtocol.isLoading()) {
                        return;
                    }
                    if (stationProtocol.getTaskNo() > 0) {
                        return;
                    }
                }
            }
            if (send) {
                idx++;
                redisUtil.set(RedisKeyType.DUAL_CRN_COMMAND_IDX.key + firstCommand.getTaskNo(), idx, 60 * 60 * 24);
                sendCommand(dualCommand);
            }
            return;
        }
    }
    private void logDualCrnWaitLimited(String lockKey, int seconds, String format, Object... arguments) {
        String redisKey = RedisKeyType.LOG_LIMIT.key + "dual_crn_wait_" + lockKey;
        try {
            Object lock = redisUtil.get(redisKey);
            if (lock != null) {
                return;
            }
            redisUtil.set(redisKey, "lock", seconds);
        } catch (Exception e) {
            // 诊断日志不能影响主流程。
        }
        News.info(format, arguments);
    }
    public boolean sendComm(Integer taskNo, Integer current) {
        //两个工位只允许放相同类型任务
        if (taskNo != null && taskNo > 0) {
            WrkMastService mastService = SpringUtils.getBean(WrkMastService.class);
            WrkMast wrkMast = mastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", taskNo));
            WrkMast wrkMast1 = mastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", current));
            if (!Objects.isNull(wrkMast) && !Objects.isNull(wrkMast1)) {
                if (wrkMast1.getIoType() != wrkMast.getIoType()) {
                    return false;
                }
            }
        }
        return true;
    }
    /**
@@ -232,6 +348,7 @@
        //工位1
        crnProtocol.setTaskNo(0);
        crnProtocol.setDeviceTaskNo(0);
        crnProtocol.setStatus(-1);
        crnProtocol.setBay(0);
        crnProtocol.setLevel(0);
@@ -242,6 +359,7 @@
        //工位2
        crnProtocol.setTaskNoTwo(0);
        crnProtocol.setDeviceTaskNoTwo(0);
        crnProtocol.setStatusTwo(-1);
        crnProtocol.setBayTwo(0);
        crnProtocol.setLevelTwo(0);
@@ -262,12 +380,12 @@
        BasDualCrnpService basDualCrnpService = null;
        try {
            basDualCrnpService = SpringUtils.getBean(BasDualCrnpService.class);
        }catch (Exception e){
        } catch (Exception e) {
        }
        if (basDualCrnpService != null) {
            BasDualCrnp basDualCrnp = basDualCrnpService.selectOne(new EntityWrapper<BasDualCrnp>().eq("crn_no", deviceConfig.getDeviceNo()));
            if(basDualCrnp == null) {
            if (basDualCrnp == null) {
                basDualCrnp = new BasDualCrnp();
                basDualCrnp.setCrnNo(deviceConfig.getDeviceNo());
                basDualCrnp.setStatus(1);
@@ -292,7 +410,7 @@
    /**
     * 读取状态
     */
    private void readStatus(){
    private void readStatus() {
        ZyDualCrnStatusEntity crnStatus = zyDualCrnConnectDriver.getStatus();
        if (crnStatus == null) {
            OutputQueue.DUAL_CRN.offer(MessageFormat.format("【{0}】读取双工位堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort()));
@@ -301,18 +419,20 @@
        crnProtocol.setMode(crnStatus.getMode());
        //工位1
        crnProtocol.setTaskNo(crnStatus.getTaskNo());
        crnProtocol.setDeviceTaskNo(crnStatus.getTaskNo());
        crnProtocol.setStatus(crnStatus.getStatus());
        crnProtocol.setForkPos(crnStatus.getForkPos());
        crnProtocol.setLoaded(crnStatus.getLoaded());
        crnProtocol.setTaskReceive(crnStatus.getTaskReceive());
        crnProtocol.setTaskSend(crnStatus.getTaskSend());
        //工位2
        crnProtocol.setTaskNoTwo(crnStatus.getTaskNoTwo());
        crnProtocol.setDeviceTaskNoTwo(crnStatus.getTaskNoTwo());
        crnProtocol.setStatusTwo(crnStatus.getStatusTwo());
        crnProtocol.setForkPosTwo(crnStatus.getForkPosTwo());
        crnProtocol.setLoadedTwo(crnStatus.getLoadedTwo());
        crnProtocol.setTaskReceiveTwo(crnStatus.getTaskReceiveTwo());
        crnProtocol.setTaskSendTwo(crnStatus.getTaskSendTwo());
        crnProtocol.setBay(crnStatus.getBay());
        crnProtocol.setLevel(crnStatus.getLevel());
@@ -333,7 +453,7 @@
        crnProtocol.setGoodsType(crnStatus.getGoodsType());
        crnProtocol.setBarcode(crnStatus.getBarcode());
        OutputQueue.DUAL_CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), deviceConfig.getDeviceNo()));
        OutputQueue.DUAL_CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), deviceConfig.getDeviceNo()));
        if (crnProtocol.getAlarm() > 0) {
            crnProtocol.setLastCommandTime(-1L);
@@ -356,7 +476,7 @@
            //更新采集时间
            crnProtocol.setDeviceDataLog(System.currentTimeMillis());
        }
        try {
            BasDualCrnpErrLogService errLogService = SpringUtils.getBean(BasDualCrnpErrLogService.class);
            if (errLogService != null) {
@@ -392,7 +512,8 @@
                    }
                }
            }
        } catch (Exception ignore) {}
        } catch (Exception ignore) {
        }
    }
    @Override
@@ -475,10 +596,10 @@
    }
    @Override
    public DualCrnCommand getResetCommand(Integer crnNo, Integer station) {
    public DualCrnCommand getResetCommand(Integer taskNo, Integer crnNo, Integer station) {
        DualCrnCommand crnCommand = new DualCrnCommand();
        crnCommand.setCrnNo(crnNo); // 堆垛机编号
        crnCommand.setTaskNo(0); // 工作号
        crnCommand.setTaskNo(taskNo); // 工作号
        crnCommand.setTaskMode(DualCrnTaskModeType.CONFIRM.id); // 任务模式:  确认
        crnCommand.setSourcePosX(0);     // 源库位排
        crnCommand.setSourcePosY(0);     // 源库位列
@@ -492,7 +613,7 @@
    }
    @Override
    public synchronized CommandResponse sendCommand(DualCrnCommand command) {
    public CommandResponse sendCommand(DualCrnCommand command) {
        this.crnProtocol.setLastCommandTime(System.currentTimeMillis());
        CommandResponse response = null;
        try {
@@ -523,4 +644,77 @@
            }
        }
    }
    public List<SendDualCrnCommandParam> getDualCrnCommandList() {
        List<SendDualCrnCommandParam> commandList = new ArrayList<>();
        SendDualCrnCommandParam command1 = getDualCrnCommandList(1);
        SendDualCrnCommandParam command2 = getDualCrnCommandList(2);
        if (command1 != null) {
            commandList.add(command1);
        }
        if (command2 != null) {
            commandList.add(command2);
        }
        return commandList;
    }
    public SendDualCrnCommandParam getDualCrnCommandList(int station) {
        SendDualCrnCommandParam sendDualCrnCommandParam = null;
        String key = null;
        if (station == 1 && crnProtocol.getTaskNo() > 0) {
            key = RedisKeyType.DUAL_CRN_COMMAND_.key + crnProtocol.getTaskNo();
        } else if (station == 2 && crnProtocol.getTaskNoTwo() > 0) {
            key = RedisKeyType.DUAL_CRN_COMMAND_.key + crnProtocol.getTaskNoTwo();
        }
        if (key == null) {
            return null;
        }
        Object commandObj = redisUtil.get(key);
        if (commandObj == null) {
            return null;
        }
        sendDualCrnCommandParam = JSON.parseObject(commandObj.toString(), SendDualCrnCommandParam.class);
        if (sendDualCrnCommandParam == null) {
            return null;
        }
        if (station == 1) {
            if (crnProtocol.getTaskNoTwo() > 0) {
                Object object = redisUtil.get(RedisKeyType.DUAL_CRN_COMMAND_.key + crnProtocol.getTaskNoTwo());
                if (object != null) {
                    SendDualCrnCommandParam jsonObject = JSON.parseObject(object.toString(), SendDualCrnCommandParam.class);
                    ;
                    if (!jsonObject.getCommands().get(0).getTaskMode().equals(sendDualCrnCommandParam.getCommands().get(0).getTaskMode())) {
                        return null;
                    }
                }
            }
        } else {
            if (crnProtocol.getTaskNo() > 0) {
                WrkMastService mastService = SpringUtils.getBean(WrkMastService.class);
                WrkMast wrkMast = mastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", crnProtocol.getTaskNo()));
                WrkMast wrkMast1 = mastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", crnProtocol.getTaskNoTwo()));
                if (!Objects.isNull(wrkMast) && !Objects.isNull(wrkMast1)) {
                    if (!wrkMast1.getIoType().equals(wrkMast.getIoType())) {
                        return null;
                    }
                }
//                Object object = redisUtil.get(RedisKeyType.DUAL_CRN_COMMAND_.key + crnProtocol.getTaskNo());
//                if (object != null) {
//                    SendDualCrnCommandParam jsonObject = JSON.parseObject(object.toString(), SendDualCrnCommandParam.class);
//                    ;
//                    if (!jsonObject.getCommands().get(0).getTaskMode().equals(sendDualCrnCommandParam.getCommands().get(0).getTaskMode())) {
//                        return null;
//                    }
//                }
            }
        }
        return sendDualCrnCommandParam;
    }
}