Junjie
2 天以前 63b01db83d9aad8a15276b4236a9a22e4aeef065
src/main/java/com/zy/ai/service/impl/AutoTuneSnapshotServiceImpl.java
@@ -1,20 +1,29 @@
package com.zy.ai.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.ai.domain.autotune.AutoTuneControlModeSnapshot;
import com.zy.ai.domain.autotune.AutoTuneTaskDetailItem;
import com.zy.ai.domain.autotune.AutoTuneParameterSnapshot;
import com.zy.ai.domain.autotune.AutoTuneRoutePressureSnapshot;
import com.zy.ai.domain.autotune.AutoTuneRuleDefinition;
import com.zy.ai.domain.autotune.AutoTuneRuleSnapshotItem;
import com.zy.ai.domain.autotune.AutoTuneSnapshot;
import com.zy.ai.domain.autotune.AutoTuneStationRuntimeItem;
import com.zy.ai.domain.autotune.AutoTuneTaskSnapshot;
import com.zy.ai.service.AutoTuneControlModeService;
import com.zy.ai.service.AutoTuneSnapshotService;
import com.zy.ai.service.FlowTopologySnapshotService;
import com.zy.ai.service.RoutePressureSnapshotService;
import com.zy.asrs.domain.vo.StationCycleCapacityVo;
import com.zy.asrs.domain.vo.StationCycleLoopVo;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.entity.BasDualCrnp;
import com.zy.asrs.entity.BasStation;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.BasDualCrnpService;
import com.zy.asrs.service.BasStationService;
import com.zy.asrs.service.DeviceConfigService;
@@ -22,28 +31,39 @@
import com.zy.asrs.service.WrkMastService;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.enums.WrkIoType;
import com.zy.core.enums.WrkStsType;
import com.zy.core.model.StationObjModel;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.thread.StationThread;
import com.zy.system.service.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service("autoTuneSnapshotService")
public class AutoTuneSnapshotServiceImpl implements AutoTuneSnapshotService {
    private static final Logger LOGGER = LoggerFactory.getLogger(AutoTuneSnapshotServiceImpl.class);
    private static final int DEFAULT_CRN_OUT_BATCH_RUNNING_LIMIT = 5;
    private static final int DEFAULT_CONVEYOR_STATION_TASK_LIMIT = 30;
    private static final int DEFAULT_AI_AUTO_TUNE_INTERVAL_MINUTES = 10;
    private static final int OUTBOUND_TASK_SAMPLE_LIMIT = 50;
    private static final int STATION_LIMIT_BLOCKED_TASK_LIMIT = 50;
    private static final int SYSTEM_MESSAGE_LIMIT = 160;
    @Autowired
    private WrkMastService wrkMastService;
@@ -57,10 +77,19 @@
    private FlowTopologySnapshotService flowTopologySnapshotService;
    @Autowired
    private RoutePressureSnapshotService routePressureSnapshotService;
    @Autowired
    private AutoTuneControlModeService autoTuneControlModeService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private BasStationService basStationService;
    @Autowired
    private BasDevpService basDevpService;
    @Autowired
    private BasCrnpService basCrnpService;
@@ -70,29 +99,197 @@
    @Override
    public AutoTuneSnapshot buildSnapshot() {
        List<WrkMast> activeTasks = loadActiveTasks();
        AutoTuneTaskSnapshot taskSnapshot = buildTaskSnapshot(activeTasks);
        List<AutoTuneStationRuntimeItem> stationRuntimeSnapshot = buildStationRuntimeSnapshot();
        AutoTuneRoutePressureSnapshot routePressureSnapshot = buildRoutePressureSnapshot(
                activeTasks,
                taskSnapshot,
                stationRuntimeSnapshot
        );
        AutoTuneSnapshot snapshot = new AutoTuneSnapshot();
        snapshot.setTaskSnapshot(buildTaskSnapshot());
        snapshot.setTaskSnapshot(taskSnapshot);
        snapshot.setStationRuntimeSnapshot(stationRuntimeSnapshot);
        snapshot.setRoutePressureSnapshot(routePressureSnapshot);
        snapshot.setCycleLoadSnapshot(buildCycleLoadSnapshot());
        snapshot.setFlowTopologySnapshot(flowTopologySnapshotService.buildSnapshot(stationRuntimeSnapshot));
        snapshot.setCurrentParameterSnapshot(buildCurrentParameterSnapshot());
        snapshot.setRuleSnapshot(buildRuleSnapshot());
        snapshot.setControlModeSnapshot(buildControlModeSnapshot());
        snapshot.setSnapshotTime(new Date());
        return snapshot;
    }
    private AutoTuneTaskSnapshot buildTaskSnapshot() {
        List<WrkMast> activeTasks = loadActiveTasks();
    private AutoTuneControlModeSnapshot buildControlModeSnapshot() {
        return autoTuneControlModeService.currentMode();
    }
    List<AutoTuneRuleSnapshotItem> buildRuleSnapshot() {
        List<AutoTuneRuleSnapshotItem> result = new ArrayList<>();
        for (AutoTuneRuleDefinition.Rule rule : AutoTuneRuleDefinition.rules().values()) {
            AutoTuneRuleSnapshotItem item = new AutoTuneRuleSnapshotItem();
            item.setTargetType(rule.getTargetType().getCode());
            item.setTargetKey(rule.getTargetKey());
            item.setMinValue(rule.getMinValue());
            item.setMaxValue(rule.getMaxValue());
            item.setMaxStep(rule.getMaxStep());
            item.setCooldownMinutes(rule.getCooldownMinutes());
            item.setDynamicMaxValue(rule.isDynamicMaxValue());
            item.setDynamicMaxSource(rule.getDynamicMaxSource());
            item.setNote(rule.getNote());
            result.add(item);
        }
        return result;
    }
    private AutoTuneTaskSnapshot buildTaskSnapshot() {
        return buildTaskSnapshot(loadActiveTasks());
    }
    private AutoTuneTaskSnapshot buildTaskSnapshot(List<WrkMast> activeTasks) {
        AutoTuneTaskSnapshot snapshot = new AutoTuneTaskSnapshot();
        snapshot.setActiveTaskCount(activeTasks.size());
        snapshot.setStationLimitBlockedTasks(buildStationLimitBlockedTasks(activeTasks));
        snapshot.setOutboundTaskSamples(buildOutboundTaskSamples(activeTasks));
        snapshot.setByTargetStation(countByTargetStation(activeTasks));
        snapshot.setByBatch(countByBatch(activeTasks));
        snapshot.setByStatus(countByStatus(activeTasks));
        snapshot.setByCrn(countByCrn(activeTasks));
        snapshot.setByDualCrn(countByDualCrn(activeTasks));
        snapshot.setByIoType(countByIoType(activeTasks));
        return snapshot;
    }
    private AutoTuneRoutePressureSnapshot buildRoutePressureSnapshot(List<WrkMast> activeTasks,
                                                                     AutoTuneTaskSnapshot taskSnapshot,
                                                                     List<AutoTuneStationRuntimeItem> stationRuntimeSnapshot) {
        if (routePressureSnapshotService == null) {
            return new AutoTuneRoutePressureSnapshot();
        }
        try {
            AutoTuneRoutePressureSnapshot snapshot = routePressureSnapshotService.buildSnapshot(
                    activeTasks,
                    taskSnapshot,
                    stationRuntimeSnapshot
            );
            return snapshot == null ? new AutoTuneRoutePressureSnapshot() : snapshot;
        } catch (Exception exception) {
            LOGGER.warn(
                    "Build auto tune route pressure snapshot failed, fallback to empty snapshot. activeTaskCount={}, stationRuntimeCount={}",
                    safeList(activeTasks).size(),
                    safeList(stationRuntimeSnapshot).size(),
                    exception
            );
            return new AutoTuneRoutePressureSnapshot();
        }
    }
    private List<AutoTuneTaskDetailItem> buildStationLimitBlockedTasks(List<WrkMast> activeTasks) {
        List<AutoTuneTaskDetailItem> result = new ArrayList<>();
        for (WrkMast task : sortOutboundTasks(activeTasks)) {
            if (!hasStationLimitBlockedMessage(task)) {
                continue;
            }
            result.add(toTaskDetailItem(task));
            if (result.size() >= STATION_LIMIT_BLOCKED_TASK_LIMIT) {
                break;
            }
        }
        return result;
    }
    private List<AutoTuneTaskDetailItem> buildOutboundTaskSamples(List<WrkMast> activeTasks) {
        List<AutoTuneTaskDetailItem> result = new ArrayList<>();
        for (WrkMast task : sortOutboundTasks(activeTasks)) {
            result.add(toTaskDetailItem(task));
            if (result.size() >= OUTBOUND_TASK_SAMPLE_LIMIT) {
                break;
            }
        }
        return result;
    }
    private List<WrkMast> sortOutboundTasks(List<WrkMast> activeTasks) {
        List<WrkMast> outboundTasks = new ArrayList<>();
        for (WrkMast task : safeList(activeTasks)) {
            if (isOutboundTask(task)) {
                outboundTasks.add(task);
            }
        }
        outboundTasks.sort(Comparator
                .comparing(this::taskBatch, Comparator.nullsLast(String::compareTo))
                .thenComparing(this::taskBatchSeq, Comparator.nullsLast(Integer::compareTo))
                .thenComparing(this::taskWrkNo, Comparator.nullsLast(Integer::compareTo)));
        return outboundTasks;
    }
    private boolean isOutboundTask(WrkMast task) {
        return task != null && Integer.valueOf(WrkIoType.OUT.id).equals(task.getIoType());
    }
    private boolean hasStationLimitBlockedMessage(WrkMast task) {
        if (task == null || task.getSystemMsg() == null) {
            return false;
        }
        return task.getSystemMsg().contains("出库任务上限");
    }
    private AutoTuneTaskDetailItem toTaskDetailItem(WrkMast task) {
        AutoTuneTaskDetailItem item = new AutoTuneTaskDetailItem();
        item.setWrkNo(task.getWrkNo());
        item.setWrkSts(task.getWrkSts());
        item.setWrkStsDesc(wrkStsDesc(task.getWrkSts()));
        item.setIoType(task.getIoType());
        item.setIoTypeDesc(ioTypeDesc(task.getIoType()));
        item.setStaNo(task.getStaNo());
        item.setSourceStaNo(task.getSourceStaNo());
        item.setSourceLocNo(task.getSourceLocNo());
        item.setCrnNo(task.getCrnNo());
        item.setDualCrnNo(task.getDualCrnNo());
        item.setBatch(task.getBatch());
        item.setBatchSeq(task.getBatchSeq());
        item.setIoTime(task.getIoTime());
        item.setSystemMsg(limitText(task.getSystemMsg(), SYSTEM_MESSAGE_LIMIT));
        return item;
    }
    private String wrkStsDesc(Long wrkSts) {
        if (wrkSts == null) {
            return null;
        }
        try {
            return WrkStsType.query(wrkSts).desc;
        } catch (Exception ignore) {
            return null;
        }
    }
    private String ioTypeDesc(Integer ioType) {
        if (ioType == null) {
            return null;
        }
        WrkIoType wrkIoType = WrkIoType.get(ioType);
        return wrkIoType == null ? null : wrkIoType.desc;
    }
    private String limitText(String value, int maxLength) {
        if (value == null || value.length() <= maxLength) {
            return value;
        }
        return value.substring(0, maxLength);
    }
    private String taskBatch(WrkMast task) {
        return task == null ? null : task.getBatch();
    }
    private Integer taskBatchSeq(WrkMast task) {
        return task == null ? null : task.getBatchSeq();
    }
    private Integer taskWrkNo(WrkMast task) {
        return task == null ? null : task.getWrkNo();
    }
    private List<WrkMast> loadActiveTasks() {
@@ -153,6 +350,7 @@
        item.setAutoing(protocol.isAutoing() ? 1 : 0);
        item.setLoading(protocol.isLoading() ? 1 : 0);
        item.setTaskNo(protocol.getTaskNo() == null ? 0 : protocol.getTaskNo());
        item.setRunBlock(protocol.isRunBlock() ? 1 : 0);
        item.setIoMode(protocol.getIoMode() == null ? null : String.valueOf(protocol.getIoMode()));
        return item;
    }
@@ -216,7 +414,9 @@
        ));
        List<BasCrnp> crnList = loadCrnList();
        List<BasDualCrnp> dualCrnList = loadDualCrnList();
        snapshot.setStationOutTaskLimits(loadStationOutTaskLimits());
        List<BasStation> outStationList = loadOutStationList();
        snapshot.setStationOutTaskLimits(buildStationOutTaskLimitMap(outStationList));
        snapshot.setStationOutBufferCapacities(buildStationOutBufferCapacityMap(outStationList));
        snapshot.setCrnMaxOutTask(buildCrnMaxOutTask(crnList));
        snapshot.setCrnMaxInTask(buildCrnMaxInTask(crnList));
        snapshot.setDualCrnMaxOutTask(buildDualCrnMaxOutTask(dualCrnList));
@@ -239,14 +439,41 @@
        }
    }
    private Map<String, Integer> loadStationOutTaskLimits() {
        Map<String, Integer> result = new LinkedHashMap<>();
    private List<BasStation> loadOutStationList() {
        if (basStationService == null) {
            return result;
            return Collections.emptyList();
        }
        Set<Integer> outStationIds = loadOutStationIds();
        if (outStationIds.isEmpty()) {
            return Collections.emptyList();
        }
        QueryWrapper<BasStation> wrapper = new QueryWrapper<>();
        wrapper.in("station_id", outStationIds);
        wrapper.orderByAsc("station_id");
        return buildStationOutTaskLimitMap(basStationService.list(wrapper));
        return safeList(basStationService.list(wrapper));
    }
    private Set<Integer> loadOutStationIds() {
        LinkedHashSet<Integer> stationIds = new LinkedHashSet<>();
        if (basDevpService == null) {
            return stationIds;
        }
        QueryWrapper<BasDevp> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1);
        wrapper.orderByAsc("devp_no");
        List<BasDevp> basDevpList = safeList(basDevpService.list(wrapper));
        for (BasDevp basDevp : basDevpList) {
            if (basDevp == null) {
                continue;
            }
            List<StationObjModel> outStationList = safeList(basDevp.getOutStationList$());
            for (StationObjModel stationObjModel : outStationList) {
                if (stationObjModel != null && stationObjModel.getStationId() != null) {
                    stationIds.add(stationObjModel.getStationId());
                }
            }
        }
        return stationIds;
    }
    Map<String, Integer> buildStationOutTaskLimitMap(List<BasStation> stationList) {
@@ -254,6 +481,16 @@
        for (BasStation station : safeList(stationList)) {
            if (station != null && station.getStationId() != null) {
                result.put(String.valueOf(station.getStationId()), station.getOutTaskLimit());
            }
        }
        return result;
    }
    Map<String, Integer> buildStationOutBufferCapacityMap(List<BasStation> stationList) {
        Map<String, Integer> result = new LinkedHashMap<>();
        for (BasStation station : safeList(stationList)) {
            if (station != null && station.getStationId() != null) {
                result.put(String.valueOf(station.getStationId()), station.getOutBufferCapacity());
            }
        }
        return result;
@@ -340,6 +577,15 @@
        return result;
    }
    private Map<String, Integer> countByStatus(List<WrkMast> activeTasks) {
        Map<String, Integer> result = new LinkedHashMap<>();
        for (WrkMast task : activeTasks) {
            Long wrkSts = task == null ? null : task.getWrkSts();
            increment(result, wrkSts == null ? null : String.valueOf(wrkSts));
        }
        return result;
    }
    private Map<String, Integer> countByCrn(List<WrkMast> activeTasks) {
        Map<String, Integer> result = new LinkedHashMap<>();
        for (WrkMast task : activeTasks) {