package com.zy.ai.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.zy.ai.domain.autotune.AutoTuneParameterSnapshot;
|
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.AutoTuneSnapshotService;
|
import com.zy.ai.service.FlowTopologySnapshotService;
|
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;
|
import com.zy.asrs.service.StationCycleCapacityService;
|
import com.zy.asrs.service.WrkMastService;
|
import com.zy.core.cache.SlaveConnection;
|
import com.zy.core.enums.SlaveType;
|
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.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.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 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;
|
|
@Autowired
|
private WrkMastService wrkMastService;
|
|
@Autowired
|
private DeviceConfigService deviceConfigService;
|
|
@Autowired
|
private StationCycleCapacityService stationCycleCapacityService;
|
|
@Autowired
|
private FlowTopologySnapshotService flowTopologySnapshotService;
|
|
@Autowired
|
private ConfigService configService;
|
|
@Autowired
|
private BasStationService basStationService;
|
|
@Autowired
|
private BasDevpService basDevpService;
|
|
@Autowired
|
private BasCrnpService basCrnpService;
|
|
@Autowired
|
private BasDualCrnpService basDualCrnpService;
|
|
@Override
|
public AutoTuneSnapshot buildSnapshot() {
|
List<AutoTuneStationRuntimeItem> stationRuntimeSnapshot = buildStationRuntimeSnapshot();
|
|
AutoTuneSnapshot snapshot = new AutoTuneSnapshot();
|
snapshot.setTaskSnapshot(buildTaskSnapshot());
|
snapshot.setStationRuntimeSnapshot(stationRuntimeSnapshot);
|
snapshot.setCycleLoadSnapshot(buildCycleLoadSnapshot());
|
snapshot.setFlowTopologySnapshot(flowTopologySnapshotService.buildSnapshot(stationRuntimeSnapshot));
|
snapshot.setCurrentParameterSnapshot(buildCurrentParameterSnapshot());
|
snapshot.setSnapshotTime(new Date());
|
return snapshot;
|
}
|
|
private AutoTuneTaskSnapshot buildTaskSnapshot() {
|
List<WrkMast> activeTasks = loadActiveTasks();
|
|
AutoTuneTaskSnapshot snapshot = new AutoTuneTaskSnapshot();
|
snapshot.setActiveTaskCount(activeTasks.size());
|
snapshot.setByTargetStation(countByTargetStation(activeTasks));
|
snapshot.setByBatch(countByBatch(activeTasks));
|
snapshot.setByCrn(countByCrn(activeTasks));
|
snapshot.setByDualCrn(countByDualCrn(activeTasks));
|
snapshot.setByIoType(countByIoType(activeTasks));
|
return snapshot;
|
}
|
|
private List<WrkMast> loadActiveTasks() {
|
if (wrkMastService == null) {
|
return Collections.emptyList();
|
}
|
QueryWrapper<WrkMast> wrapper = new QueryWrapper<>();
|
wrapper.and(query -> query.notIn("wrk_sts", Arrays.asList(
|
WrkStsType.COMPLETE_INBOUND.sts,
|
WrkStsType.SETTLE_INBOUND.sts,
|
WrkStsType.COMPLETE_OUTBOUND.sts,
|
WrkStsType.SETTLE_OUTBOUND.sts,
|
WrkStsType.COMPLETE_LOC_MOVE.sts,
|
WrkStsType.COMPLETE_CRN_MOVE.sts
|
))
|
.or()
|
.isNull("wrk_sts"));
|
return safeList(wrkMastService.list(wrapper));
|
}
|
|
private List<AutoTuneStationRuntimeItem> buildStationRuntimeSnapshot() {
|
if (deviceConfigService == null) {
|
return Collections.emptyList();
|
}
|
QueryWrapper<DeviceConfig> wrapper = new QueryWrapper<>();
|
wrapper.eq("device_type", String.valueOf(SlaveType.Devp));
|
wrapper.orderByAsc("device_no");
|
List<DeviceConfig> deviceConfigList = safeList(deviceConfigService.list(wrapper));
|
Map<Integer, AutoTuneStationRuntimeItem> runtimeMap = new LinkedHashMap<>();
|
for (DeviceConfig deviceConfig : deviceConfigList) {
|
appendStationRuntime(runtimeMap, deviceConfig);
|
}
|
return new ArrayList<>(runtimeMap.values());
|
}
|
|
private void appendStationRuntime(Map<Integer, AutoTuneStationRuntimeItem> runtimeMap, DeviceConfig deviceConfig) {
|
if (deviceConfig == null || deviceConfig.getDeviceNo() == null) {
|
return;
|
}
|
StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, deviceConfig.getDeviceNo());
|
if (stationThread == null || stationThread.getStatusMap() == null) {
|
return;
|
}
|
for (StationProtocol protocol : stationThread.getStatusMap().values()) {
|
AutoTuneStationRuntimeItem runtimeItem = toRuntimeItem(protocol);
|
if (runtimeItem != null) {
|
runtimeMap.put(runtimeItem.getStationId(), runtimeItem);
|
}
|
}
|
}
|
|
private AutoTuneStationRuntimeItem toRuntimeItem(StationProtocol protocol) {
|
if (protocol == null || protocol.getStationId() == null) {
|
return null;
|
}
|
AutoTuneStationRuntimeItem item = new AutoTuneStationRuntimeItem();
|
item.setStationId(protocol.getStationId());
|
item.setAutoing(protocol.isAutoing() ? 1 : 0);
|
item.setLoading(protocol.isLoading() ? 1 : 0);
|
item.setTaskNo(protocol.getTaskNo() == null ? 0 : protocol.getTaskNo());
|
item.setIoMode(protocol.getIoMode() == null ? null : String.valueOf(protocol.getIoMode()));
|
return item;
|
}
|
|
private Map<String, Object> buildCycleLoadSnapshot() {
|
if (stationCycleCapacityService == null) {
|
return new LinkedHashMap<>();
|
}
|
return toCycleLoadMap(stationCycleCapacityService.getLatestSnapshot());
|
}
|
|
private Map<String, Object> toCycleLoadMap(StationCycleCapacityVo cycleCapacityVo) {
|
Map<String, Object> result = new LinkedHashMap<>();
|
if (cycleCapacityVo == null) {
|
return result;
|
}
|
result.put("loopList", toLoopMapList(cycleCapacityVo.getLoopList()));
|
result.put("loopCount", cycleCapacityVo.getLoopCount());
|
result.put("totalStationCount", cycleCapacityVo.getTotalStationCount());
|
result.put("taskStationCount", cycleCapacityVo.getTaskStationCount());
|
result.put("manualStationCount", cycleCapacityVo.getManualStationCount());
|
result.put("occupiedStationCount", cycleCapacityVo.getOccupiedStationCount());
|
result.put("currentLoad", cycleCapacityVo.getCurrentLoad());
|
result.put("refreshTime", cycleCapacityVo.getRefreshTime());
|
return result;
|
}
|
|
private List<Map<String, Object>> toLoopMapList(List<StationCycleLoopVo> loopList) {
|
List<Map<String, Object>> result = new ArrayList<>();
|
for (StationCycleLoopVo loopVo : safeList(loopList)) {
|
if (loopVo == null) {
|
continue;
|
}
|
Map<String, Object> loopMap = new LinkedHashMap<>();
|
loopMap.put("loopNo", loopVo.getLoopNo());
|
loopMap.put("stationIdList", loopVo.getStationIdList());
|
loopMap.put("workNoList", loopVo.getWorkNoList());
|
loopMap.put("stationCount", loopVo.getStationCount());
|
loopMap.put("taskCount", loopVo.getTaskCount());
|
loopMap.put("manualStationCount", loopVo.getManualStationCount());
|
loopMap.put("occupiedStationCount", loopVo.getOccupiedStationCount());
|
loopMap.put("currentLoad", loopVo.getCurrentLoad());
|
result.add(loopMap);
|
}
|
return result;
|
}
|
|
private AutoTuneParameterSnapshot buildCurrentParameterSnapshot() {
|
AutoTuneParameterSnapshot snapshot = new AutoTuneParameterSnapshot();
|
snapshot.setCrnOutBatchRunningLimit(readConfigInt(
|
"crnOutBatchRunningLimit",
|
DEFAULT_CRN_OUT_BATCH_RUNNING_LIMIT
|
));
|
snapshot.setConveyorStationTaskLimit(readConfigInt(
|
"conveyorStationTaskLimit",
|
DEFAULT_CONVEYOR_STATION_TASK_LIMIT
|
));
|
snapshot.setAiAutoTuneIntervalMinutes(readConfigInt(
|
"aiAutoTuneIntervalMinutes",
|
DEFAULT_AI_AUTO_TUNE_INTERVAL_MINUTES
|
));
|
List<BasCrnp> crnList = loadCrnList();
|
List<BasDualCrnp> dualCrnList = loadDualCrnList();
|
List<BasStation> outStationList = loadOutStationList();
|
snapshot.setStationOutTaskLimits(buildStationOutTaskLimitMap(outStationList));
|
snapshot.setStationOutBufferCapacities(buildStationOutBufferCapacityMap(outStationList));
|
snapshot.setCrnMaxOutTask(buildCrnMaxOutTask(crnList));
|
snapshot.setCrnMaxInTask(buildCrnMaxInTask(crnList));
|
snapshot.setDualCrnMaxOutTask(buildDualCrnMaxOutTask(dualCrnList));
|
snapshot.setDualCrnMaxInTask(buildDualCrnMaxInTask(dualCrnList));
|
return snapshot;
|
}
|
|
private int readConfigInt(String code, int defaultValue) {
|
if (configService == null) {
|
return defaultValue;
|
}
|
String value = configService.getConfigValue(code, String.valueOf(defaultValue));
|
if (value == null || value.trim().isEmpty()) {
|
return defaultValue;
|
}
|
try {
|
return Integer.parseInt(value.trim());
|
} catch (NumberFormatException exception) {
|
return defaultValue;
|
}
|
}
|
|
private List<BasStation> loadOutStationList() {
|
if (basStationService == null) {
|
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 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) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
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;
|
}
|
|
private Map<String, Integer> buildCrnMaxOutTask(List<BasCrnp> crnList) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (BasCrnp crn : safeList(crnList)) {
|
if (crn == null || crn.getCrnNo() == null) {
|
continue;
|
}
|
result.put(String.valueOf(crn.getCrnNo()), defaultInt(crn.getMaxOutTask()));
|
}
|
return result;
|
}
|
|
private Map<String, Integer> buildCrnMaxInTask(List<BasCrnp> crnList) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (BasCrnp crn : safeList(crnList)) {
|
if (crn == null || crn.getCrnNo() == null) {
|
continue;
|
}
|
result.put(String.valueOf(crn.getCrnNo()), defaultInt(crn.getMaxInTask()));
|
}
|
return result;
|
}
|
|
private Map<String, Integer> buildDualCrnMaxOutTask(List<BasDualCrnp> dualCrnList) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (BasDualCrnp dualCrn : safeList(dualCrnList)) {
|
if (dualCrn == null || dualCrn.getCrnNo() == null) {
|
continue;
|
}
|
result.put(String.valueOf(dualCrn.getCrnNo()), defaultInt(dualCrn.getMaxOutTask()));
|
}
|
return result;
|
}
|
|
private Map<String, Integer> buildDualCrnMaxInTask(List<BasDualCrnp> dualCrnList) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (BasDualCrnp dualCrn : safeList(dualCrnList)) {
|
if (dualCrn == null || dualCrn.getCrnNo() == null) {
|
continue;
|
}
|
result.put(String.valueOf(dualCrn.getCrnNo()), defaultInt(dualCrn.getMaxInTask()));
|
}
|
return result;
|
}
|
|
private List<BasCrnp> loadCrnList() {
|
if (basCrnpService == null) {
|
return Collections.emptyList();
|
}
|
QueryWrapper<BasCrnp> wrapper = new QueryWrapper<>();
|
wrapper.orderByAsc("crn_no");
|
return safeList(basCrnpService.list(wrapper));
|
}
|
|
private List<BasDualCrnp> loadDualCrnList() {
|
if (basDualCrnpService == null) {
|
return Collections.emptyList();
|
}
|
QueryWrapper<BasDualCrnp> wrapper = new QueryWrapper<>();
|
wrapper.orderByAsc("crn_no");
|
return safeList(basDualCrnpService.list(wrapper));
|
}
|
|
private Map<String, Integer> countByTargetStation(List<WrkMast> activeTasks) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (WrkMast task : activeTasks) {
|
increment(result, task == null ? null : task.getStaNo());
|
}
|
return result;
|
}
|
|
private Map<String, Integer> countByBatch(List<WrkMast> activeTasks) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (WrkMast task : activeTasks) {
|
String batch = task == null ? null : task.getBatch();
|
if (batch != null && !batch.trim().isEmpty()) {
|
increment(result, batch.trim());
|
}
|
}
|
return result;
|
}
|
|
private Map<String, Integer> countByCrn(List<WrkMast> activeTasks) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (WrkMast task : activeTasks) {
|
increment(result, task == null ? null : task.getCrnNo());
|
}
|
return result;
|
}
|
|
private Map<String, Integer> countByDualCrn(List<WrkMast> activeTasks) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (WrkMast task : activeTasks) {
|
increment(result, task == null ? null : task.getDualCrnNo());
|
}
|
return result;
|
}
|
|
private Map<String, Integer> countByIoType(List<WrkMast> activeTasks) {
|
Map<String, Integer> result = new LinkedHashMap<>();
|
for (WrkMast task : activeTasks) {
|
increment(result, task == null ? null : task.getIoType());
|
}
|
return result;
|
}
|
|
private void increment(Map<String, Integer> result, Integer key) {
|
if (key == null) {
|
return;
|
}
|
increment(result, String.valueOf(key));
|
}
|
|
private void increment(Map<String, Integer> result, String key) {
|
if (key == null || key.trim().isEmpty()) {
|
return;
|
}
|
String normalizedKey = key.trim();
|
result.put(normalizedKey, result.getOrDefault(normalizedKey, 0) + 1);
|
}
|
|
private int defaultInt(Integer value) {
|
return value == null ? 0 : value;
|
}
|
|
private <T> List<T> safeList(List<T> value) {
|
return value == null ? Collections.emptyList() : value;
|
}
|
}
|