|
@@ -0,0 +1,357 @@
|
|
|
+package com.gyee.power.fitting.service.custom;
|
|
|
+
|
|
|
+import com.gyee.power.fitting.common.alg.WindDirectionALG;
|
|
|
+import com.gyee.power.fitting.common.constants.Constants;
|
|
|
+import com.gyee.power.fitting.common.spring.InitialRunner;
|
|
|
+import com.gyee.power.fitting.common.util.DateUtil;
|
|
|
+import com.gyee.power.fitting.common.util.FileUtil;
|
|
|
+import com.gyee.power.fitting.model.Poweranalysisreport;
|
|
|
+import com.gyee.power.fitting.model.Powerfittinganalysis;
|
|
|
+import com.gyee.power.fitting.model.Powerwindinfo;
|
|
|
+import com.gyee.power.fitting.model.custom.PowerFittingData;
|
|
|
+import com.gyee.power.fitting.model.custom.PowerPointData;
|
|
|
+import com.gyee.power.fitting.service.PoweranalysisreportService;
|
|
|
+import com.gyee.power.fitting.service.PowerfittinganalysisService;
|
|
|
+import com.gyee.power.fitting.service.PowerwindinfoService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import lombok.val;
|
|
|
+import lombok.var;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class ReportService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PowerfittinganalysisService powerService;
|
|
|
+ @Autowired
|
|
|
+ private PowerwindinfoService windinfoService;
|
|
|
+ @Autowired
|
|
|
+ private PoweranalysisreportService reportService;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 曲线偏差率分析
|
|
|
+ */
|
|
|
+ public void calCurve(Date st, Date et){
|
|
|
+ log.info("=====曲线偏差率分析");
|
|
|
+ List<Poweranalysisreport> result = new ArrayList<>();
|
|
|
+ var list = powerService.selectByTime(Constants.DATA_FITTING, st, et);
|
|
|
+ val collect = list.stream().collect(Collectors.groupingBy(Powerfittinganalysis::getStationcn, Collectors.toList()));
|
|
|
+ collect.forEach((k, v) -> {
|
|
|
+ String date = null;
|
|
|
+ List<String> pcl_all = new ArrayList<>();
|
|
|
+ List<String> pcl_5 = new ArrayList<>();
|
|
|
+ List<String> pcl_10 = new ArrayList<>();
|
|
|
+ List<String> pcl_12 = new ArrayList<>();
|
|
|
+ List<String> pcl_25 = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ for (Powerfittinganalysis obj : v) {
|
|
|
+ if (date == null) {
|
|
|
+ date = DateUtil.format(obj.getCreatetime(), DateUtil.YYYY_MM);
|
|
|
+ }
|
|
|
+ //3-25m风速区间曲线偏差率小于0
|
|
|
+ if (obj.getPcratio() < 0) {
|
|
|
+ pcl_all.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ //3-5m风速区间曲线偏差率小于0
|
|
|
+ if (obj.getPc5ratio() < 0) {
|
|
|
+ pcl_5.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ //5-10m风速区间曲线偏差率小于0
|
|
|
+ if (obj.getPc10ratio() < 0) {
|
|
|
+ pcl_10.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ //10-12m风速区间曲线偏差率小于0
|
|
|
+ if (obj.getPc12ratio() < 0) {
|
|
|
+ pcl_12.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ //12-25m风速区间曲线偏差率小于0
|
|
|
+ if (obj.getPc25ratio() < 0) {
|
|
|
+ pcl_25.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (pcl_all.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_CURVE, "3-25m", pcl_all, null);
|
|
|
+ }
|
|
|
+ if (pcl_5.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_CURVE, "3-5m", pcl_5, null);
|
|
|
+ }
|
|
|
+ if (pcl_10.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_CURVE, "5-10m", pcl_10, null);
|
|
|
+ }
|
|
|
+ if (pcl_12.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_CURVE, "10-12m", pcl_12, null);
|
|
|
+ }
|
|
|
+ if (pcl_25.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_CURVE, "12-25m", pcl_12, null);
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("ReportService--calCurve" + e.getMessage());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ reportService.saveBatch(result, Constants.MODULE_CURVE);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 静态偏航对风分析
|
|
|
+ */
|
|
|
+ public void calJTPCDF(Date st, Date et){
|
|
|
+ log.info("=====静态偏航对风分析");
|
|
|
+ List<Poweranalysisreport> result = new ArrayList<>();
|
|
|
+ var list = powerService.selectByTime(Constants.DATA_PROCESS, st, et);
|
|
|
+ val collect = list.stream().collect(Collectors.groupingBy(Powerfittinganalysis::getStationcn, Collectors.toList()));
|
|
|
+ collect.forEach((k, v) -> {
|
|
|
+ String date = null;
|
|
|
+ // 负值偏大、中度负值、中度正值、正值偏大
|
|
|
+ List<String> lsL2 = new ArrayList<>();
|
|
|
+ List<String> lsL1 = new ArrayList<>();
|
|
|
+ List<String> lsR1 = new ArrayList<>();
|
|
|
+ List<String> lsR2 = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ for (Powerfittinganalysis obj : v){
|
|
|
+ List<PowerPointData> data = fileParse(obj, false);
|
|
|
+ //静态偏航数据
|
|
|
+ Map<String, Object> mp = WindDirectionALG.windDeviationPoint(data);
|
|
|
+ int avg = (int) mp.get("avg");
|
|
|
+ List<Object> ls = (List<Object>) mp.get("data");
|
|
|
+ //点太少不做计算
|
|
|
+ if (ls.size() < 50){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (date == null){
|
|
|
+ date = DateUtil.format(obj.getCreatetime(), DateUtil.YYYY_MM);
|
|
|
+ }
|
|
|
+ if (avg <= -15){
|
|
|
+ lsL2.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+// if (avg > -15 && avg <= -10){
|
|
|
+// lsL1.add(obj.getWindturbine());
|
|
|
+// }
|
|
|
+// if (avg >= 10 && avg < 15){
|
|
|
+// lsR1.add(obj.getWindturbine());
|
|
|
+// }
|
|
|
+ if (avg >= 15){
|
|
|
+ lsR2.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (lsL2.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_STATIC_WIND, "负值偏大(15+deg)", lsL2, null);
|
|
|
+ }
|
|
|
+// if (lsL1.size() > 0){
|
|
|
+// buildObj(result, k, date, Constants.MODULE_STATIC_WIND, "中度负值(10-15deg)", lsL1);
|
|
|
+// }
|
|
|
+// if (lsR1.size() > 0){
|
|
|
+// buildObj(result, k, date, Constants.MODULE_STATIC_WIND, "中度正值(10-15deg)", lsR1);
|
|
|
+// }
|
|
|
+ if (lsR2.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_STATIC_WIND, "正值偏大(15+deg)", lsR2, null);
|
|
|
+ }
|
|
|
+ } catch (Exception e){
|
|
|
+ log.error("ReportService--calJTPCDF" + e.getMessage());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ reportService.saveBatch(result, Constants.MODULE_STATIC_WIND);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 容量系数分析
|
|
|
+ */
|
|
|
+ public void calMRLXS(Date st, Date et){
|
|
|
+ log.info("=====容量系数分析");
|
|
|
+ List<Poweranalysisreport> result = new ArrayList<>();
|
|
|
+ var list = windinfoService.selectByTime(DateUtil.format(st, DateUtil.YYYY_MM), DateUtil.format(et, DateUtil.YYYY_MM));
|
|
|
+ val collect = list.stream().collect(Collectors.groupingBy(Powerwindinfo::getStation, Collectors.toList()));
|
|
|
+ collect.forEach((k, v) -> {
|
|
|
+ String date = null;
|
|
|
+ // 毛容量系数 0-0.15 0.15-0.2
|
|
|
+ List<String> ls1 = new ArrayList<>();
|
|
|
+ List<String> ls2 = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ for (Powerwindinfo obj : v){
|
|
|
+ if (date == null){
|
|
|
+ date = obj.getTime();
|
|
|
+ }
|
|
|
+ if (obj.getAvgspeed() < 5 && obj.getMrxs() <= 0.15){
|
|
|
+ ls1.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ if (obj.getAvgspeed() >= 5 && obj.getMrxs() > 0.15 && obj.getMrxs() <= 0.2){
|
|
|
+ ls2.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if (ls1.size() > 0){
|
|
|
+ buildObj(result, InitialRunner.stationMap.get(k), date, Constants.MODULE_MLXS, "0-15%", ls1, null);
|
|
|
+ }
|
|
|
+ if (ls2.size() > 0){
|
|
|
+ buildObj(result, InitialRunner.stationMap.get(k), date, Constants.MODULE_MLXS, "15-20%", ls2, null);
|
|
|
+ }
|
|
|
+ } catch (Exception e){
|
|
|
+ log.info("ReportService--calMRLXS" + e.getMessage());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ reportService.saveBatch(result, Constants.MODULE_MLXS);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 桨距角分析
|
|
|
+ */
|
|
|
+ public void calBlade(Date st, Date et){
|
|
|
+ log.info("=====桨距角分析");
|
|
|
+ List<Poweranalysisreport> result = new ArrayList<>();
|
|
|
+ var list = powerService.selectByTime(Constants.DATA_PROCESS, st, et);
|
|
|
+ val collect = list.stream().collect(Collectors.groupingBy(Powerfittinganalysis::getStationcn, Collectors.toList()));
|
|
|
+ collect.forEach((k, v) -> {
|
|
|
+ String date = null;
|
|
|
+ // 并网分析、停机分析
|
|
|
+ List<String> lsbw = new ArrayList<>();
|
|
|
+ List<String> lstj = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ for (Powerfittinganalysis obj : v){
|
|
|
+ List<PowerPointData> ls = fileParse(obj, true);
|
|
|
+ int countBW = 0;
|
|
|
+ int countTJ = 0;
|
|
|
+ for (PowerPointData item : ls){
|
|
|
+ if (date == null){
|
|
|
+ date = DateUtil.format(obj.getCreatetime(), DateUtil.YYYY_MM);
|
|
|
+ }
|
|
|
+ double angle = (item.getYp1() + item.getYp2() + item.getYp3()) / 3;
|
|
|
+ double avg = new BigDecimal(angle).setScale(2, RoundingMode.CEILING).doubleValue();
|
|
|
+ if (item.getFilter() == 0 && avg < 20){
|
|
|
+ //风机正常并网且风速在5-12m
|
|
|
+ if (item.getMxzt() == 2 && item.getSpeed() >= 5 && item.getSpeed() <= 12 && avg > 6){
|
|
|
+ countBW += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //风机在不发电情况下
|
|
|
+ if (item.getFilter() == 2 && avg > 70){
|
|
|
+ if ((90 - avg) > 6){
|
|
|
+ countTJ += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (countBW >= 50){
|
|
|
+ lsbw.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ if (countTJ >= 50){
|
|
|
+ lstj.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (lsbw.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_BLADE, "并网桨距角偏大", lsbw, null);
|
|
|
+ }
|
|
|
+ if (lstj.size() > 0){
|
|
|
+ buildObj(result, k, date, Constants.MODULE_BLADE, "停机桨距角偏大", lstj, null);
|
|
|
+ }
|
|
|
+ } catch (Exception e){
|
|
|
+ log.error("ReportService--calBLADE" + e.getMessage());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ reportService.saveBatch(result, Constants.MODULE_BLADE);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停机时间
|
|
|
+ */
|
|
|
+ public void calStopTime(Date st, Date et){
|
|
|
+ log.info("=====停机时间");
|
|
|
+ List<Poweranalysisreport> result = new ArrayList<>();
|
|
|
+ var list = powerService.selectByTime(Constants.DATA_PREPARE, st, et);
|
|
|
+ val collect = list.stream().collect(Collectors.groupingBy(Powerfittinganalysis::getStationcn, Collectors.toList()));
|
|
|
+ collect.forEach((k, v) -> {
|
|
|
+ String date = null;
|
|
|
+ double time1 = 0.0, time2 = 0.0;
|
|
|
+ List<String> ls1 = new ArrayList<>();
|
|
|
+ List<String> ls2 = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ for (Powerfittinganalysis obj : v) {
|
|
|
+ if (date == null){
|
|
|
+ date = DateUtil.format(obj.getCreatetime(), DateUtil.YYYY_MM);
|
|
|
+ }
|
|
|
+ List<PowerPointData> datas = fileParse(obj, false);
|
|
|
+ if (datas == null || datas.size() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //3-5m的停机时间、大于25m的停机时间
|
|
|
+ double times1 = 0.0, times2 = 0.0;
|
|
|
+ double interval = DateUtil.getTimeDiff(datas.get(1).getTime(), datas.get(2).getTime()); //两条数据的间隔时间
|
|
|
+ for (PowerPointData item : datas){
|
|
|
+ if (item.getMxzt() != 2 && item.getSpeed() > 3.0 && item.getSpeed() < 5.0){
|
|
|
+ times1 += interval;
|
|
|
+ }
|
|
|
+ if (item.getSpeed() >= 25 && item.getMxzt() == 2){
|
|
|
+ times2 += interval;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 3-5m风速停机时长超过5000分钟
|
|
|
+ if (times1 > 5000) {
|
|
|
+ time1 += times1;
|
|
|
+ ls1.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ // 暴风天气未停机
|
|
|
+ if (times2 > 10) {
|
|
|
+ time2 += times2;
|
|
|
+ ls2.add(obj.getWindturbine());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (ls1.size() > 0) {
|
|
|
+ buildObj(result, k, date, Constants.MODULE_STOP_TIME, "3-5m", ls1, String.valueOf(time1));
|
|
|
+ }
|
|
|
+ if (ls2.size() > 0) {
|
|
|
+ buildObj(result, k, date, Constants.MODULE_STOP_TIME, "大于25m", ls2, String.valueOf(time2));
|
|
|
+ }
|
|
|
+ } catch (Exception e){
|
|
|
+ log.error("ReportService--calStopTime" + e.getMessage());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ reportService.saveBatch(result, Constants.MODULE_STOP_TIME);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void buildObj(List<Poweranalysisreport> list, String station, String date, String module, String section, List<String> wtIds, String remark){
|
|
|
+ Poweranalysisreport report = new Poweranalysisreport();
|
|
|
+ report.setStation(station);
|
|
|
+ report.setModule(module);
|
|
|
+ report.setSection(section);
|
|
|
+ report.setTime(date);
|
|
|
+ report.setWtidcount(wtIds.size());
|
|
|
+ report.setWindturbine(StringUtils.join(wtIds, ","));
|
|
|
+ report.setRemark(remark);
|
|
|
+ list.add(report);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<PowerFittingData> csvParse(Powerfittinganalysis obj){
|
|
|
+ var list = new ArrayList<PowerFittingData>();
|
|
|
+ val content = FileUtil.readFile(obj.getPath(), true);
|
|
|
+ for (int i = 1; i < content.size(); i++){
|
|
|
+ PowerFittingData data = new PowerFittingData(content.get(i).split(","));
|
|
|
+ list.add(data);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<PowerPointData> fileParse(Powerfittinganalysis obj, boolean isFilter){
|
|
|
+ val list = new ArrayList<PowerPointData>();
|
|
|
+ val content = FileUtil.readFile(obj.getPath(), true);
|
|
|
+ for (int i = 1; i < content.size(); i++){
|
|
|
+ String[] split = content.get(i).split(",");
|
|
|
+ PowerPointData data = new PowerPointData(split, isFilter);
|
|
|
+ list.add(data);
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+}
|