Commit ca7aee96 authored by ZWT's avatar ZWT

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

1.开发间开优化长期间开优化定时任务,完成并网流程绿电消纳优先策略;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent 6e9f161f
...@@ -100,223 +100,224 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou ...@@ -100,223 +100,224 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
List<SpaceOptimizeLongDurationView> longDurationList = new ArrayList<>(128); List<SpaceOptimizeLongDurationView> longDurationList = new ArrayList<>(128);
String executionCycleForMonth = BaseUtils.getExecutionCycleForMonth(date); String executionCycleForMonth = BaseUtils.getExecutionCycleForMonth(date);
DateTime optimizeDeadline = DateUtil.endOfMonth(date); DateTime optimizeDeadline = DateUtil.endOfMonth(date);
//开启事务 //优化
return XTransactionHelper.begin(context, () -> { for (SpaceInstitutionDetailEnt detail : detailEntList) {
//优化 String detailId = detail.getId();
for (SpaceInstitutionDetailEnt detail : detailEntList) { String lineId = detail.getLineId();
String detailId = detail.getId(); Integer startInterval = detail.getStartInterval();
String lineId = detail.getLineId(); //创建记录
Integer startInterval = detail.getStartInterval(); String longPeriodId = this.createOptimizeLongPeriod(longPeriodList, detailId, lineId, executionCycleForMonth, optimizeDeadline);
//创建记录 switch (detail.getGridTypeKey()) {
String longPeriodId = this.createOptimizeLongPeriod(longPeriodList, detailId, lineId, executionCycleForMonth, optimizeDeadline); //并网型优化
switch (detail.getGridTypeKey()) { case "1":
//并网型优化 //获取当前制度对应的光伏预测数据列表
case "1": List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context,
//获取当前制度对应的光伏预测数据列表 DynamicQueryPlantPredictedPowerInput.builder()
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context, .plantIds(
DynamicQueryPlantPredictedPowerInput.builder() plantList.stream()
.plantIds( .filter(p -> StringUtils.equals(lineId, p.getLineId()))
plantList.stream() .map(DynamicQueryBasePowerLinePlantOutput::getPlantId)
.filter(p -> StringUtils.equals(lineId, p.getLineId())) .collect(Collectors.toList())
.map(DynamicQueryBasePowerLinePlantOutput::getPlantId) )
.collect(Collectors.toList()) .yearTime(String.valueOf(year))
) .monthTime(month)
.yearTime(String.valueOf(year)) .build()
.monthTime(month) );
.build() //取光伏出力峰值
BigDecimal powerMax = avgPowerList.stream()
.map(DynamicQueryPlantPredictedPowerOutput::getPower)
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
//取当前制度下井口的总功率
BigDecimal wellheadTotalPower = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()))
.map(SpaceInstitutionWellheadView::getServiceRating)
.reduce(BigDecimal.ZERO, BigDecimal::add);
int compare = powerMax.compareTo(wellheadTotalPower);
//光伏出力峰值大于等于井口总功率:绿电消纳优先策略
if (compare >= BusinessConstant.ZERO) {
//根据类型过滤井口:大间开,连抽井不优化
List<SpaceInstitutionWellheadView> wellheadViewList = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()) &&
StringUtils.equals("INTERVAL", w.getRunTypeKey()) &&
StringUtils.equals("0", w.getIntervalTypeKey()))
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq))
.collect(Collectors.toList());
if (CollUtil.isEmpty(wellheadViewList)) {
continue;
}
//通过间开ID和井口ID查所有井口时段配置
List<SpaceInstitutionDurationEnt> durationList = durationMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDurationEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDurationEnt::getInstitutionId, detailId)
.orderByAsc(SpaceInstitutionDurationEnt::getOpenWellTime)
); );
//取光伏出力峰值 if (CollUtil.isEmpty(durationList)) {
BigDecimal powerMax = avgPowerList.stream() //没有设置时间段,无法优化
.map(DynamicQueryPlantPredictedPowerOutput::getPower) continue;
.max(BigDecimal::compareTo) }
.orElse(BigDecimal.ZERO); //---------------------------------井口优化---------------------------------
//取当前制度下井口的总功率 Map<String, List<SpaceInstitutionDurationEnt>> durationMap = durationList.stream()
BigDecimal wellheadTotalPower = spaceWellheadList.stream() .collect(Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId));
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId())) int between = 0;
.map(SpaceInstitutionWellheadView::getServiceRating) //判断是否第一口井
.reduce(BigDecimal.ZERO, BigDecimal::add); boolean isFirstWellhead;
int compare = powerMax.compareTo(wellheadTotalPower); //第一口井启动时间
//光伏出力峰值大于等于井口总功率:绿电消纳优先策略 DateTime firstStartTime = null;
if (compare >= BusinessConstant.ZERO) { //井口累积运行总功率
//根据类型过滤井口:大间开,连抽井不优化 BigDecimal totalOperatingPower = BigDecimal.ZERO;
List<SpaceInstitutionWellheadView> wellheadViewList = spaceWellheadList.stream() for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()) && SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
StringUtils.equals("INTERVAL", w.getRunTypeKey()) && String wellheadId = wellhead.getWellheadId();
StringUtils.equals("0", w.getIntervalTypeKey())) this.createOptimizeLongWellhead(longWellheadList, longPeriodId, wellheadId, wellhead.getWellNumber());
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq)) //取当前井口最大发电量
.collect(Collectors.toList()); BigDecimal serviceRating = wellhead.getServiceRating();
if (CollUtil.isEmpty(wellheadViewList)) { List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
continue; if (CollUtil.isEmpty(durationConfigList)) {
}
//通过间开ID和井口ID查所有井口时段配置
List<SpaceInstitutionDurationEnt> durationList = durationMapper.selectList(new LambdaQueryWrapper<SpaceInstitutionDurationEnt>()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDurationEnt::getInstitutionId, detailId)
.orderByAsc(SpaceInstitutionDurationEnt::getOpenWellTime)
);
if (CollUtil.isEmpty(durationList)) {
//没有设置时间段,无法优化 //没有设置时间段,无法优化
continue; continue;
} }
//---------------------------------井口优化--------------------------------- if (w == 0) {
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = durationList.stream() //第一个井口
.collect(Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId)); isFirstWellhead = true;
int between = 0; totalOperatingPower.add(serviceRating);
//判断是否第一口井 } else {
boolean isFirstWellhead; isFirstWellhead = false;
//第一口井启动时间 }
DateTime firstStartTime = null; for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
//井口累积运行总功率 SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
BigDecimal totalOperatingPower = BigDecimal.ZERO; String openWellTime = duration.getOpenWellTime();
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) { DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w); DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
String wellheadId = wellhead.getWellheadId(); //第一次启动
this.createOptimizeLongWellhead(longWellheadList, longPeriodId, wellheadId, wellhead.getWellNumber()); if (d == 0) {
//取当前井口最大发电量 //第一口井的启动时间
BigDecimal serviceRating = wellhead.getServiceRating(); if (isFirstWellhead) {
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead); firstStartTime = startTime;
if (CollUtil.isEmpty(durationConfigList)) { //计算关井时间
//没有设置时间段,无法优化 int endIndex = 0;
continue; for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
} DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a);
if (w == 0) { if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT).compareTo(startTime) < 0) {
//第一个井口 continue;
isFirstWellhead = true; }
totalOperatingPower.add(serviceRating); //当日时间段平均光伏出力>第一口井运行负荷时,该时间为第一口井运行时间
} else { if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
isFirstWellhead = false; endIndex = a;
} break;
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) { }
SpaceInstitutionDurationEnt duration = durationConfigList.get(d); }
String openWellTime = duration.getOpenWellTime(); DynamicQueryPlantPredictedPowerOutput end = avgPowerList.get(endIndex);
DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT); String endTimeString = end.getHourTime() + end.getMinTime();
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT); this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null,
//第一次启动 openWellTime, StringUtils.substringBeforeLast(endTimeString, BusinessConstant.INITIALIZATION_SECOND)
if (d == 0) { );
//第一口井的启动时间 //计算
if (isFirstWellhead) { DateTime endTimeOptimize = DateUtil.parse(endTimeString, BusinessConstant.TIME_FORMAT);
firstStartTime = startTime; //取时间间隔(分钟)
//计算关井时间 between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE);
int endIndex = 0; if (endTimeOptimize.compareTo(endTime) < 0) {
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) { between = ~between + 1;
DynamicQueryPlantPredictedPowerOutput predictedPower = avgPowerList.get(a); }
if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT).compareTo(startTime) < 0) { }
continue; //其它井口的第一次启动时间
} else {
//当日时间段平均光伏出力>第一口井运行负荷时,该时间为第一口井运行时间 DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) { int startIndex = -1;
endIndex = a; BigDecimal add = serviceRating.add(totalOperatingPower);
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(add) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔
startIndex = a;
break; break;
} }
} }
DynamicQueryPlantPredictedPowerOutput end = avgPowerList.get(endIndex); }
String endTimeString = end.getHourTime() + end.getMinTime(); 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);
String endTimeString;
if (endTimeOptimize.compareTo(dateFlag) > 0) {
endTimeString = BusinessConstant.END_OF_DAY_TIME;
} else {
endTimeString = endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT);
}
this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null, this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null,
openWellTime, StringUtils.substringBeforeLast(endTimeString, BusinessConstant.INITIALIZATION_SECOND) openWellTime, endTimeString
); );
//计算
DateTime endTimeOptimize = DateUtil.parse(endTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟) //取时间间隔(分钟)
between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE); between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE);
if (endTimeOptimize.compareTo(endTime) < 0) { if (endTimeOptimize.compareTo(endTime) < 0) {
between = ~between + 1; between = ~between + 1;
} }
} //累加
//其它井口的第一次启动时间 totalOperatingPower = totalOperatingPower.add(serviceRating);
else { startInterval = startInterval + startInterval;
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
int startIndex = -1;
BigDecimal add = serviceRating.add(totalOperatingPower);
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(add) >= 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);
String endTimeString;
if (endTimeOptimize.compareTo(dateFlag) > 0) {
endTimeString = BusinessConstant.END_OF_DAY_TIME;
} else {
endTimeString = endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT);
}
this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null,
openWellTime, endTimeString
);
//取时间间隔(分钟)
between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE);
if (endTimeOptimize.compareTo(endTime) < 0) {
between = ~between + 1;
}
//累加
totalOperatingPower = totalOperatingPower.add(serviceRating);
startInterval = startInterval + startInterval;
} else {
//无法优化
}
}
} else {
DateTime offset = startTime.offset(DateField.MINUTE, between);
if (offset.compareTo(dateFlag) > 0) {
//如果时间超过当天,舍弃
continue;
}
DateTime endDate = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between);
String closeWellTime;
if (endDate.compareTo(dateFlag) > 0) {
closeWellTime = BusinessConstant.END_OF_DAY_TIME;
} else { } else {
closeWellTime = endDate.toString(BusinessConstant.MINUTES_FORMAT); //无法优化
} }
//计算偏移
this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null,
offset.toString(BusinessConstant.MINUTES_FORMAT), closeWellTime
);
} }
} else {
DateTime offset = startTime.offset(DateField.MINUTE, between);
if (offset.compareTo(dateFlag) > 0) {
//如果时间超过当天,舍弃
continue;
}
DateTime endDate = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between);
String closeWellTime;
if (endDate.compareTo(dateFlag) > 0) {
closeWellTime = BusinessConstant.END_OF_DAY_TIME;
} else {
closeWellTime = endDate.toString(BusinessConstant.MINUTES_FORMAT);
}
//计算偏移
this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null,
offset.toString(BusinessConstant.MINUTES_FORMAT), closeWellTime
);
} }
} }
} else { }
//遍历井口,按发电功率大于等于光伏出力峰值条件分组 } else {
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = spaceWellheadList.stream() //遍历井口,按发电功率大于等于光伏出力峰值条件分组
.filter(w -> Map<Boolean, List<SpaceInstitutionWellheadView>> collect = spaceWellheadList.stream()
StringUtils.equals(detailId, w.getInstitutionId()) .filter(w ->
) StringUtils.equals(detailId, w.getInstitutionId())
.collect(Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO)); )
.collect(Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO));
List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false); List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
int size = spaceWellheadList.size(); int size = spaceWellheadList.size();
int lowWellheadListSize = lowWellheadList.size(); int lowWellheadListSize = lowWellheadList.size();
//光伏出力峰值<任何一口井的运行功率:消峰平谷策略 //光伏出力峰值<任何一口井的运行功率:消峰平谷策略
if (size == lowWellheadListSize) { if (size == lowWellheadListSize) {
} }
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷 //光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
else { else {
List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true); List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
}
} }
break; }
//离网型优化 break;
case "0": //离网型优化
break; case "0":
default: break;
//电网类型不存在 default:
} //电网类型不存在
} }
}
//开启事务
return XTransactionHelper.begin(context, () -> {
return XServiceResult.OK; return XServiceResult.OK;
}); });
} }
......
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