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<String, List<DataValueVO>> predictValueMap, int t, String nIndex, Date predictTime) {
|
List<InfluxModelResultPOJO> importList = new ArrayList<>();
|
List<InfluxModelResultPOJO> lastList = new ArrayList<>();
|
List<InfluxModelResultPOJO> lastBakList = new ArrayList<>();
|
List<MmItemResultJsonEntity> resultJsonList = new ArrayList<>();
|
|
for (Map.Entry<String, List<DataValueVO>> 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<DataValueVO> 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<Double> 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<DataValueVO> getPredictValue(String outputid, Date startTime, Date endTime) {
|
InfluxModelResultPOJO pojo = new InfluxModelResultPOJO();
|
pojo.setType(DataTypeEnum.FLOAT.getCode());
|
pojo.setOutPutId(outputid);
|
List<InfluxModelResultVO> influxModelResultVOS = influxDBService.queryModelResults(pojo, startTime, endTime);
|
List<DataValueVO> 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<DataValueVO> getPredictValueLast(String outputid, Date startTime, int mins) {
|
List<DataValueVO> 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<InfluxModelResultVO> 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<Object[]> getData(String outputid, Date startTime, Date endTime, String timeFormat) {
|
List<Object[]> result = new ArrayList<>();
|
InfluxModelResultPOJO pojo = new InfluxModelResultPOJO();
|
pojo.setType(DataTypeEnum.FLOAT.getCode());
|
pojo.setOutPutId(outputid);
|
List<InfluxModelResultVO> 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<Object[]> getData(String outputid, Date startTime, Date endTime, String timeFormat, int decimalPlaces) {
|
List<Object[]> result = new ArrayList<>();
|
InfluxModelResultPOJO pojo = new InfluxModelResultPOJO();
|
pojo.setType(DataTypeEnum.FLOAT.getCode());
|
pojo.setOutPutId(outputid);
|
List<InfluxModelResultVO> 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<String> outIds = reqVO.getOutIds();
|
List<String> legends = new ArrayList<>();
|
List<PreDataViewRespDTO> dataViewList = new ArrayList<>();
|
if (CollectionUtils.isEmpty(outIds)) {
|
return result;
|
}
|
Date predictTime = reqVO.getPredictTime();
|
if (predictTime == null) {
|
MmItemOutputEntity output = null;
|
for (String outId : outIds) {
|
output = mmItemOutputService.getOutPutById(outId);
|
if (output != null) {
|
break;
|
}
|
}
|
ItemVO predictItem = mmPredictItemService.getItemById(output.getItemid());
|
if (predictItem.getLastTime() != null) {
|
predictTime = predictItem.getLastTime();
|
} else {
|
Calendar calendar = Calendar.getInstance();
|
calendar.set(Calendar.MILLISECOND, 0);
|
calendar.set(Calendar.SECOND, 0);
|
predictTime = calendar.getTime();
|
}
|
}
|
Date startTime = reqVO.getStartTime();
|
if (startTime == null) {
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(predictTime);
|
calendar.add(Calendar.HOUR_OF_DAY, -1);
|
startTime = calendar.getTime();
|
}
|
Date endTime = reqVO.getEndTime();
|
if (endTime == null) {
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(predictTime);
|
calendar.add(Calendar.HOUR_OF_DAY, 1);
|
calendar.add(Calendar.MINUTE, 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<Double> values = new ArrayList<>();
|
if (!CollectionUtils.isEmpty(viewDto.getRealData())) {
|
List<Double> 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<Double> 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<Double> 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<Object[]> getHisData(String pointId, Date startTime, Date endTime, Integer prec) {
|
List<Object[]> 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<ApiPointValueDTO> 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;
|
}
|
}
|