潘志宝
2025-02-14 5695efca830831992f796b563a0b206969f97245
提交 | 用户 | 时间
7fd198 1 package com.iailab.module.model.api;
2
3 import com.alibaba.fastjson.JSON;
268c71 4 import com.alibaba.fastjson.JSONObject;
95066d 5 import com.iailab.module.data.api.point.DataPointApi;
D 6 import com.iailab.module.data.api.point.dto.ApiPointValueWriteDTO;
7 import com.iailab.module.model.api.mcs.dto.StScheduleModelOutDTO;
7fd198 8 import com.iailab.module.model.api.mdk.MdkApi;
9 import com.iailab.module.model.api.mdk.dto.*;
2b47c5 10 import com.iailab.module.model.common.enums.IsWriteEnum;
D 11 import com.iailab.module.model.common.enums.ModelOutResultType;
12 import com.iailab.module.model.common.enums.OutResultType;
5695ef 13 import com.iailab.module.model.enums.CommonConstant;
7fd198 14 import com.iailab.module.model.mcs.pre.entity.DmModuleEntity;
15 import com.iailab.module.model.mcs.pre.service.DmModuleService;
16 import com.iailab.module.model.mcs.pre.service.MmPredictItemService;
95066d 17 import com.iailab.module.model.mcs.sche.service.StScheduleModelOutService;
ac52ae 18 import com.iailab.module.model.mcs.sche.service.StScheduleRecordService;
19 import com.iailab.module.model.mcs.sche.service.StScheduleSchemeService;
7fd198 20 import com.iailab.module.model.mdk.predict.PredictModuleHandler;
9162d9 21 import com.iailab.module.model.mdk.predict.PredictResultHandler;
054fb9 22 import com.iailab.module.model.mdk.schedule.ScheduleModelHandler;
9162d9 23 import com.iailab.module.model.mdk.vo.DataValueVO;
7fd198 24 import com.iailab.module.model.mdk.vo.ItemVO;
25 import com.iailab.module.model.mdk.vo.PredictResultVO;
054fb9 26 import com.iailab.module.model.mdk.vo.ScheduleResultVO;
7fd198 27 import lombok.extern.slf4j.Slf4j;
5695ef 28 import org.apache.commons.lang3.StringUtils;
7fd198 29 import org.springframework.beans.factory.annotation.Autowired;
268c71 30 import org.springframework.data.redis.core.RedisTemplate;
9162d9 31 import org.springframework.util.CollectionUtils;
7fd198 32 import org.springframework.validation.annotation.Validated;
33 import org.springframework.web.bind.annotation.RestController;
34
b2aca2 35 import java.util.*;
268c71 36 import java.util.concurrent.TimeUnit;
7fd198 37 import java.util.stream.Collectors;
2b47c5 38
D 39 import static com.iailab.module.model.common.enums.ModelOutResultType.D;
7fd198 40
41 /**
42  * @author PanZhibao
43  * @Description
44  * @createTime 2024年08月26日
45  */
46 @Slf4j
47 @RestController
48 @Validated
49 public class MdkApiImpl implements MdkApi {
50
51     @Autowired
52     private DmModuleService dmModuleService;
53
54     @Autowired
55     private MmPredictItemService mmPredictItemService;
56
57     @Autowired
58     private PredictModuleHandler predictModuleHandler;
9162d9 59
60     @Autowired
61     private PredictResultHandler predictResultHandler;
054fb9 62
63     @Autowired
64     private ScheduleModelHandler scheduleModelHandler;
ac52ae 65
66     @Autowired
67     private StScheduleRecordService stScheduleRecordService;
68
69     @Autowired
70     private StScheduleSchemeService stScheduleSchemeService;
95066d 71
D 72     @Autowired
73     private StScheduleModelOutService stScheduleModelOutService;
74
75     @Autowired
76     private DataPointApi dataPointApi;
268c71 77
78     @Autowired
79     private RedisTemplate<String, Object> redisTemplate;
80
81     public static final long offset = 60 * 3L;
7fd198 82
83     /**
84      * 按模块预测
85      *
86      * @param reqDTO
87      * @return
88      */
89     @Override
148842 90     public MdkPredictModuleRespDTO predictModule(MdkPredictReqDTO reqDTO) {
7fd198 91         MdkPredictModuleRespDTO resp = new MdkPredictModuleRespDTO();
69bd5e 92         resp.setPredictTime(reqDTO.getPredictTime());
D 93         resp.setModuleType(reqDTO.getModuleType());
94
7fd198 95         Map<String, MdkPredictItemRespDTO> predictItemRespMap = new HashMap<>();
96         try {
97             if (reqDTO.getPredictTime() == null) {
98                 throw new Exception("PredictTime不能为空");
99             }
100             if (reqDTO.getModuleType() == null) {
101                 throw new Exception("ModuleType不能为空");
102             }
e691b9 103
7fd198 104             log.info("预测参数:" + JSON.toJSONString(reqDTO));
105             List<DmModuleEntity> moduleList = dmModuleService.getModuleByModuleType(reqDTO.getModuleType());
106             log.info("预测计算开始: " + System.currentTimeMillis());
107             for (DmModuleEntity module : moduleList) {
108                 int intervalTime = 0;
109                 if (module.getPredicttime() != null) {
110                     intervalTime = (int) (reqDTO.getPredictTime().getTime() - module.getPredicttime().getTime()) / (1000 * 60);
111                 }
112                 List<ItemVO> predictItemList = mmPredictItemService.getByModuleId(module.getId());
07890e 113                 Map<String, PredictResultVO> predictResultMap = new HashMap<>(predictItemList.size());
D 114                 // 分组,先运行normal预测项,再将结果传递给merge预测项
115                 List<ItemVO> normalItems = predictItemList.stream().filter(e -> e.getItemType().equals("NormalItem")).collect(Collectors.toList());
116                 if (!CollectionUtils.isEmpty(normalItems)) {
ac52ae 117                     predictModuleHandler.predict(normalItems, reqDTO.getPredictTime(), intervalTime, predictResultMap);
fde993 118                     List<ItemVO> mergeItems = predictItemList.stream().filter(e -> e.getItemType().equals("MergeItem")).collect(Collectors.toList());
D 119                     if (!CollectionUtils.isEmpty(mergeItems)) {
ac52ae 120                         predictModuleHandler.predict(mergeItems, reqDTO.getPredictTime(), intervalTime, predictResultMap);
07890e 121                     }
D 122                 }
4f1717 123                 // 更新Module时间
124                 dmModuleService.updatePredictTime(module.getId(), reqDTO.getPredictTime());
125                 if (reqDTO.getIsResult() == null || !reqDTO.getIsResult()) {
126                     return resp;
127                 }
128                 for (Map.Entry<String, PredictResultVO> entry : predictResultMap.entrySet()) {
129                     MdkPredictItemRespDTO itemResp = new MdkPredictItemRespDTO();
130                     itemResp.setItemId(entry.getKey());
131                     itemResp.setPredictTime(reqDTO.getPredictTime());
132                     Map<String, List<MdkPredictDataDTO>> itemPredictData = new HashMap<>();
133
134                     Map<String, List<DataValueVO>> predictLists = predictResultHandler.convertToPredictData2(entry.getValue());
135                     for (Map.Entry<String, List<DataValueVO>> dataListEntry : predictLists.entrySet()) {
136                         List<MdkPredictDataDTO> predictData = dataListEntry.getValue().stream().map(t -> {
137                             MdkPredictDataDTO dto1 = new MdkPredictDataDTO();
138                             dto1.setDataTime(t.getDataTime());
139                             dto1.setDataValue(t.getDataValue());
140                             return dto1;
141                         }).collect(Collectors.toList());
142                         itemPredictData.put(dataListEntry.getKey(), predictData);
143                     }
144                     itemResp.setPredictData(itemPredictData);
145                     predictItemRespMap.put(entry.getKey(), itemResp);
146                 }
7fd198 147             }
148             log.info("预测计算结束: " + System.currentTimeMillis());
149         } catch (Exception ex) {
148842 150             ex.printStackTrace();
151             return resp;
7fd198 152         }
153         resp.setPredictItemRespMap(predictItemRespMap);
148842 154         return resp;
7fd198 155     }
156
157     /**
158      * 单个预测
159      *
160      * @param reqDTO
161      * @return
162      */
163     @Override
148842 164     public MdkPredictItemRespDTO predictItem(MdkPredictReqDTO reqDTO) {
7fd198 165         MdkPredictItemRespDTO resp = new MdkPredictItemRespDTO();
9162d9 166         try {
1178da 167
D 168             ItemVO itemByItemNo = mmPredictItemService.getItemByItemNo(reqDTO.getItemNo());
169             List<ItemVO> predictItemList = new ArrayList<>();
170             predictItemList.add(itemByItemNo);
171             Map<String, PredictResultVO> predictResultMap = new HashMap<>(predictItemList.size());
ac52ae 172             predictModuleHandler.predict(predictItemList, reqDTO.getPredictTime(), 0, predictResultMap);
1178da 173
D 174             Map<String, List<MdkPredictDataDTO>> itemPredictData = new HashMap<>();
175
176             Map<String, List<DataValueVO>> predictLists = predictResultHandler.convertToPredictData2(predictResultMap.get(reqDTO.getItemNo()));
177             for (Map.Entry<String, List<DataValueVO>> dataListEntry : predictLists.entrySet()) {
178                 List<MdkPredictDataDTO> predictData = dataListEntry.getValue().stream().map(t -> {
179                     MdkPredictDataDTO dto1 = new MdkPredictDataDTO();
180                     dto1.setDataTime(t.getDataTime());
181                     dto1.setDataValue(t.getDataValue());
182                     return dto1;
183                 }).collect(Collectors.toList());
184                 itemPredictData.put(dataListEntry.getKey(), predictData);
9162d9 185             }
1178da 186             resp.setItemId(reqDTO.getItemNo());
9162d9 187             resp.setPredictTime(reqDTO.getPredictTime());
1178da 188             resp.setPredictData(itemPredictData);
D 189         } catch (Exception e) {
190             throw new RuntimeException(e);
9162d9 191         }
192
148842 193         return resp;
7fd198 194     }
195
196     /**
197      * 预测调整
198      *
199      * @param reqDTO
200      * @return
201      */
202     @Override
148842 203     public Boolean predictAutoAdjust(MdkPredictReqDTO reqDTO) {
7fd198 204
205
148842 206         return true;
7fd198 207     }
208
209     /**
210      * 执行调度模型
211      *
212      * @param reqDTO
213      * @return
214      */
215     @Override
148842 216     public MdkScheduleRespDTO doSchedule(MdkScheduleReqDTO reqDTO) {
7fd198 217         MdkScheduleRespDTO resp = new MdkScheduleRespDTO();
054fb9 218         resp.setScheduleCode(reqDTO.getScheduleCode());
219         resp.setScheduleTime(reqDTO.getScheduleTime());
220         try {
221             log.info("调度计算开始: " + System.currentTimeMillis());
bab433 222             log.info("reqDTO=" + JSON.toJSONString(reqDTO));
81ce77 223             ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getScheduleCode(), reqDTO.getScheduleTime(),
224                     reqDTO.getDynamicDataLength(), reqDTO.getDynamicSettings());
b2bb7d 225             resp.setStatusCode(scheduleResult.getResultCode());
054fb9 226             resp.setResult(scheduleResult.getResult());
ac52ae 227             stScheduleRecordService.create(scheduleResult);
b2bb7d 228             stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), scheduleResult.getResultCode());
054fb9 229             log.info("预测计算结束: " + System.currentTimeMillis());
230         } catch (Exception ex) {
231             log.info("调度计算异常: " + System.currentTimeMillis());
ac52ae 232             ex.printStackTrace();
148842 233             return resp;
054fb9 234         }
148842 235         return resp;
7fd198 236     }
95066d 237
268c71 238     /**
239      * 执行调度模型
240      *
241      * @param reqDTO
242      * @return
243      */
244     @Override
245     public MdkScheduleRespDTO runSchedule(MdkScheduleReqDTO reqDTO) {
246         MdkScheduleRespDTO resp = new MdkScheduleRespDTO();
d322fe 247         if (reqDTO.getScheduleTime() == null) {
248             Calendar calendar = Calendar.getInstance();
249             calendar.set(Calendar.MILLISECOND, 0);
250             calendar.set(Calendar.SECOND, 0);
f853b0 251             reqDTO.setScheduleTime(calendar.getTime());
d322fe 252         }
f853b0 253         resp.setScheduleCode(reqDTO.getScheduleCode());
254         resp.setScheduleTime(reqDTO.getScheduleTime());
268c71 255         String catchKey = "ScheduleResult:" + reqDTO.getScheduleCode();
256         try {
257             if (redisTemplate.hasKey(catchKey)) {
258                 log.info("查找调度结果缓存: " + catchKey);
e14de7 259                 return JSON.parseObject(redisTemplate.opsForValue().get(catchKey).toString(), MdkScheduleRespDTO.class);
268c71 260             }
261             log.info("调度计算开始: " + System.currentTimeMillis());
262             log.info("reqDTO=" + JSON.toJSONString(reqDTO));
263             ScheduleResultVO scheduleResult = scheduleModelHandler.doSchedule(reqDTO.getScheduleCode(), reqDTO.getScheduleTime(),
264                     reqDTO.getDynamicDataLength(), reqDTO.getDynamicSettings());
5695ef 265             if(StringUtils.isBlank(scheduleResult.getResultCode()) || !CommonConstant.MDK_STATUS_100.equals(scheduleResult.getResultCode())) {
266                 stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), CommonConstant.MDK_STATUS_500);
267                 throw new Exception("模型调用失败!");
268             }
268c71 269             resp.setStatusCode(scheduleResult.getResultCode());
270             resp.setResult(scheduleResult.getResult());
271             redisTemplate.opsForValue().set(catchKey, JSON.toJSONString(resp), offset, TimeUnit.SECONDS);
272             stScheduleSchemeService.updateTime(scheduleResult.getSchemeId(), scheduleResult.getScheduleTime(), scheduleResult.getResultCode());
273             log.info("预测计算结束: " + System.currentTimeMillis());
274         } catch (Exception ex) {
275             log.info("调度计算异常: " + System.currentTimeMillis());
276             ex.printStackTrace();
277             return resp;
278         }
279         return resp;
280     }
281
95066d 282     @Override
D 283     public Boolean scheduleModelOut(MdkScheduleRespDTO dto) {
284         String modelId = stScheduleSchemeService.getByCode(dto.getScheduleCode()).getModelId();
2b47c5 285         Map<String, Object> result = dto.getResult();
D 286         List<StScheduleModelOutDTO> list = stScheduleModelOutService.list(modelId);
287         try {
288             for (StScheduleModelOutDTO stScheduleModelOutDTO : list) {
289                 double value = 0;
290                 //判断点位是否下发
291                 if (stScheduleModelOutDTO.getIsWrite().equals(IsWriteEnum.NOTWRITE.value())) {
292                     continue;
293                 }
294                 //返回结果是否存在
295                 if (result.get(stScheduleModelOutDTO.getResultKey()) == null) {
296                     log.error(result.get(stScheduleModelOutDTO.getResultKey()) + "resultKey匹配失败");
297                     continue;
298                 }
299                 Object resultValue = result.get(stScheduleModelOutDTO.getResultKey());
300                 //判断解析方式
301                 ModelOutResultType modelOutResultType = ModelOutResultType.getEumByCode(stScheduleModelOutDTO.getResultType());
302                 switch (modelOutResultType) {
303                     case D:
7628fc 304                         if (resultValue instanceof Integer) {
D 305                              value = ((Integer) resultValue).doubleValue();
306                         } else if (resultValue instanceof Double) {
307                              value = (Double) resultValue;
308                         } else {
309                             System.out.println("resultValue is not a number");
310                         }
2b47c5 311                         break;
D 312                     case D1:
313                         ArrayList<Double> doubleList = (ArrayList<Double>) resultValue;
314                         double[] array1 = new double[doubleList.size()];
315                         for (int i = 0; i < doubleList.size(); i++) {
316                             array1[i] = doubleList.get(i);
95066d 317                         }
2b47c5 318                         if (stScheduleModelOutDTO.getResultPort() < array1.length) {
D 319                             value = array1[stScheduleModelOutDTO.getResultPort()];
320                         } else {
321                             log.error(result.get(stScheduleModelOutDTO.getResultKey()) + "下角标超限");
322                         }
323                         break;
324                     case D2:
325                         ArrayList<ArrayList<Double>> doubleListList = (ArrayList<ArrayList<Double>>) resultValue;
326                         double[][] array2 = new double[doubleListList.size()][];
327                         for (int i = 0; i < doubleListList.size(); i++) {
328                             ArrayList<Double> doubleList2 = doubleListList.get(i);
329                             array2[i] = new double[doubleList2.size()];
330                             for (int j = 0; j < doubleList2.size(); j++) {
331                                 array2[i][j] = doubleList2.get(j);
332                             }
333                         }
334                         if (stScheduleModelOutDTO.getResultPort() < array2.length && stScheduleModelOutDTO.getResultIndex() < array2[stScheduleModelOutDTO.getResultPort()].length) {
335                             value = array2[stScheduleModelOutDTO.getResultPort()][stScheduleModelOutDTO.getResultIndex()];
336                         } else {
337                             log.error(result.get(stScheduleModelOutDTO.getResultKey()) + "下标超限");
338                         }
339                         break;
340                 }
341                 //下发到point点位
342                 ApiPointValueWriteDTO ApiPointValueWriteDTO = new ApiPointValueWriteDTO();
343                 ApiPointValueWriteDTO.setPointNo(stScheduleModelOutDTO.getPointNo());
344                 ApiPointValueWriteDTO.setValue(value);
345                 if (!dataPointApi.writePointRealValue(ApiPointValueWriteDTO)) {
346                     log.error(result.get(stScheduleModelOutDTO.getResultKey()) + "下发数据异常");
347                 }
348             }
349         } catch (Exception ex) {
95066d 350             log.error("下发数据异常");
D 351             ex.printStackTrace();
352         }
353         return true;
354     }
7fd198 355 }