1
zhang
5 天以前 510a21954afdf40479bdf293568cc7979e6043ad
src/main/java/com/zy/asrs/service/impl/CtuMainServiceImpl.java
@@ -1,14 +1,12 @@
package com.zy.asrs.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.core.common.DateUtils;
import com.core.exception.CoolException;
import com.zy.asrs.domain.param.OpenBusSubmitParam;
import com.zy.asrs.domain.param.TaskDto;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.controller.requestParam.StationRequestParam;
import com.zy.asrs.domain.vo.StationStatus;
import com.zy.asrs.service.CtuMainService;
import com.zy.common.utils.HttpHandler;
import com.zy.common.utils.News;
import com.zy.core.cache.MessageQueue;
@@ -26,8 +24,10 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 立体仓库WCS系统主流程业务
@@ -37,436 +37,351 @@
@Service("ctuMainService")
@Transactional
@Data
public class CtuMainServiceImpl {
public class CtuMainServiceImpl implements CtuMainService {
    public static final long COMMAND_TIMEOUT = 5 * 1000;
    private static final long SLEEP_DURATION = 8000L;
    private static final int MAX_WORK_NO = 9999;
    private static final int RANDOM_WORK_NO_MAX = 10000;
    private static final int CTU_STATION_1001 = 1001;
    private static final int CTU_STATION_1007 = 1007;
    private static final int CTU_STATION_1006 = 1006;
    private static final int CTU_STATION_1004 = 1004;
    @Value("${ctu.url}")
    private String ctuUrl;
    @Value("${ctu.sendTask}")
    private String sendTask;
    @Value("${ctu.getLoc}")
    private String getLoc;
    @Value("${ctu.update}")
    private String updateSta;
    @Value("${ctu.station}")
    private String station;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private WrkMastMapper wrkMastMapper;
    // 为不同的操作添加细粒度锁
    private final ReentrantLock outLock = new ReentrantLock();
    private final ReentrantLock inLock = new ReentrantLock();
    private final ReentrantLock in2Lock = new ReentrantLock();
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private WrkMastService wrkMastService;
    private boolean flag1001 = false;
    private boolean flag1007 = false;
    private Map<Integer, Long> staNoSet = new HashMap<>();
    public Map<Integer, Long> getStaNoSet() {
        return staNoSet;
    }
    public void setStaNoSet(Map<Integer, Long> staNoSet) {
        this.staNoSet = staNoSet;
    /**
     * 出库的时候,设备上走
     */
    @Override
    public void out(Integer mark) {
        executeWithLock(outLock, () -> {
            for (DevpSlave devp : slaveProperties.getDevp()) {
                for (DevpSlave.Sta outSta : devp.getOutSta()) {
                    processOutboundStation(devp, outSta, mark);
                }
            }
        }, "出库处理");
    }
    /**
     * 入库,从拣料站到入库站(CTU取货站)
     */
    public synchronized void generateStoreWrkFile(Integer mark) {
        for (Map.Entry<Integer, Long> entry : staNoSet.entrySet()) {
            if (entry.getValue() != null && System.currentTimeMillis() - entry.getValue() > 1000 * 60 * 5) {
                log.info("超时:{}", entry.getKey());
                staNoSet.remove(entry.getKey());
    @Override
    public void in(Integer mark) {
        executeWithLock(inLock, () -> processInboundStation(mark, CTU_STATION_1004, (short) CTU_STATION_1006), "入库处理");
    }
    @Override
    public void in2(Integer mark) {
        executeWithLock(in2Lock, () -> {
            // 获取1007站点信息
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            if (devpThread == null) {
                log.warn("无法获取设备线程,设备ID: 1");
                return;
            }
        }
        // 根据输送线plc遍历
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        StaProtocol staProtocol = devpThread.getStation().get(1004);
        if (staProtocol == null) {
            return;
        } else {
            staProtocol = staProtocol.clone();
        }
        // 判断是否满足条件
        if (!staProtocol.isLoading()) {
            return;
        }
        Long i = staNoSet.get(staProtocol.getWorkNo());
        if (i != null) {
            return;
        }
        // && staProtocol.isInEnable()
        if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing() && !staProtocol.isEmptyMk() && staProtocol.isPakMk()) {
            if (staProtocol.getStaNo() == 1004) {
                try {
                    Thread.sleep(8000L);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
            StaProtocol staProtocol = getStationProtocol(devpThread, CTU_STATION_1007);
            if (staProtocol == null || !isStationReadyForProcessing(staProtocol)) {
                return;
            }
            if (staProtocol.getWorkNo() > 0 &&
                staProtocol.isAutoing() &&
                !staProtocol.isEmptyMk() &&
                staProtocol.isPakMk()) {
                if (station(CTU_STATION_1007)) {
                    Integer workNo = staProtocol.getWorkNo();
                    // 清空1007站点
                    clearStationProtocol(staProtocol, devpThread);
                    // 更新1006站点信息
                    updateStation1006(devpThread, workNo);
                }
                staProtocol.setStaNo((short) 1007);
            }
        }, "入库第二步处理");
    }
    @Override
    @Transactional
    public boolean station(Integer staNo) {
        return checkStationStatus(staNo);
    }
    /**
     * 在锁的保护下执行操作
     * @param lock 锁
     * @param operation 要执行的操作
     * @param operationName 操作名称,用于日志
     */
    private void executeWithLock(ReentrantLock lock, Runnable operation, String operationName) {
        lock.lock();
        try {
            operation.run();
        } catch (Exception e) {
            log.error("{}异常", operationName, e);
            News.error("{}异常: {}", operationName, e.getMessage());
        } finally {
            lock.unlock();
        }
    }
    /**
     * 处理出库站点
     * @param devp 设备
     * @param outSta 出库站点
     * @param mark 标记
     */
    private void processOutboundStation(DevpSlave devp, DevpSlave.Sta outSta, Integer mark) {
        SiemensDevpThread devpThread = getDeviceThread(SlaveType.Devp, devp.getId());
        if (devpThread == null) {
            log.warn("无法获取设备线程,设备ID: {}", devp.getId());
            return;
        }
        StaProtocol staProtocol = getStationProtocol(devpThread, outSta.getStaNo());
        if (staProtocol == null || !isStationReadyForProcessing(staProtocol)) {
            return;
        }
        if (isOutboundConditionMet(staProtocol) && station(CTU_STATION_1001)) {
            executeOutboundProcess(staProtocol, devp, mark, devpThread);
        } else {
            logStationConditionError(mark, staProtocol);
        }
    }
    /**
     * 检查出库条件是否满足
     * @param staProtocol 站点协议
     * @return 条件是否满足
     */
    private boolean isOutboundConditionMet(StaProtocol staProtocol) {
        return staProtocol.isAutoing() &&
               !staProtocol.isEmptyMk() &&
               (staProtocol.getWorkNo() == 0 || staProtocol.getWorkNo() == MAX_WORK_NO) &&
               staProtocol.isPakMk();
    }
    /**
     * 执行出库处理
     * @param staProtocol 站点协议
     * @param devp 设备
     * @param mark 标记
     * @param devpThread 设备线程
     */
    private void executeOutboundProcess(StaProtocol staProtocol, DevpSlave devp, Integer mark, SiemensDevpThread devpThread) {
        News.warnNoLog("" + mark + " - 0" + " - 开始执行");
        // 更新站点信息 且 下发plc命令
        staProtocol.setWorkNo((int) (Math.random() * RANDOM_WORK_NO_MAX));
        staProtocol.setStaNo((short) CTU_STATION_1004);
        devpThread.setPakMk(staProtocol.getSiteId(), false);
        boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
        log.info("输送线下发3:{},{}", staProtocol.getWorkNo(), CTU_STATION_1004);
        if (result) {
            sleepWithInterruptHandling(SLEEP_DURATION, "出库处理");
        } else {
            News.error("" + mark + " - 2" + " - 发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
        }
    }
    /**
     * 记录站点条件错误日志
     * @param mark 标记
     * @param staProtocol 站点协议
     */
    private void logStationConditionError(Integer mark, StaProtocol staProtocol) {
        String errorMsg = String.format(
            "%s - 6 - 站点信息不符合入库条件!!! 自动信号:%s、可入信号:%s、空板信号:%s、工作号:%s、锁定标记%s、入库印记:%s",
            mark,
            staProtocol.isLoading(),
            staProtocol.isInEnable(),
            staProtocol.isEmptyMk(),
            staProtocol.getWorkNo(),
            staProtocol.isPakMk(),
            staProtocol.getStamp()
        );
        News.errorNoLog(errorMsg);
        log.warn(errorMsg);
    }
    /**
     * 处理入库站点
     * @param mark 标记
     * @param sourceStaNo 源站点编号
     * @param targetStaNo 目标站点编号
     */
    private void processInboundStation(Integer mark, int sourceStaNo, short targetStaNo) {
        SiemensDevpThread devpThread = getDeviceThread(SlaveType.Devp, 1);
        if (devpThread == null) {
            log.warn("无法获取设备线程,设备ID: 1");
            return;
        }
        StaProtocol staProtocol = getStationProtocol(devpThread, sourceStaNo);
        if (staProtocol == null || !isStationReadyForProcessing(staProtocol)) {
            return;
        }
        if (staProtocol.getWorkNo() > 0 &&
            staProtocol.isAutoing() &&
            !staProtocol.isEmptyMk() &&
            staProtocol.isPakMk()) {
            if (staProtocol.getStaNo() == sourceStaNo) {
                sleepWithInterruptHandling(SLEEP_DURATION, "入库处理");
                staProtocol.setStaNo(targetStaNo);
                boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
                staNoSet.put(staProtocol.getWorkNo(), System.currentTimeMillis());
                log.info("入库输送线下发:{},{}", staProtocol.getWorkNo(), 1007);
                log.info("入库输送线下发:{},{}", staProtocol.getWorkNo(), targetStaNo);
            }
//                    WrkMast wrkMast = wrkMastMapper.selectByWrkNo(staProtocol.getWorkNo());
//                    if (wrkMast != null) {
//                        //下发移动任务,并生成入库工作档
//                        WrkMast in = new WrkMast();
//                        wrkMast.setWrkSts(223L);
//                        wrkMast.setModiTime(new Date());
//                        wrkMastService.updateById(wrkMast);
//                        in.setSourceLocNo("1007");
//                        in.setLocNo(wrkMast.getSourceLocNo());
//                        in.setIoType(10);
//                        in.setIoTime(new Date());
//                        in.setWrkSts(1L); // 工作状态:11.生成出库ID
//                        in.setIoPri(13D); // 优先级:13
//                        in.setFullPlt("Y"); // 满板:Y
//                        in.setPicking("N"); // 拣料
//                        in.setExitMk("N"); // 退出
//                        in.setEmptyMk("Y"); // 空板
//                        in.setLinkMis("N");
//                        in.setAppeTime(new Date());
//                        in.setModiTime(new Date());
//                        in.setBarcode(wrkMast.getBarcode());
//                        in.setPlcWrkNo(wrkMast.getPlcWrkNo());
//                        wrkMastService.insert(in);
//                        LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo());
//                        locMast.setLocSts("S");
//                        locMast.setModiTime(new Date());
//                        locMastService.updateById(locMast);
//                    }
        }
    }
    public synchronized void outToPlc(Integer mark) {
        // 根据输送线plc遍历
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        StaProtocol staProtocol = devpThread.getStation().get(1007);
        if (staProtocol == null) {
            return;
        } else {
            staProtocol = staProtocol.clone();
        }
        // 判断是否满足条件
        if (!staProtocol.isLoading()) {
            return;
        }
        if (flag1007 && staProtocol.getWorkNo() > 0 && staProtocol.isAutoing() && !staProtocol.isEmptyMk() && staProtocol.isPakMk()) {
            staProtocol.setWorkNo(0);
            staProtocol.setStaNo((short) 0);
            boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
            log.info("取走写入确认位:{},{}", staProtocol.getWorkNo(), 1007);
        }
    }
    /**
     * 出库
     * 获取设备线程
     * @param slaveType 从类型
     * @param id 设备ID
     * @return 设备线程
     */
    public synchronized void out(Integer mark) {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库口
            for (DevpSlave.Sta inSta : devp.getOutSta()) {
                // 获取入库站信息
                SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                } else {
                    staProtocol = staProtocol.clone();
                }
                // 判断是否满足条件
                if (!staProtocol.isLoading()) {
                    continue;
                }
                //&& staProtocol.isOutEnable()
                if (staProtocol.isAutoing() && !staProtocol.isEmptyMk() && (staProtocol.getWorkNo() == 0 || staProtocol.getWorkNo() == 9999) && staProtocol.isPakMk()) {
                    News.warnNoLog("" + mark + " - 0" + " - 开始执行");
                    // 判断重复工作档
                    // 106也算上,以后106-》107用于更新库存
//                    WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("loc_no", "1001").in("wrk_sts", 106, 107));
//                    if (wrkMast == null) {
//                        continue;
//                    }
                    // 命令下发区 --------------------------------------------------------------------------
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo((int) (Math.random() * 10000));
                    staProtocol.setStaNo((short) 1004);
                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    log.info("输送线下发3:{},{}", staProtocol.getWorkNo(), 1004);
                    if (result) {
                        try {
                            Thread.sleep(8000L);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        setFlag1001(false);
                    } else {
                        News.error("" + mark + " - 2" + " - 发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                    }
                } else {
                    News.errorNoLog("" + mark + " - 6" + " - 站点信息不符合入库条件!!!" + " 自动信号:" + staProtocol.isLoading() + "、可入信号:" + staProtocol.isInEnable() + "、空板信号:" + staProtocol.isEmptyMk() + "、工作号:" + staProtocol.getWorkNo() + "、锁定标记" + staProtocol.isPakMk() + "、入库印记:" + staProtocol.getStamp());
                }
            }
        }
    }
    public static final ArrayList<Integer> staNos1 = new ArrayList<Integer>() {{
        add(1001);
        add(1002);
        add(1003);
        add(1004);
        add(1005);
        add(1006);
        add(1007);
    }};
    public static final ArrayList<Integer> staNos2 = new ArrayList<Integer>() {{
        add(101);
        add(102);
        add(103);
        add(104);
        add(105);
        add(106);
        add(107);
        add(108);
    }};
    public synchronized void in(Integer mark) {
        // 遍历入库口
        for (Integer inSta : staNos2) {
            // 获取入库站信息
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            StaProtocol staProtocol = devpThread.getStation().get(inSta);
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            // 判断是否满足条件
            if (!staProtocol.isAutoing() && !staProtocol.isLoading()) {
                continue;
            }
            // && staProtocol.isInEnable()
            if (staProtocol.isInEnable()) {
                OpenBusSubmitParam openBusSubmitParam = new OpenBusSubmitParam();
                openBusSubmitParam.setBatch(DateUtils.convert(new Date()));
                List<TaskDto> taskList = new ArrayList<>();
                TaskDto taskDto = new TaskDto();
                Random rand = new Random();
                taskDto.setSeqNum(rand.nextInt(10000) + "");
                taskDto.setDestLoc(getFLoc(staProtocol.getSiteId() + "-2", "15"));
                taskDto.setOriSta(staProtocol.getSiteId() + "-2");
                taskDto.setPriority(123);
                taskList.add(taskDto);
                openBusSubmitParam.setTaskList(taskList);
                sendTask(openBusSubmitParam, staProtocol);
            }
            if (staProtocol.isOutEnable()) {
                OpenBusSubmitParam openBusSubmitParam = new OpenBusSubmitParam();
                openBusSubmitParam.setBatch(DateUtils.convert(new Date()));
                List<TaskDto> taskList = new ArrayList<>();
                TaskDto taskDto = new TaskDto();
                Random rand = new Random();
                taskDto.setSeqNum(rand.nextInt(10000) + "");
                taskDto.setDestLoc(getFLoc(staProtocol.getSiteId() + "-3", "15"));
                taskDto.setOriSta(staProtocol.getSiteId() + "-3");
                taskDto.setPriority(123);
                taskList.add(taskDto);
                openBusSubmitParam.setTaskList(taskList);
                sendTask(openBusSubmitParam, staProtocol);
            }
        }
    }
    public synchronized void autoOut(Integer mark) {
        int i = 0;
        for (Integer staNo : staNos1) {
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            StaProtocol staProtocol = devpThread.getStation().get(staNo);
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            // 判断是否满足条件
            if (!staProtocol.isAutoing()) {
                continue;
            }
            if (staProtocol.isLoading()) {
                continue;
            }
            if (staProtocol.getStaNo() != 0) {
                continue;
            }
            i++;
        }
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        StaProtocol staProtocol = devpThread.getStation().get(1001);
        if (i >= 7) {
            OpenBusSubmitParam openBusSubmitParam = new OpenBusSubmitParam();
            openBusSubmitParam.setBatch(DateUtils.convert(new Date()));
            List<TaskDto> taskList = new ArrayList<>();
            TaskDto taskDto = new TaskDto();
            Random rand = new Random();
            taskDto.setSeqNum("SSX-CK" + rand.nextInt() * 10000);
            taskDto.setOriLoc(getFLoc("1001", "16"));
            taskDto.setDestSta("1001");
            taskDto.setPriority(123);
            taskList.add(taskDto);
            openBusSubmitParam.setTaskList(taskList);
            sendTask(openBusSubmitParam, staProtocol);
        }
    }
    /**
     * 1007入库
     *
     * @param mark
     */
    public synchronized void autoIn(Integer mark) {
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        StaProtocol staProtocol = devpThread.getStation().get(1007);
        if (staProtocol == null) {
            return;
        } else {
            staProtocol = staProtocol.clone();
        }
        // 判断是否满足条件
        if (!staProtocol.isAutoing()) {
            return;
        }
        if (!staProtocol.isLoading()) {
            return;
        }
        if (staProtocol.getStaNo() <= 0) {
            return;
        }
        OpenBusSubmitParam openBusSubmitParam = new OpenBusSubmitParam();
        openBusSubmitParam.setBatch(DateUtils.convert(new Date()));
        List<TaskDto> taskList = new ArrayList<>();
        TaskDto taskDto = new TaskDto();
        taskDto.setSeqNum("SSX-RK" + staProtocol.getWorkNo());
        taskDto.setDestLoc(getFLoc("1007", "15"));
        taskDto.setOriSta("1007");
        taskDto.setPriority(123);
        taskList.add(taskDto);
        openBusSubmitParam.setTaskList(taskList);
        sendTask(openBusSubmitParam, staProtocol);
    }
    public void updateSta(Integer mark) {
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        StaProtocol staProtocol1 = devpThread.getStation().get(1001);
        StaProtocol staProtocol7 = devpThread.getStation().get(1007);
        if (staProtocol1 == null) {
            return;
        }
        if (staProtocol7 == null) {
            return;
        }
        updateSta("1001", staProtocol1.isLoading() ? "16" : "15");
        updateSta("1007", staProtocol7.isLoading() ? "16" : "15");
    }
    @Transactional
    public boolean sendTask(OpenBusSubmitParam openBusSubmitParam, StaProtocol staProtocol) {
        String response = "";
        try {
            response = new HttpHandler.Builder()
                    .setUri(ctuUrl)
                    .setPath(sendTask)
                    .setTimeout(1200, TimeUnit.SECONDS)
                    .setJson(JSON.toJSONString(openBusSubmitParam))
                    .build()
                    .doPost();
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger("code").equals(200)) {
                log.info("下发任务返回数据:{}", response);
                return true;
            } else {
                log.error("请求接口失败!!!url:{};request:{};response:{}", ctuUrl + sendTask, JSON.toJSONString(openBusSubmitParam), response);
                throw new CoolException("调用下发任务接口报错");
            }
        } catch (Exception e) {
            //log.error("fail", e);
        }
        return false;
    }
    @Transactional
    public void updateSta(String staNo, String sts) {
        Map<String, String> data = new HashMap<String, String>();
        data.put("staNo", staNo);
        data.put("sts", sts);
        String response = "";
        try {
            response = new HttpHandler.Builder()
                    .setUri(ctuUrl)
                    .setPath(updateSta)
                    .setTimeout(1200, TimeUnit.SECONDS)
                    .setJson(JSON.toJSONString(data))
                    .build()
                    .doPost();
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger("code").equals(200)) {
                //log.info("下发任务返回数据:{}", response);
            } else {
                //log.error("请求接口失败!!!url:{};request:{};response:{}", ctuUrl + sendTask, JSON.toJSONString(data), response);
                //throw new CoolException("调用下发任务接口报错");
            }
        } catch (Exception e) {
            log.error("fail", e);
        }
    }
    @Transactional
    public String getFLoc(String staNo, String sts) {
        Map<String, String> data = new HashMap<String, String>();
        data.put("staNo", staNo);
        data.put("sts", sts);
        String response = "";
        try {
            response = new HttpHandler.Builder()
                    .setUri(ctuUrl)
                    .setPath(getLoc)
                    .setTimeout(1200, TimeUnit.SECONDS)
                    .setJson(JSON.toJSONString(data))
                    .build()
                    .doPost();
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger("code").equals(200)) {
                //log.info("下发任务返回数据:{}", response);
                JSONObject loc = JSON.parseObject(jsonObject.getString("data"));
                return loc.getString("locNo");
            } else {
                log.error("请求接口失败!!!url:{};request:{};response:{}", ctuUrl + sendTask, JSON.toJSONString(data), response);
                throw new CoolException("调用下发任务接口报错");
            }
        } catch (Exception e) {
            log.error("fail", e);
    private SiemensDevpThread getDeviceThread(SlaveType slaveType, Integer id) {
        Object device = SlaveConnection.get(slaveType, id);
        if (device instanceof SiemensDevpThread) {
            return (SiemensDevpThread) device;
        }
        return null;
    }
}
    /**
     * 获取站点协议对象
     * @param devpThread 设备线程
     * @param staNo 站点编号
     * @return 站点协议对象
     */
    private StaProtocol getStationProtocol(SiemensDevpThread devpThread, int staNo) {
        try {
            StaProtocol staProtocol = devpThread.getStation().get(staNo);
            if (staProtocol != null) {
                return staProtocol.clone();
            }
        } catch (Exception e) {
            log.error("获取站点协议异常,站点编号: {}", staNo, e);
        }
        return null;
    }
    /**
     * 检查站点是否准备好处理
     * @param staProtocol 站点协议
     * @return 是否准备好
     */
    private boolean isStationReadyForProcessing(StaProtocol staProtocol) {
        return staProtocol != null && staProtocol.isLoading();
    }
    /**
     * 带中断处理的睡眠
     * @param duration 休眠时间
     * @param operationName 操作名称,用于日志
     */
    private void sleepWithInterruptHandling(long duration, String operationName) {
        try {
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("{}线程中断异常", operationName, e);
            throw new RuntimeException(operationName + "线程中断", e);
        }
    }
    /**
     * 清空站点协议
     * @param staProtocol 站点协议
     * @param devpThread 设备线程
     */
    private void clearStationProtocol(StaProtocol staProtocol, SiemensDevpThread devpThread) {
        staProtocol.setWorkNo(0);
        staProtocol.setStaNo((short) 0);
        boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
        log.info("1007站点清空:{},{}", staProtocol.getWorkNo(), CTU_STATION_1006);
    }
    /**
     * 更新1006站点
     * @param devpThread 设备线程
     * @param workNo 工作号
     */
    private void updateStation1006(SiemensDevpThread devpThread, Integer workNo) {
        StaProtocol staProtocol1006 = devpThread.getStation().get(CTU_STATION_1006);
        if (staProtocol1006 != null) {
            staProtocol1006.setWorkNo(workNo);
            staProtocol1006.setStaNo((short) CTU_STATION_1007);
            boolean result2 = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol1006));
            log.info("1006站点往前走一格:{},{}", staProtocol1006.getWorkNo(), CTU_STATION_1007);
        } else {
            log.warn("无法获取1006站点协议");
        }
    }
    /**
     * 检查站点状态
     * @param staNo 站点编号
     * @return 站点是否可通行
     */
    private boolean checkStationStatus(Integer staNo) {
        StationRequestParam stationRequestParam = new StationRequestParam();
        List<String> staNos = new ArrayList<>();
        staNos.add(staNo + "");
        stationRequestParam.setStaNos(staNos);
        String response = "";
        try {
            response = new HttpHandler.Builder()
                    .setUri(ctuUrl)
                    .setPath(station)
                    .setTimeout(1200, TimeUnit.SECONDS)
                    .setJson(JSON.toJSONString(stationRequestParam))
                    .build()
                    .doPost();
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger("code").equals(200)) {
                log.info("RCS返回数据:{}", response);
                JSONArray data = jsonObject.getJSONArray("data");
                List<StationStatus> stationStatuses = JSONArray.parseArray(data.toString(), StationStatus.class);
                for (StationStatus object : stationStatuses) {
                    if (object.getStaNo().equals(staNo + "")) {
                        if (object.getConveyable()) {
                            return true;
                        } else {
                            log.info("站点:{}状态不对", staNo);
                            return false;
                        }
                    }
                }
                log.info("未返回站点状态:{}", staNo);
            } else {
                log.error("调用下发任务接口报错,响应码:{},响应内容:{}", jsonObject.getInteger("code"), response);
                throw new CoolException("调用下发任务接口报错,响应码:" + jsonObject.getInteger("code"));
            }
        } catch (CoolException e) {
            log.error("调用站点状态接口异常", e);
            throw e;
        } catch (Exception e) {
            log.error("检查站点状态失败,站点编号:{}", staNo, e);
        }
        return false;
    }
}