|
@@ -10,14 +10,14 @@
|
|
|
*/
|
|
|
package com.ruoyi.ems.service.analysis;
|
|
|
|
|
|
+import com.ruoyi.ems.domain.CaEmissionForecast;
|
|
|
import com.ruoyi.ems.domain.CaMeterD;
|
|
|
import com.ruoyi.ems.domain.ElecPgSupplyH;
|
|
|
import com.ruoyi.ems.domain.ElecPvSupplyH;
|
|
|
import com.ruoyi.ems.domain.EmissionFactor;
|
|
|
-import com.ruoyi.ems.domain.EnergyMeter;
|
|
|
+import com.ruoyi.ems.mapper.CaEmissionForecastMapper;
|
|
|
import com.ruoyi.ems.mapper.CaMeterDMapper;
|
|
|
import com.ruoyi.ems.model.QueryMeter;
|
|
|
-import com.ruoyi.ems.service.IElecMeterHService;
|
|
|
import com.ruoyi.ems.service.IElecPgSupplyHService;
|
|
|
import com.ruoyi.ems.service.IElecPvSupplyHService;
|
|
|
import com.ruoyi.ems.service.IEmissionFactorService;
|
|
@@ -31,8 +31,12 @@ import java.math.RoundingMode;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.ZoneId;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
+import java.time.temporal.TemporalAdjusters;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 碳计算任务
|
|
@@ -49,10 +53,22 @@ public class CarbonCalculationService {
|
|
|
|
|
|
private final DateTimeFormatter dateForm = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
|
|
|
+ private final DateTimeFormatter monthForm = DateTimeFormatter.ofPattern("yyyy-MM");
|
|
|
+
|
|
|
+ // 历史数据权重配置
|
|
|
+ private static final double WEIGHT_CURRENT_MONTH = 0.5; // 最近一个月权重
|
|
|
+
|
|
|
+ private static final double WEIGHT_PREVIOUS_MONTH = 0.3; // 前一个月权重
|
|
|
+
|
|
|
+ private static final double WEIGHT_OLDEST_MONTH = 0.2; // 最早一个月权重
|
|
|
+
|
|
|
@Resource
|
|
|
private CaMeterDMapper caMeterDMapper;
|
|
|
|
|
|
@Resource
|
|
|
+ private CaEmissionForecastMapper caEmissionForecastMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
private IElecPgSupplyHService pgSupplyHService;
|
|
|
|
|
|
@Resource
|
|
@@ -76,7 +92,7 @@ public class CarbonCalculationService {
|
|
|
|
|
|
// 计算碳排放量(基于电网用电数据)
|
|
|
ElecPgSupplyH totalElectricity = getDailyElectricityConsumption(areaCode, date);
|
|
|
- Double emission = calculateCarbonEmission(totalElectricity);
|
|
|
+ Double emission = calculateCarbonEmission(totalElectricity != null ? totalElectricity.getUseElecQuantity() : null);
|
|
|
caMeterD.setCaEmissionQuantity(emission);
|
|
|
|
|
|
// 计算碳汇量(基于光伏产能数据)
|
|
@@ -93,6 +109,28 @@ public class CarbonCalculationService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public void calculateMonthCarbonForecast(String areaCode, LocalDate date) {
|
|
|
+ try {
|
|
|
+ List<ElecPgSupplyH> totalElectricitys = getMonthElectricityConsumption(areaCode, date);
|
|
|
+ Map<String, Double> monthElectricityMap = totalElectricitys.stream()
|
|
|
+ .collect(Collectors.toMap(ElecPgSupplyH::getStartRecTime, ElecPgSupplyH::getUseElecQuantity));
|
|
|
+ Double totalElectricity = calculateForecastElectricity(monthElectricityMap);
|
|
|
+ Double emission = calculateCarbonEmission(totalElectricity);
|
|
|
+
|
|
|
+ CaEmissionForecast caEmissionForecast = new CaEmissionForecast();
|
|
|
+ caEmissionForecast.setAreaCode(areaCode);
|
|
|
+ caEmissionForecast.setMonth(date.format(monthForm));
|
|
|
+ caEmissionForecast.setCaEmission(emission);
|
|
|
+
|
|
|
+ caEmissionForecastMapper.deleteCaMeterDByArea(areaCode, date.format(monthForm));
|
|
|
+ caEmissionForecastMapper.insertCaEmissionForecast(caEmissionForecast);
|
|
|
+ }
|
|
|
+ catch (Exception e) {
|
|
|
+ log.error("calculate month carbon forecast error! areaCode:{}, date:{}", areaCode, date.format(dateForm),
|
|
|
+ e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private ElecPvSupplyH getDailyPVProduction(String areaCode, LocalDate date) {
|
|
|
QueryMeter queryMeter = new QueryMeter();
|
|
|
queryMeter.setAreaCode(areaCode);
|
|
@@ -108,29 +146,33 @@ public class CarbonCalculationService {
|
|
|
return pgSupplyHService.calDaySupplyByH(queryMeter);
|
|
|
}
|
|
|
|
|
|
+ private List<ElecPgSupplyH> getMonthElectricityConsumption(String areaCode, LocalDate date) {
|
|
|
+ LocalDate startTime = date.minusMonths(3).withDayOfMonth(1);
|
|
|
+ LocalDate endTime = date.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
|
|
|
+
|
|
|
+ ElecPgSupplyH queryMeter = new ElecPgSupplyH();
|
|
|
+ queryMeter.setAreaCode(areaCode);
|
|
|
+ queryMeter.setStartRecTime(startTime.format(dateForm));
|
|
|
+ queryMeter.setEndRecTime(endTime.format(dateForm));
|
|
|
+ return pgSupplyHService.calMonthSupplyByH(queryMeter);
|
|
|
+ }
|
|
|
+
|
|
|
// 计算碳排放量
|
|
|
- private Double calculateCarbonEmission(ElecPgSupplyH totalElectricity) {
|
|
|
+ private Double calculateCarbonEmission(Double useElecQuantity) {
|
|
|
EmissionFactor factor = emissionFactorService.selectByRegion("CN", 1);
|
|
|
|
|
|
- if (null == factor || factor.getFactorValue() == null) {
|
|
|
+ if (null == factor || useElecQuantity == null || factor.getFactorValue() == null) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- if (totalElectricity == null || totalElectricity.getUseElecQuantity() == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- return round(totalElectricity.getUseElecQuantity() * factor.getFactorValue(), 2);
|
|
|
+ return round(useElecQuantity * factor.getFactorValue(), 2);
|
|
|
}
|
|
|
|
|
|
private Double calculateCarbonSink(ElecPvSupplyH totalPVProduction) {
|
|
|
EmissionFactor factor = emissionFactorService.selectByRegion("CN", 4);
|
|
|
|
|
|
- if (null == factor || factor.getFactorValue() == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- if (totalPVProduction == null || totalPVProduction.getGenElecQuantity() == null) {
|
|
|
+ if (null == factor || totalPVProduction == null || factor.getFactorValue() == null
|
|
|
+ || totalPVProduction.getGenElecQuantity() == null) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
@@ -145,4 +187,30 @@ public class CarbonCalculationService {
|
|
|
bd = bd.setScale(scale, RoundingMode.HALF_UP);
|
|
|
return bd.doubleValue();
|
|
|
}
|
|
|
+
|
|
|
+ // 计算预测电网购电量
|
|
|
+ private double calculateForecastElectricity(Map<String, Double> historicalData) {
|
|
|
+ // 按月份排序(从近到远)
|
|
|
+ List<Map.Entry<String, Double>> sortedData = historicalData.entrySet().stream()
|
|
|
+ .sorted(Map.Entry.<String, Double>comparingByKey().reversed()).collect(Collectors.toList());
|
|
|
+
|
|
|
+ double forecast = 0.0;
|
|
|
+
|
|
|
+ // 加权平均计算
|
|
|
+ if (sortedData.size() >= 3) {
|
|
|
+ forecast = sortedData.get(0).getValue() * WEIGHT_CURRENT_MONTH
|
|
|
+ + sortedData.get(1).getValue() * WEIGHT_PREVIOUS_MONTH
|
|
|
+ + sortedData.get(2).getValue() * WEIGHT_OLDEST_MONTH;
|
|
|
+ }
|
|
|
+ else if (sortedData.size() == 2) {
|
|
|
+ // 如果只有两个月数据,平均分配权重
|
|
|
+ forecast = sortedData.get(0).getValue() * 0.6 + sortedData.get(1).getValue() * 0.4;
|
|
|
+ }
|
|
|
+ else if (sortedData.size() == 1) {
|
|
|
+ // 如果只有一个月数据,直接使用
|
|
|
+ forecast = sortedData.get(0).getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ return forecast;
|
|
|
+ }
|
|
|
}
|