潘志宝
2025-03-24 fa8ae4322ab7cc3bf6067c418469b158f23efad6
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
@@ -1,6 +1,7 @@
package com.iailab.module.model.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iailab.module.data.api.point.DataPointApi;
import com.iailab.module.data.api.point.dto.ApiPointValueWriteDTO;
import com.iailab.module.model.api.mcs.dto.StScheduleModelOutDTO;
@@ -8,30 +9,34 @@
import com.iailab.module.model.api.mdk.dto.*;
import com.iailab.module.model.common.enums.IsWriteEnum;
import com.iailab.module.model.common.enums.ModelOutResultType;
import com.iailab.module.model.common.enums.OutResultType;
import com.iailab.module.model.enums.CommonConstant;
import com.iailab.module.model.enums.PredictItemTypeEnum;
import com.iailab.module.model.mcs.pre.entity.DmModuleEntity;
import com.iailab.module.model.mcs.pre.service.DmModuleService;
import com.iailab.module.model.mcs.pre.service.MmPredictItemService;
import com.iailab.module.model.mcs.sche.entity.StAdjustConfigDetEntity;
import com.iailab.module.model.mcs.sche.entity.StAdjustConfigEntity;
import com.iailab.module.model.mcs.sche.entity.StScheduleSchemeEntity;
import com.iailab.module.model.mcs.sche.service.StAdjustConfigService;
import com.iailab.module.model.mcs.sche.service.StScheduleModelOutService;
import com.iailab.module.model.mcs.sche.service.StScheduleRecordService;
import com.iailab.module.model.mcs.sche.service.StScheduleSchemeService;
import com.iailab.module.model.mdk.predict.PredictModuleHandler;
import com.iailab.module.model.mdk.predict.PredictResultHandler;
import com.iailab.module.model.mdk.schedule.ScheduleModelHandler;
import com.iailab.module.model.mdk.vo.DataValueVO;
import com.iailab.module.model.mdk.vo.ItemVO;
import com.iailab.module.model.mdk.vo.PredictResultVO;
import com.iailab.module.model.mdk.vo.ScheduleResultVO;
import com.iailab.module.model.mdk.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.iailab.module.model.common.enums.ModelOutResultType.D;
/**
 * @author PanZhibao
@@ -70,6 +75,14 @@
    @Autowired
    private DataPointApi dataPointApi;
    @Autowired
    private StAdjustConfigService stAdjustConfigService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    public static final long offset = 60 * 3L;
    /**
     * 按模块预测
     *
@@ -90,15 +103,8 @@
            if (reqDTO.getModuleType() == null) {
                throw new Exception("ModuleType不能为空");
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(reqDTO.getPredictTime());
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            reqDTO.setPredictTime(calendar.getTime());
            log.info("预测参数:" + JSON.toJSONString(reqDTO));
            MdkPredictModuleRespDTO result = new MdkPredictModuleRespDTO();
            result.setPredictTime(reqDTO.getPredictTime());
            result.setModuleType(reqDTO.getModuleType());
            List<DmModuleEntity> moduleList = dmModuleService.getModuleByModuleType(reqDTO.getModuleType());
            log.info("预测计算开始: " + System.currentTimeMillis());
            for (DmModuleEntity module : moduleList) {
@@ -190,6 +196,60 @@
        return resp;
    }
    @Override
    public Boolean predictSimAdjust(MdkPredictSimAdjustReqDTO reqDTO) {
        log.info("开始模拟调整");
        log.info("ModelResult:" + JSONObject.toJSONString(reqDTO.getModelResult()));
        StScheduleSchemeEntity scheduleScheme = stScheduleSchemeService.getByCode(reqDTO.getScheduleCode());
        Map<StAdjustConfigEntity, List<StAdjustConfigDetEntity>> configMap = stAdjustConfigService.getAdjustConfigMap(scheduleScheme.getModelId());
        if (CollectionUtils.isEmpty(configMap)) {
            return Boolean.FALSE;
        }
        for (Map.Entry<StAdjustConfigEntity, List<StAdjustConfigDetEntity>> entry : configMap.entrySet()) {
            log.info("AdjustConfigID=" + entry.getKey().getId());
            if (CollectionUtils.isEmpty(entry.getValue())) {
                continue;
            }
            String firstOutKey = entry.getValue().get(0).getOutKey();
            if(StringUtils.isBlank(firstOutKey)) {
                continue;
            }
            if(reqDTO.getModelResult().get(firstOutKey) == null || StringUtils.isBlank(reqDTO.getModelResult().get(firstOutKey).toString())) {
                continue;
            }
            BigDecimal firstAdjustValue = new BigDecimal(reqDTO.getModelResult().get(firstOutKey.trim()).toString().trim());
            if (BigDecimal.ZERO.compareTo(firstAdjustValue) == 0) {
                log.info("firstAdjustValue = ZERO");
                continue;
            }
            for (StAdjustConfigDetEntity det : entry.getValue()) {
                ItemVO predictItem = mmPredictItemService.getItemById(det.getPredictItemId());
                List<StAdjustDeviationDTO> deviationList = new ArrayList<>();
                switch (PredictItemTypeEnum.getEumById(det.getItemTypeId())) {
                    case NormalItem:
                        double adjustValue = 0;
                        if (StringUtils.isNotBlank(det.getOutKey())) {
                            adjustValue = new BigDecimal(reqDTO.getModelResult().get(det.getOutKey()).toString()).doubleValue();
                        }
                        StAdjustDeviationDTO deviationItem = new StAdjustDeviationDTO();
                        deviationItem.setPortIdx(det.getModelParamPortOrder() == null ? 0 : det.getModelParamPortOrder());
                        deviationItem.setParamIdx(det.getModelParamOrder() == null ? 0 : det.getModelParamOrder());
                        deviationItem.setValue(adjustValue);
                        deviationList.add(deviationItem);
                        break;
                    case MergeItem:
                        break;
                    default:
                        break;
                }
                // 开始预测
                predictModuleHandler.predictAdjust(predictItem, reqDTO.getPredictTime(), deviationList, scheduleScheme.getModelId(), det.getConfigId());
            }
        }
        return Boolean.TRUE;
    }
    /**
     * 预测调整
     *
@@ -216,10 +276,56 @@
        resp.setScheduleTime(reqDTO.getScheduleTime());
        try {
            log.info("调度计算开始: " + System.currentTimeMillis());
            ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getScheduleCode(), reqDTO.getScheduleTime(), reqDTO.getDynamicDataLength());
            log.info("reqDTO=" + JSON.toJSONString(reqDTO));
            ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getScheduleCode(), reqDTO.getScheduleTime(),
                    reqDTO.getDynamicDataLength(), reqDTO.getDynamicSettings());
            resp.setStatusCode(scheduleResult.getResultCode());
            resp.setResult(scheduleResult.getResult());
            stScheduleRecordService.create(scheduleResult);
            stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), scheduleResult.getResultCode());
            log.info("预测计算结束: " + System.currentTimeMillis());
        } catch (Exception ex) {
            log.info("调度计算异常: " + System.currentTimeMillis());
            ex.printStackTrace();
            return resp;
        }
        return resp;
    }
    /**
     * 执行调度模型
     *
     * @param reqDTO
     * @return
     */
    @Override
    public MdkScheduleRespDTO runSchedule(MdkScheduleReqDTO reqDTO) {
        MdkScheduleRespDTO resp = new MdkScheduleRespDTO();
        if (reqDTO.getScheduleTime() == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.SECOND, 0);
            reqDTO.setScheduleTime(calendar.getTime());
        }
        resp.setScheduleCode(reqDTO.getScheduleCode());
        resp.setScheduleTime(reqDTO.getScheduleTime());
        String catchKey = "ScheduleResult:" + reqDTO.getScheduleCode();
        try {
            if (redisTemplate.hasKey(catchKey)) {
                log.info("查找调度结果缓存: " + catchKey);
                return JSON.parseObject(redisTemplate.opsForValue().get(catchKey).toString(), MdkScheduleRespDTO.class);
            }
            log.info("调度计算开始: " + System.currentTimeMillis());
            log.info("reqDTO=" + JSON.toJSONString(reqDTO));
            ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getScheduleCode(), reqDTO.getScheduleTime(),
                    reqDTO.getDynamicDataLength(), reqDTO.getDynamicSettings());
            if(StringUtils.isBlank(scheduleResult.getResultCode()) || !CommonConstant.MDK_STATUS_100.equals(scheduleResult.getResultCode())) {
                stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), CommonConstant.MDK_STATUS_500);
                throw new Exception("模型调用失败!");
            }
            resp.setStatusCode(scheduleResult.getResultCode());
            resp.setResult(scheduleResult.getResult());
            redisTemplate.opsForValue().set(catchKey, JSON.toJSONString(resp), offset, TimeUnit.SECONDS);
            stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), scheduleResult.getResultCode());
            log.info("预测计算结束: " + System.currentTimeMillis());
        } catch (Exception ex) {
@@ -244,7 +350,7 @@
                }
                //返回结果是否存在
                if (result.get(stScheduleModelOutDTO.getResultKey()) == null) {
                    log.error(result.get(stScheduleModelOutDTO.getResultKey()) + "resultKey匹配失败");
                    log.error(stScheduleModelOutDTO.getResultKey() + "resultKey匹配失败");
                    continue;
                }
                Object resultValue = result.get(stScheduleModelOutDTO.getResultKey());
@@ -252,7 +358,13 @@
                ModelOutResultType modelOutResultType = ModelOutResultType.getEumByCode(stScheduleModelOutDTO.getResultType());
                switch (modelOutResultType) {
                    case D:
                        value = (Double) resultValue;
                        if (resultValue instanceof Integer) {
                             value = ((Integer) resultValue).doubleValue();
                        } else if (resultValue instanceof Double) {
                             value = (Double) resultValue;
                        } else {
                            System.out.println("resultValue is not a number");
                        }
                        break;
                    case D1:
                        ArrayList<Double> doubleList = (ArrayList<Double>) resultValue;