Commit 34396975 authored by ZWT's avatar ZWT

feat(能源管理系统): 间开优化定时任务

1.开发间开优化定期校准定时任务,配置表达式修改定时任务配置文件,创建cloud模块方法;
2.开发间开优化定期校准定时任务,完成业务逻辑开发;
3.修改间开制度管理模块定期校准新增功能,增加初始化校准历史业务逻辑;
4.开发间开优化短期间开优化定时任务,配置表达式修改定时任务配置文件,创建cloud模块方法;
5.修改长期间开优化定时任务,添加离网型线路数据处理逻辑;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent 54f765fd
...@@ -15,6 +15,7 @@ public enum BusinessError implements XError { ...@@ -15,6 +15,7 @@ public enum BusinessError implements XError {
DidNotFindWellhead(2103, "未发现可优化井口"), DidNotFindWellhead(2103, "未发现可优化井口"),
DidNotFindPlant(2104, "未发现可用光伏电站"), DidNotFindPlant(2104, "未发现可用光伏电站"),
DidNotFindCalibration(2105, "未发现可用周期配置"), DidNotFindCalibration(2105, "未发现可用周期配置"),
UnableToOptimize(2106, "无法优化"),
; ;
private int code; private int code;
......
...@@ -386,13 +386,12 @@ public class SpaceOptimizeBaseService { ...@@ -386,13 +386,12 @@ public class SpaceOptimizeBaseService {
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) { for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId); this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
} }
//累加
totalOperatingPower = totalOperatingPower.add(serviceRating);
if (w == 0) { if (w == 0) {
//第一个井口 //第一个井口
isFirstWellhead = true; isFirstWellhead = true;
totalOperatingPower.add(serviceRating);
} else { } else {
//累加
totalOperatingPower = totalOperatingPower.add(serviceRating);
startInterval = startInterval + detail.getStartInterval(); startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false; isFirstWellhead = false;
} }
...@@ -433,13 +432,12 @@ public class SpaceOptimizeBaseService { ...@@ -433,13 +432,12 @@ public class SpaceOptimizeBaseService {
else { else {
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval); DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
int startIndex = -1; int startIndex = -1;
BigDecimal add = serviceRating.add(totalOperatingPower);
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) { for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a); DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT) if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT)
.compareTo(startTimeOffset) >= 0) { .compareTo(startTimeOffset) >= 0) {
//判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数 //判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数
if (predictedPower.getPower().compareTo(add) >= 0) { if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔 //确定第二口井第一次开井时间为第一口井启动时间+启动间隔
startIndex = a; startIndex = a;
break; break;
......
package pps.core.space.service; package pps.core.space.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerInput; import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerInput;
import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput; import pps.cloud.prediction.service.data.plant_predicted_power_data.DynamicQueryPlantPredictedPowerOutput;
...@@ -9,6 +11,7 @@ import pps.cloud.space.service.ISpaceOptimizeLongCloudService; ...@@ -9,6 +11,7 @@ import pps.cloud.space.service.ISpaceOptimizeLongCloudService;
import pps.core.common.constant.BusinessConstant; import pps.core.common.constant.BusinessConstant;
import pps.core.common.utils.BaseUtils; import pps.core.common.utils.BaseUtils;
import pps.core.space.entity.*; import pps.core.space.entity.*;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.SpaceInstitutionDurationMapper; import pps.core.space.mapper.SpaceInstitutionDurationMapper;
import pps.core.space.mapper.SpaceOptimizeViewMapper; import pps.core.space.mapper.SpaceOptimizeViewMapper;
import pps.core.space.service.data.SpaceOptimizeWellheadAndPlant; import pps.core.space.service.data.SpaceOptimizeWellheadAndPlant;
...@@ -17,6 +20,7 @@ import xstartup.base.XContext; ...@@ -17,6 +20,7 @@ import xstartup.base.XContext;
import xstartup.data.XServiceResult; import xstartup.data.XServiceResult;
import xstartup.helper.XTransactionHelper; import xstartup.helper.XTransactionHelper;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -68,11 +72,12 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService ...@@ -68,11 +72,12 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService
String lineId = detail.getLineId(); String lineId = detail.getLineId();
//创建记录 //创建记录
String periodId = super.createOptimizePeriod(periodDTOList, detailId, lineId, executionCycleForMonth, optimizeDeadline); String periodId = super.createOptimizePeriod(periodDTOList, detailId, lineId, executionCycleForMonth, optimizeDeadline);
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList;
switch (detail.getGridTypeKey()) { switch (detail.getGridTypeKey()) {
//并网型优化 //并网型优化
case "1": case "1":
//获取当前制度对应的光伏预测数据列表 //获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = super.getAveragePowerGenerationListByPlantIds(context, avgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder() DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(plantIdsByLineIdMap.get(lineId)) .plantIds(plantIdsByLineIdMap.get(lineId))
.yearTime(String.valueOf(year)) .yearTime(String.valueOf(year))
...@@ -84,6 +89,149 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService ...@@ -84,6 +89,149 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService
break; break;
//离网型优化 //离网型优化
case "0": case "0":
//获取当前制度对应的光伏预测数据列表
avgPowerList = super.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(plantIdsByLineIdMap.get(lineId))
.yearTime(String.valueOf(year))
.monthTime(month)
.build()
);
//根据类型过滤井口:大间开,连抽井不优化
List<SpaceInstitutionWellheadView> wellheadViewList = this.getWellheadViewList(spaceWellheadList, detailId);
if (CollUtil.isEmpty(wellheadViewList)) {
continue;
}
//获取井口间开时间段
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(durationMapper, detailId);
if (CollUtil.isEmpty(durationMap)) {
//没有设置时间段,无法优化
continue;
}
//时间差
int between = 0;
//启动间隔累积
int startInterval = 0;
//判断是否第一口井
boolean isFirstWellhead;
//第一口井启动时间
DateTime firstStartTime = null;
//第一口井开井时间
int firstIndex = 0;
//井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO;
//离网时间段
List<SpaceOptimizeDurationDTO> offGridPeriodList = new ArrayList<>(32);
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
String recordId = this.createOptimizeWellhead(wellheadDTOList, periodId, wellheadId, wellhead.getWellNumber());
//取当前井口最大发电量
BigDecimal serviceRating = wellhead.getServiceRating();
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
}
totalOperatingPower = totalOperatingPower.add(serviceRating);
if (w == 0) {
//第一个井口
isFirstWellhead = true;
} else {
//累加
startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false;
}
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
String openWellTime = duration.getOpenWellTime();
DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//第一次启动
if (d == 0) {
//第一口井的启动时间
if (isFirstWellhead) {
firstStartTime = startTime;
//计算开井时间
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
//当日时间段平均光伏出力>=第一口井运行负荷时,该时间为第一口井运行时间
if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
firstIndex = a;
break;
}
}
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(firstIndex);
String startTimeString = start.getHourTime() + start.getMinTime();
//计算第一次关井时间,按照间开时间段顺延
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, startTimeString, endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT));
//计算时间偏移
DateTime startTimeOptimize = DateUtil.parse(startTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(startTimeOptimize, startTime);
}
//其它井口的第一次启动时间
else {
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
int startIndex = -1;
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT)
.compareTo(startTimeOffset) >= 0) {
//判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数
if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔
startIndex = a;
break;
}
}
}
if (startIndex > -1) {
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
DateTime startTimeOptimize = DateUtil.parse(start.getHourTime() + start.getMinTime(), BusinessConstant.TIME_FORMAT);
//计算未优化启动间隔
int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration);
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, openWellTime, BaseUtils.getEndTimeString(endTimeOptimize));
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime);
} else {
//无法优化
}
}
} else {
DateTime offset = startTime.offset(DateField.MINUTE, between);
if (offset.compareTo(BusinessConstant.DATE_FLAG) > 0) {
//如果时间超过当天,舍弃
continue;
}
//计算偏移
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId,
offset.toString(BusinessConstant.MINUTES_FORMAT),
BaseUtils.getEndTimeString(DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between))
);
}
}
}
//离网优化
if (CollUtil.isNotEmpty(offGridPeriodList)) {
//截取从第一次开井时间往后的时间段
List<DynamicQueryPlantPredictedPowerOutput> subAvgPowerList = CollUtil.sub(avgPowerList, firstIndex + 1, avgPowerList.size());
if (CollUtil.isEmpty(subAvgPowerList)) {
return XServiceResult.error(context, BusinessError.UnableToOptimize);
}
//逐15分钟计算光伏出力-井场运行功率之和,获得光伏出力不足时间段
for (DynamicQueryPlantPredictedPowerOutput avg : subAvgPowerList) {
avg.setMeetFlag(avg.getPower().compareTo(totalOperatingPower) >= 0);
}
}
break; break;
default: default:
//电网类型不存在 //电网类型不存在
...@@ -134,4 +282,14 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService ...@@ -134,4 +282,14 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService
} }
/*-----------------------------------private-----------------------------------*/ /*-----------------------------------private-----------------------------------*/
public void createDurationOffGridPeriod(List<SpaceOptimizeDurationDTO> offGridPeriodList, String wellheadId,
String openWellTime, String endTimeString) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
durationDTO.setWellheadId(wellheadId);
durationDTO.setOpenWellTime(openWellTime);
durationDTO.setCloseWellTime(endTimeString);
offGridPeriodList.add(durationDTO);
}
} }
\ No newline at end of file
...@@ -28,4 +28,7 @@ public class DynamicQueryPlantPredictedPowerOutput { ...@@ -28,4 +28,7 @@ public class DynamicQueryPlantPredictedPowerOutput {
@XText("预测功率") @XText("预测功率")
private BigDecimal power; private BigDecimal power;
@XText("是否满足")
private boolean meetFlag;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment