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
List<SpaceOptimizeLongDurationView> longDurationList = new ArrayList<>(128);
String executionCycleForMonth = BaseUtils.getExecutionCycleForMonth(date);
DateTime optimizeDeadline = DateUtil.endOfMonth(date);
//开启事务
return XTransactionHelper.begin(context, () -> {
//优化
for (SpaceInstitutionDetailEnt detail : detailEntList) {
String detailId = detail.getId();
String lineId = detail.getLineId();
Integer startInterval = detail.getStartInterval();
//创建记录
String longPeriodId = this.createOptimizeLongPeriod(longPeriodList, detailId, lineId, executionCycleForMonth, optimizeDeadline);
switch (detail.getGridTypeKey()) {
//并网型优化
case "1":
//获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(
plantList.stream()
.filter(p -> StringUtils.equals(lineId, p.getLineId()))
.map(DynamicQueryBasePowerLinePlantOutput::getPlantId)
.collect(Collectors.toList())
)
.yearTime(String.valueOf(year))
.monthTime(month)
.build()
//优化
for (SpaceInstitutionDetailEnt detail : detailEntList) {
String detailId = detail.getId();
String lineId = detail.getLineId();
Integer startInterval = detail.getStartInterval();
//创建记录
String longPeriodId = this.createOptimizeLongPeriod(longPeriodList, detailId, lineId, executionCycleForMonth, optimizeDeadline);
switch (detail.getGridTypeKey()) {
//并网型优化
case "1":
//获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context,
DynamicQueryPlantPredictedPowerInput.builder()
.plantIds(
plantList.stream()
.filter(p -> StringUtils.equals(lineId, p.getLineId()))
.map(DynamicQueryBasePowerLinePlantOutput::getPlantId)
.collect(Collectors.toList())
)
.yearTime(String.valueOf(year))
.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)
);
//取光伏出力峰值
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)) {
if (CollUtil.isEmpty(durationList)) {
//没有设置时间段,无法优化
continue;
}
//---------------------------------井口优化---------------------------------
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = durationList.stream()
.collect(Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId));
int between = 0;
//判断是否第一口井
boolean isFirstWellhead;
//第一口井启动时间
DateTime firstStartTime = null;
//井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO;
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
this.createOptimizeLongWellhead(longWellheadList, longPeriodId, wellheadId, wellhead.getWellNumber());
//取当前井口最大发电量
BigDecimal serviceRating = wellhead.getServiceRating();
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
//---------------------------------井口优化---------------------------------
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = durationList.stream()
.collect(Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId));
int between = 0;
//判断是否第一口井
boolean isFirstWellhead;
//第一口井启动时间
DateTime firstStartTime = null;
//井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO;
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
this.createOptimizeLongWellhead(longWellheadList, longPeriodId, wellheadId, wellhead.getWellNumber());
//取当前井口最大发电量
BigDecimal serviceRating = wellhead.getServiceRating();
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
if (w == 0) {
//第一个井口
isFirstWellhead = true;
totalOperatingPower.add(serviceRating);
} else {
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;
//计算关井时间
int endIndex = 0;
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(startTime) < 0) {
continue;
}
//当日时间段平均光伏出力>第一口井运行负荷时,该时间为第一口井运行时间
if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
endIndex = a;
if (w == 0) {
//第一个井口
isFirstWellhead = true;
totalOperatingPower.add(serviceRating);
} else {
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;
//计算关井时间
int endIndex = 0;
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(startTime) < 0) {
continue;
}
//当日时间段平均光伏出力>第一口井运行负荷时,该时间为第一口井运行时间
if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
endIndex = a;
break;
}
}
DynamicQueryPlantPredictedPowerOutput end = avgPowerList.get(endIndex);
String endTimeString = end.getHourTime() + end.getMinTime();
this.createOptimizeLongDuration(longDurationList, duration, longPeriodId, wellheadId, null,
openWellTime, StringUtils.substringBeforeLast(endTimeString, BusinessConstant.INITIALIZATION_SECOND)
);
//计算
DateTime endTimeOptimize = DateUtil.parse(endTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE);
if (endTimeOptimize.compareTo(endTime) < 0) {
between = ~between + 1;
}
}
//其它井口的第一次启动时间
else {
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;
}
}
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,
openWellTime, StringUtils.substringBeforeLast(endTimeString, BusinessConstant.INITIALIZATION_SECOND)
openWellTime, endTimeString
);
//计算
DateTime endTimeOptimize = DateUtil.parse(endTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE);
if (endTimeOptimize.compareTo(endTime) < 0) {
between = ~between + 1;
}
}
//其它井口的第一次启动时间
else {
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;
//累加
totalOperatingPower = totalOperatingPower.add(serviceRating);
startInterval = startInterval + startInterval;
} 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 {
//遍历井口,按发电功率大于等于光伏出力峰值条件分组
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = spaceWellheadList.stream()
.filter(w ->
StringUtils.equals(detailId, w.getInstitutionId())
)
.collect(Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO));
}
} else {
//遍历井口,按发电功率大于等于光伏出力峰值条件分组
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = spaceWellheadList.stream()
.filter(w ->
StringUtils.equals(detailId, w.getInstitutionId())
)
.collect(Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO));
List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
int size = spaceWellheadList.size();
int lowWellheadListSize = lowWellheadList.size();
//光伏出力峰值<任何一口井的运行功率:消峰平谷策略
if (size == lowWellheadListSize) {
List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
int size = spaceWellheadList.size();
int lowWellheadListSize = lowWellheadList.size();
//光伏出力峰值<任何一口井的运行功率:消峰平谷策略
if (size == lowWellheadListSize) {
}
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
else {
List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
}
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
else {
List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
}
}
break;
//离网型优化
case "0":
break;
default:
//电网类型不存在
}
}
break;
//离网型优化
case "0":
break;
default:
//电网类型不存在
}
}
//开启事务
return XTransactionHelper.begin(context, () -> {
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