|
|
|
@ -7,9 +7,11 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
import com.hnac.hzims.equipment.vo.EminfoAndEmParamVo; |
|
|
|
|
import com.hnac.hzims.hzimsweather.response.weather.Daily; |
|
|
|
|
import com.hnac.hzims.hzimsweather.response.weather.HeWeatherWeatherDailyResponse; |
|
|
|
|
import com.hnac.hzims.hzimsweather.response.weather.HeWeatherWeatherNowResponse; |
|
|
|
|
import com.hnac.hzims.operational.fill.entity.WindEntity; |
|
|
|
|
import com.hnac.hzims.operational.fill.service.WindService; |
|
|
|
|
import com.hnac.hzims.operational.main.constant.HomePageConstant; |
|
|
|
|
import com.hnac.hzims.operational.main.service.AreaService; |
|
|
|
|
import com.hnac.hzims.operational.main.service.IWeatherService; |
|
|
|
|
import com.hnac.hzims.operational.main.service.WindHomeService; |
|
|
|
|
import com.hnac.hzims.operational.main.vo.*; |
|
|
|
@ -18,10 +20,14 @@ import com.hnac.hzims.operational.station.service.IStationService;
|
|
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
import org.apache.commons.collections4.MapUtils; |
|
|
|
|
import org.springblade.core.tool.api.R; |
|
|
|
|
import org.springblade.core.tool.utils.CollectionUtil; |
|
|
|
|
import org.springblade.core.tool.utils.DateUtil; |
|
|
|
|
import org.springblade.core.tool.utils.ObjectUtil; |
|
|
|
|
import org.springblade.server.domain.Sys; |
|
|
|
|
import org.springblade.core.tool.utils.StringUtil; |
|
|
|
|
import org.springblade.system.entity.Dept; |
|
|
|
|
import org.springblade.system.entity.Region; |
|
|
|
|
import org.springblade.system.feign.ISysClient; |
|
|
|
|
import org.springframework.data.redis.core.RedisTemplate; |
|
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
|
@ -43,12 +49,16 @@ public class WindHomeServiceImpl implements WindHomeService {
|
|
|
|
|
|
|
|
|
|
private final WindService windService; |
|
|
|
|
|
|
|
|
|
private final AreaService areaService; |
|
|
|
|
|
|
|
|
|
private final IWeatherService weatherService; |
|
|
|
|
|
|
|
|
|
private final IStationService stationService; |
|
|
|
|
|
|
|
|
|
private final RedisTemplate redisTemplate; |
|
|
|
|
|
|
|
|
|
private final ISysClient sysClient; |
|
|
|
|
|
|
|
|
|
public final static String device_cache_final = "hzims:equipment:emInfo:deviceCode.emInfoList"; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -63,32 +73,198 @@ public class WindHomeServiceImpl implements WindHomeService {
|
|
|
|
|
eq(StationEntity::getServeType, HomePageConstant.HYDROPOWER_SERVETYPE); |
|
|
|
|
eq(StationEntity::getType,HomePageConstant.WIND_POWER); |
|
|
|
|
}}); |
|
|
|
|
if(CollectionUtil.isNotEmpty(stations)){ |
|
|
|
|
if(CollectionUtil.isEmpty(stations)){ |
|
|
|
|
return new WindScoreVo(); |
|
|
|
|
} |
|
|
|
|
// 查询站点年填报数据
|
|
|
|
|
List<WindEntity> years = windService.list(new LambdaQueryWrapper<WindEntity>() {{ |
|
|
|
|
like(WindEntity::getFillDate, DateUtil.format(new Date(),"yyyy")); |
|
|
|
|
in(WindEntity::getStationCode,stations.stream().map(StationEntity::getCode).collect(Collectors.toList())); |
|
|
|
|
}}); |
|
|
|
|
// 查询站点月填报数据
|
|
|
|
|
List<WindEntity> mons = windService.list(new LambdaQueryWrapper<WindEntity>() {{ |
|
|
|
|
like(WindEntity::getFillDate, DateUtil.format(new Date(),"yyyy-MM")); |
|
|
|
|
in(WindEntity::getStationCode,stations.stream().map(StationEntity::getCode).collect(Collectors.toList())); |
|
|
|
|
}}); |
|
|
|
|
// 查询站点日填报数据
|
|
|
|
|
List<WindEntity> days = windService.list(new LambdaQueryWrapper<WindEntity>() {{ |
|
|
|
|
like(WindEntity::getFillDate, DateUtil.format(new Date(), DateUtil.format(new Date(),DateUtil.PATTERN_DATE))); |
|
|
|
|
// 查询站点填报数据
|
|
|
|
|
List<WindEntity> winds = windService.list(new LambdaQueryWrapper<WindEntity>() {{ |
|
|
|
|
in(WindEntity::getStationCode,stations.stream().map(StationEntity::getCode).collect(Collectors.toList())); |
|
|
|
|
}}); |
|
|
|
|
WindScoreVo score = new WindScoreVo(); |
|
|
|
|
// 站点数量
|
|
|
|
|
score.setStationCount(stations.size()); |
|
|
|
|
this.year(years,score); |
|
|
|
|
this.mon(mons,score); |
|
|
|
|
this.days(days,score); |
|
|
|
|
if(CollectionUtil.isEmpty(winds)){ |
|
|
|
|
return score; |
|
|
|
|
} |
|
|
|
|
// 装机容量
|
|
|
|
|
List<EminfoAndEmParamVo> devices = JSONObject.parseObject(redisTemplate.opsForValue().get(device_cache_final).toString(), new TypeReference<List<EminfoAndEmParamVo>>() {}); |
|
|
|
|
if(CollectionUtil.isNotEmpty(devices)){ |
|
|
|
|
score.setInstalledCapacity(devices.stream().filter(o->stations.stream().map(StationEntity::getRefDept).collect(Collectors.toList()).contains(o.getCreateDept())).mapToDouble(EminfoAndEmParamVo::getInstalledCapacity).sum()); |
|
|
|
|
} |
|
|
|
|
// 年发电量
|
|
|
|
|
score.setGenerateYear(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),"yyyy"))).mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
// 年计划发电量
|
|
|
|
|
score.setPlanYear(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),"yyyy"))).mapToDouble(WindEntity::getPlan).sum()); |
|
|
|
|
// 年发电完成率
|
|
|
|
|
if(Math.abs(score.getGenerateYear()) > 0 && Math.abs(score.getPlanYear()) > 0){ |
|
|
|
|
score.setCompleteRate(BigDecimal.valueOf(score.getGenerateYear() / score.getPlanYear() * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); |
|
|
|
|
} |
|
|
|
|
// 月发电量
|
|
|
|
|
score.setGenerateMon(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),"yyyy-MM"))).mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
// 月平均风速
|
|
|
|
|
score.setSpeedRate(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),"yyyy-MM"))).mapToDouble(WindEntity::getSpeed).average().getAsDouble()); |
|
|
|
|
// 月短期准确率
|
|
|
|
|
score.setAccuracy(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),"yyyy-MM"))).mapToDouble(WindEntity::getAccuracy).average().getAsDouble()); |
|
|
|
|
// 月超短期准确率
|
|
|
|
|
score.setUltraShortAccuracyRate(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),"yyyy-MM"))).mapToDouble(WindEntity::getUltraShortAccuracy).average().getAsDouble()); |
|
|
|
|
// 日发电量
|
|
|
|
|
score.setGenerateDay(winds.stream().filter(o->o.getFillDate().contains(DateUtil.format(new Date(),DateUtil.PATTERN_DATE))).mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
// 近年发电量
|
|
|
|
|
score.setPowerYearVoList(this.threeGenerateYear(winds)); |
|
|
|
|
// 计划发电完成率
|
|
|
|
|
score.setPowerMonthVoList(this.currentGenerateCurve(winds)); |
|
|
|
|
return score; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 近3年发电量 |
|
|
|
|
* @param winds |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private List<PowerYearVo> threeGenerateYear(List<WindEntity> winds) { |
|
|
|
|
List<String> mons = this.mons(2,12,false); |
|
|
|
|
// 月份发电量赋值
|
|
|
|
|
List<PowerMonthVo> list = mons.stream().map(mon->{ |
|
|
|
|
PowerMonthVo power = new PowerMonthVo(); |
|
|
|
|
LocalDate localDate = LocalDate.parse(DateUtil.format(new Date(), mon), DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE)); |
|
|
|
|
power.setYear(localDate.getYear()); |
|
|
|
|
power.setStrMonth(localDate.getMonthValue() > 9 ? String.valueOf(localDate.getMonthValue()) : "0" + localDate.getMonthValue()); |
|
|
|
|
power.setPower((float) winds.stream().filter(o->o.getFillDate().contains(localDate.getYear() + "-" + power.getStrMonth())).mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
return power; |
|
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
if(CollectionUtil.isEmpty(list)){ |
|
|
|
|
return new ArrayList<>(); |
|
|
|
|
} |
|
|
|
|
// 转换年份分组
|
|
|
|
|
return list.stream().collect(Collectors.groupingBy(PowerMonthVo::getYear)).entrySet().stream().map(entry->{ |
|
|
|
|
PowerYearVo year = new PowerYearVo(); |
|
|
|
|
year.setYear(entry.getKey()); |
|
|
|
|
year.setPowerMonthVoList(entry.getValue()); |
|
|
|
|
return year; |
|
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 年发电量趋势 |
|
|
|
|
* @param winds |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private List<PowerMonthVo> currentGenerateCurve(List<WindEntity> winds) { |
|
|
|
|
List<String> mons = this.mons(0,12,false); |
|
|
|
|
return mons.stream().map(mon->{ |
|
|
|
|
PowerMonthVo power = new PowerMonthVo(); |
|
|
|
|
LocalDate localDate = LocalDate.parse(DateUtil.format(new Date(), mon), DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE)); |
|
|
|
|
power.setYear(localDate.getYear()); |
|
|
|
|
power.setStrMonth(localDate.getMonthValue() > 9 ? String.valueOf(localDate.getMonthValue()) : "0" + localDate.getMonthValue()); |
|
|
|
|
power.setPlanPower((float) winds.stream().filter(o->o.getFillDate().contains(localDate.getYear() + "-" + power.getStrMonth())).mapToDouble(WindEntity::getPlan).sum()); |
|
|
|
|
power.setPower((float) winds.stream().filter(o->o.getFillDate().contains(localDate.getYear() + "-" + power.getStrMonth())).mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
return power; |
|
|
|
|
}).collect(Collectors.toList()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 风电站集团/区域占比 |
|
|
|
|
* @param deptId |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
@Override |
|
|
|
|
public List<WindSubordinateVo> subordinate(Long deptId) { |
|
|
|
|
Map<Dept, List<StationEntity>> areas = areaService.areaOrStaion(deptId, Collections.singletonList(HomePageConstant.WIND_POWER)); |
|
|
|
|
if (MapUtils.isEmpty(areas)) { |
|
|
|
|
return new ArrayList<>(); |
|
|
|
|
} |
|
|
|
|
// 风电站填报数据查询
|
|
|
|
|
List<String> codes = new ArrayList<>(); |
|
|
|
|
areas.forEach((key,value)-> codes.addAll(value.stream().map(StationEntity::getCode).collect(Collectors.toList()))); |
|
|
|
|
List<WindEntity> winds = windService.list(new LambdaQueryWrapper<WindEntity>() {{ |
|
|
|
|
in(WindEntity::getStationCode,codes) |
|
|
|
|
.like(WindEntity::getFillDate,DateUtil.format(new Date(),"yyyy")); |
|
|
|
|
}}); |
|
|
|
|
// 获取站点编码集合
|
|
|
|
|
List<String> stations = areas.values().stream().map(values -> values.get(0).getCode()).collect(Collectors.toList()); |
|
|
|
|
// 获取站点实时天气
|
|
|
|
|
Map<String, HeWeatherWeatherNowResponse> nowWeather = this.weatherService.getNowWeather(stations); |
|
|
|
|
// 获取站点7日天气
|
|
|
|
|
Map<String, HeWeatherWeatherDailyResponse> weekWeather = this.weatherService.getWeekWeather(stations); |
|
|
|
|
return areas.entrySet().stream().map(entry -> { |
|
|
|
|
WindSubordinateVo subordinate = new WindSubordinateVo(); |
|
|
|
|
// 获取第一个站点经纬度、行政编码信息
|
|
|
|
|
StationEntity station = entry.getValue().get(0); |
|
|
|
|
subordinate.setLttd(station.getLttd()); |
|
|
|
|
subordinate.setLgtd(station.getLgtd()); |
|
|
|
|
// 省市编码
|
|
|
|
|
String areaCode = station.getAreaCode(); |
|
|
|
|
subordinate.setAreaCode(areaCode); |
|
|
|
|
if (!StringUtil.isEmpty(areaCode)) { |
|
|
|
|
String[] arrCode = areaCode.split(","); |
|
|
|
|
R<Region> R = sysClient.getRegion(arrCode[1]); |
|
|
|
|
if (R.isSuccess() && ObjectUtil.isNotEmpty(R.getData())) { |
|
|
|
|
subordinate.setAreaName(R.getData().getName()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 机构Id
|
|
|
|
|
subordinate.setDepartId(entry.getKey().getId()); |
|
|
|
|
// 机构名称
|
|
|
|
|
subordinate.setDepartName(entry.getKey().getDeptName()); |
|
|
|
|
// 天气
|
|
|
|
|
this.getAreaWearther(subordinate, nowWeather, weekWeather, entry.getValue().get(0).getCode()); |
|
|
|
|
if(CollectionUtil.isNotEmpty(winds)){ |
|
|
|
|
List<WindEntity> piece = winds.stream().filter(o->entry.getValue().stream().map(StationEntity::getCode).collect(Collectors.toList()).contains(o.getStationCode())).collect(Collectors.toList()); |
|
|
|
|
if(CollectionUtil.isEmpty(piece)){ |
|
|
|
|
return subordinate; |
|
|
|
|
} |
|
|
|
|
// 发电量
|
|
|
|
|
subordinate.setGeneration(piece.stream().mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
// 集团发电占比
|
|
|
|
|
if(Math.abs(subordinate.getGeneration()) > 0 && Math.abs(winds.stream().mapToDouble(WindEntity::getPower).sum()) > 0){ |
|
|
|
|
subordinate.setGenerationRate(BigDecimal.valueOf(subordinate.getGeneration() / winds.stream().mapToDouble(WindEntity::getPower).sum() * 100).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()); |
|
|
|
|
} |
|
|
|
|
// 发电完成率
|
|
|
|
|
double plan = piece.stream().mapToDouble(WindEntity::getPlan).sum(); |
|
|
|
|
if(Math.abs(subordinate.getGeneration()) > 0 && Math.abs(plan) > 0){ |
|
|
|
|
subordinate.setGenerationComplete(BigDecimal.valueOf(subordinate.getGeneration() / plan * 100).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()); |
|
|
|
|
} |
|
|
|
|
// 风机利用率 : (总时间 - 故障时间) / 总时间
|
|
|
|
|
double fault = piece.stream().mapToDouble(WindEntity::getFaultHours).sum(); |
|
|
|
|
if(Math.abs(fault) > 0 ){ |
|
|
|
|
subordinate.setFanUse(BigDecimal.valueOf(fault / (30 * 24) * 100).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()); |
|
|
|
|
} |
|
|
|
|
// 厂用电率 : (发电量-上网电量+下网电量)/发电量
|
|
|
|
|
double surf = piece.stream().mapToDouble(WindEntity::getSurfPower).sum(); |
|
|
|
|
double below = piece.stream().mapToDouble(WindEntity::getBelowPower).sum(); |
|
|
|
|
if(Math.abs(subordinate.getGeneration()) > 0 && Math.abs(surf + below) > 0){ |
|
|
|
|
subordinate.setFactoryUse(BigDecimal.valueOf(subordinate.getGeneration() - surf + below / subordinate.getGeneration() * 100).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return subordinate; |
|
|
|
|
}).filter(o-> Math.abs(o.getGeneration()) > 0 || Math.abs(o.getGenerationRate()) > 0 || Math.abs(o.getGenerationComplete()) > 0 |
|
|
|
|
|| Math.abs(o.getFactoryUse()) > 0 || Math.abs(o.getFanUse()) > 0 ).sorted(Comparator.comparing(WindSubordinateVo::getGeneration).reversed()).collect(Collectors.toList()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 区域天气 |
|
|
|
|
* @param scale |
|
|
|
|
* @param nowWeather |
|
|
|
|
* @param weekWeather |
|
|
|
|
* @param code |
|
|
|
|
*/ |
|
|
|
|
private void getAreaWearther(WindSubordinateVo scale,Map<String, HeWeatherWeatherNowResponse> nowWeather, Map<String, HeWeatherWeatherDailyResponse> weekWeather, String code) { |
|
|
|
|
// 实时天气
|
|
|
|
|
if(MapUtils.isNotEmpty(nowWeather) && nowWeather.containsKey(code)){ |
|
|
|
|
HeWeatherWeatherNowResponse nowData = nowWeather.get(code); |
|
|
|
|
if(ObjectUtil.isNotEmpty(nowData.getNow())){ |
|
|
|
|
scale.setTemp(nowData.getNow().getTemp()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 站点七日内天气
|
|
|
|
|
if(MapUtils.isNotEmpty(weekWeather) && weekWeather.containsKey(code)){ |
|
|
|
|
HeWeatherWeatherDailyResponse weekData = weekWeather.get(code); |
|
|
|
|
List<Daily> dailyList = weekData.getDaily(); |
|
|
|
|
if (CollectionUtil.isNotEmpty(dailyList)) { |
|
|
|
|
scale.setWeather(dailyList); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 站点指标数据 |
|
|
|
@ -109,7 +285,10 @@ public class WindHomeServiceImpl implements WindHomeService {
|
|
|
|
|
// 机构名称
|
|
|
|
|
wind.setDepartName(station.getName()); |
|
|
|
|
// 站点行政区域编码
|
|
|
|
|
wind.setAreaCode(station.getAreaCode()); |
|
|
|
|
if(!StringUtil.isEmpty(station.getAreaCode())){ |
|
|
|
|
String[] code = station.getAreaCode().split(","); |
|
|
|
|
wind.setAreaCode(code[code.length - 1]); |
|
|
|
|
} |
|
|
|
|
// 站点七天天气
|
|
|
|
|
Map<String, HeWeatherWeatherDailyResponse> weekWeather = weatherService.getWeekWeather(Collections.singletonList(station.getCode())); |
|
|
|
|
wind.setWeather(this.getDailyList(weekWeather,station.getCode())); |
|
|
|
@ -243,51 +422,6 @@ public class WindHomeServiceImpl implements WindHomeService {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 风电数据 - 年 |
|
|
|
|
* @param years |
|
|
|
|
* @param score |
|
|
|
|
*/ |
|
|
|
|
private void year(List<WindEntity> years, WindScoreVo score) { |
|
|
|
|
if(CollectionUtil.isNotEmpty(years)){ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// 年发电量
|
|
|
|
|
score.setGenerateYear(years.stream().mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
// 年计划发电量
|
|
|
|
|
score.setPlanYear(years.stream().mapToDouble(WindEntity::getPlan).sum()); |
|
|
|
|
// 年发电完成率
|
|
|
|
|
if(Math.abs(score.getGenerateYear()) > 0 && Math.abs(score.getPlanYear()) > 0){ |
|
|
|
|
score.setSpeedRate(BigDecimal.valueOf(score.getGenerateYear() / score.getPlanYear() * 100).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 风电数据 - 月 |
|
|
|
|
* @param mons |
|
|
|
|
* @param score |
|
|
|
|
*/ |
|
|
|
|
private void mon(List<WindEntity> mons, WindScoreVo score) { |
|
|
|
|
// 月发电量
|
|
|
|
|
score.setGenerateMon(mons.stream().mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
// 月平均风速
|
|
|
|
|
score.setSpeedRate(mons.stream().mapToDouble(WindEntity::getSpeed).average().getAsDouble()); |
|
|
|
|
// 月短期准确率
|
|
|
|
|
score.setAccuracy(mons.stream().mapToDouble(WindEntity::getAccuracy).average().getAsDouble()); |
|
|
|
|
// 月超短期准确率
|
|
|
|
|
score.setUltraShortAccuracyRate(mons.stream().mapToDouble(WindEntity::getUltraShortAccuracy).average().getAsDouble()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 风电数据 - 日 |
|
|
|
|
* @param days |
|
|
|
|
* @param score |
|
|
|
|
*/ |
|
|
|
|
private void days(List<WindEntity> days, WindScoreVo score) { |
|
|
|
|
// 日发电量
|
|
|
|
|
score.setGenerateDay(days.stream().mapToDouble(WindEntity::getPower).sum()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取近年月份集合 |
|
|
|
|
* @param year |
|
|
|
|
* @return |
|
|
|
|