package com.iailab.module.model.mcs.pre.service.impl; import com.alibaba.fastjson.JSONArray; import com.iailab.framework.common.util.date.DateUtils; import com.iailab.module.data.api.point.DataPointApi; import com.iailab.module.data.api.point.dto.ApiPointDTO; import com.iailab.module.data.api.point.dto.ApiPointValueDTO; import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO; import com.iailab.module.model.api.mcs.dto.PreDataBarLineReqVO; import com.iailab.module.model.api.mcs.dto.PreDataBarLineRespVO; import com.iailab.module.model.api.mcs.dto.PreDataViewRespDTO; import com.iailab.module.model.common.enums.CommonDict; import com.iailab.module.model.common.enums.DataTypeEnum; import com.iailab.module.model.influxdb.pojo.InfluxModelResultLastBakSimPOJO; import com.iailab.module.model.influxdb.pojo.InfluxModelResultLastSimPOJO; import com.iailab.module.model.influxdb.pojo.InfluxModelResultPOJO; import com.iailab.module.model.influxdb.pojo.InfluxModelResultSimPOJO; import com.iailab.module.model.influxdb.service.InfluxDBService; import com.iailab.module.model.influxdb.vo.InfluxModelResultVO; import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity; import com.iailab.module.model.mcs.pre.entity.MmItemResultJsonEntity; import com.iailab.module.model.mcs.pre.service.*; import com.iailab.module.model.mcs.sche.service.StAdjustResultService; import com.iailab.module.model.mdk.vo.DataValueVO; import com.iailab.module.model.mdk.vo.ItemVO; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * @author PanZhibao * @date 2021年05月28日 10:34 */ @Service public class MmItemResultServiceImpl implements MmItemResultService { @Autowired private MmItemResultJsonService mmItemResultJsonService; @Autowired private InfluxDBService influxDBService; @Autowired private MmItemOutputService mmItemOutputService; @Autowired private MmPredictItemService mmPredictItemService; @Autowired private DataPointApi dataPointApi; @Autowired private MmItemResultService mmItemResultService; @Autowired private StAdjustResultService stAdjustResultService; @Autowired private MmItemResultLastPointService mmItemResultLastPointService; private int HOUR_MINS = 60; @Override public void savePredictValue(Map> predictValueMap, int t, String nIndex, Date predictTime) { List importList = new ArrayList<>(); List lastList = new ArrayList<>(); List lastBakList = new ArrayList<>(); List resultJsonList = new ArrayList<>(); for (Map.Entry> entry : predictValueMap.entrySet()) { for (DataValueVO dataVo : entry.getValue()) { InfluxModelResultSimPOJO pojo = new InfluxModelResultSimPOJO(); pojo.setValue(dataVo.getDataValue()); pojo.setTimestamp(dataVo.getDataTime().toInstant()); pojo.setOutPutId(entry.getKey()); importList.add(pojo); } List lastVoList = new ArrayList<>(); int size = entry.getValue().size(); t = Math.max(t, 0); int n = "n".equals(nIndex) ? size : Integer.parseInt(nIndex); int length = Math.max((n - t), 0); //预测完不变的数据长度 if (size >= n) { for (int i = 0; i < (size - length); i ++) { int index = length + i; lastVoList.add(entry.getValue().get(index)); } } else { lastVoList = entry.getValue(); } for (DataValueVO dataVo : lastVoList) { InfluxModelResultLastSimPOJO pojo = new InfluxModelResultLastSimPOJO(); pojo.setValue(dataVo.getDataValue()); pojo.setTimestamp(dataVo.getDataTime().toInstant()); pojo.setOutPutId(entry.getKey()); lastList.add(pojo); InfluxModelResultLastBakSimPOJO bakSimPojo = new InfluxModelResultLastBakSimPOJO(); bakSimPojo.setValue(dataVo.getDataValue()); bakSimPojo.setTimestamp(dataVo.getDataTime().toInstant()); bakSimPojo.setOutPutId(entry.getKey()); lastBakList.add(bakSimPojo); } MmItemResultJsonEntity resultJson = new MmItemResultJsonEntity(); resultJson.setId(UUID.randomUUID().toString()); resultJson.setOutputid(entry.getKey()); resultJson.setPredicttime(predictTime); List jsonValueList = entry.getValue().stream().map(valueVO -> valueVO.getDataValue()).collect(Collectors.toList()); resultJson.setJsonvalue(JSONArray.toJSONString(jsonValueList)); resultJson.setCumulant(""); resultJsonList.add(resultJson); } // json结果存入mysql mmItemResultJsonService.insert(resultJsonList); // double结果存入influxdb influxDBService.asyncWriteModelResults(importList); influxDBService.asyncWriteModelResults(lastList); // t+l备份 influxDBService.asyncWriteModelResults(lastBakList); } @Override public List getPredictValue(String outputid, Date startTime, Date endTime) { InfluxModelResultPOJO pojo = new InfluxModelResultPOJO(); pojo.setType(DataTypeEnum.FLOAT.getCode()); pojo.setOutPutId(outputid); List influxModelResultVOS = influxDBService.queryModelResults(pojo, startTime, endTime); List result = influxModelResultVOS.stream().map(t -> { DataValueVO dv = new DataValueVO(); dv.setDataTime(Date.from(t.getTimestamp())); dv.setDataValue(Double.valueOf(t.getValue().toString())); return dv; }).collect(Collectors.toList()); return result; } @Override public List getPredictValueLast(String outputid, Date startTime, int mins) { List result = new ArrayList<>(); Calendar calendar = Calendar.getInstance(); calendar.setTime(startTime); calendar.add(Calendar.MINUTE, mins * -1); Date startTimeNew = calendar.getTime(); Date endTimeNew = new Date(); InfluxModelResultPOJO pojo = new InfluxModelResultPOJO(); pojo.setType(DataTypeEnum.FLOAT.getCode()); pojo.setOutPutId(outputid); List influxModelResultVOS = influxDBService.queryModelResults(pojo, startTimeNew, endTimeNew); if (!CollectionUtils.isEmpty(influxModelResultVOS)) { InfluxModelResultVO t = influxModelResultVOS.get(influxModelResultVOS.size() - 1); DataValueVO dv = new DataValueVO(); dv.setDataTime(Date.from(t.getTimestamp())); dv.setDataValue(Double.valueOf(t.getValue().toString())); result.add(dv); } return result; } @Override public List getData(String outputid, Date startTime, Date endTime, String timeFormat) { List result = new ArrayList<>(); InfluxModelResultPOJO pojo = new InfluxModelResultPOJO(); pojo.setType(DataTypeEnum.FLOAT.getCode()); pojo.setOutPutId(outputid); List influxModelResultVOS = influxDBService.queryModelResults(pojo, startTime, endTime); influxModelResultVOS.forEach(item -> { Object[] dataItem = new Object[2]; dataItem[0] = DateUtils.format(Date.from(item.getTimestamp()), timeFormat); dataItem[1] = BigDecimal.valueOf(Double.valueOf(item.getValue().toString())).setScale(3, BigDecimal.ROUND_HALF_UP); result.add(dataItem); }); return result; } @Override public List getData(String outputid, Date startTime, Date endTime, String timeFormat, int decimalPlaces) { List result = new ArrayList<>(); InfluxModelResultPOJO pojo = new InfluxModelResultPOJO(); pojo.setType(DataTypeEnum.FLOAT.getCode()); pojo.setOutPutId(outputid); List influxModelResultVOS = influxDBService.queryModelResults(pojo, startTime, endTime); influxModelResultVOS.forEach(item -> { Object[] dataItem = new Object[2]; dataItem[0] = DateUtils.format(Date.from(item.getTimestamp()), timeFormat); dataItem[1] = BigDecimal.valueOf(Double.valueOf(item.getValue().toString())).setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP); result.add(dataItem); }); return result; } @Override public PreDataBarLineRespVO getPreDataCharts(PreDataBarLineReqVO reqVO) { PreDataBarLineRespVO result = new PreDataBarLineRespVO(); List outIds = reqVO.getOutIds(); List legends = new ArrayList<>(); List dataViewList = new ArrayList<>(); if (CollectionUtils.isEmpty(outIds)) { return result; } Date predictTime = reqVO.getPredictTime(); Integer predictLength = null; if (predictTime == null) { MmItemOutputEntity output = null; for (String outId : outIds) { output = mmItemOutputService.getOutPutById(outId); if (output != null) { ItemVO predictItem = mmPredictItemService.getItemById(output.getItemid()); if (predictItem != null && predictItem.getLastTime() != null) { predictTime = predictItem.getLastTime(); predictLength = predictItem.getPredictLength(); break; } } } } if (predictTime == null) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); predictTime = calendar.getTime(); } if (predictLength == null) { predictLength = 120; } Date startTime = reqVO.getStartTime(); if (startTime == null) { Calendar calendar = Calendar.getInstance(); calendar.setTime(predictTime); calendar.add(Calendar.MINUTE, -1 * predictLength); startTime = calendar.getTime(); } Date endTime = reqVO.getEndTime(); if (endTime == null) { Calendar calendar = Calendar.getInstance(); calendar.setTime(predictTime); calendar.add(Calendar.MINUTE, predictLength + 1); endTime = calendar.getTime(); } for (int i = 0; i < outIds.size(); i++) { // 根据预测长度动态开始结束时间 PreDataViewRespDTO viewDto = new PreDataViewRespDTO(); String outId = outIds.get(i); MmItemOutputEntity output = mmItemOutputService.getOutPutById(outId); if (output == null) { continue; } legends.add(output.getResultName()); viewDto.setItemId(output.getItemid()); viewDto.setOutId(outId); viewDto.setResultstr(output.getResultstr()); viewDto.setResultName(output.getResultName()); viewDto.setRealData(getHisData(output.getPointid(), startTime, endTime, reqVO.getPrec())); viewDto.setPreDataN(mmItemResultService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)); viewDto.setPreDataL(mmItemResultLastPointService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)); viewDto.setPreDataLOriginal(mmItemResultLastPointService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, DataTypeEnum.FLOAT_LAST_BAK)); viewDto.setCurData(mmItemResultJsonService.getData(output.getId(), predictTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)); // 模拟调整曲线 viewDto.setAdjData(stAdjustResultService.getData(output.getId(), predictTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)); List values = new ArrayList<>(); if (!CollectionUtils.isEmpty(viewDto.getRealData())) { List hisValues = new ArrayList<>(); viewDto.getRealData().forEach(item -> { values.add(Double.parseDouble(item[1].toString())); hisValues.add(Double.parseDouble(item[1].toString())); }); viewDto.setHisMax(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); viewDto.setHisMin(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); viewDto.setHisAvg(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).average().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); viewDto.setHisCumulant(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).sum()) .divide(new BigDecimal(HOUR_MINS), 2, BigDecimal.ROUND_HALF_UP)); } if (!CollectionUtils.isEmpty(viewDto.getPreDataN())) { viewDto.getPreDataN().forEach(item -> { values.add(Double.parseDouble(item[1].toString())); }); } if (!CollectionUtils.isEmpty(viewDto.getPreDataL())) { List preValues = new ArrayList<>(); viewDto.getPreDataL().forEach(item -> { values.add(Double.parseDouble(item[1].toString())); preValues.add(Double.parseDouble(item[1].toString())); }); viewDto.setPreMax(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); viewDto.setPreMin(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); viewDto.setPreAvg(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).average().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); } if (!CollectionUtils.isEmpty(viewDto.getCurData())) { List preValues = new ArrayList<>(); viewDto.getCurData().forEach(item -> { values.add(Double.parseDouble(item[1].toString())); preValues.add(Double.parseDouble(item[1].toString())); }); viewDto.setPreCumulant(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).sum()) .divide(new BigDecimal(HOUR_MINS), 2, BigDecimal.ROUND_HALF_UP)); } if (!CollectionUtils.isEmpty(viewDto.getAdjData())) { viewDto.getAdjData().forEach(item -> { values.add(Double.parseDouble(item[1].toString())); }); } if (!CollectionUtils.isEmpty(values)) { viewDto.setMaxValue(new BigDecimal(values.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); viewDto.setMinValue(new BigDecimal(values.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP)); } //处理预测累计 if (output.getIscumulant() == 1) { if (StringUtils.isNotBlank(output.getCumulpoint())) { viewDto.setCumulantRealData(getHisData(output.getCumulpoint(), startTime, endTime, reqVO.getPrec())); } viewDto.setCumulantPreData(mmItemResultService.getData(output.getId() + CommonDict.CUMULANT_SUFFIX, startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)); } dataViewList.add(viewDto); } result.setStartTime(startTime); result.setEndTime(endTime); result.setPredictTime(predictTime); result.setCategories(DateUtils.getTimeScale(startTime, endTime, 60)); result.setLegend(legends); result.setDataViewList(dataViewList); return result; } private List getHisData(String pointId, Date startTime, Date endTime, Integer prec) { List result = new ArrayList<>(); if (StringUtils.isBlank(pointId)) { return result; } ApiPointDTO pointDTO = dataPointApi.getInfoById(pointId); ApiPointValueQueryDTO queryPointDto = new ApiPointValueQueryDTO(); queryPointDto.setPointNo(pointDTO.getPointNo()); queryPointDto.setStart(startTime); queryPointDto.setEnd(endTime); List valueDTOS = dataPointApi.queryPointHistoryValue(queryPointDto); if (CollectionUtils.isEmpty(valueDTOS)) { return result; } int defaultPrec = 3; valueDTOS.forEach(item -> { Object[] values = new Object[2]; values[0] = DateUtils.format(item.getT(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND); if (prec != null && prec < 0) { values[1] = item.getV(); } else if (prec != null && prec > 0) { values[1] = new BigDecimal(item.getV()).setScale(prec, BigDecimal.ROUND_HALF_UP); } else { values[1] = new BigDecimal(item.getV()).setScale(defaultPrec, BigDecimal.ROUND_HALF_UP); } result.add(values); }); return result; } }