InverterPowerAnalysis2.java 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package com.gyee.power.fitting.dispersionanalysis;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.gyee.power.fitting.common.alg.PolynomialCurveFitting;
  6. import com.gyee.power.fitting.common.result.JsonResult;
  7. import com.gyee.power.fitting.common.result.ResultCode;
  8. import com.gyee.power.fitting.model.custom.PhotovoltaicInfo;
  9. import com.gyee.power.fitting.model.custom.TsDoubleData;
  10. import com.gyee.power.fitting.service.impl.IvPvCurveFittingService;
  11. import org.apache.commons.math3.fitting.WeightedObservedPoints;
  12. import org.springframework.stereotype.Component;
  13. import org.springframework.web.bind.annotation.GetMapping;
  14. import org.springframework.web.bind.annotation.RequestParam;
  15. import javax.annotation.Resource;
  16. import java.util.*;
  17. import java.util.stream.Collectors;
  18. //逆变器单位装机输出功率离散率分析
  19. //@CrossOrigin
  20. //@RequestMapping("/discreteness")
  21. //@RestController
  22. @Component
  23. public class InverterPowerAnalysis2 {
  24. @Resource
  25. private IvPvCurveFittingService curveFittingService;
  26. @Resource
  27. private PolynomialCurveFitting pncf;
  28. // 计算平均功率
  29. public double calculateAveragePower(List<Double> powerData) {
  30. double sum = 0.0;
  31. for (Double power : powerData) {
  32. sum += power;
  33. }
  34. return sum / powerData.size();
  35. }
  36. // 根据复杂规则分析逆变器状态
  37. public String analyzeInverterStatus(double powerDeviation, double averagePower) {
  38. if (powerDeviation < 5 && averagePower > 200) {
  39. return "运行稳定";
  40. } else if (powerDeviation < 8 && averagePower > 35) {
  41. return "运行良好";
  42. } else if (powerDeviation < 20 && averagePower > 20) {
  43. return "运行水平有待提高";
  44. } else {
  45. return "必须整改";
  46. }
  47. }
  48. @GetMapping("/rate")
  49. private JSONObject getFileList(
  50. @RequestParam(value = "station", required = true) String station,
  51. @RequestParam(value = "inverters", required = false) List<String> inverters,
  52. @RequestParam(value = "startdate", required = true) long startdate,
  53. @RequestParam(value = "interval", required = false) Integer interval,
  54. @RequestParam(value = "enddate", required = true) long enddate) {
  55. Map<String, List<PhotovoltaicInfo>> datasInfos = curveFittingService.getDatas2File1(station, startdate, enddate, interval);
  56. /*List<PhotovoltaicInfo> infos = new ArrayList<>();
  57. //单台拟合
  58. if (inverters.size() == 1) {
  59. infos = datasInfos.get(inverters.get(0));
  60. //多台拟合
  61. } else if (inverters.size() > 1) {
  62. infos = inverters.stream().flatMap(inverter -> datasInfos.get(inverter).stream()).collect(Collectors.toList());
  63. //全场拟合
  64. } else {
  65. infos = datasInfos.values().stream().flatMap(List::stream).collect(Collectors.toList());
  66. }*/
  67. List<InverterData2> inverterData2s = new ArrayList<>();
  68. datasInfos.forEach((k, v) -> {
  69. WeightedObservedPoints points = new WeightedObservedPoints();
  70. for (PhotovoltaicInfo info : v) {
  71. if (info.getS() < 1) {
  72. points.add(0, 0);
  73. }
  74. points.add(info.getS(), info.getActualP());
  75. }
  76. double[] run = pncf.run(points);
  77. inverterData2s.add(analyzeInverterPerformance(v, run, k));
  78. });
  79. return JsonResult.successData(ResultCode.SUCCESS, inverterData2s);
  80. }
  81. // 分析逆变器性能,包括计算离散率和平均功率
  82. public InverterData2 analyzeInverterPerformance(List<PhotovoltaicInfo> infos, double[] run, String inverterId) {
  83. List<Double> collect = infos.stream().map(info -> info.getS()).collect(Collectors.toList());
  84. // 计算功率离散率
  85. double powerDeviation = calculatePowerDeviation(collect, run);
  86. // 计算平均功率
  87. double averagePower = calculateAveragePower(collect);
  88. // 分析逆变器状态
  89. String inverterStatus = analyzeInverterStatus(powerDeviation, averagePower);
  90. return new InverterData2(inverterId, powerDeviation, averagePower, inverterStatus, "离散率");
  91. }
  92. // 计算功率离散率
  93. private double calculatePowerDeviation(List<Double> powerData, double[] run) {
  94. double sum = 0.0;
  95. // 计算标准差
  96. for (Double power : powerData) {
  97. sum += Math.pow(power - pncf.calcPoly(power, run), 2);
  98. }
  99. return Math.sqrt(sum / powerData.size());
  100. }
  101. // 计算功率离散率
  102. public double calcPowerDeviation(List<TsDoubleData> gzqd, List<TsDoubleData> yggl, double averagePower, long startTime, long endTime) {
  103. if (CollUtil.isEmpty(gzqd) || CollUtil.isEmpty(yggl)) return 0;
  104. //List<TsDoubleData> S = dataCompletion(gzqd, startTime, endTime);
  105. //List<TsDoubleData> P = dataCompletion(yggl, startTime, endTime);
  106. WeightedObservedPoints points = new WeightedObservedPoints();
  107. double s, p;
  108. for (int i = 0; i < gzqd.size(); i++) {
  109. s = gzqd.get(i).getDoubleValue();
  110. p = yggl.get(i).getDoubleValue();
  111. if (s < 1 || p < 1) {
  112. points.add(0, 0);
  113. }
  114. points.add(s, p);
  115. }
  116. double[] run = pncf.run(points);
  117. double sum = 0.0, power;
  118. // 计算标准差
  119. for (int i = 0; i < gzqd.size(); i++) {
  120. s = gzqd.get(i).getDoubleValue();
  121. p = yggl.get(i).getDoubleValue();
  122. sum += Math.pow(p - pncf.calcPoly(s, run), 2);
  123. }
  124. double sqrt = Math.sqrt(sum / gzqd.size());
  125. if (sqrt > 80) sqrt = 80;
  126. return sqrt;
  127. }
  128. private List<TsDoubleData> dataCompletion(List<TsDoubleData> gzqd, long startTime, long endTime) {
  129. Collections.sort(gzqd, Comparator.comparing(TsDoubleData::getTs));
  130. List<TsDoubleData> result = new ArrayList<>();
  131. double last = gzqd.get(0).getDoubleValue();
  132. int j = 0;
  133. long ts;
  134. for (long i = startTime; i < endTime; i += 1000) {
  135. ts = gzqd.get(j).getTs();
  136. if (ts > startTime) {
  137. result.add(new TsDoubleData(startTime, last));
  138. } else if (ts == startTime) {
  139. result.add(new TsDoubleData(startTime, gzqd.get(j).getDoubleValue()));
  140. j++;
  141. last = gzqd.get(j).getDoubleValue();
  142. } else {
  143. result.add(new TsDoubleData(startTime, gzqd.get(j).getDoubleValue()));
  144. j++;
  145. last = gzqd.get(j).getDoubleValue();
  146. }
  147. }
  148. return result;
  149. }
  150. }