Junjie
8 天以前 fc67e7de548d5fc4ba84a2c09d3e99aad2fc11d7
src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -37,15 +37,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
@Component
public class CrnOperateProcessUtils {
@@ -149,10 +141,10 @@
                        WrkStsType.NEW_OUTBOUND.sts,
                        WrkStsType.NEW_LOC_MOVE.sts));
        taskQueue.sort(Comparator.comparingInt((WrkMast wrkMast) -> resolveTaskTypeRank(wrkMast, lastIo))
                .thenComparingInt(this::resolveBatchOutboundRank)
                .thenComparingInt(this::resolveBatchSeqOrder)
                .thenComparingDouble(this::resolveTaskIoPri)
                .thenComparingLong(this::resolveTaskQueueTime)
                .thenComparingInt(this::resolveBatchOutboundRank)
                .thenComparingInt(this::resolveBatchSeqOrder)
                .thenComparingInt(this::resolveTaskQueueNo));
        for (WrkMast wrkMast : taskQueue) {
@@ -377,7 +369,7 @@
            return false;
        }
        if (isOutboundStationTaskLimitReached()) {
        if (isConveyorStationTaskLimitReached()) {
            return false;
        }
@@ -388,6 +380,12 @@
        }
        if (!allowBatchOutboundExecute(wrkMast, true)) {
            return false;
        }
        //检查是否为出库模式
        if(!checkOutTargetStationIoMode(wrkMast)) {
            News.taskInfo(wrkMast.getWrkNo(), "堆垛机:{} 任务:{}禁止执行,出库站:{} 不处于出库模式", basCrnp.getCrnNo(), wrkMast.getWrkNo(), wrkMast.getStaNo());
            return false;
        }
@@ -588,15 +586,17 @@
        return false;
    }
    private boolean isOutboundStationTaskLimitReached() {
        int stationMaxTaskCount = getSystemConfigInt("stationMaxTaskCountLimit", 30);
        if (stationMaxTaskCount <= 0) {
    private boolean isConveyorStationTaskLimitReached() {
        int conveyorStationTaskLimit = getSystemConfigInt("conveyorStationTaskLimit", 30);
        if (conveyorStationTaskLimit <= 0) {
            return false;
        }
        int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
        if (currentStationTaskCount >= stationMaxTaskCount) {
            News.warn("输送站点任务数量达到上限,已停止任务下发。当前任务数={},上限={}", currentStationTaskCount, stationMaxTaskCount);
        if (currentStationTaskCount >= conveyorStationTaskLimit) {
            News.warn("输送站点任务数量达到上限,已停止任务下发。当前任务数={},上限={}",
                    currentStationTaskCount,
                    conveyorStationTaskLimit);
            return true;
        }
        return false;
@@ -618,6 +618,36 @@
                    currentStationTaskCount,
                    basStation.getOutTaskLimit());
            return true;
        }
        return false;
    }
    //检查是否为出库模式
    private boolean checkOutTargetStationIoMode(WrkMast wrkMast) {
        if (wrkMast == null || wrkMast.getStaNo() == null) {
            return false;
        }
        BasStation basStation = basStationService.getById(wrkMast.getStaNo());
        if (basStation == null) {
            return false;
        }
        StationThread targetStationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
        if (targetStationThread == null) {
            return false;
        }
        StationProtocol targetStationProtocol = targetStationThread.getStatusMap().get(wrkMast.getStaNo());
        if (targetStationProtocol == null) {
            return false;
        }
        if (targetStationProtocol.getIoMode() == null) {
            return false;
        }
        if (targetStationProtocol.getIoMode() == 2) {
            return true;//出库模式
        }
        return false;
    }
@@ -690,36 +720,53 @@
                return;
            }
            Long updateWrkSts = null;
            Date now = new Date();
            if(wrkMast.getWrkSts() == WrkStsType.INBOUND_RUN.sts){
                updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts;
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null);
            }else if(wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts){
                updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts;
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_COMPLETE, null);
            }else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){
                updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null);
            }else if(wrkMast.getWrkSts() == WrkStsType.CRN_MOVE_RUN.sts){
                updateWrkSts = WrkStsType.COMPLETE_CRN_MOVE.sts;
            }else{
                News.error("堆垛机处于等待确认且任务完成状态,但工作状态异常。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
            String ownerLockKey = RedisKeyType.CRN_IO_EXECUTE_FINISH_OWNER_LOCK.key + wrkMast.getWrkNo();
            String ownerLockToken = UUID.randomUUID().toString();
            if (!redisUtil.trySetStringIfAbsent(ownerLockKey, ownerLockToken, 10)) {
                return;
            }
            try {
                wrkMast = wrkMastService.selectByWorkNo(crnProtocol.getTaskNo());
                if (wrkMast == null) {
                    News.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
                    return;
                }
            wrkMast.setWrkSts(updateWrkSts);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markCraneComplete(wrkMast, now, updateWrkSts);
                CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo());
                MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand));
                News.info("堆垛机任务状态更新成功,堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
                Long currentWrkSts = wrkMast.getWrkSts();
                Long updateWrkSts = null;
                Date now = new Date();
                if(currentWrkSts == WrkStsType.INBOUND_RUN.sts){
                    updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts;
                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null);
                }else if(currentWrkSts == WrkStsType.OUTBOUND_RUN.sts){
                    updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts;
                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_COMPLETE, null);
                }else if(currentWrkSts == WrkStsType.LOC_MOVE_RUN.sts){
                    updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null);
                }else if(currentWrkSts == WrkStsType.CRN_MOVE_RUN.sts){
                    updateWrkSts = WrkStsType.COMPLETE_CRN_MOVE.sts;
                }else{
                    News.error("堆垛机处于等待确认且任务完成状态,但工作状态异常。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
                    return;
                }
                if (wrkMastService.updateWrkStsByWrkNoAndCurrentWrkSts(wrkMast.getWrkNo(), updateWrkSts, currentWrkSts) > 0) {
                    wrkMast.setWrkSts(updateWrkSts);
                    wrkMast.setSystemMsg("");
                    wrkMast.setIoTime(now);
                    wrkMast.setModiTime(now);
                    wrkAnalysisService.markCraneComplete(wrkMast, now, updateWrkSts);
                    CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo());
                    MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand));
                    News.info("堆垛机任务状态更新成功,堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
                    redisUtil.set(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo(), "lock",10);
                } else {
                    News.info("堆垛机完成确认跳过,任务状态已变化。堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
                }
            } finally {
                redisUtil.compareAndDelete(ownerLockKey, ownerLockToken);
            }
            redisUtil.set(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo(), "lock",10);
        }
    }
@@ -728,96 +775,96 @@
        if (basCrnp == null || basCrnp.getCrnNo() == null) {
            return;
        }
            String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo();
            List<Object> items = redisUtil.lGet(key, 0, -1);
            if (items == null || items.isEmpty()) {
                return;
        String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo();
        List<Object> items = redisUtil.lGet(key, 0, -1);
        if (items == null || items.isEmpty()) {
            return;
        }
        CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
        if (crnThread == null) {
            return;
        }
        CrnProtocol crnProtocol = crnThread.getStatus();
        if (crnProtocol == null) {
            return;
        }
        List<WrkMast> running = wrkMastService.list(new QueryWrapper<WrkMast>()
                .eq("crn_no", basCrnp.getCrnNo())
                .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts, WrkStsType.CRN_MOVE_RUN.sts)
        );
        if (!running.isEmpty()) {
            return;
        }
        if (!(crnProtocol.getMode() == CrnModeType.AUTO.id
                && crnProtocol.getTaskNo() == 0
                && crnProtocol.getStatus() == CrnStatusType.IDLE.id
                && crnProtocol.getLoaded() == 0
                && crnProtocol.getForkPos() == 0
                && crnProtocol.getAlarm() == 0)) {
            return;
        }
        for (Object v : items) {
            String s = String.valueOf(v);
            JSONObject obj = null;
            try { obj = JSON.parseObject(s); } catch (Exception ignore) {}
            if (obj == null) {
                continue;
            }
            Integer startEpochSec = obj.getInteger("startEpochSec");
            Integer endEpochSec = obj.getInteger("endEpochSec");
            Integer taskId = obj.getInteger("taskId");
            String taskType = obj.getString("taskType");
            if (startEpochSec == null || taskId == null || taskType == null) {
                continue;
            }
            int earlySlackSec = 5;
            int lateSlackSec = 10;
            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
            if (systemConfigMapObj != null) {
                try {
                    HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
                    String es = systemConfigMap.getOrDefault("plannerEarlySlackSec", "60");
                    String ls = systemConfigMap.getOrDefault("plannerLateSlackSec", "10");
                    earlySlackSec = Integer.parseInt(es);
                    lateSlackSec = Integer.parseInt(ls);
                } catch (Exception ignore) {}
            }
            if (nowSec < startEpochSec - earlySlackSec) {
                continue;
            }
            if (endEpochSec != null && nowSec > endEpochSec + lateSlackSec) {
                redisUtil.lRemove(key, 1, s);
                continue;
            }
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
            if (crnThread == null) {
                return;
            }
            CrnProtocol crnProtocol = crnThread.getStatus();
            if (crnProtocol == null) {
                return;
            }
            List<WrkMast> running = wrkMastService.list(new QueryWrapper<WrkMast>()
                    .eq("crn_no", basCrnp.getCrnNo())
                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts, WrkStsType.CRN_MOVE_RUN.sts)
            );
            if (!running.isEmpty()) {
                return;
            }
            if (!(crnProtocol.getMode() == CrnModeType.AUTO.id
                    && crnProtocol.getTaskNo() == 0
                    && crnProtocol.getStatus() == CrnStatusType.IDLE.id
                    && crnProtocol.getLoaded() == 0
                    && crnProtocol.getForkPos() == 0
                    && crnProtocol.getAlarm() == 0)) {
                return;
            WrkMast wrkMast = wrkMastService.selectByWorkNo(taskId);
            if (wrkMast == null) {
                redisUtil.lRemove(key, 1, s);
                continue;
            }
            for (Object v : items) {
                String s = String.valueOf(v);
                JSONObject obj = null;
                try { obj = JSON.parseObject(s); } catch (Exception ignore) {}
                if (obj == null) {
                    continue;
                }
                Integer startEpochSec = obj.getInteger("startEpochSec");
                Integer endEpochSec = obj.getInteger("endEpochSec");
                Integer taskId = obj.getInteger("taskId");
                String taskType = obj.getString("taskType");
                if (startEpochSec == null || taskId == null || taskType == null) {
                    continue;
                }
                int earlySlackSec = 5;
                int lateSlackSec = 10;
                Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
                if (systemConfigMapObj != null) {
                    try {
                        HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
                        String es = systemConfigMap.getOrDefault("plannerEarlySlackSec", "60");
                        String ls = systemConfigMap.getOrDefault("plannerLateSlackSec", "10");
                        earlySlackSec = Integer.parseInt(es);
                        lateSlackSec = Integer.parseInt(ls);
                    } catch (Exception ignore) {}
                }
                if (nowSec < startEpochSec - earlySlackSec) {
                    continue;
                }
                if (endEpochSec != null && nowSec > endEpochSec + lateSlackSec) {
            if ("IN".equalsIgnoreCase(taskType)) {
                boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);//入库
                if (result) {
                    redisUtil.lRemove(key, 1, s);
                    continue;
                    break;
                }
                WrkMast wrkMast = wrkMastService.selectByWorkNo(taskId);
                if (wrkMast == null) {
            } else if ("OUT".equalsIgnoreCase(taskType)) {
                boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);//出库
                if (result) {
                    redisUtil.lRemove(key, 1, s);
                    continue;
                    break;
                }
                if ("IN".equalsIgnoreCase(taskType)) {
                    boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);//入库
                    if (result) {
                        redisUtil.lRemove(key, 1, s);
                        break;
                    }
                } else if ("OUT".equalsIgnoreCase(taskType)) {
                    boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);//出库
                    if (result) {
                        redisUtil.lRemove(key, 1, s);
                        break;
                    }
                } else if ("MOVE".equalsIgnoreCase(taskType)) {
                    boolean result = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);//移库
                    if (result) {
                        redisUtil.lRemove(key, 1, s);
                        break;
                    }
            } else if ("MOVE".equalsIgnoreCase(taskType)) {
                boolean result = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);//移库
                if (result) {
                    redisUtil.lRemove(key, 1, s);
                    break;
                }
            }
        }
    }
    private synchronized boolean crnExecuteMovePlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {