Commit c314899a authored by ZWT's avatar ZWT

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

1.开发间开优化长期间开优化定时任务,了解长期并网型流程算法;
2.定时任务模块新增CRON常量类,定义常用表达式;
3.基础信息管理--井口配置Cloud模块,添加通过井口ID集合获取井口列表接口,完成接口冒烟测试;
4.基础信息管理--输电线路配置Cloud模块,添加通过线路ID集合获取线路配置光伏电站列表接口,完成接口冒烟测试;
5.光伏预测--光伏预测Cloud模块,添加条件查询获取光伏预测时间段平均值列表接口,完成接口冒烟测试;
6.修改prediction模块pom引用,添加接口;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent 5e46bc85
......@@ -28,6 +28,21 @@ public class BusinessConstant {
*/
public static final String PARENT_OU_ID = "00000000-0000-0000-0000-000000000000";
/**
* 时间格式
*/
public static final String TIME_FORMAT = "HH:mm:ss";
/**
* 分钟格式
*/
public static final String MINUTES_FORMAT = "HH:mm";
/**
* 初始化秒
*/
public static final String INITIALIZATION_SECOND = ":00";
/*------------------------------字典------------------------------*/
/**
......
......@@ -2,7 +2,10 @@ package pps.core.space.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import pps.core.common.entity.BaseModel;
import xstartup.annotation.XText;
......@@ -15,6 +18,9 @@ import java.io.Serializable;
* @date 2023/09/05
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("space_optimize_long_duration")
public class SpaceOptimizeLongDurationEnt extends BaseModel implements Serializable {
......
package pps.core.space.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
......@@ -18,9 +20,12 @@ import pps.cloud.space.service.ISpaceOptimizeLongCloudService;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.entity.BaseModel;
import pps.core.space.entity.SpaceInstitutionDetailEnt;
import pps.core.space.entity.SpaceInstitutionDurationEnt;
import pps.core.space.entity.SpaceInstitutionWellheadView;
import pps.core.space.entity.SpaceOptimizeLongDurationEnt;
import pps.core.space.enums.BusinessError;
import pps.core.space.mapper.SpaceInstitutionDetailMapper;
import pps.core.space.mapper.SpaceInstitutionDurationMapper;
import pps.core.space.mapper.SpaceInstitutionWellheadViewMapper;
import xstartup.annotation.XService;
import xstartup.base.XContext;
......@@ -28,10 +33,7 @@ import xstartup.data.XListResult;
import xstartup.data.XServiceResult;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -92,8 +94,11 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
} else {
month = String.valueOf(monthNum);
}
SpaceInstitutionDurationMapper durationMapper = context.getBean(SpaceInstitutionDurationMapper.class);
DateTime dateFlag = DateUtil.parse("1970-01-02 00:00:00", "yyyy-mm-dd HH:mm:ss");
//优化
for (SpaceInstitutionDetailEnt detail : detailEntList) {
String detailId = detail.getId();
switch (detail.getGridTypeKey()) {
//并网型优化
case "1":
......@@ -117,29 +122,119 @@ public class SpaceOptimizeLongCloudServiceImpl implements ISpaceOptimizeLongClou
.orElse(BigDecimal.ZERO);
//取当前制度下井口的总功率
BigDecimal wellheadTotalPower = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detail.getId(), w.getInstitutionId()))
.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<String> wellheadIds = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detail.getId(), w.getInstitutionId()) &&
List<SpaceInstitutionWellheadView> wellheadViewList = spaceWellheadList.stream()
.filter(w -> StringUtils.equals(detailId, w.getInstitutionId()) &&
StringUtils.equals("INTERVAL", w.getRunTypeKey()) &&
StringUtils.equals("0", w.getIntervalTypeKey()))
.map(SpaceInstitutionWellheadView::getWellheadId)
.sorted(Comparator.comparing(SpaceInstitutionWellheadView::getStartSeq))
.collect(Collectors.toList());
if (CollUtil.isEmpty(wellheadIds)) {
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)) {
//没有设置时间段,无法优化
continue;
}
Map<String, List<SpaceInstitutionDurationEnt>> durationMap = durationList.stream()
.collect(Collectors.groupingBy(SpaceInstitutionDurationEnt::getWellheadId));
int between = 0;
for (int w = 0, wellheadSize = wellheadViewList.size(); w < wellheadSize; w++) {
SpaceInstitutionWellheadView wellhead = wellheadViewList.get(w);
String wellheadId = wellhead.getWellheadId();
//取当前井口最大发电量
BigDecimal serviceRating = wellhead.getServiceRating();
List<SpaceInstitutionDurationEnt> durationConfigList = durationMap.get(wellhead);
if (CollUtil.isEmpty(durationConfigList)) {
//没有设置时间段,无法优化
continue;
}
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);
//第一次启动
if (d == 0) {
//累计发电量
BigDecimal totalPower = BigDecimal.ZERO;
//计算开井时间
int endIndex = 0;
DynamicQueryPlantPredictedPowerOutput predictedPower;
for (int a = 0, avgPowerSize = avgPowerList.size(); a < avgPowerSize; a++) {
predictedPower = avgPowerList.get(a);
if (DateUtil.parse(predictedPower.getHourTime() + predictedPower.getMinTime(), BusinessConstant.TIME_FORMAT).compareTo(startTime) < 0) {
continue;
}
totalPower.add(predictedPower.getPower());
//当日时间段平均光伏出力总和>第一口井运行负荷时,该时间为第一口井启动时间
if (totalPower.compareTo(serviceRating) >= BusinessConstant.ZERO) {
endIndex = a;
break;
}
}
DynamicQueryPlantPredictedPowerOutput end = avgPowerList.get(endIndex);
String endTimeString = end.getHourTime() + end.getMinTime();
SpaceOptimizeLongDurationEnt.builder()
.wellheadId(wellheadId)
.isOptimize(BusinessConstant.ZERO)
.openWellTime(openWellTime)
.closeWellTime(StringUtils.substringBeforeLast(endTimeString, ":00"))
.build();
//计算
DateTime endTimeOptimize = DateUtil.parse(endTimeString, BusinessConstant.TIME_FORMAT);
DateTime endTime = DateUtil.parse(duration.getCloseWellTime() + BusinessConstant.INITIALIZATION_SECOND, BusinessConstant.TIME_FORMAT);
//取时间间隔(分钟)
between = (int) endTimeOptimize.between(endTime, DateUnit.MINUTE);
if (endTimeOptimize.compareTo(endTime) < 0) {
between = ~between + 1;
}
} 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 = "23:30";
} else {
closeWellTime = endDate.toString(BusinessConstant.MINUTES_FORMAT);
}
//计算偏移
SpaceOptimizeLongDurationEnt.builder()
.wellheadId(wellheadId)
.isOptimize(BusinessConstant.ZERO)
.openWellTime(
offset.toString(BusinessConstant.MINUTES_FORMAT)
)
.closeWellTime(closeWellTime)
.build();
}
}
}
} else {
//遍历井口,按发电功率大于等于光伏出力峰值条件分组
Map<Boolean, List<SpaceInstitutionWellheadView>> collect = spaceWellheadList.stream()
.filter(w ->
StringUtils.equals(detail.getId(), w.getInstitutionId())
StringUtils.equals(detailId, w.getInstitutionId())
)
.collect(Collectors.partitioningBy(w -> powerMax.compareTo(w.getServiceRating()) >= BusinessConstant.ZERO));
......
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