|
@@ -0,0 +1,148 @@
|
|
|
+package com.gyee.power.fitting.dispersionanalysis;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.gyee.power.fitting.common.feign.RemoteServiceBuilder;
|
|
|
+import com.gyee.power.fitting.common.result.JsonResult;
|
|
|
+import com.gyee.power.fitting.common.result.ResultCode;
|
|
|
+import com.gyee.power.fitting.model.ProBasicEquipment;
|
|
|
+import com.gyee.power.fitting.model.ProBasicEquipmentPoint;
|
|
|
+import com.gyee.power.fitting.model.ProEconEquipmentmodel;
|
|
|
+import com.gyee.power.fitting.model.custom.TsDoubleData;
|
|
|
+import com.gyee.power.fitting.service.ProBasicEquipmentPointService;
|
|
|
+import com.gyee.power.fitting.service.ProBasicEquipmentService;
|
|
|
+import com.gyee.power.fitting.service.ProEconEquipmentmodelService;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+//等效发电时分析
|
|
|
+@CrossOrigin
|
|
|
+@RequestMapping("/equivalent")
|
|
|
+@RestController
|
|
|
+public class InverterAnalysis2 {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ProBasicEquipmentService proBasicEquipmentService;
|
|
|
+ @Resource
|
|
|
+ private ProEconEquipmentmodelService proEconEquipmentmodelService;
|
|
|
+ @Resource
|
|
|
+ private ProBasicEquipmentPointService proBasicEquipmentPointService;
|
|
|
+ @Resource
|
|
|
+ private RemoteServiceBuilder remoteService;
|
|
|
+
|
|
|
+ // 计算等效发电时的标准差
|
|
|
+ private static double calculateStandardDeviationEquivalentOperatingHours(Map<String, Double> data, double average) {
|
|
|
+ double sum = 0.0;
|
|
|
+ for (double value : data.values()) {
|
|
|
+ sum += Math.pow(value - average, 2);
|
|
|
+ }
|
|
|
+ return Math.sqrt(sum / data.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/powertime")
|
|
|
+ private JSONObject getFileList(
|
|
|
+ @RequestParam(value = "station", required = true) String station,
|
|
|
+ @RequestParam(value = "inverters", required = false) List<String> inverters,
|
|
|
+ @RequestParam(value = "startdate", required = true) long startdate,
|
|
|
+ @RequestParam(value = "enddate", required = true) long enddate) {
|
|
|
+
|
|
|
+ //获取逆变器
|
|
|
+ QueryWrapper<ProBasicEquipment> eWrapper = new QueryWrapper<>();
|
|
|
+ eWrapper.eq("spare1", "IN").eq("windpowerstation_id", station);
|
|
|
+ List<ProBasicEquipment> eList = proBasicEquipmentService.list(eWrapper);
|
|
|
+ List<String> inverterIds = eList.stream().map(ProBasicEquipment::getId).collect(Collectors.toList());
|
|
|
+ //逆变器id,机型
|
|
|
+ Map<String, String> inverterModelMap = eList.stream().collect(Collectors.toMap(ProBasicEquipment::getId, ProBasicEquipment::getModelId));
|
|
|
+
|
|
|
+ //获取机型的装机容量
|
|
|
+ List<ProEconEquipmentmodel> emList = proEconEquipmentmodelService.list();
|
|
|
+ //机型、装机容量
|
|
|
+ Map<String, Double> emMap = emList.stream().collect(Collectors.toMap(ProEconEquipmentmodel::getNemCode, ProEconEquipmentmodel::getPowerProduction));
|
|
|
+
|
|
|
+ //获取年发电量
|
|
|
+ QueryWrapper<ProBasicEquipmentPoint> epWrapper = new QueryWrapper<>();
|
|
|
+ epWrapper.eq("uniform_code", "NFDL").eq("windpowerstation_id", station).like("windturbine_id", "_IN_");
|
|
|
+ List<ProBasicEquipmentPoint> epList = proBasicEquipmentPointService.list(epWrapper);
|
|
|
+ String points = epList.stream().map(ProBasicEquipmentPoint::getNemCode).collect(Collectors.joining(","));
|
|
|
+ //逆变器id,测点
|
|
|
+ Map<String, String> epMap = epList.stream().collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
|
|
|
+
|
|
|
+ //开始、结束时间的年发电量
|
|
|
+ Map<String, TsDoubleData> startSection = remoteService.adaptergf().getHistorySection(points, startdate);
|
|
|
+ Map<String, TsDoubleData> endSection = remoteService.adaptergf().getHistorySection(points, enddate);
|
|
|
+
|
|
|
+ // 模拟全站逆变单元的发电数据,这里用一个Map来表示每个逆变单元的发电量
|
|
|
+ Map<String, Double> dxfdsData = new HashMap<>();
|
|
|
+ double dxfdsSum = 0;//等效发电时之和
|
|
|
+ TsDoubleData endData, startData;
|
|
|
+ String ims, p;
|
|
|
+ double dxfds;
|
|
|
+ for (String s : inverterIds) {
|
|
|
+ p = epMap.get(s);
|
|
|
+ if (StringUtils.isEmpty(p)) continue;
|
|
|
+ endData = endSection.get(p);
|
|
|
+ startData = startSection.get(p);
|
|
|
+ ims = inverterModelMap.get(s);
|
|
|
+ if (endData == null || startData == null || ims == null) {
|
|
|
+ dxfds = 0;
|
|
|
+ } else {
|
|
|
+ dxfds = calculateEquivalentOperatingHours(endData.getDoubleValue() - startData.getDoubleValue(), emMap.get(ims));
|
|
|
+ }
|
|
|
+ dxfdsSum += dxfds;
|
|
|
+ dxfdsData.put(s, dxfds);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 时间段,以小时为单位
|
|
|
+ //double hours = DateUtil.between(new Date(startdate),new Date(enddate), DateUnit.HOUR);
|
|
|
+
|
|
|
+ // 计算等效发电时的平均值
|
|
|
+ double average = dxfdsSum / inverterIds.size();
|
|
|
+
|
|
|
+ // 计算等效发电时的标准差
|
|
|
+ double stdDeviation = calculateStandardDeviationEquivalentOperatingHours(dxfdsData, average);
|
|
|
+
|
|
|
+ // 存储极差逆变单元的列表
|
|
|
+ List<String> outlierInverters = new ArrayList<>();
|
|
|
+
|
|
|
+ // 进行等效发电时分析并找出极差逆变单元
|
|
|
+ List<InverterData2> inverterData2s = new ArrayList<>();
|
|
|
+ dxfdsData.forEach((k, v) -> {
|
|
|
+ // 判断逆变单元的运行水平并根据枚举值进行分类
|
|
|
+ String currentLevel = determineOperatingLevel(v, average, stdDeviation);
|
|
|
+ inverterData2s.add(new InverterData2(k, v, average, currentLevel, "等效发电时"));
|
|
|
+ });
|
|
|
+
|
|
|
+ return JsonResult.successData(ResultCode.SUCCESS, inverterData2s);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算等效发电时
|
|
|
+ private double calculateEquivalentOperatingHours(double power, double installedCapacity) {
|
|
|
+ if (installedCapacity == 0) return 0;
|
|
|
+ return power / installedCapacity;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据等效发电时、平均值和标准差确定运行水平
|
|
|
+ private String determineOperatingLevel(double equivalentOperatingHours, double average, double stdDeviation) {
|
|
|
+ double deviation = equivalentOperatingHours - average;
|
|
|
+
|
|
|
+ // 使用标准差的倍数来判断运行水平
|
|
|
+ if (deviation > 2 * stdDeviation) {
|
|
|
+ return "优秀";
|
|
|
+ } else if (deviation > stdDeviation) {
|
|
|
+ return "良好";
|
|
|
+ } else if (deviation >= -stdDeviation && deviation <= stdDeviation) {
|
|
|
+ return "平均";
|
|
|
+ } else if (deviation >= -2 * stdDeviation) {
|
|
|
+ return "差";
|
|
|
+ } else {
|
|
|
+ return "非常差";
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|