package com.iailab.module.job.task; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.iailab.framework.common.util.object.ConvertUtils; import com.iailab.common.utils.DateUtils; import com.iailab.module.device.commons.HealthIndexTypeEnum; import com.iailab.module.device.commons.HealthLevelEnum; import com.iailab.module.device.entity.DeviceStatCountEntity; import com.iailab.module.device.entity.DeviceStatNewnessEntity; import com.iailab.module.device.dto.*; import com.iailab.module.device.service.*; import com.iailab.module.model.handler.ModelHandler; import com.iailab.module.model.sample.constructor.SampleDataConstructor; import com.iailab.module.model.sample.constructor.SampleInfoConstructor; import com.iailab.module.model.sample.dto.ColumnItem; import com.iailab.module.model.sample.entity.DataEntity; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Resource; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * 设备健康评价 * 10 0 0/1 * * ? * * @author PanZhibao * @Description * @createTime 2024年06月29日 */ @Component("deviceHealthTask") public class DeviceHealthTask implements ITask { private Logger logger = LoggerFactory.getLogger(getClass()); private BigDecimal DEFAULT_HEALTH_SCORE = new BigDecimal(100); private String DEFAULT_REPORT_CONTENT = "设备运行正常"; private int DEFAULT_DATA_LENGTH = 60; @Resource private DeviceHealthEvaluateService deviceHealthEvaluateService; @Resource private DeviceEvaluateIndexService deviceEvaluateIndexService; @Resource private SampleInfoConstructor sampleInfoConstructor; @Resource private SampleDataConstructor sampleDataConstructor; @Resource private ModelHandler modelHandler; @Resource private DeviceHealthReportService deviceHealthReportService; @Resource private DeviceStatCountService deviceStatCountService; @Resource private DeviceInfoService deviceInfoService; @Resource private DeviceFaultService deviceFaultService; @Resource private DeviceStatNewnessService deviceStatNewnessService; private final int GRANULARITY = 60; private Map HEALTH_FAULT_TYPE = new HashMap<>(); private Map ALARM_INDEX_TYPE = new HashMap<>(); private String[] indexArr = new String[]{HealthIndexTypeEnum.elec.getCode(), HealthIndexTypeEnum.temperature.getCode(), HealthIndexTypeEnum.flutter.getCode(), HealthIndexTypeEnum.runTime.getCode()}; DeviceHealthTask() { HEALTH_FAULT_TYPE.put(1, "波动正常,趋势正常"); HEALTH_FAULT_TYPE.put(2, "波动正常,趋势异常"); HEALTH_FAULT_TYPE.put(3, "波动异常,趋势正常"); HEALTH_FAULT_TYPE.put(4, "波动异常,趋势异常"); ALARM_INDEX_TYPE.put("temperature", "温度"); ALARM_INDEX_TYPE.put("flutter", "震动"); ALARM_INDEX_TYPE.put("elec", "电流"); } @Override public void run(String params) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); try { List newnessList = new ArrayList<>(); Map queryParams = new HashMap<>(); queryParams.put("isEnable", 1); List evaList = deviceHealthEvaluateService.list(queryParams); if (CollectionUtils.isEmpty(evaList)) { return; } // 开始健康评价 evaList.forEach(item -> { this.runModel(item, calendar.getTime(), newnessList); }); // 统计数量 deviceStatCount(calendar); // 更新设备新度系数 deviceStatNewnessService.statNewness(newnessList, calendar.getTime()); } catch (Exception ex) { logger.error("DeviceHealthTask运行异常"); ex.printStackTrace(); } logger.info("DeviceHealthTask运行完成"); } public void runModel(DeviceHealthEvaluateDTO dto, Date runTime, List newnessList) { try { List indexList = deviceEvaluateIndexService.listByEvaluateId(dto.getId()); if (CollectionUtils.isEmpty(indexList)) { DeviceHealthEvaluateDTO updateDto = new DeviceHealthEvaluateDTO(); updateDto.setId(dto.getId()); updateDto.setReportContent(DEFAULT_REPORT_CONTENT); updateDto.setReportDate(runTime); updateDto.setReportId(""); updateDto.setAbnormalCount(0); updateDto.setHealthScore(DEFAULT_HEALTH_SCORE); updateDto.setHealthLevel(HealthLevelEnum.Level1.getCode()); deviceHealthEvaluateService.updateReport(updateDto); return; } Map indexMap = new HashMap<>(); indexList.forEach(item -> { indexMap.put(item.getIndexType(), item); }); DEFAULT_DATA_LENGTH = indexList.get(0).getDataLength(); ColumnItem columnItem = new ColumnItem(); columnItem.setEndTime(runTime); columnItem.setStartTime(sampleInfoConstructor.calculateTime(runTime, true, DEFAULT_DATA_LENGTH - 1, GRANULARITY)); List sampleDataList = new ArrayList<>(); Map> dataMap = new LinkedHashMap<>(); double[][] matrix1 = new double[DEFAULT_DATA_LENGTH][indexArr.length]; double[][] matrix2 = new double[1][3]; for (int i = 0; i < indexArr.length; i++) { if (indexMap.get(indexArr[i]) == null) { for (int k = 0; k < DEFAULT_DATA_LENGTH; k++) { matrix1[k][i] = -2; } continue; } DeviceEvaluateIndexDTO indDTO = indexMap.get(indexArr[i]); columnItem.setParamId(indDTO.getParamId()); columnItem.setParamType(indDTO.getParamType()); List dataEntityList = sampleDataConstructor.getColumnData(columnItem); logger.info("BEF:ParamType=" + indDTO.getParamType() + ";ParamId=" + indDTO.getParamId() + ";size=" + dataEntityList.size()); //补全数据 dataEntityList = sampleDataConstructor.completionData(matrix1.length, dataEntityList, columnItem.startTime, columnItem.endTime, GRANULARITY); logger.info("AFT:ParamType=" + indDTO.getParamType() + ";ParamId=" + indDTO.getParamId() + ";size=" + dataEntityList.size()); if (CollectionUtils.isEmpty(dataEntityList)) { continue; } for (int k = 0; k < DEFAULT_DATA_LENGTH; k++) { matrix1[k][i] = dataEntityList.get(k).getDataValue(); } dataMap.put(indexArr[i], dataEntityList); if (i < 3) { matrix2[0][i] = indDTO.getNominalValue().doubleValue(); } } sampleDataList.add(matrix1); sampleDataList.add(matrix2); // 调用模型 logger.info("调用模型,DevNo=" + dto.getDevNo()); Map modelCommonResult = modelHandler.run(dto.getModelCode(), sampleDataList); // 生成评价报告 this.saveReport(dto, runTime, modelCommonResult, dataMap, indexMap); // 更新新度系数 if (modelCommonResult.get("run_time_adjust") != null) { DeviceStatNewnessEntity deviceStatNewness = new DeviceStatNewnessEntity(); deviceStatNewness.setDevNo(dto.getDevNo()); deviceStatNewness.setDevName(dto.getDevName()); deviceStatNewness.setRunTime(new BigDecimal(modelCommonResult.get("run_time_normal").toString()).intValue()); deviceStatNewness.setLossTime(new BigDecimal(modelCommonResult.get("run_time_adjust").toString()).intValue()); deviceStatNewness.setLossRate(new BigDecimal(deviceStatNewness.getLossTime()).divide(new BigDecimal(deviceStatNewness.getRunTime()),2,BigDecimal.ROUND_HALF_UP)); newnessList.add(deviceStatNewness); } } catch (Exception ex) { ex.printStackTrace(); logger.error("设备健康评价计算异常,devNo=" + dto.getDevNo()); } } public void saveReport(DeviceHealthEvaluateDTO evaluateDTO, Date runTime, Map modelCommonResult, Map> dataMap, Map indexMap) { DeviceInfoDTO deviceInfo = deviceInfoService.getByDevNo(evaluateDTO.getDevNo()); DeviceHealthReportDTO reportDTO = new DeviceHealthReportDTO(); reportDTO.setId(UUID.randomUUID().toString()); reportDTO.setReportNo("H" + DateUtils.format(runTime, "yyyyMMddHHmmss") + getRand(evaluateDTO.getDevNo())); reportDTO.setReportName(evaluateDTO.getDevName() + "健康评价报告"); reportDTO.setReportDate(runTime); String deviceHealthLevel = modelCommonResult.get("isqualified").toString(); reportDTO.setHealthLevel(deviceHealthLevel); reportDTO.setAbnormalCount(getAbnormalCount(JSONArray.toJSONString(modelCommonResult.get("part_grade")))); reportDTO.setContent(modelCommonResult.get("health_evaluate").toString()); reportDTO.setHealthScore(new BigDecimal(modelCommonResult.get("health_score").toString())); reportDTO.setDataLength(DEFAULT_DATA_LENGTH); reportDTO.setRunTime(new BigDecimal(modelCommonResult.get("run_time_adjust").toString()).intValue()); reportDTO.setDevNo(evaluateDTO.getDevNo()); reportDTO.setDevName(evaluateDTO.getDevName()); if (deviceInfo != null) { reportDTO.setClassNo(deviceInfo.getClassNo()); reportDTO.setClassName(deviceInfo.getClassName()); reportDTO.setWorkshop(deviceInfo.getWorkshop()); reportDTO.setModel(deviceInfo.getModel()); } List partGrade = getIntValueArr(modelCommonResult.get("part_grade")); List maxArr = getValueArr(modelCommonResult.get("max_arr")); List minArr = getValueArr(modelCommonResult.get("min_arr")); List meanArr = getValueArr(modelCommonResult.get("mean_arr")); List detList = new ArrayList<>(); List deviceHealthAlarmDetailDTOList = new ArrayList<>(); List alarmIndexTypes = new ArrayList<>(); List alarmSolutions = new ArrayList<>(); // 故障id String alarmId = UUID.randomUUID().toString(); for (int i = 0; i < indexArr.length; i++) { List dataList = dataMap.get(indexArr[i]); if (CollectionUtils.isEmpty(dataList)) { continue; } List dataCont = dataList.stream().map(t -> { return new Object[]{DateUtils.format(t.getTimeStamp(), DateUtils.DATE_TIME_PATTERN_MIN), new BigDecimal(t.getDataValue()).setScale(4, BigDecimal.ROUND_HALF_UP)}; }).collect(Collectors.toList()); DeviceHealthReportDataDTO det = new DeviceHealthReportDataDTO(); det.setSort(i); det.setDataName(indexMap.get(indexArr[i]).getParamName()); det.setDataValue(JSONArray.toJSONString(dataCont)); if (!HealthIndexTypeEnum.runTime.getCode().equals(indexArr[i])) { det.setDataMax(maxArr.get(i)); det.setDataMin(minArr.get(i)); det.setDataAvg(meanArr.get(i)); det.setGradeCode(partGrade.get(i).toString()); det.setGradeName(HEALTH_FAULT_TYPE.get(partGrade.get(i))); DeviceFaultDTO querySoluDto = new DeviceFaultDTO(); querySoluDto.setClassNo(deviceInfo.getClassNo()); querySoluDto.setIndexType(indexArr[i]); querySoluDto.setFaultType(det.getGradeCode()); DeviceFaultDTO faultDTO = deviceFaultService.getSolution(querySoluDto); if (faultDTO != null) { det.setSolution(faultDTO.getSolution()); det.setFaultCode(faultDTO.getFaultCode()); } // 设备健康故障详情记录 if (HealthLevelEnum.Level3.getCode().equals(deviceHealthLevel) && faultDTO != null){ DeviceHealthAlarmDetailDTO deviceHealthAlarmDetail = new DeviceHealthAlarmDetailDTO(); deviceHealthAlarmDetail.setId(UUID.randomUUID().toString()); deviceHealthAlarmDetail.setAlarmId(alarmId); deviceHealthAlarmDetail.setFaultCode(faultDTO.getFaultCode()); deviceHealthAlarmDetail.setFaultName(HEALTH_FAULT_TYPE.get(partGrade.get(i))); deviceHealthAlarmDetail.setSolution(faultDTO.getSolution()); alarmIndexTypes.add(ALARM_INDEX_TYPE.get(faultDTO.getIndexType())); alarmSolutions.add(faultDTO.getSolution()); deviceHealthAlarmDetailDTOList.add(deviceHealthAlarmDetail); } } else { StringBuilder rsb = new StringBuilder(); rsb.append("运行时长:"); rsb.append(modelCommonResult.get("run_time_normal").toString()); det.setRemark(rsb.toString()); } detList.add(det); } // 设备健康故障记录 if (deviceHealthAlarmDetailDTOList.size() > 0) { DeviceHealthAlarmDTO deviceHealthAlarm = new DeviceHealthAlarmDTO(); deviceHealthAlarm.setId(alarmId); deviceHealthAlarm.setReportId(reportDTO.getId()); deviceHealthAlarm.setDevNo(evaluateDTO.getDevNo()); deviceHealthAlarm.setDevName(evaluateDTO.getDevName()); deviceHealthAlarm.setFaultTime(runTime); deviceHealthAlarm.setIsPushed(0); deviceHealthAlarm.setPushType(evaluateDTO.getIsPushed() == 0 ? 2 : 1); deviceHealthAlarm.setCreateDate(new Date()); deviceHealthAlarm.setAlarmIndexTypes(String.join(",", alarmIndexTypes)); deviceHealthAlarm.setAlarmSolutions(String.join("\n", alarmSolutions)); reportDTO.setDeviceHealthAlarm(deviceHealthAlarm); reportDTO.setDeviceHealthAlarmDetails(deviceHealthAlarmDetailDTOList); } reportDTO.setDetList(detList); deviceHealthReportService.save(reportDTO); DeviceHealthEvaluateDTO updateDto = new DeviceHealthEvaluateDTO(); updateDto.setId(evaluateDTO.getId()); updateDto.setReportContent(reportDTO.getContent()); updateDto.setReportDate(runTime); updateDto.setReportId(reportDTO.getId()); updateDto.setAbnormalCount(reportDTO.getAbnormalCount()); updateDto.setHealthScore(reportDTO.getHealthScore()); updateDto.setHealthLevel(reportDTO.getHealthLevel()); deviceHealthEvaluateService.updateReport(updateDto); } public void deviceStatCount(Calendar calendar) { DeviceStatCountDTO deviceStatCountDTO = deviceStatCountService.getDeviceStatCount(); DeviceStatCountEntity deviceStatCount = ConvertUtils.sourceToTarget(deviceStatCountDTO, DeviceStatCountEntity.class); deviceStatCount.setId(UUID.randomUUID().toString()); deviceStatCount.setDate(calendar.getTime()); deviceStatCount.setCreateDate(new Date()); deviceStatCountService.insert(deviceStatCount); } private String getRand(String devNo) { String t = Long.toString(System.currentTimeMillis()); return devNo.substring(0, 1) + t.substring(t.length() - 4); } private int getAbnormalCount(String partGrade) { int result = 0; if (StringUtils.isBlank(partGrade)) { return result; } List pgList = JSONArray.parseArray(partGrade, Integer.class); if (CollectionUtils.isEmpty(pgList)) { return result; } for (int i = 0; i < pgList.size(); i++) { if (pgList.get(i) != 1) { result = result + 1; } } return result; } private List getValueArr(Object value) { List result = new ArrayList<>(); if (value == null) { return result; } result = JSONArray.parseArray(JSON.toJSONString(value), BigDecimal.class); return result; } private List getIntValueArr(Object value) { List result = new ArrayList<>(); if (value == null) { return result; } result = JSONArray.parseArray(JSON.toJSONString(value), Integer.class); return result; } }