package com.gyee.power.fitting.dispersionanalysis; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson.JSONObject; import com.gyee.power.fitting.common.alg.PolynomialCurveFitting; import com.gyee.power.fitting.common.result.JsonResult; import com.gyee.power.fitting.common.result.ResultCode; import com.gyee.power.fitting.model.custom.PhotovoltaicInfo; import com.gyee.power.fitting.model.custom.TsDoubleData; import com.gyee.power.fitting.service.impl.IvPvCurveFittingService; import org.apache.commons.math3.fitting.WeightedObservedPoints; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; //逆变器单位装机输出功率离散率分析 //@CrossOrigin //@RequestMapping("/discreteness") //@RestController @Component public class InverterPowerAnalysis2 { @Resource private IvPvCurveFittingService curveFittingService; @Resource private PolynomialCurveFitting pncf; // 计算平均功率 public double calculateAveragePower(List powerData) { double sum = 0.0; for (Double power : powerData) { sum += power; } return sum / powerData.size(); } // 根据复杂规则分析逆变器状态 public String analyzeInverterStatus(double powerDeviation, double averagePower) { if (powerDeviation < 5 && averagePower > 200) { return "运行稳定"; } else if (powerDeviation < 8 && averagePower > 35) { return "运行良好"; } else if (powerDeviation < 20 && averagePower > 20) { return "运行水平有待提高"; } else { return "必须整改"; } } @GetMapping("/rate") private JSONObject getFileList( @RequestParam(value = "station", required = true) String station, @RequestParam(value = "inverters", required = false) List inverters, @RequestParam(value = "startdate", required = true) long startdate, @RequestParam(value = "interval", required = false) Integer interval, @RequestParam(value = "enddate", required = true) long enddate) { Map> datasInfos = curveFittingService.getDatas2File1(station, startdate, enddate, interval); /*List infos = new ArrayList<>(); //单台拟合 if (inverters.size() == 1) { infos = datasInfos.get(inverters.get(0)); //多台拟合 } else if (inverters.size() > 1) { infos = inverters.stream().flatMap(inverter -> datasInfos.get(inverter).stream()).collect(Collectors.toList()); //全场拟合 } else { infos = datasInfos.values().stream().flatMap(List::stream).collect(Collectors.toList()); }*/ List inverterData2s = new ArrayList<>(); datasInfos.forEach((k, v) -> { WeightedObservedPoints points = new WeightedObservedPoints(); for (PhotovoltaicInfo info : v) { if (info.getS() < 1) { points.add(0, 0); } points.add(info.getS(), info.getActualP()); } double[] run = pncf.run(points); inverterData2s.add(analyzeInverterPerformance(v, run, k)); }); return JsonResult.successData(ResultCode.SUCCESS, inverterData2s); } // 分析逆变器性能,包括计算离散率和平均功率 public InverterData2 analyzeInverterPerformance(List infos, double[] run, String inverterId) { List collect = infos.stream().map(info -> info.getS()).collect(Collectors.toList()); // 计算功率离散率 double powerDeviation = calculatePowerDeviation(collect, run); // 计算平均功率 double averagePower = calculateAveragePower(collect); // 分析逆变器状态 String inverterStatus = analyzeInverterStatus(powerDeviation, averagePower); return new InverterData2(inverterId, powerDeviation, averagePower, inverterStatus, "离散率"); } // 计算功率离散率 private double calculatePowerDeviation(List powerData, double[] run) { double sum = 0.0; // 计算标准差 for (Double power : powerData) { sum += Math.pow(power - pncf.calcPoly(power, run), 2); } return Math.sqrt(sum / powerData.size()); } // 计算功率离散率 public double calcPowerDeviation(List gzqd, List yggl, double averagePower, long startTime, long endTime) { if (CollUtil.isEmpty(gzqd) || CollUtil.isEmpty(yggl)) return 0; //List S = dataCompletion(gzqd, startTime, endTime); //List P = dataCompletion(yggl, startTime, endTime); WeightedObservedPoints points = new WeightedObservedPoints(); double s, p; for (int i = 0; i < gzqd.size(); i++) { s = gzqd.get(i).getDoubleValue(); p = yggl.get(i).getDoubleValue(); if (s < 1 || p < 1) { points.add(0, 0); } points.add(s, p); } double[] run = pncf.run(points); double sum = 0.0, power; // 计算标准差 for (int i = 0; i < gzqd.size(); i++) { s = gzqd.get(i).getDoubleValue(); p = yggl.get(i).getDoubleValue(); sum += Math.pow(p - pncf.calcPoly(s, run), 2); } double sqrt = Math.sqrt(sum / gzqd.size()); if (sqrt > 80) sqrt = 80; return sqrt; } private List dataCompletion(List gzqd, long startTime, long endTime) { Collections.sort(gzqd, Comparator.comparing(TsDoubleData::getTs)); List result = new ArrayList<>(); double last = gzqd.get(0).getDoubleValue(); int j = 0; long ts; for (long i = startTime; i < endTime; i += 1000) { ts = gzqd.get(j).getTs(); if (ts > startTime) { result.add(new TsDoubleData(startTime, last)); } else if (ts == startTime) { result.add(new TsDoubleData(startTime, gzqd.get(j).getDoubleValue())); j++; last = gzqd.get(j).getDoubleValue(); } else { result.add(new TsDoubleData(startTime, gzqd.get(j).getDoubleValue())); j++; last = gzqd.get(j).getDoubleValue(); } } return result; } }