提交 | 用户 | 时间
a6de49 1 package com.iailab.module.job.task;
H 2
3 import com.alibaba.fastjson.JSON;
4 import com.alibaba.fastjson.JSONArray;
5 import com.iailab.framework.common.util.object.ConvertUtils;
6 import com.iailab.common.utils.DateUtils;
7 import com.iailab.module.device.commons.HealthIndexTypeEnum;
8 import com.iailab.module.device.commons.HealthLevelEnum;
9 import com.iailab.module.device.entity.DeviceStatCountEntity;
10 import com.iailab.module.device.entity.DeviceStatNewnessEntity;
11 import com.iailab.module.device.dto.*;
12 import com.iailab.module.device.service.*;
13 import com.iailab.module.model.handler.ModelHandler;
14 import com.iailab.module.model.sample.constructor.SampleDataConstructor;
15 import com.iailab.module.model.sample.constructor.SampleInfoConstructor;
16 import com.iailab.module.model.sample.dto.ColumnItem;
17 import com.iailab.module.model.sample.entity.DataEntity;
325d2f 18 import com.xxl.job.core.handler.annotation.XxlJob;
a6de49 19 import org.apache.commons.lang3.StringUtils;
H 20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import javax.annotation.Resource;
23 import org.springframework.stereotype.Component;
24 import org.springframework.util.CollectionUtils;
25
26 import java.math.BigDecimal;
27 import java.util.*;
28 import java.util.stream.Collectors;
29
30 /**
31  * 设备健康评价
32  * 10 0 0/1 * * ?
33  *
34  * @author PanZhibao
35  * @Description
36  * @createTime 2024年06月29日
37  */
38 @Component("deviceHealthTask")
39 public class DeviceHealthTask implements ITask {
40     private Logger logger = LoggerFactory.getLogger(getClass());
41
42
43     private BigDecimal DEFAULT_HEALTH_SCORE = new BigDecimal(100);
44
45     private String DEFAULT_REPORT_CONTENT = "设备运行正常";
46
47     private int DEFAULT_DATA_LENGTH = 60;
48
49     @Resource
50     private DeviceHealthEvaluateService deviceHealthEvaluateService;
51
52     @Resource
53     private DeviceEvaluateIndexService deviceEvaluateIndexService;
54
55     @Resource
56     private SampleInfoConstructor sampleInfoConstructor;
57
58     @Resource
59     private SampleDataConstructor sampleDataConstructor;
60
61     @Resource
62     private ModelHandler modelHandler;
63
64     @Resource
65     private DeviceHealthReportService deviceHealthReportService;
66
67     @Resource
68     private DeviceStatCountService deviceStatCountService;
69
70     @Resource
71     private DeviceInfoService deviceInfoService;
72
73     @Resource
74     private DeviceFaultService deviceFaultService;
75
76     @Resource
77     private DeviceStatNewnessService deviceStatNewnessService;
78
79     private final int GRANULARITY = 60;
80
81     private Map<Integer, String> HEALTH_FAULT_TYPE = new HashMap<>();
82     private Map<String, String> ALARM_INDEX_TYPE = new HashMap<>();
83
84     private String[] indexArr = new String[]{HealthIndexTypeEnum.elec.getCode(), HealthIndexTypeEnum.temperature.getCode(),
85             HealthIndexTypeEnum.flutter.getCode(), HealthIndexTypeEnum.runTime.getCode()};
86
87
88
89     DeviceHealthTask() {
90         HEALTH_FAULT_TYPE.put(1, "波动正常,趋势正常");
91         HEALTH_FAULT_TYPE.put(2, "波动正常,趋势异常");
92         HEALTH_FAULT_TYPE.put(3, "波动异常,趋势正常");
93         HEALTH_FAULT_TYPE.put(4, "波动异常,趋势异常");
94
95         ALARM_INDEX_TYPE.put("temperature", "温度");
96         ALARM_INDEX_TYPE.put("flutter", "震动");
97         ALARM_INDEX_TYPE.put("elec", "电流");
98     }
99
100     @Override
325d2f 101     @XxlJob("deviceHealthTask")
a6de49 102     public void run(String params) {
H 103         Calendar calendar = Calendar.getInstance();
104         calendar.set(Calendar.MILLISECOND, 0);
105         calendar.set(Calendar.SECOND, 0);
106         try {
107             List<DeviceStatNewnessEntity> newnessList = new ArrayList<>();
108             Map<String, Object> queryParams = new HashMap<>();
109             queryParams.put("isEnable", 1);
110             List<DeviceHealthEvaluateDTO> evaList = deviceHealthEvaluateService.list(queryParams);
111             if (CollectionUtils.isEmpty(evaList)) {
112                 return;
113             }
114             // 开始健康评价
115             evaList.forEach(item -> {
116                 this.runModel(item, calendar.getTime(), newnessList);
117             });
118
119             // 统计数量
120             deviceStatCount(calendar);
121
122             // 更新设备新度系数
123             deviceStatNewnessService.statNewness(newnessList, calendar.getTime());
124
125         } catch (Exception ex) {
126             logger.error("DeviceHealthTask运行异常");
127             ex.printStackTrace();
128         }
129         logger.info("DeviceHealthTask运行完成");
130     }
131
132     public void runModel(DeviceHealthEvaluateDTO dto, Date runTime, List<DeviceStatNewnessEntity> newnessList) {
133         try {
134             List<DeviceEvaluateIndexDTO> indexList = deviceEvaluateIndexService.listByEvaluateId(dto.getId());
135             if (CollectionUtils.isEmpty(indexList)) {
136                 DeviceHealthEvaluateDTO updateDto = new DeviceHealthEvaluateDTO();
137                 updateDto.setId(dto.getId());
138                 updateDto.setReportContent(DEFAULT_REPORT_CONTENT);
139                 updateDto.setReportDate(runTime);
140                 updateDto.setReportId("");
141                 updateDto.setAbnormalCount(0);
142                 updateDto.setHealthScore(DEFAULT_HEALTH_SCORE);
143                 updateDto.setHealthLevel(HealthLevelEnum.Level1.getCode());
144                 deviceHealthEvaluateService.updateReport(updateDto);
145                 return;
146             }
147             Map<String, DeviceEvaluateIndexDTO> indexMap = new HashMap<>();
148             indexList.forEach(item -> {
149                 indexMap.put(item.getIndexType(), item);
150             });
151
152             DEFAULT_DATA_LENGTH = indexList.get(0).getDataLength();
153
154             ColumnItem columnItem = new ColumnItem();
155             columnItem.setEndTime(runTime);
156             columnItem.setStartTime(sampleInfoConstructor.calculateTime(runTime, true, DEFAULT_DATA_LENGTH - 1, GRANULARITY));
157             List<double[][]> sampleDataList = new ArrayList<>();
158             Map<String, List<DataEntity>> dataMap = new LinkedHashMap<>();
159
160             double[][] matrix1 = new double[DEFAULT_DATA_LENGTH][indexArr.length];
161             double[][] matrix2 = new double[1][3];
162             for (int i = 0; i < indexArr.length; i++) {
163                 if (indexMap.get(indexArr[i]) == null) {
164                     for (int k = 0; k < DEFAULT_DATA_LENGTH; k++) {
165                         matrix1[k][i] = -2;
166                     }
167                     continue;
168                 }
169                 DeviceEvaluateIndexDTO indDTO = indexMap.get(indexArr[i]);
170                 columnItem.setParamId(indDTO.getParamId());
171                 columnItem.setParamType(indDTO.getParamType());
172                 List<DataEntity> dataEntityList = sampleDataConstructor.getColumnData(columnItem);
173                 logger.info("BEF:ParamType=" + indDTO.getParamType() + ";ParamId=" + indDTO.getParamId() + ";size=" + dataEntityList.size());
174                 //补全数据
175                 dataEntityList = sampleDataConstructor.completionData(matrix1.length, dataEntityList, columnItem.startTime, columnItem.endTime, GRANULARITY);
176                 logger.info("AFT:ParamType=" + indDTO.getParamType() + ";ParamId=" + indDTO.getParamId() + ";size=" + dataEntityList.size());
177                 if (CollectionUtils.isEmpty(dataEntityList)) {
178                     continue;
179                 }
180                 for (int k = 0; k < DEFAULT_DATA_LENGTH; k++) {
181                     matrix1[k][i] = dataEntityList.get(k).getDataValue();
182                 }
183                 dataMap.put(indexArr[i], dataEntityList);
184
185                 if (i < 3) {
186                     matrix2[0][i] = indDTO.getNominalValue().doubleValue();
187                 }
188             }
189             sampleDataList.add(matrix1);
190             sampleDataList.add(matrix2);
191
192             // 调用模型
193             logger.info("调用模型,DevNo=" + dto.getDevNo());
194             Map<String, Object> modelCommonResult = modelHandler.run(dto.getModelCode(), sampleDataList);
195
196             // 生成评价报告
197             this.saveReport(dto, runTime, modelCommonResult, dataMap, indexMap);
198
199             // 更新新度系数
200             if (modelCommonResult.get("run_time_adjust") != null) {
201                 DeviceStatNewnessEntity deviceStatNewness = new DeviceStatNewnessEntity();
202                 deviceStatNewness.setDevNo(dto.getDevNo());
203                 deviceStatNewness.setDevName(dto.getDevName());
204                 deviceStatNewness.setRunTime(new BigDecimal(modelCommonResult.get("run_time_normal").toString()).intValue());
205                 deviceStatNewness.setLossTime(new BigDecimal(modelCommonResult.get("run_time_adjust").toString()).intValue());
206                 deviceStatNewness.setLossRate(new BigDecimal(deviceStatNewness.getLossTime()).divide(new BigDecimal(deviceStatNewness.getRunTime()),2,BigDecimal.ROUND_HALF_UP));
207                 newnessList.add(deviceStatNewness);
208             }
209         } catch (Exception ex) {
210             ex.printStackTrace();
211             logger.error("设备健康评价计算异常,devNo=" + dto.getDevNo());
212         }
213     }
214
215     public void saveReport(DeviceHealthEvaluateDTO evaluateDTO, Date runTime, Map<String, Object> modelCommonResult,
216                            Map<String, List<DataEntity>> dataMap, Map<String, DeviceEvaluateIndexDTO> indexMap) {
217
218         DeviceInfoDTO deviceInfo = deviceInfoService.getByDevNo(evaluateDTO.getDevNo());
219
220         DeviceHealthReportDTO reportDTO = new DeviceHealthReportDTO();
221         reportDTO.setId(UUID.randomUUID().toString());
222         reportDTO.setReportNo("H" + DateUtils.format(runTime, "yyyyMMddHHmmss") + getRand(evaluateDTO.getDevNo()));
223         reportDTO.setReportName(evaluateDTO.getDevName() + "健康评价报告");
224         reportDTO.setReportDate(runTime);
225         String deviceHealthLevel = modelCommonResult.get("isqualified").toString();
226         reportDTO.setHealthLevel(deviceHealthLevel);
227         reportDTO.setAbnormalCount(getAbnormalCount(JSONArray.toJSONString(modelCommonResult.get("part_grade"))));
228         reportDTO.setContent(modelCommonResult.get("health_evaluate").toString());
229         reportDTO.setHealthScore(new BigDecimal(modelCommonResult.get("health_score").toString()));
230         reportDTO.setDataLength(DEFAULT_DATA_LENGTH);
231         reportDTO.setRunTime(new BigDecimal(modelCommonResult.get("run_time_adjust").toString()).intValue());
232         reportDTO.setDevNo(evaluateDTO.getDevNo());
233         reportDTO.setDevName(evaluateDTO.getDevName());
234         if (deviceInfo != null) {
235             reportDTO.setClassNo(deviceInfo.getClassNo());
236             reportDTO.setClassName(deviceInfo.getClassName());
237             reportDTO.setWorkshop(deviceInfo.getWorkshop());
238             reportDTO.setModel(deviceInfo.getModel());
239         }
240         List<Integer> partGrade = getIntValueArr(modelCommonResult.get("part_grade"));
241         List<BigDecimal> maxArr = getValueArr(modelCommonResult.get("max_arr"));
242         List<BigDecimal> minArr = getValueArr(modelCommonResult.get("min_arr"));
243         List<BigDecimal> meanArr = getValueArr(modelCommonResult.get("mean_arr"));
244         List<DeviceHealthReportDataDTO> detList = new ArrayList<>();
245         List<DeviceHealthAlarmDetailDTO> deviceHealthAlarmDetailDTOList = new ArrayList<>();
246         List<String> alarmIndexTypes = new ArrayList<>();
247         List<String> alarmSolutions = new ArrayList<>();
248         // 故障id
249         String alarmId = UUID.randomUUID().toString();
250         for (int i = 0; i < indexArr.length; i++) {
251             List<DataEntity> dataList = dataMap.get(indexArr[i]);
252             if (CollectionUtils.isEmpty(dataList)) {
253                 continue;
254             }
255             List<Object[]> dataCont = dataList.stream().map(t -> {
256                 return new Object[]{DateUtils.format(t.getTimeStamp(), DateUtils.DATE_TIME_PATTERN_MIN), new BigDecimal(t.getDataValue()).setScale(4, BigDecimal.ROUND_HALF_UP)};
257             }).collect(Collectors.toList());
258             DeviceHealthReportDataDTO det = new DeviceHealthReportDataDTO();
259             det.setSort(i);
260             det.setDataName(indexMap.get(indexArr[i]).getParamName());
261             det.setDataValue(JSONArray.toJSONString(dataCont));
262             if (!HealthIndexTypeEnum.runTime.getCode().equals(indexArr[i])) {
263                 det.setDataMax(maxArr.get(i));
264                 det.setDataMin(minArr.get(i));
265                 det.setDataAvg(meanArr.get(i));
266                 det.setGradeCode(partGrade.get(i).toString());
267                 det.setGradeName(HEALTH_FAULT_TYPE.get(partGrade.get(i)));
268
269                 DeviceFaultDTO querySoluDto = new DeviceFaultDTO();
270                 querySoluDto.setClassNo(deviceInfo.getClassNo());
271                 querySoluDto.setIndexType(indexArr[i]);
272                 querySoluDto.setFaultType(det.getGradeCode());
273                 DeviceFaultDTO faultDTO = deviceFaultService.getSolution(querySoluDto);
274                 if (faultDTO != null) {
275                     det.setSolution(faultDTO.getSolution());
276                     det.setFaultCode(faultDTO.getFaultCode());
277                 }
278
279                 // 设备健康故障详情记录
280                 if (HealthLevelEnum.Level3.getCode().equals(deviceHealthLevel) && faultDTO != null){
281                     DeviceHealthAlarmDetailDTO deviceHealthAlarmDetail = new DeviceHealthAlarmDetailDTO();
282                     deviceHealthAlarmDetail.setId(UUID.randomUUID().toString());
283                     deviceHealthAlarmDetail.setAlarmId(alarmId);
284                     deviceHealthAlarmDetail.setFaultCode(faultDTO.getFaultCode());
285                     deviceHealthAlarmDetail.setFaultName(HEALTH_FAULT_TYPE.get(partGrade.get(i)));
286                     deviceHealthAlarmDetail.setSolution(faultDTO.getSolution());
287
288                     alarmIndexTypes.add(ALARM_INDEX_TYPE.get(faultDTO.getIndexType()));
289                     alarmSolutions.add(faultDTO.getSolution());
290                     deviceHealthAlarmDetailDTOList.add(deviceHealthAlarmDetail);
291                 }
292             } else {
293                 StringBuilder rsb = new StringBuilder();
294                 rsb.append("运行时长:");
295                 rsb.append(modelCommonResult.get("run_time_normal").toString());
296                 det.setRemark(rsb.toString());
297             }
298             detList.add(det);
299         }
300
301         // 设备健康故障记录
302         if (deviceHealthAlarmDetailDTOList.size() > 0) {
303             DeviceHealthAlarmDTO deviceHealthAlarm = new DeviceHealthAlarmDTO();
304             deviceHealthAlarm.setId(alarmId);
305             deviceHealthAlarm.setReportId(reportDTO.getId());
306             deviceHealthAlarm.setDevNo(evaluateDTO.getDevNo());
307             deviceHealthAlarm.setDevName(evaluateDTO.getDevName());
308             deviceHealthAlarm.setFaultTime(runTime);
309             deviceHealthAlarm.setIsPushed(0);
310             deviceHealthAlarm.setPushType(evaluateDTO.getIsPushed() == 0 ? 2 : 1);
311             deviceHealthAlarm.setCreateDate(new Date());
312             deviceHealthAlarm.setAlarmIndexTypes(String.join(",", alarmIndexTypes));
313             deviceHealthAlarm.setAlarmSolutions(String.join("\n", alarmSolutions));
314
315             reportDTO.setDeviceHealthAlarm(deviceHealthAlarm);
316             reportDTO.setDeviceHealthAlarmDetails(deviceHealthAlarmDetailDTOList);
317         }
318         reportDTO.setDetList(detList);
319
320         deviceHealthReportService.save(reportDTO);
321
322         DeviceHealthEvaluateDTO updateDto = new DeviceHealthEvaluateDTO();
323         updateDto.setId(evaluateDTO.getId());
324         updateDto.setReportContent(reportDTO.getContent());
325         updateDto.setReportDate(runTime);
326         updateDto.setReportId(reportDTO.getId());
327         updateDto.setAbnormalCount(reportDTO.getAbnormalCount());
328         updateDto.setHealthScore(reportDTO.getHealthScore());
329         updateDto.setHealthLevel(reportDTO.getHealthLevel());
330         deviceHealthEvaluateService.updateReport(updateDto);
331     }
332     public void deviceStatCount(Calendar calendar) {
333         DeviceStatCountDTO deviceStatCountDTO = deviceStatCountService.getDeviceStatCount();
334         DeviceStatCountEntity deviceStatCount = ConvertUtils.sourceToTarget(deviceStatCountDTO, DeviceStatCountEntity.class);
335         deviceStatCount.setId(UUID.randomUUID().toString());
336         deviceStatCount.setDate(calendar.getTime());
337         deviceStatCount.setCreateDate(new Date());
338         deviceStatCountService.insert(deviceStatCount);
339     }
340
341     private String getRand(String devNo) {
342         String t = Long.toString(System.currentTimeMillis());
343         return devNo.substring(0, 1) + t.substring(t.length() - 4);
344     }
345
346     private int getAbnormalCount(String partGrade) {
347         int result = 0;
348         if (StringUtils.isBlank(partGrade)) {
349             return result;
350         }
351         List<Integer> pgList = JSONArray.parseArray(partGrade, Integer.class);
352         if (CollectionUtils.isEmpty(pgList)) {
353             return result;
354         }
355         for (int i = 0; i < pgList.size(); i++) {
356             if (pgList.get(i) != 1) {
357                 result = result + 1;
358             }
359         }
360         return result;
361     }
362
363     private List<BigDecimal> getValueArr(Object value) {
364         List<BigDecimal> result = new ArrayList<>();
365         if (value == null) {
366             return result;
367         }
368         result = JSONArray.parseArray(JSON.toJSONString(value), BigDecimal.class);
369         return result;
370
371     }
372
373     private List<Integer> getIntValueArr(Object value) {
374         List<Integer> result = new ArrayList<>();
375         if (value == null) {
376             return result;
377         }
378         result = JSONArray.parseArray(JSON.toJSONString(value), Integer.class);
379         return result;
380
381     }
382 }