Commit 5e29c267 authored by ZWT's avatar ZWT

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

1.开发间开优化定期校准定时任务,配置表达式修改定时任务配置文件,创建cloud模块方法;
2.开发间开优化定期校准定时任务,完成业务逻辑开发;
3.修改间开制度管理模块定期校准新增功能,增加初始化校准历史业务逻辑;
4.开发间开优化短期间开优化定时任务,配置表达式修改定时任务配置文件,创建cloud模块方法;
5.修改长期间开优化定时任务,添加离网型线路数据处理逻辑;
6.创建储能预测电量数据(模拟数据测试用)表,生成对应代码,添加条件查询各时段储能预测数据Cloud模块接口;
7.修改长期间开优化定时任务,增加离网型算法计算储能可用时长逻辑;
8.修改长期间开优化定时任务,优化部分sql查询语句查询逻辑,优化代码结构;
9.光伏预测Cloud模块查询预测发电量接口修改,增加查询长期发电量逻辑;
10.修改中短期间开优化定时任务,添加离网型优化逻辑;
11.修改长期/中短期间开优化定时任务,优化代码结构;
12.修改基础间开配置模块设为基础间开制度及重新优化接口,增加并网型优化逻辑;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent 1c8db3fa
...@@ -90,6 +90,11 @@ public class BusinessConstant { ...@@ -90,6 +90,11 @@ public class BusinessConstant {
*/ */
public static final String END_OF_DAY_TIME = "23:59"; public static final String END_OF_DAY_TIME = "23:59";
/**
* 一天开始时间
*/
public static final String START_OF_DAY_TIME = "00:00";
/** /**
* 日期标志 * 日期标志
*/ */
......
...@@ -117,308 +117,109 @@ public class SpaceOptimizeBaseService { ...@@ -117,308 +117,109 @@ public class SpaceOptimizeBaseService {
} }
/** /**
* 条件获取获取光伏预测各时段平均值列表 * 并网优化
*
* @param context 上下文
* @param input 输入
* @return {@link List}<{@link DynamicQueryPlantPredictedPowerOutput}>
*/
public List<DynamicQueryPlantPredictedPowerOutput> getAveragePowerGenerationListByPlantIds(XContext context, DynamicQueryPlantPredictedPowerInput input) {
IPlantPredictedPowerCloudService cloudService = context.getBean(IPlantPredictedPowerCloudService.class);
XListResult<DynamicQueryPlantPredictedPowerOutput> result = cloudService.queryAveragePowerGenerationListByParam(context, input);
result.throwIfFail();
return result.getResult();
}
/**
* 条件查询时段储能电量平均值(模拟测试用)
* todo: 模拟测试用,后续替换
* *
* @param context 上下文 * @param context 上下文
* @param input 输入 * @param wellheadDTOList 井口dtolist
* @return {@link List}<{@link DynamicQueryStoragePredictedPowerOutput}> * @param durationDTOList 持续时间dtolist
*/ * @param unOptimizeDurationList 取消优化工期列表
public List<DynamicQueryStoragePredictedPowerOutput> getAverageEnergyStorageListByParam(XContext context, DynamicQueryStoragePredictedPowerInput input) {
IStoragePredictedPowerCloudService cloudService = context.getBean(IStoragePredictedPowerCloudService.class);
XListResult<DynamicQueryStoragePredictedPowerOutput> result = cloudService.queryAverageEnergyStorageListByParam(context, input);
result.throwIfFail();
return result.getResult();
}
/**
* 获得最大功率
*
* @param avgPowerList 平均功率列表
* @return {@link BigDecimal}
*/
public BigDecimal getPowerMax(List<DynamicQueryPlantPredictedPowerOutput> avgPowerList) {
return avgPowerList.stream()
.map(DynamicQueryPlantPredictedPowerOutput::getPower)
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
}
/**
* 获取井口总功率
*
* @param spaceWellheadList 空间井口清单 * @param spaceWellheadList 空间井口清单
* @param detailId 详细信息id * @param detail 细节
* @return {@link BigDecimal} * @param monthNum 月份
* @param periodId 期间id
* @param plantPowerInput 电厂功率输入
*/ */
public BigDecimal getWellheadTotalPower(List<SpaceInstitutionWellheadView> spaceWellheadList, String detailId) { public void gridConnectedOptimization(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList,
return spaceWellheadList.stream() List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId())) List<SpaceInstitutionWellheadView> spaceWellheadList,
.map(SpaceInstitutionWellheadView::getServiceRating) SpaceInstitutionDetailEnt detail, int monthNum, String periodId,
.reduce(BigDecimal.ZERO, BigDecimal::add); DynamicQueryPlantPredictedPowerInput plantPowerInput) {
//获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context, plantPowerInput);
if (CollUtil.isEmpty(avgPowerList)) {
return;
} }
//取光伏出力峰值
/** BigDecimal powerMax = this.getPowerMax(avgPowerList);
* 获取当前制度关联的井口按照是否可优化分组 //取当前制度下井口的总功率
* BigDecimal wellheadTotalPower = this.getWellheadTotalPower(spaceWellheadList, detail.getId());
* @param spaceWellheadList 空间井口清单 //根据类型过滤井口:大间开,连抽井不优化
* @param detailId 详细信息id Map<Boolean, List<SpaceInstitutionWellheadView>> wellheadViewMap = this.getWellheadViewList(spaceWellheadList, detail.getId());
* @return {@link Map}<{@link Boolean}, {@link List}<{@link SpaceInstitutionWellheadView}>> List<SpaceInstitutionWellheadView> wellheadViewList = wellheadViewMap.get(true);
*/ if (CollUtil.isEmpty(wellheadViewList)) {
public Map<Boolean, List<SpaceInstitutionWellheadView>> getWellheadViewList(List<SpaceInstitutionWellheadView> spaceWellheadList, String detailId) { return;
return spaceWellheadList.stream()
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq))
.collect(
Collectors.partitioningBy(w -> StringUtils.equals(detailId, w.getInstitutionId()) &&
StringUtils.equals("INTERVAL", w.getRunTypeKey()) &&
StringUtils.equals("0", w.getIntervalTypeKey())
)
);
} }
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(context, detail.getId());
/** if (CollUtil.isEmpty(durationMap)) {
* 获取井口间开时间段
*
* @param context 上下文
* @param detailId 详细信息id
* @return {@link Map}<{@link String}, {@link List}<{@link SpaceInstitutionDurationEnt}>>
*/
public Map<String, List<SpaceInstitutionDurationEnt>> getDurationMap(XContext context, String detailId) {
SpaceInstitutionDurationMapper durationMapper = context.getBean(SpaceInstitutionDurationMapper.class);
//通过间开ID和井口ID查所有井口时段配置
List<SpaceInstitutionDurationEnt> durationList = durationMapper.selectList(new QueryWrapper<SpaceInstitutionDurationEnt>()
.select("*",
"STR_TO_DATE( CONCAT( open_well_time, ':00' ), '%H:%i:%s' ) AS openTime",
"STR_TO_DATE( CONCAT( close_well_time, ':00' ), '%H:%i:%s' ) AS closeTime"
)
.lambda()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDurationEnt::getInstitutionId, detailId)
.orderByAsc(SpaceInstitutionDurationEnt::getOpenWellTime)
);
if (CollUtil.isEmpty(durationList)) {
//没有设置时间段,无法优化 //没有设置时间段,无法优化
return null; return;
}
return durationList.stream()
.collect(
Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId)
);
} }
//光伏出力峰值大于等于井口总功率:绿电消纳优先策略
/*-----------------------------------private-----------------------------------*/ if (powerMax.compareTo(wellheadTotalPower) >= BusinessConstant.ZERO) {
//---------------------------------绿电消纳策略---------------------------------
/** this.greenElectricityConsumptionStrategy(wellheadDTOList, unOptimizeDurationList, durationDTOList,
* 获取井口Map通过最大功率区分 wellheadViewList, avgPowerList, durationMap, detail, periodId);
* } else {
* @param wellheadViewList 井口视图列表 //遍历井口,按发电功率大于等于光伏出力峰值条件分组
* @param powerMax 最大功率 Map<Boolean, List<SpaceInstitutionWellheadView>> collect = this.getWellheadViewMapByPower(wellheadViewList, powerMax);
* @return {@link Map}<{@link Boolean}, {@link List}<{@link SpaceInstitutionWellheadView}>> List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
*/ int size = spaceWellheadList.size();
private Map<Boolean, List<SpaceInstitutionWellheadView>> getWellheadViewMapByPower(List<SpaceInstitutionWellheadView> wellheadViewList, BigDecimal powerMax) { int lowWellheadListSize = lowWellheadList.size();
return wellheadViewList.stream() //光伏出力峰值<任何一口井的运行功率:消峰平谷策略
.collect( if (size == lowWellheadListSize) {
Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO) //---------------------------------消峰平谷策略---------------------------------
); this.peakEliminationAndValleyLevelingStrategy(context, wellheadDTOList, unOptimizeDurationList, durationDTOList, wellheadViewList,
durationMap, detail, monthNum, periodId);
} }
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
/** else {
* 按线路ID集合获取电站列表 List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
* this.greenElectricityConsumptionStrategy(wellheadDTOList, unOptimizeDurationList, durationDTOList,
* @param context 上下文 highWellheadList, avgPowerList, durationMap, detail, periodId);
* @param lineIds 线路ID this.peakEliminationAndValleyLevelingStrategy(context, wellheadDTOList, unOptimizeDurationList, durationDTOList,
* @return {@link List}<{@link DynamicQueryBasePowerLinePlantOutput}> lowWellheadList, durationMap, detail, monthNum, periodId);
*/
private List<DynamicQueryBasePowerLinePlantOutput> getPowerLinePlantListByLineIds(XContext context, Set<String> lineIds) {
IBasePowerLineCloudService cloudService = context.getBean(IBasePowerLineCloudService.class);
XListResult<DynamicQueryBasePowerLinePlantOutput> result = cloudService.queryPowerLinePlantListByParam(context,
DynamicQueryBasePowerLinePlantInput.builder()
.lineIds(lineIds)
.build()
);
result.throwIfFail();
return result.getResult();
} }
/**
* 条件查询线路关联储能设备参数平均值
*
* @param context 上下文
* @param lineIds 线路ID
* @return {@link Map}<{@link String}, {@link List}<{@link DynamicQueryBasePowerLineStorageViewOutput}>>
*/
private Map<String, List<DynamicQueryBasePowerLineStorageViewOutput>> getPowerLineStorageListByLineIds(XContext context, Set<String> lineIds) {
IBasePowerLineCloudService cloudService = context.getBean(IBasePowerLineCloudService.class);
XListResult<DynamicQueryBasePowerLineStorageViewOutput> result = cloudService.queryPowerLineStorageListByLineIds(context,
DynamicQueryBasePowerLineStorageInput.builder()
.lineIds(lineIds)
.build()
);
result.throwIfFail();
List<DynamicQueryBasePowerLineStorageViewOutput> list = result.getResult();
Map<String, List<DynamicQueryBasePowerLineStorageViewOutput>> collect;
if (CollUtil.isEmpty(list)) {
collect = new HashMap<>(0);
} else {
collect = list.stream()
.collect(Collectors.groupingBy(DynamicQueryBasePowerLineStorageViewOutput::getLineId));
} }
return collect; //保存不需要优化的井口
this.setUnOptimizeWellheadConfig(wellheadDTOList, unOptimizeDurationList, durationDTOList,
wellheadViewMap.get(false), durationMap, periodId);
} }
/** /**
* 为间开井口列表设置发电功率 * 离网优化
* *
* @param context 上下文 * @param context 上下文
* @param wellheadDTOList 井口dtolist
* @param durationDTOList 持续时间dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param spaceWellheadList 空间井口清单 * @param spaceWellheadList 空间井口清单
* @param storageAvgMap 存储平均值映射
* @param detail 细节
* @param periodId 期间id
* @param input 输入
* @param plantPowerInput 电厂功率输入
*/ */
private void setServiceRatingForSpaceWellheadList(XContext context, List<SpaceInstitutionWellheadView> spaceWellheadList) { public void offGridOptimization(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> durationDTOList,
IBaseWellheadCloudService cloudService = context.getBean(IBaseWellheadCloudService.class); List<SpaceOptimizeDurationDTO> unOptimizeDurationList, List<SpaceInstitutionWellheadView> spaceWellheadList,
XListResult<DynamicQueryBaseWellheadOutput> result = cloudService.queryBaseWellheadListByParam(context, Map<String, List<DynamicQueryBasePowerLineStorageViewOutput>> storageAvgMap, SpaceInstitutionDetailEnt detail, String periodId,
DynamicQueryBaseWellheadInput.builder() DynamicQueryStoragePredictedPowerInput input, DynamicQueryPlantPredictedPowerInput plantPowerInput) {
.wellheadIds(spaceWellheadList.stream() //获取当前制度对应的光伏预测数据列表
.map(SpaceInstitutionWellheadView::getWellheadId) List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context, plantPowerInput);
.collect(Collectors.toList()) if (CollUtil.isEmpty(avgPowerList)) {
)
.build());
result.throwIfFail();
List<DynamicQueryBaseWellheadOutput> wellheadOutputList = result.getResult();
if (CollUtil.isEmpty(wellheadOutputList)) {
return; return;
} }
spaceWellheadList.forEach(s -> { //根据类型过滤井口:大间开,连抽井不优化
s.setServiceRating( Map<Boolean, List<SpaceInstitutionWellheadView>> wellheadViewMap = this.getWellheadViewList(spaceWellheadList, detail.getId());
wellheadOutputList.stream() List<SpaceInstitutionWellheadView> wellheadViewList = wellheadViewMap.get(true);
.filter(w -> StringUtils.equals(s.getWellheadId(), w.getId())) if (CollUtil.isEmpty(wellheadViewList)) {
.findAny() return;
.map(DynamicQueryBaseWellheadOutput::getServiceRating)
.orElse(BigDecimal.ZERO)
);
});
} }
//获取井口间开时间段
/** Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(context, detail.getId());
* 创建间开优化信息 if (CollUtil.isEmpty(durationMap)) {
* //没有设置时间段,无法优化
* @param periodDTOList 时期数据主义者 return;
* @param detailId 详细信息id
* @param lineId 线路id
* @param executionCycleForMonth 月执行周期
* @param optimizeDeadline 优化截止日期
* @return {@link String}
*/
public String createOptimizePeriod(List<SpaceOptimizePeriodDTO> periodDTOList, String detailId,
String lineId, String executionCycleForMonth, Date optimizeDeadline) {
SpaceOptimizePeriodDTO periodDTO = new SpaceOptimizePeriodDTO();
BaseUtils.setBaseModelDefaultForJob(periodDTO);
periodDTO.setInstitutionId(detailId);
periodDTO.setLineId(lineId);
periodDTO.setExecutionCycle(executionCycleForMonth);
periodDTO.setOptimizeState(BusinessConstant.ZERO);
periodDTO.setOptimizeDeadline(optimizeDeadline);
periodDTOList.add(periodDTO);
return periodDTO.getId();
}
/**
* 创建间开优化井口信息
*
* @param wellheadDTOList 井口dtolist
* @param periodId 期间id
* @param wellheadId 井口id
* @param wellNumber 井号
* @return {@link String}
*/
public String createOptimizeWellhead(List<SpaceOptimizeWellheadDTO> wellheadDTOList, String periodId,
String wellheadId, String wellNumber) {
SpaceOptimizeWellheadDTO wellheadDTO = new SpaceOptimizeWellheadDTO();
BaseUtils.setBaseModelDefaultForJob(wellheadDTO);
wellheadDTO.setPeriodId(periodId);
wellheadDTO.setWellheadId(wellheadId);
wellheadDTO.setWellNumber(wellNumber);
wellheadDTOList.add(wellheadDTO);
return wellheadDTO.getId();
}
/**
* 创建间开优化井口区间配置信息
*
* @param durationDTOList 持续时间dtolist
* @param periodId 期间id
* @param recordId 记录id
* @param wellheadId 井口id
* @param generationTypeKey 生成类型密钥
* @param openWellTime 开井时间
* @param endTimeString 结束时间字符串
*/
public void createOptimizeDuration(List<SpaceOptimizeDurationDTO> durationDTOList, String periodId,
String recordId, String wellheadId, String generationTypeKey,
String openWellTime, String endTimeString) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
BaseUtils.setBaseModelDefaultForJob(durationDTO);
durationDTO.setRecordId(recordId);
durationDTO.setPeriodId(periodId);
durationDTO.setWellheadId(wellheadId);
durationDTO.setGenerationTypeKey(generationTypeKey);
durationDTO.setIsOptimize(BusinessConstant.ZERO);
durationDTO.setOpenWellTime(openWellTime);
durationDTO.setCloseWellTime(endTimeString);
durationDTOList.add(durationDTO);
}
/**
* 创建间开原始间开区间
*
* @param unOptimizeDurationList 取消优化工期列表
* @param durationEnt 持续时间ent
* @param periodId 期间id
* @param recordId 记录id
* @param wellheadId 井口id
*/
public void createUnOptimizeDuration(List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
SpaceInstitutionDurationEnt durationEnt,
String periodId, String recordId, String wellheadId) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
BaseUtils.setBaseModelDefaultForJob(durationDTO);
durationDTO.setRecordId(recordId);
durationDTO.setPeriodId(periodId);
durationDTO.setWellheadId(wellheadId);
durationDTO.setIsOptimize(BusinessConstant.ONE);
durationDTO.setOpenWellTime(durationEnt.getOpenWellTime());
durationDTO.setCloseWellTime(durationEnt.getCloseWellTime());
unOptimizeDurationList.add(durationDTO);
} }
/**
* 绿电消纳策略
*
* @param wellheadDTOList 井口dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param durationDTOList 持续时间dtolist
* @param wellheadViewList 井口视图列表
* @param avgPowerList 平均功率列表
* @param durationMap 持续时间图
* @param detail 细节
* @param periodId 期间id
*/
public void greenElectricityConsumptionStrategy(List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> wellheadViewList,
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList, Map<String, List<SpaceInstitutionDurationEnt>> durationMap,
SpaceInstitutionDetailEnt detail, String periodId) {
//时间差 //时间差
int between = 0; int between = 0;
//启动间隔累积 //启动间隔累积
...@@ -427,8 +228,12 @@ public class SpaceOptimizeBaseService { ...@@ -427,8 +228,12 @@ public class SpaceOptimizeBaseService {
boolean isFirstWellhead; boolean isFirstWellhead;
//第一口井启动时间 //第一口井启动时间
DateTime firstStartTime = null; DateTime firstStartTime = null;
//第一口井开井时间
int firstIndex = 0;
//井口累积运行总功率 //井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO; BigDecimal totalOperatingPower = BigDecimal.ZERO;
//离网时间段
List<SpaceOptimizeDurationDTO> offGridPeriodList = new ArrayList<>(32);
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) { for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w); SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId(); String wellheadId = wellhead.getWellheadId();
...@@ -444,46 +249,40 @@ public class SpaceOptimizeBaseService { ...@@ -444,46 +249,40 @@ 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); totalOperatingPower = totalOperatingPower.add(serviceRating);
if (w == 0) { if (w == 0) {
//第一个井口 //第一个井口
isFirstWellhead = true; isFirstWellhead = true;
} else { } else {
//累加
startInterval = startInterval + detail.getStartInterval(); startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false; isFirstWellhead = false;
} }
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) { for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
SpaceInstitutionDurationEnt duration = durationConfigList.get(d); SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
String openWellTime = duration.getOpenWellTime(); DateTime startTime = DateUtil.date(duration.getOpenTime());
DateTime startTime = DateUtil.parse(openWellTime + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT); DateTime endTime = DateUtil.date(duration.getCloseTime());
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//第一次启动 //第一次启动
if (d == 0) { if (d == 0) {
//第一口井的启动时间 //第一口井的启动时间
if (isFirstWellhead) { if (isFirstWellhead) {
firstStartTime = startTime; firstStartTime = startTime;
//计算开井时间 //计算开井时间
int startIndex = 0;
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 (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) { if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
startIndex = a; firstIndex = a;
break; break;
} }
} }
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex); DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(firstIndex);
String startTimeString = start.getHourTime() + start.getMinTime(); DateTime startTimeOptimize = DateUtil.date(start.getCreateTime());
//计算第一次关井时间,按照间开时间段顺延 //计算第一次关井时间,按照间开时间段顺延
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE); int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration); DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null, this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, startTimeOptimize, endTimeOptimize);
StringUtils.substringBeforeLast(startTimeString, BusinessConstant.INITIALIZATION_SECOND), endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT) //计算时间偏移,取时间间隔(分钟)
);
//计算时间偏移
DateTime startTimeOptimize = DateUtil.parse(startTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(startTimeOptimize, startTime); between = BaseUtils.getTimeDifferenceMinute(startTimeOptimize, startTime);
} }
//其它井口的第一次启动时间 //其它井口的第一次启动时间
...@@ -492,8 +291,7 @@ public class SpaceOptimizeBaseService { ...@@ -492,8 +291,7 @@ public class SpaceOptimizeBaseService {
int startIndex = -1; int startIndex = -1;
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.date(predictedPower.getCreateTime()).compareTo(startTimeOffset) >= 0) {
.compareTo(startTimeOffset) >= 0) {
//判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数 //判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数
if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) { if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔 //确定第二口井第一次开井时间为第一口井启动时间+启动间隔
...@@ -504,13 +302,11 @@ public class SpaceOptimizeBaseService { ...@@ -504,13 +302,11 @@ public class SpaceOptimizeBaseService {
} }
if (startIndex > -1) { if (startIndex > -1) {
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex); DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
DateTime startTimeOptimize = DateUtil.parse(start.getHourTime() + start.getMinTime(), BusinessConstant.TIME_FORMAT); DateTime startTimeOptimize = DateUtil.date(start.getCreateTime());
//计算未优化启动间隔 //计算未优化启动间隔
int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE); int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration); DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null, this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, startTimeOptimize, endTimeOptimize);
startTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT), BaseUtils.getEndTimeString(endTimeOptimize)
);
//取时间间隔(分钟) //取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime); between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime);
} else { } else {
...@@ -524,250 +320,151 @@ public class SpaceOptimizeBaseService { ...@@ -524,250 +320,151 @@ public class SpaceOptimizeBaseService {
continue; continue;
} }
//计算偏移 //计算偏移
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null, this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, offset,
offset.toString(BusinessConstant.MINUTES_FORMAT), DateUtil.date(duration.getCloseTime()).offset(DateField.MINUTE, between)
BaseUtils.getEndTimeString(DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
.offset(DateField.MINUTE, between))
); );
} }
} }
} }
//离网优化
if (CollUtil.isNotEmpty(offGridPeriodList)) {
if (!storageAvgMap.containsKey(detail.getLineId())) {
//没有储能设备,无法计算
return;
} }
//截取从第一次开井时间往后的时间段
/** List<DynamicQueryPlantPredictedPowerOutput> subAvgPowerList = CollUtil.sub(avgPowerList, firstIndex + 1, avgPowerList.size());
* 消峰平谷策略 if (CollUtil.isEmpty(subAvgPowerList)) {
* //没有时间段,无法计算
* @param context 上下文
* @param wellheadDTOList 井口dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param durationDTOList 持续时间dtolist
* @param wellheadViewList 井口视图列表
* @param durationMap 持续时间图
* @param detail 细节
* @param monthNum 月份
* @param midPeriodId 中期id
*/
public void peakEliminationAndValleyLevelingStrategy(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> wellheadViewList,
Map<String, List<SpaceInstitutionDurationEnt>> durationMap, SpaceInstitutionDetailEnt detail,
int monthNum, String periodId) {
//通过线路ID和月份获取市电峰谷策略明细配置
List<GetBasePriceStrategyDetailOutput> strategyDetailList = ServiceUtil.getStrategyDetailList(context,
GetBasePriceStrategyDetailInput.builder()
.lineId(detail.getLineId())
.strategyMonth(String.valueOf(monthNum))
.build()
);
if (CollUtil.isEmpty(strategyDetailList)) {
//没有配置,不优化
return; return;
} }
//获取第一段谷电阶段的开始时间为第一口井的开井时间 //查获取前一个月该时间点储能剩余电量,求平均数
Optional<GetBasePriceStrategyDetailOutput> low = strategyDetailList.stream() List<DynamicQueryStoragePredictedPowerOutput> averageEnergyStorageList = this.getAverageEnergyStorageListByParam(context, input);
.filter(s -> !StringUtils.isAnyBlank(s.getEndTime(), s.getStartTime()) && StringUtils.equals("LOW", s.getPeriodTypeKey())) if (CollUtil.isEmpty(averageEnergyStorageList)) {
.findFirst(); //没有储能发电量,无法计算
if (!low.isPresent()) {
//没有谷电,不优化
return; return;
} }
GetBasePriceStrategyDetailOutput strategyDetailOutput = low.get(); //取储能计算参数
//第一口井启动时间 List<DynamicQueryBasePowerLineStorageViewOutput> avgStorageViewList = storageAvgMap.get(detail.getLineId());
DateTime firstStartTime = DateUtil.parse(strategyDetailOutput.getStartTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT); DynamicQueryBasePowerLineStorageViewOutput avgStorageView = avgStorageViewList.get(0);
DateTime firstEndTime = DateUtil.parse(strategyDetailOutput.getEndTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT); //平均额定放电效率(%)
//判断是否第一口井 BigDecimal avgRatedDischargeEfficiency = avgStorageView.getRatedDischargeEfficiency();
boolean isFirstWellhead; //平均额定放电深度(%)
//时间差 BigDecimal avgRatedDischargeDepth = avgStorageView.getRatedDischargeDepth();
int between = 0; //平均额定放电功率(KW)
//启动间隔累积 BigDecimal avgRatedDischargePower = avgStorageView.getRatedDischargePower();
int startInterval = 0; //逐15分钟计算光伏出力-井场运行功率之和,获得光伏出力不足时间段,并计算储能可用时长
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) { Iterator<DynamicQueryStoragePredictedPowerOutput> iterator = averageEnergyStorageList.iterator();
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w); for (DynamicQueryPlantPredictedPowerOutput avg : subAvgPowerList) {
String wellheadId = wellhead.getWellheadId(); if (avg.getPower().compareTo(totalOperatingPower) >= 0) {
String recordId = this.createOptimizeWellhead(wellheadDTOList, periodId, wellheadId, wellhead.getWellNumber()); //电量不足,计算储能可用时长
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellheadId); avg.setBatteryLowFlag(false);
if (CollUtil.isEmpty(durationConfigList)) { String hourTime = avg.getHourTime();
//没有设置时间段,无法优化 String minTime = avg.getMinTime();
continue; while (iterator.hasNext()) {
DynamicQueryStoragePredictedPowerOutput storagePredicted = iterator.next();
if (StringUtils.equals(hourTime, storagePredicted.getHourTime()) && StringUtils.equals(minTime, storagePredicted.getMinTime())) {
//计算储能可供电时长:(储能剩余容量*放电深度*放电效率)/额定放电功率
avg.setPowerDuration(
storagePredicted.getPower()
.multiply(avgRatedDischargeDepth)
.multiply(avgRatedDischargeEfficiency)
.divide(avgRatedDischargePower)
.setScale(BusinessConstant.ZERO, RoundingMode.DOWN)
.intValueExact()
);
break;
} }
//保存原始记录 //删除计算过的时间段
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) { iterator.remove();
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
} }
if (w == 0) {
//第一个井口
isFirstWellhead = true;
} else { } else {
//计算启动间隔 avg.setBatteryLowFlag(true);
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) {
//计算优化后的时间差优化后的第一口井开井时间-优化前第一次开井时间
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
//第一次关井时间按照启动时长顺延
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
strategyDetailOutput.getStartTime(), endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
}//其它井口的第一次启动时间
else {
//其它井启动时间:第一口井启动时间+启动间隔
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
DateTime endTimeOffset = firstEndTime.offset(DateField.MINUTE, startInterval);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
startTimeOffset.toString(BusinessConstant.MINUTES_FORMAT), endTimeOffset.toString(BusinessConstant.MINUTES_FORMAT)
);
} }
} else { //拆分时间段
//计算偏移 for (SpaceOptimizeDurationDTO durationDTO : offGridPeriodList) {
DateTime offset = startTime.offset(DateField.MINUTE, between); Date openTime = durationDTO.getOpenTime();
if (offset.compareTo(BusinessConstant.DATE_FLAG) > 0) { Date closeTime = durationDTO.getCloseTime();
//如果时间超过当天,舍弃 if (closeTime.compareTo(BusinessConstant.DATE_FLAG) > 0) {
continue; closeTime = DateUtil.endOfDay(DateUtil.date());
} }
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null, //匹配时间
offset.toString(BusinessConstant.MINUTES_FORMAT), BaseUtils.getEndTimeString( for (int i = 0, size = subAvgPowerList.size(); i < size; i++) {
DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT) DynamicQueryPlantPredictedPowerOutput avg = subAvgPowerList.get(i);
.offset(DateField.MINUTE, between) DateTime createTime = DateUtil.date(avg.getCreateTime());
) //计算时间范围:大于等于开始时间,小于等于结束时间
if (openTime.compareTo(createTime) >= 0 && closeTime.compareTo(createTime) <= 0) {
String endString = createTime.offset(DateField.MINUTE, 15).toString(BusinessConstant.MINUTES_FORMAT);
String startString = createTime.toString(BusinessConstant.MINUTES_FORMAT);
//电量满足跳过
if (avg.getBatteryLowFlag()) {
//创建光伏
this.createOptimizeDuration(durationDTOList, periodId, durationDTO.getRecordId(), durationDTO.getWellheadId(), BusinessConstant.PHOTOVOLTAIC,
startString, endString
);
} else {
int powerDuration = avg.getPowerDuration();
String offset = createTime.offset(DateField.MINUTE, powerDuration).toString(BusinessConstant.MINUTES_FORMAT);
//储能发电时长
this.createOptimizeDuration(durationDTOList, periodId, durationDTO.getRecordId(), durationDTO.getWellheadId(), BusinessConstant.STORED_ENERGY,
startString, offset
);
//柴发发电时长
this.createOptimizeDuration(durationDTOList, periodId, durationDTO.getRecordId(), durationDTO.getWellheadId(), BusinessConstant.DIESEL_POWER,
offset, endString
); );
} }
} }
} }
} }
}
//保存不需要优化的井口
this.setUnOptimizeWellheadConfig(wellheadDTOList, unOptimizeDurationList, durationDTOList,
wellheadViewMap.get(false), durationMap, periodId);
}
/** /**
* 并网优化 * 创建间开优化信息
* *
* @param context 上下文 * @param periodDTOList 时期数据主义者
* @param wellheadDTOList 井口dtolist * @param detailId 详细信息id
* @param durationDTOList 持续时间dtolist * @param lineId 线路id
* @param unOptimizeDurationList 取消优化工期列表 * @param executionCycleForMonth 月执行周期
* @param spaceWellheadList 空间井口清单 * @param optimizeDeadline 优化截止日期
* @param detail 细节 * @return {@link String}
* @param monthNum 月份
* @param periodId 期间id
* @param plantPowerInput 电厂功率输入
*/ */
public void gridConnectedOptimization(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList, public String createOptimizePeriod(List<SpaceOptimizePeriodDTO> periodDTOList, String detailId,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList, String lineId, String executionCycleForMonth, Date optimizeDeadline) {
List<SpaceInstitutionWellheadView> spaceWellheadList, SpaceOptimizePeriodDTO periodDTO = new SpaceOptimizePeriodDTO();
SpaceInstitutionDetailEnt detail, int monthNum, String periodId, BaseUtils.setBaseModelDefaultForJob(periodDTO);
DynamicQueryPlantPredictedPowerInput plantPowerInput) { periodDTO.setInstitutionId(detailId);
//获取当前制度对应的光伏预测数据列表 periodDTO.setLineId(lineId);
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context, plantPowerInput); periodDTO.setExecutionCycle(executionCycleForMonth);
if (CollUtil.isEmpty(avgPowerList)) { periodDTO.setOptimizeState(BusinessConstant.ZERO);
return; periodDTO.setOptimizeDeadline(optimizeDeadline);
} periodDTOList.add(periodDTO);
//取光伏出力峰值 return periodDTO.getId();
BigDecimal powerMax = this.getPowerMax(avgPowerList);
//取当前制度下井口的总功率
BigDecimal wellheadTotalPower = this.getWellheadTotalPower(spaceWellheadList, detail.getId());
//根据类型过滤井口:大间开,连抽井不优化
Map<Boolean, List<SpaceInstitutionWellheadView>> wellheadViewMap = this.getWellheadViewList(spaceWellheadList, detail.getId());
List<SpaceInstitutionWellheadView> wellheadViewList = wellheadViewMap.get(true);
if (CollUtil.isEmpty(wellheadViewList)) {
return;
}
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(context, detail.getId());
if (CollUtil.isEmpty(durationMap)) {
//没有设置时间段,无法优化
return;
}
//光伏出力峰值大于等于井口总功率:绿电消纳优先策略
if (powerMax.compareTo(wellheadTotalPower) >= BusinessConstant.ZERO) {
//---------------------------------绿电消纳策略---------------------------------
this.greenElectricityConsumptionStrategy(wellheadDTOList, unOptimizeDurationList, durationDTOList,
wellheadViewList, avgPowerList, durationMap, detail, periodId);
} else {
//遍历井口,按发电功率大于等于光伏出力峰值条件分组
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = this.getWellheadViewMapByPower(wellheadViewList, powerMax);
List<SpaceInstitutionWellheadView> lowWellheadList = collect.get(false);
int size = spaceWellheadList.size();
int lowWellheadListSize = lowWellheadList.size();
//光伏出力峰值<任何一口井的运行功率:消峰平谷策略
if (size == lowWellheadListSize) {
//---------------------------------消峰平谷策略---------------------------------
this.peakEliminationAndValleyLevelingStrategy(context, wellheadDTOList, unOptimizeDurationList, durationDTOList, wellheadViewList,
durationMap, detail, monthNum, periodId);
}
//光伏出力峰值>=线路哪部分井口运行功率:满足的部分井口采用绿电消纳优先,不满足的井采用消峰平谷
else {
List<SpaceInstitutionWellheadView> highWellheadList = collect.get(true);
this.greenElectricityConsumptionStrategy(wellheadDTOList, unOptimizeDurationList, durationDTOList,
highWellheadList, avgPowerList, durationMap, detail, periodId);
this.peakEliminationAndValleyLevelingStrategy(context, wellheadDTOList, unOptimizeDurationList, durationDTOList,
lowWellheadList, durationMap, detail, monthNum, periodId);
}
} }
//保存不需要优化的井口 /*-----------------------------------private-----------------------------------*/
List<SpaceInstitutionWellheadView> unOptimizeWellheadList = wellheadViewMap.get(false);
if (CollUtil.isEmpty(unOptimizeWellheadList)) {
return;
}
for (SpaceInstitutionWellheadView unOptimizeWellhead : unOptimizeWellheadList) {
String wellheadId = unOptimizeWellhead.getWellheadId();
String recordId = this.createOptimizeWellhead(wellheadDTOList, periodId, wellheadId, unOptimizeWellhead.getWellNumber());
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellheadId);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
}
}
}
/** /**
* 离网优化 * 绿电消纳策略
* *
* @param context 上下文
* @param wellheadDTOList 井口dtolist * @param wellheadDTOList 井口dtolist
* @param durationDTOList 持续时间dtolist
* @param unOptimizeDurationList 取消优化工期列表 * @param unOptimizeDurationList 取消优化工期列表
* @param spaceWellheadList 空间井口清单 * @param durationDTOList 持续时间dtolist
* @param storageAvgMap 存储平均值映射 * @param wellheadViewList 井口视图列表
* @param avgPowerList 平均功率列表
* @param durationMap 持续时间图
* @param detail 细节 * @param detail 细节
* @param periodId 期间id * @param periodId 期间id
* @param input 输入
* @param plantPowerInput 电厂功率输入
*/ */
public void offGridOptimization(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> durationDTOList, private void greenElectricityConsumptionStrategy(List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceOptimizeDurationDTO> unOptimizeDurationList, List<SpaceInstitutionWellheadView> spaceWellheadList, List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> wellheadViewList,
Map<String, List<DynamicQueryBasePowerLineStorageViewOutput>> storageAvgMap, SpaceInstitutionDetailEnt detail, String periodId, List<DynamicQueryPlantPredictedPowerOutput> avgPowerList, Map<String, List<SpaceInstitutionDurationEnt>> durationMap,
DynamicQueryStoragePredictedPowerInput input, DynamicQueryPlantPredictedPowerInput plantPowerInput) { SpaceInstitutionDetailEnt detail, String periodId) {
//获取当前制度对应的光伏预测数据列表
List<DynamicQueryPlantPredictedPowerOutput> avgPowerList = this.getAveragePowerGenerationListByPlantIds(context, plantPowerInput);
if (CollUtil.isEmpty(avgPowerList)) {
return;
}
//根据类型过滤井口:大间开,连抽井不优化
Map<Boolean, List<SpaceInstitutionWellheadView>> wellheadViewMap = this.getWellheadViewList(spaceWellheadList, detail.getId());
List<SpaceInstitutionWellheadView> wellheadViewList = wellheadViewMap.get(true);
if (CollUtil.isEmpty(wellheadViewList)) {
return;
}
//获取井口间开时间段
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = this.getDurationMap(context, detail.getId());
if (CollUtil.isEmpty(durationMap)) {
//没有设置时间段,无法优化
return;
}
//时间差 //时间差
int between = 0; int between = 0;
//启动间隔累积 //启动间隔累积
...@@ -776,12 +473,8 @@ public class SpaceOptimizeBaseService { ...@@ -776,12 +473,8 @@ public class SpaceOptimizeBaseService {
boolean isFirstWellhead; boolean isFirstWellhead;
//第一口井启动时间 //第一口井启动时间
DateTime firstStartTime = null; DateTime firstStartTime = null;
//第一口井开井时间
int firstIndex = 0;
//井口累积运行总功率 //井口累积运行总功率
BigDecimal totalOperatingPower = BigDecimal.ZERO; BigDecimal totalOperatingPower = BigDecimal.ZERO;
//离网时间段
List<SpaceOptimizeDurationDTO> offGridPeriodList = new ArrayList<>(32);
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) { for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w); SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId(); String wellheadId = wellhead.getWellheadId();
...@@ -797,40 +490,46 @@ public class SpaceOptimizeBaseService { ...@@ -797,40 +490,46 @@ 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); totalOperatingPower = totalOperatingPower.add(serviceRating);
if (w == 0) { if (w == 0) {
//第一个井口 //第一个井口
isFirstWellhead = true; isFirstWellhead = true;
} else { } else {
//累加
startInterval = startInterval + detail.getStartInterval(); startInterval = startInterval + detail.getStartInterval();
isFirstWellhead = false; isFirstWellhead = false;
} }
for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) { for (int d = 0, durationSize = durationConfigList.size(); d < durationSize; d++) {
SpaceInstitutionDurationEnt duration = durationConfigList.get(d); SpaceInstitutionDurationEnt duration = durationConfigList.get(d);
DateTime startTime = DateUtil.date(duration.getOpenTime()); String openWellTime = duration.getOpenWellTime();
DateTime endTime = DateUtil.date(duration.getCloseTime()); 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 (d == 0) {
//第一口井的启动时间 //第一口井的启动时间
if (isFirstWellhead) { if (isFirstWellhead) {
firstStartTime = startTime; firstStartTime = startTime;
//计算开井时间 //计算开井时间
int startIndex = 0;
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 (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) { if (predictedPower.getPower().compareTo(serviceRating) >= BusinessConstant.ZERO) {
firstIndex = a; startIndex = a;
break; break;
} }
} }
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(firstIndex); DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
DateTime startTimeOptimize = DateUtil.date(start.getCreateTime()); String startTimeString = start.getHourTime() + start.getMinTime();
//计算第一次关井时间,按照间开时间段顺延 //计算第一次关井时间,按照间开时间段顺延
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE); int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration); DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, startTimeOptimize, endTimeOptimize); this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
//计算时间偏移,取时间间隔(分钟) StringUtils.substringBeforeLast(startTimeString, BusinessConstant.INITIALIZATION_SECOND), endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
//计算时间偏移
DateTime startTimeOptimize = DateUtil.parse(startTimeString, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(startTimeOptimize, startTime); between = BaseUtils.getTimeDifferenceMinute(startTimeOptimize, startTime);
} }
//其它井口的第一次启动时间 //其它井口的第一次启动时间
...@@ -839,7 +538,8 @@ public class SpaceOptimizeBaseService { ...@@ -839,7 +538,8 @@ public class SpaceOptimizeBaseService {
int startIndex = -1; int startIndex = -1;
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.date(predictedPower.getCreateTime()).compareTo(startTimeOffset) >= 0) { if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT)
.compareTo(startTimeOffset) >= 0) {
//判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数 //判断第一口井启动时间+启动间隔时日平均光伏出力-前两口井的运行功率是否为正数
if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) { if (predictedPower.getPower().compareTo(totalOperatingPower) >= 0) {
//确定第二口井第一次开井时间为第一口井启动时间+启动间隔 //确定第二口井第一次开井时间为第一口井启动时间+启动间隔
...@@ -850,11 +550,13 @@ public class SpaceOptimizeBaseService { ...@@ -850,11 +550,13 @@ public class SpaceOptimizeBaseService {
} }
if (startIndex > -1) { if (startIndex > -1) {
DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex); DynamicQueryPlantPredictedPowerOutput start = avgPowerList.get(startIndex);
DateTime startTimeOptimize = DateUtil.date(start.getCreateTime()); DateTime startTimeOptimize = DateUtil.parse(start.getHourTime() + start.getMinTime(), BusinessConstant.TIME_FORMAT);
//计算未优化启动间隔 //计算未优化启动间隔
int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE); int openDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration); DateTime endTimeOptimize = startTimeOptimize.offset(DateField.MINUTE, openDuration);
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, startTimeOptimize, endTimeOptimize); this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
startTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT), BaseUtils.getEndTimeString(endTimeOptimize)
);
//取时间间隔(分钟) //取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime); between = BaseUtils.getTimeDifferenceMinute(endTimeOptimize, endTime);
} else { } else {
...@@ -868,105 +570,426 @@ public class SpaceOptimizeBaseService { ...@@ -868,105 +570,426 @@ public class SpaceOptimizeBaseService {
continue; continue;
} }
//计算偏移 //计算偏移
this.createDurationOffGridPeriod(offGridPeriodList, wellheadId, offset, this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
DateUtil.date(duration.getCloseTime()).offset(DateField.MINUTE, between) 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)) {
if (!storageAvgMap.containsKey(detail.getLineId())) {
//没有储能设备,无法计算
return;
}
//截取从第一次开井时间往后的时间段
List<DynamicQueryPlantPredictedPowerOutput> subAvgPowerList = CollUtil.sub(avgPowerList, firstIndex + 1, avgPowerList.size());
if (CollUtil.isEmpty(subAvgPowerList)) {
//没有时间段,无法计算
return;
}
//查获取前一个月该时间点储能剩余电量,求平均数
List<DynamicQueryStoragePredictedPowerOutput> averageEnergyStorageList = this.getAverageEnergyStorageListByParam(context, input);
if (CollUtil.isEmpty(averageEnergyStorageList)) {
//没有储能发电量,无法计算
return;
} }
//取储能计算参数
List<DynamicQueryBasePowerLineStorageViewOutput> avgStorageViewList = storageAvgMap.get(detail.getLineId()); /**
DynamicQueryBasePowerLineStorageViewOutput avgStorageView = avgStorageViewList.get(0); * 消峰平谷策略
//平均额定放电效率(%) *
BigDecimal avgRatedDischargeEfficiency = avgStorageView.getRatedDischargeEfficiency(); * @param context 上下文
//平均额定放电深度(%) * @param wellheadDTOList 井口dtolist
BigDecimal avgRatedDischargeDepth = avgStorageView.getRatedDischargeDepth(); * @param unOptimizeDurationList 取消优化工期列表
//平均额定放电功率(KW) * @param durationDTOList 持续时间dtolist
BigDecimal avgRatedDischargePower = avgStorageView.getRatedDischargePower(); * @param wellheadViewList 井口视图列表
//逐15分钟计算光伏出力-井场运行功率之和,获得光伏出力不足时间段,并计算储能可用时长 * @param durationMap 持续时间图
Iterator<DynamicQueryStoragePredictedPowerOutput> iterator = averageEnergyStorageList.iterator(); * @param detail 细节
for (DynamicQueryPlantPredictedPowerOutput avg : subAvgPowerList) { * @param monthNum 月份
if (avg.getPower().compareTo(totalOperatingPower) >= 0) { * @param periodId id
//电量不足,计算储能可用时长 */
avg.setBatteryLowFlag(false); private void peakEliminationAndValleyLevelingStrategy(XContext context, List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
String hourTime = avg.getHourTime(); List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> wellheadViewList,
String minTime = avg.getMinTime(); Map<String, List<SpaceInstitutionDurationEnt>> durationMap, SpaceInstitutionDetailEnt detail,
while (iterator.hasNext()) { int monthNum, String periodId) {
DynamicQueryStoragePredictedPowerOutput storagePredicted = iterator.next(); //通过线路ID和月份获取市电峰谷策略明细配置
if (StringUtils.equals(hourTime, storagePredicted.getHourTime()) && StringUtils.equals(minTime, storagePredicted.getMinTime())) { List<GetBasePriceStrategyDetailOutput> strategyDetailList = ServiceUtil.getStrategyDetailList(context,
//计算储能可供电时长:(储能剩余容量*放电深度*放电效率)/额定放电功率 GetBasePriceStrategyDetailInput.builder()
avg.setPowerDuration( .lineId(detail.getLineId())
storagePredicted.getPower() .strategyMonth(String.valueOf(monthNum))
.multiply(avgRatedDischargeDepth) .build()
.multiply(avgRatedDischargeEfficiency)
.divide(avgRatedDischargePower)
.setScale(BusinessConstant.ZERO, RoundingMode.DOWN)
.intValueExact()
); );
break; if (CollUtil.isEmpty(strategyDetailList)) {
//没有配置,不优化
return;
} }
//删除计算过的时间段 //获取第一段谷电阶段的开始时间为第一口井的开井时间
iterator.remove(); Optional<GetBasePriceStrategyDetailOutput> low = strategyDetailList.stream()
.filter(s -> !StringUtils.isAnyBlank(s.getEndTime(), s.getStartTime()) && StringUtils.equals("LOW", s.getPeriodTypeKey()))
.findFirst();
if (!low.isPresent()) {
//没有谷电,不优化
return;
} }
GetBasePriceStrategyDetailOutput strategyDetailOutput = low.get();
//第一口井启动时间
DateTime firstStartTime = DateUtil.parse(strategyDetailOutput.getStartTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
DateTime firstEndTime = DateUtil.parse(strategyDetailOutput.getEndTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//判断是否第一口井
boolean isFirstWellhead;
//时间差
int between = 0;
//启动间隔累积
int startInterval = 0;
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());
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellheadId);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
//保存原始记录
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
}
if (w == 0) {
//第一个井口
isFirstWellhead = true;
} else { } else {
avg.setBatteryLowFlag(true); //计算启动间隔
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) {
//计算优化后的时间差优化后的第一口井开井时间-优化前第一次开井时间
int startDuration = (int) startTime.between(endTime, DateUnit.MINUTE);
//第一次关井时间按照启动时长顺延
DateTime endTimeOptimize = startTime.offset(DateField.MINUTE, startDuration);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
strategyDetailOutput.getStartTime(), endTimeOptimize.toString(BusinessConstant.MINUTES_FORMAT)
);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
}//其它井口的第一次启动时间
else {
//其它井启动时间:第一口井启动时间+启动间隔
DateTime startTimeOffset = firstStartTime.offset(DateField.MINUTE, startInterval);
DateTime endTimeOffset = firstEndTime.offset(DateField.MINUTE, startInterval);
//取时间间隔(分钟)
between = BaseUtils.getTimeDifferenceMinute(firstEndTime, endTime);
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
startTimeOffset.toString(BusinessConstant.MINUTES_FORMAT), endTimeOffset.toString(BusinessConstant.MINUTES_FORMAT)
);
} }
//拆分时间段 } else {
for (SpaceOptimizeDurationDTO durationDTO : offGridPeriodList) { //计算偏移
Date openTime = durationDTO.getOpenTime(); DateTime offset = startTime.offset(DateField.MINUTE, between);
Date closeTime = durationDTO.getCloseTime(); if (offset.compareTo(BusinessConstant.DATE_FLAG) > 0) {
if (closeTime.compareTo(BusinessConstant.DATE_FLAG) > 0) { //如果时间超过当天,舍弃
closeTime = DateUtil.endOfDay(DateUtil.date()); continue;
} }
//匹配时间 this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
for (int i = 0, size = subAvgPowerList.size(); i < size; i++) { offset.toString(BusinessConstant.MINUTES_FORMAT), BaseUtils.getEndTimeString(
DynamicQueryPlantPredictedPowerOutput avg = subAvgPowerList.get(i); DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT)
DateTime createTime = DateUtil.date(avg.getCreateTime()); .offset(DateField.MINUTE, between)
//计算时间范围:大于等于开始时间,小于等于结束时间 )
if (openTime.compareTo(createTime) >= 0 && closeTime.compareTo(createTime) <= 0) { );
String endString = createTime.offset(DateField.MINUTE, 15).toString(BusinessConstant.MINUTES_FORMAT); }
String startString = createTime.toString(BusinessConstant.MINUTES_FORMAT); }
//电量满足跳过 }
if (avg.getBatteryLowFlag()) { }
//创建光伏
this.createOptimizeDuration(durationDTOList, periodId, durationDTO.getRecordId(), durationDTO.getWellheadId(), BusinessConstant.PHOTOVOLTAIC, /**
startString, endString * 获得最大功率
*
* @param avgPowerList 平均功率列表
* @return {@link BigDecimal}
*/
private BigDecimal getPowerMax(List<DynamicQueryPlantPredictedPowerOutput> avgPowerList) {
return avgPowerList.stream()
.map(DynamicQueryPlantPredictedPowerOutput::getPower)
.max(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
}
/**
* 获取井口总功率
*
* @param spaceWellheadList 空间井口清单
* @param detailId 详细信息id
* @return {@link BigDecimal}
*/
private BigDecimal getWellheadTotalPower(List<SpaceInstitutionWellheadView> spaceWellheadList, String detailId) {
return spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()))
.map(SpaceInstitutionWellheadView::getServiceRating)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 获取当前制度关联的井口按照是否可优化分组
*
* @param spaceWellheadList 空间井口清单
* @param detailId 详细信息id
* @return {@link Map}<{@link Boolean}, {@link List}<{@link SpaceInstitutionWellheadView}>>
*/
private Map<Boolean, List<SpaceInstitutionWellheadView>> getWellheadViewList(List<SpaceInstitutionWellheadView> spaceWellheadList, String detailId) {
return spaceWellheadList.stream()
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq))
.collect(
Collectors.partitioningBy(w -> StringUtils.equals(detailId, w.getInstitutionId()) &&
StringUtils.equals("INTERVAL", w.getRunTypeKey()) &&
StringUtils.equals("0", w.getIntervalTypeKey())
)
); );
}
/**
* 获取井口间开时间段
*
* @param context 上下文
* @param detailId 详细信息id
* @return {@link Map}<{@link String}, {@link List}<{@link SpaceInstitutionDurationEnt}>>
*/
private Map<String, List<SpaceInstitutionDurationEnt>> getDurationMap(XContext context, String detailId) {
SpaceInstitutionDurationMapper durationMapper = context.getBean(SpaceInstitutionDurationMapper.class);
//通过间开ID和井口ID查所有井口时段配置
List<SpaceInstitutionDurationEnt> durationList = durationMapper.selectList(new QueryWrapper<SpaceInstitutionDurationEnt>()
.select("*",
"STR_TO_DATE( CONCAT( open_well_time, ':00' ), '%H:%i:%s' ) AS openTime",
"STR_TO_DATE( CONCAT( close_well_time, ':00' ), '%H:%i:%s' ) AS closeTime"
)
.lambda()
.eq(BaseModel::getIsDeleted, BusinessConstant.ONE)
.eq(SpaceInstitutionDurationEnt::getInstitutionId, detailId)
.orderByAsc(SpaceInstitutionDurationEnt::getOpenWellTime)
);
if (CollUtil.isEmpty(durationList)) {
//没有设置时间段,无法优化
return null;
}
return durationList.stream()
.collect(
Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId)
);
}
/**
* 按线路ID集合获取电站列表
*
* @param context 上下文
* @param lineIds 线路ID
* @return {@link List}<{@link DynamicQueryBasePowerLinePlantOutput}>
*/
private List<DynamicQueryBasePowerLinePlantOutput> getPowerLinePlantListByLineIds(XContext context, Set<String> lineIds) {
IBasePowerLineCloudService cloudService = context.getBean(IBasePowerLineCloudService.class);
XListResult<DynamicQueryBasePowerLinePlantOutput> result = cloudService.queryPowerLinePlantListByParam(context,
DynamicQueryBasePowerLinePlantInput.builder()
.lineIds(lineIds)
.build()
);
result.throwIfFail();
return result.getResult();
}
/**
* 条件查询线路关联储能设备参数平均值
*
* @param context 上下文
* @param lineIds 线路ID
* @return {@link Map}<{@link String}, {@link List}<{@link DynamicQueryBasePowerLineStorageViewOutput}>>
*/
private Map<String, List<DynamicQueryBasePowerLineStorageViewOutput>> getPowerLineStorageListByLineIds(XContext context, Set<String> lineIds) {
IBasePowerLineCloudService cloudService = context.getBean(IBasePowerLineCloudService.class);
XListResult<DynamicQueryBasePowerLineStorageViewOutput> result = cloudService.queryPowerLineStorageListByLineIds(context,
DynamicQueryBasePowerLineStorageInput.builder()
.lineIds(lineIds)
.build()
);
result.throwIfFail();
List<DynamicQueryBasePowerLineStorageViewOutput> list = result.getResult();
Map<String, List<DynamicQueryBasePowerLineStorageViewOutput>> collect;
if (CollUtil.isEmpty(list)) {
collect = new HashMap<>(0);
} else { } else {
int powerDuration = avg.getPowerDuration(); collect = list.stream()
String offset = createTime.offset(DateField.MINUTE, powerDuration).toString(BusinessConstant.MINUTES_FORMAT); .collect(Collectors.groupingBy(DynamicQueryBasePowerLineStorageViewOutput::getLineId));
//储能发电时长 }
this.createOptimizeDuration(durationDTOList, periodId, durationDTO.getRecordId(), durationDTO.getWellheadId(), BusinessConstant.STORED_ENERGY, return collect;
startString, offset }
/**
* 为间开井口列表设置发电功率
*
* @param context 上下文
* @param spaceWellheadList 空间井口清单
*/
private void setServiceRatingForSpaceWellheadList(XContext context, List<SpaceInstitutionWellheadView> spaceWellheadList) {
IBaseWellheadCloudService cloudService = context.getBean(IBaseWellheadCloudService.class);
XListResult<DynamicQueryBaseWellheadOutput> result = cloudService.queryBaseWellheadListByParam(context,
DynamicQueryBaseWellheadInput.builder()
.wellheadIds(spaceWellheadList.stream()
.map(SpaceInstitutionWellheadView::getWellheadId)
.collect(Collectors.toList())
)
.build());
result.throwIfFail();
List<DynamicQueryBaseWellheadOutput> wellheadOutputList = result.getResult();
if (CollUtil.isEmpty(wellheadOutputList)) {
return;
}
spaceWellheadList.forEach(s -> {
s.setServiceRating(
wellheadOutputList.stream()
.filter(w -> StringUtils.equals(s.getWellheadId(), w.getId()))
.findAny()
.map(DynamicQueryBaseWellheadOutput::getServiceRating)
.orElse(BigDecimal.ZERO)
); );
//柴发发电时长 });
this.createOptimizeDuration(durationDTOList, periodId, durationDTO.getRecordId(), durationDTO.getWellheadId(), BusinessConstant.DIESEL_POWER, }
offset, endString
/**
* 条件获取获取光伏预测各时段平均值列表
*
* @param context 上下文
* @param input 输入
* @return {@link List}<{@link DynamicQueryPlantPredictedPowerOutput}>
*/
private List<DynamicQueryPlantPredictedPowerOutput> getAveragePowerGenerationListByPlantIds(XContext context, DynamicQueryPlantPredictedPowerInput input) {
IPlantPredictedPowerCloudService cloudService = context.getBean(IPlantPredictedPowerCloudService.class);
XListResult<DynamicQueryPlantPredictedPowerOutput> result = cloudService.queryAveragePowerGenerationListByParam(context, input);
result.throwIfFail();
return result.getResult();
}
/**
* 条件查询时段储能电量平均值(模拟测试用)
* todo: 模拟测试用,后续替换
*
* @param context 上下文
* @param input 输入
* @return {@link List}<{@link DynamicQueryStoragePredictedPowerOutput}>
*/
private List<DynamicQueryStoragePredictedPowerOutput> getAverageEnergyStorageListByParam(XContext context, DynamicQueryStoragePredictedPowerInput input) {
IStoragePredictedPowerCloudService cloudService = context.getBean(IStoragePredictedPowerCloudService.class);
XListResult<DynamicQueryStoragePredictedPowerOutput> result = cloudService.queryAverageEnergyStorageListByParam(context, input);
result.throwIfFail();
return result.getResult();
}
/**
* 获取井口Map通过最大功率区分
*
* @param wellheadViewList 井口视图列表
* @param powerMax 最大功率
* @return {@link Map}<{@link Boolean}, {@link List}<{@link SpaceInstitutionWellheadView}>>
*/
private Map<Boolean, List<SpaceInstitutionWellheadView>> getWellheadViewMapByPower(List<SpaceInstitutionWellheadView> wellheadViewList, BigDecimal powerMax) {
return wellheadViewList.stream()
.collect(
Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO)
); );
} }
/**
* 设置不需要优化的井口配置
*
* @param wellheadDTOList 井口dtolist
* @param unOptimizeDurationList 取消优化工期列表
* @param durationDTOList 持续时间dtolist
* @param unOptimizeWellheadList 取消优化井口列表
* @param durationMap 持续时间图
* @param periodId 期间id
*/
private void setUnOptimizeWellheadConfig(List<SpaceOptimizeWellheadDTO> wellheadDTOList, List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
List<SpaceOptimizeDurationDTO> durationDTOList, List<SpaceInstitutionWellheadView> unOptimizeWellheadList,
Map<String, List<SpaceInstitutionDurationEnt>> durationMap, String periodId) {
//保存不需要优化的井口
if (CollUtil.isEmpty(unOptimizeWellheadList)) {
return;
}
for (SpaceInstitutionWellheadView unOptimizeWellhead : unOptimizeWellheadList) {
String wellheadId = unOptimizeWellhead.getWellheadId();
String recordId = this.createOptimizeWellhead(wellheadDTOList, periodId, wellheadId, unOptimizeWellhead.getWellNumber());
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellheadId);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
for (SpaceInstitutionDurationEnt durationEnt : durationConfigList) {
//保存原始记录
this.createUnOptimizeDuration(unOptimizeDurationList, durationEnt, periodId, recordId, wellheadId);
//存未优化结果
this.createOptimizeDuration(durationDTOList, periodId, recordId, wellheadId, null,
BusinessConstant.START_OF_DAY_TIME, BusinessConstant.END_OF_DAY_TIME
);
} }
} }
} }
/**
* 创建间开优化井口信息
*
* @param wellheadDTOList 井口dtolist
* @param periodId 期间id
* @param wellheadId 井口id
* @param wellNumber 井号
* @return {@link String}
*/
private String createOptimizeWellhead(List<SpaceOptimizeWellheadDTO> wellheadDTOList, String periodId,
String wellheadId, String wellNumber) {
SpaceOptimizeWellheadDTO wellheadDTO = new SpaceOptimizeWellheadDTO();
BaseUtils.setBaseModelDefaultForJob(wellheadDTO);
wellheadDTO.setPeriodId(periodId);
wellheadDTO.setWellheadId(wellheadId);
wellheadDTO.setWellNumber(wellNumber);
wellheadDTOList.add(wellheadDTO);
return wellheadDTO.getId();
}
/**
* 创建间开优化井口区间配置信息
*
* @param durationDTOList 持续时间dtolist
* @param periodId 期间id
* @param recordId 记录id
* @param wellheadId 井口id
* @param generationTypeKey 生成类型密钥
* @param openWellTime 开井时间
* @param endTimeString 结束时间字符串
*/
private void createOptimizeDuration(List<SpaceOptimizeDurationDTO> durationDTOList, String periodId,
String recordId, String wellheadId, String generationTypeKey,
String openWellTime, String endTimeString) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
BaseUtils.setBaseModelDefaultForJob(durationDTO);
durationDTO.setRecordId(recordId);
durationDTO.setPeriodId(periodId);
durationDTO.setWellheadId(wellheadId);
durationDTO.setGenerationTypeKey(generationTypeKey);
durationDTO.setIsOptimize(BusinessConstant.ZERO);
durationDTO.setOpenWellTime(openWellTime);
durationDTO.setCloseWellTime(endTimeString);
durationDTOList.add(durationDTO);
} }
/**
* 创建间开原始间开区间
*
* @param unOptimizeDurationList 取消优化工期列表
* @param durationEnt 持续时间ent
* @param periodId 期间id
* @param recordId 记录id
* @param wellheadId 井口id
*/
private void createUnOptimizeDuration(List<SpaceOptimizeDurationDTO> unOptimizeDurationList,
SpaceInstitutionDurationEnt durationEnt,
String periodId, String recordId, String wellheadId) {
SpaceOptimizeDurationDTO durationDTO = new SpaceOptimizeDurationDTO();
BaseUtils.setBaseModelDefaultForJob(durationDTO);
durationDTO.setRecordId(recordId);
durationDTO.setPeriodId(periodId);
durationDTO.setWellheadId(wellheadId);
durationDTO.setIsOptimize(BusinessConstant.ONE);
durationDTO.setOpenWellTime(durationEnt.getOpenWellTime());
durationDTO.setCloseWellTime(durationEnt.getCloseWellTime());
unOptimizeDurationList.add(durationDTO);
} }
/** /**
......
...@@ -144,6 +144,4 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService ...@@ -144,6 +144,4 @@ public class SpaceOptimizeLongCloudServiceImpl extends SpaceOptimizeBaseService
return XServiceResult.OK; return XServiceResult.OK;
}); });
} }
/*-----------------------------------private-----------------------------------*/
} }
\ No newline at end of file
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