package com.iailab.module.data.point.collection.handler;
|
|
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.data.common.enums.CommonConstant;
|
import com.iailab.module.data.enums.DataPointFreqEnum;
|
import com.iailab.module.data.influxdb.pojo.InfluxPointValuePOJO;
|
import com.iailab.module.data.point.collection.utils.GenInfluxPointValueUtils;
|
import com.iailab.module.data.point.dto.DaPointDTO;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.CollectionUtils;
|
|
import java.math.BigDecimal;
|
import java.util.*;
|
|
/**
|
* 累计点处理
|
*
|
* @author PanZhibao
|
* @Description
|
* @createTime 2024年11月29日
|
*/
|
@Slf4j
|
@Component
|
public class CumulateHandle {
|
|
@Autowired
|
private DataPointApi dataPointApi;
|
|
public List<InfluxPointValuePOJO> handle(Date collectTime, List<DaPointDTO> dtos) {
|
List<InfluxPointValuePOJO> result = new ArrayList<>();
|
try {
|
log.info("累计点处理开始");
|
if (CollectionUtils.isEmpty(dtos)) {
|
return result;
|
}
|
dtos.forEach(dto -> {
|
try {
|
Object value = singleCompute(dto, collectTime);
|
InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(dto, value);
|
pojo.setTimestamp(collectTime.toInstant());
|
result.add(pojo);
|
} catch (Exception ex) {
|
ex.printStackTrace();
|
log.info("累计点异常!PointNo=" + dto.getPointNo());
|
}
|
});
|
|
} catch (Exception ex) {
|
ex.printStackTrace();
|
log.info("累计点处理异常!");
|
}
|
return result;
|
}
|
|
|
private Object singleCompute(DaPointDTO dto, Date collectTime) {
|
ApiPointDTO pointDTO = dataPointApi.getInfoByNo(dto.getMomentPoint());
|
if (pointDTO == null) {
|
return CommonConstant.BAD_VALUE;
|
}
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(collectTime);
|
calendar.add(Calendar.MINUTE, -1);
|
Date endTime = calendar.getTime();
|
calendar.add(Calendar.MINUTE, dto.getLength() * -1);
|
Date startTime = calendar.getTime();
|
ApiPointValueQueryDTO queryDto = new ApiPointValueQueryDTO();
|
queryDto.setStart(startTime);
|
queryDto.setEnd(endTime);
|
queryDto.setPointNo(dto.getMomentPoint());
|
|
List<ApiPointValueDTO> dataList = dataPointApi.queryPointHistoryValue(queryDto);
|
if (CollectionUtils.isEmpty(dataList)) {
|
return BigDecimal.ZERO;
|
} else if (dataList.size() < dto.getLength()) {
|
// 补全数据
|
dataList = completionData(dto.getLength(), dataList, startTime, endTime, pointDTO);
|
}
|
double total = dataList.stream().mapToDouble(ApiPointValueDTO::getV).sum();
|
return new BigDecimal(total).divide(new BigDecimal(dto.getDivisor()), 2, BigDecimal.ROUND_HALF_UP);
|
}
|
|
private List<ApiPointValueDTO> completionData(int length, List<ApiPointValueDTO> dataList, Date startTime, Date endTime, ApiPointDTO pointDTO) {
|
if (CollectionUtils.isEmpty(dataList) || length == dataList.size()) {
|
return dataList;
|
} else if (length < dataList.size()) {
|
return dataList.subList(dataList.size() - length, dataList.size());
|
}
|
|
List<ApiPointValueDTO> result = new ArrayList<>();
|
long start = startTime.getTime();
|
long end = endTime.getTime();
|
long oneMin = 1000L * DataPointFreqEnum.getEumByCode(pointDTO.getMinfreqid()).getValue();
|
long mins = (end - start) / oneMin;
|
|
//找出缺少项
|
Map<Long, Double> sourceDataMap = new HashMap<>(dataList.size());
|
Map<Long, Double> dataMap = new LinkedHashMap<>();
|
for (int i = 0; i < mins; i++) {
|
Long key = start + oneMin * i;
|
Double value = sourceDataMap.get(key);
|
dataMap.put(key, value);
|
}
|
|
//补充缺少项
|
int k = 0;
|
Map.Entry<Long, Double> lastItem = null;
|
for (Map.Entry<Long, Double> item : dataMap.entrySet()) {
|
if (k == 0 && item.getValue() == null) {
|
item.setValue(getFirstValue(dataMap));
|
} else if (item.getValue() == null) {
|
item.setValue(lastItem.getValue());
|
}
|
k++;
|
lastItem = item;
|
|
ApiPointValueDTO dataEntity = new ApiPointValueDTO();
|
dataEntity.setT(new Date(item.getKey()));
|
dataEntity.setV(item.getValue());
|
result.add(dataEntity);
|
}
|
return result;
|
}
|
|
private Double getFirstValue(Map<Long, Double> dataMap) {
|
for (Map.Entry<Long, Double> item : dataMap.entrySet()) {
|
if (item.getValue() != null) {
|
return item.getValue();
|
}
|
}
|
return null;
|
}
|
}
|