dengzedong
2 天以前 13622b9e0d09945a7cad4e43d9cdf242d3b9b3f8
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java
@@ -1,20 +1,34 @@
package com.iailab.module.model.mcs.pre.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iailab.module.model.mcs.pre.dao.MmItemResultDao;
import com.iailab.module.model.mcs.pre.entity.MmItemResultEntity;
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.MmItemResultService;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -23,60 +37,47 @@
 * @date 2021年05月28日 10:34
 */
@Service
public class MmItemResultServiceImpl extends ServiceImpl<MmItemResultDao, MmItemResultEntity> implements MmItemResultService {
    private final int max_group_count = 100;
    private final String T_MM_ITEM_RESULT = "T_MM_ITEM_RESULT";
public class MmItemResultServiceImpl implements MmItemResultService {
    @Autowired
    private MmItemResultDao mmItemResultDao;
    @Override
    public List<MmItemResultEntity> getListByOutputId(String outputid, Map<String, Object> params) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startDateParam = null;
        try {
            startDateParam = sdf.parse((String)params.get("startTime"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date endDateParam = null;
        try {
            endDateParam = sdf.parse((String)params.get("endTime"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        List<MmItemResultEntity> list = mmItemResultDao.selectList(
                new QueryWrapper<MmItemResultEntity>()
                        .eq("outputid", outputid)
                        .between("datatime", startDateParam, endDateParam)
                        .orderByAsc("datatime")
        );
        return list;
    }
    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<MmItemResultEntity> importList = new ArrayList<>();
        List<MmItemResultEntity> lastList = new ArrayList<>();
        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()) {
                MmItemResultEntity importData = new MmItemResultEntity();
                importData.setId(String.valueOf(UUID.randomUUID()));
                importData.setOutputid(entry.getKey());
                importData.setDatatime(dataVo.getDataTime());
                importData.setDatavalue(new BigDecimal(dataVo.getDataValue()));
                importList.add(importData);
                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 = t > 0 ? t : 0;
            t = Math.max(t, 0);
            int n = "n".equals(nIndex) ? size : Integer.parseInt(nIndex);
            int length = (n - t) > 0 ? (n - t) : 0; //预测完不变的数据长度
            int length = Math.max((n - t), 0); //预测完不变的数据长度
            if (size >= n) {
                for (int i = 0; i < (size - length); i ++) {
                    int index = length + i;
@@ -87,80 +88,269 @@
            }
            for (DataValueVO dataVo : lastVoList) {
                MmItemResultEntity importData = new MmItemResultEntity();
                importData.setId(String.valueOf(UUID.randomUUID()));
                importData.setOutputid(entry.getKey());
                importData.setDatatime(dataVo.getDataTime());
                importData.setDatavalue(new BigDecimal(dataVo.getDataValue()));
                lastList.add(importData);
                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);
            resultJson.setJsonvalue(JSONArray.toJSONString(entry.getValue()));
            Map<String, Object> map4 = new HashMap(2);
            map4.put("TABLENAME", "T_MM_ITEM_RESULT_JSON");
            map4.put("entity", resultJson);
            mmItemResultDao.savePredictJsonValue(map4);
            List<Double> jsonValueList = entry.getValue().stream().map(valueVO -> valueVO.getDataValue()).collect(Collectors.toList());
            resultJson.setJsonvalue(JSONArray.toJSONString(jsonValueList));
            resultJson.setCumulant("");
            resultJsonList.add(resultJson);
        }
        Map<String, Object> params = new HashMap(4);
        params.put("TABLENAME", T_MM_ITEM_RESULT);
        params.put("OUTPUTID", importList.get(0).getOutputid());
        params.put("STARTTIME", importList.get(0).getDatatime());
        params.put("ENDTIME", importList.get(importList.size() - 1).getDatatime());
        mmItemResultDao.deletePredictValue(params);
        int num1 = importList.size() / max_group_count;
        int num2 = importList.size() % max_group_count;
        if (num2 != 0) {
            num1++;
        }
        List<MmItemResultEntity> tempList;
        //先删除已经存在的数据,再插入新数据
        for (int i = 0; i < num1; i++) {
            int startIndex = max_group_count * i;
            int count = max_group_count;
            if (num2!=0 && i == num1 - 1) {
                count = num2;
            }
            tempList = new ArrayList<>();
            //获取某个索引范围内的对象集合
            for (int j = startIndex; j < startIndex + count; j++) {
                tempList.add(importList.get(j));
            }
            Map<String, Object> map2 = new HashMap<>(2);
            map2.put("TABLENAME", T_MM_ITEM_RESULT);
            map2.put("list", tempList);
            mmItemResultDao.savePredictValue(map2);
        }
        Map<String, Object> map3 = new HashMap<>(2);
        map3.put("TABLENAME", "T_MM_ITEM_RESULT_LAST_POINT");
        map3.put("list", lastList);
        mmItemResultDao.savePredictValue(map3);
        // 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) {
        List<DataValueVO> result = new ArrayList<>();
        QueryWrapper<MmItemResultEntity> queryWrapper = new QueryWrapper<MmItemResultEntity>()
                .eq("outputid", outputid)
                .between("datatime", startTime, endTime)
                .orderByAsc("datatime");
        List<MmItemResultEntity> list = mmItemResultDao.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        result = list.stream().map(t -> {
        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(t.getDatatime());
            dv.setDataValue(t.getDatavalue().doubleValue());
            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();
        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<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;
    }
}