package com.iailab.module.ansteel.job.task; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.iailab.module.ansteel.api.dto.PowerPriceDetDTO; import com.iailab.module.ansteel.api.dto.PowerPriceMainDTO; import com.iailab.module.ansteel.power.dao.PeakValleyFlatDao; import com.iailab.module.ansteel.power.entity.PeakValleyFlatEntity; import com.iailab.module.ansteel.power.service.PowerPriceMainService; import com.iailab.module.data.api.point.DataPointApi; import com.iailab.module.data.api.point.dto.ApiPointValueDTO; import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO; import com.iailab.module.data.api.point.dto.ApiPointValueWriteDTO; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.*; import java.util.List; import java.util.stream.Collectors; /** * 峰谷平累计量计算 * * @author DongYukun * @Description * @createTime 2025年5月5日 */ @Slf4j @Component("runPeakValleyFlatTask") public class RunPeakValleyFlatTask implements ITask { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private PeakValleyFlatDao peakValleyFlatDao; @Autowired private DataPointApi dataPointApi; @Autowired private PowerPriceMainService powerPriceMainService; @Override public void run(String params) { try { //查询峰谷平配置列表 List configList = peakValleyFlatDao.selectList(new QueryWrapper<>()); if (CollectionUtils.isEmpty(configList)) { log.error("峰谷平累计量计算失败:峰谷平配置列表configList为空"); return; } // 峰谷平时段 List powerPriceMainDTOList = powerPriceMainService.list(new HashMap<>()); List detList = new ArrayList<>(); for (PowerPriceMainDTO powerPriceMainDTO : powerPriceMainDTOList) { detList.addAll(powerPriceMainDTO.getDetList()); } if (CollectionUtils.isEmpty(detList)) { log.error("峰谷平累计量计算失败:时段detList为空"); return; } Map> typePriceDetMap = detList.stream().collect(Collectors.groupingBy(PowerPriceDetDTO::getName)); // 当天零点 Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); Calendar cal = (Calendar) calendar.clone(); Date endTime = cal.getTime(); cal.add(Calendar.DAY_OF_YEAR, -1); Date startTime = cal.getTime(); cal.add(Calendar.DAY_OF_YEAR, -27); Date monthStartTime_29 = cal.getTime(); cal.add(Calendar.DAY_OF_YEAR, -2); Date monthStartTime_30 = cal.getTime(); for (PeakValleyFlatEntity configEntity : configList) { String type = configEntity.getType(); String powerNo = configEntity.getPowerNo(); //计算昨日的峰/谷累积量 double value = getSumValue(typePriceDetMap.get(type), 1, calendar, powerNo); //计算昨日总电耗 double totalValue = getSumValueTotal(powerNo, startTime, endTime,1440,60); //计算前29日峰/谷累积量 + 今日 double valueMonth = getSumValueTotal(configEntity.getPointNoTotal(), monthStartTime_29, endTime,29,1)+value; //计算前三十日总电耗 double totalValueMonth = getSumValueTotal(configEntity.getPowerNo(), monthStartTime_30, endTime,1440 * 30,60); logger.info("name:"+configEntity.getName()+";value:"+value+";totalValue:"+totalValue+";valueMonth:"+valueMonth+";totalValueMonth:"+totalValueMonth); //下发昨日占比 ApiPointValueWriteDTO percentDto = new ApiPointValueWriteDTO(); percentDto.setPointNo(configEntity.getPointNo()); double percent = totalValue == 0 ? 0 : value / totalValue * 100; percentDto.setValue(percent); dataPointApi.writePointRealValue(percentDto); //下发昨日峰/谷累积量 ApiPointValueWriteDTO totalDto = new ApiPointValueWriteDTO(); totalDto.setPointNo(configEntity.getPointNoTotal()); totalDto.setValue(value); dataPointApi.writePointRealValue(totalDto); //下发前三十日占比 ApiPointValueWriteDTO monthDto = new ApiPointValueWriteDTO(); monthDto.setPointNo(configEntity.getPointNoMonth()); double percentMonth = totalValueMonth == 0 ? 0 : valueMonth / totalValueMonth * 100; monthDto.setValue(percentMonth); dataPointApi.writePointRealValue(monthDto); } } catch (Exception ex) { logger.error("runPeakValleyFlatTask运行异常", ex); } } private Date getTime(String timeStr, int ago, Calendar calendar) { Calendar cal = (Calendar) calendar.clone(); String[] timeSplit = timeStr.split(":"); if (timeSplit.length != 2) { throw new IllegalArgumentException("时间配置格式不合法"); } //根据配置获取startTime、endTime cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeSplit[0])); cal.set(Calendar.MINUTE, Integer.parseInt(timeSplit[1])); cal.add(Calendar.DAY_OF_YEAR, -ago); return cal.getTime(); } private ApiPointValueDTO findDataForTime(List valueList, Date time) { long targetMinute = time.getTime() / (60 * 1000); return valueList.stream() .filter(Objects::nonNull) .filter(d -> d.getT() != null) .filter(d -> d.getT().getTime() / (60 * 1000) == targetMinute) .findFirst() .orElse(null); } private double getSumValue(List list, int ago, Calendar calendar,String powerNo) { double value = 0; for (int i = 0; i < list.size(); i++) { PowerPriceDetDTO entity = list.get(i); ApiPointValueQueryDTO dto = new ApiPointValueQueryDTO(); Date startTime = getTime(entity.getStart(), ago, calendar); Date endTime = getTime(entity.getEnd(), ago, calendar); dto.setPointNo(powerNo); dto.setStart(startTime); dto.setEnd(endTime); logger.info("开始查询,测点:" + powerNo + "startTime:" + startTime + "endTime:" + endTime); List valueList; //查找数据 try { valueList = dataPointApi.queryPointHistoryValue(dto); } catch (Exception e) { throw new RuntimeException("查询测点异常"); } // 计算 startTime和endTime中有多少个点 long total = (endTime.getTime() - startTime.getTime()) / (60 * 1000); double sum = valueList.stream().filter(e -> Double.compare(e.getV(), 0.0) > 0).mapToDouble(ApiPointValueDTO::getV).average().orElse(0.0) * Long.valueOf(total).doubleValue(); //累加 // double sum = valueList.stream().mapToDouble(ApiPointValueDTO::getV).sum(); value = value + sum; } return value / 60; } private double getSumValueTotal(String pointNo, Date startTime, Date endTime,Integer total,Integer divide) { ApiPointValueQueryDTO dto = new ApiPointValueQueryDTO(); dto.setPointNo(pointNo); dto.setStart(startTime); dto.setEnd(endTime); //查找数据 List valueList = dataPointApi.queryPointHistoryValue(dto); // 平均值 * 总数 double value = valueList.stream().filter(e -> Double.compare(e.getV(), 0.0) > 0).mapToDouble(ApiPointValueDTO::getV).average().orElse(0.0) * Double.valueOf(total); //累加 return value / divide; } }