Bladeren bron

光伏等效发电时、离散率、转换效率分析

xushili 2 jaren geleden
bovenliggende
commit
41cdfc1c77

+ 6 - 0
benchmarking-impala/pom.xml

@@ -180,6 +180,12 @@
             <scope>compile</scope>
         </dependency>
 
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-core</artifactId>
+            <version>5.8.13</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 5 - 0
power-fitting-JN/pom.xml

@@ -128,6 +128,11 @@
             <version>1.6.2</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-core</artifactId>
+            <version>5.8.16</version>
+        </dependency>
 
     </dependencies>
 

+ 3 - 4
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/feign/IAdapterService.java

@@ -1,13 +1,12 @@
 package com.gyee.power.fitting.common.feign;
 
-import com.alibaba.fastjson.JSONObject;
 import com.gyee.power.fitting.model.custom.TsDoubleData;
 import feign.Headers;
 import feign.Param;
 import feign.RequestLine;
-import org.springframework.web.bind.annotation.GetMapping;
 
 import java.util.List;
+import java.util.Map;
 
 
 public interface IAdapterService {
@@ -15,7 +14,7 @@ public interface IAdapterService {
 
     @Headers({"Content-Type: application/json", "Accept: application/json"})
     @RequestLine("GET /ts/latest?keys={points}")
-    JSONObject getLatest(@Param(value = "points") String points);
+    TsDoubleData getLatest(@Param(value = "points") String points);
 
     @Headers({"Content-Type: application/json", "Accept: application/json"})
     @RequestLine("GET /ts/history/snap?tagName={tagName}&startTs={startTs}&endTs={endTs}&interval={interval}")
@@ -34,5 +33,5 @@ public interface IAdapterService {
 
     @Headers({"Content-Type: application/json", "Accept: application/json"})
     @RequestLine("GET /ts/history/section?tagNames={tagNames}&ts={ts}")
-    JSONObject getHistorySection(@Param(value = "tagNames") String tagNames, @Param(value = "ts") long ts);
+    Map<String, TsDoubleData> getHistorySection(@Param(value = "tagNames") String tagNames, @Param(value = "ts") long ts);
 }

+ 99 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/InverterAnalysis.java

@@ -0,0 +1,99 @@
+package com.gyee.power.fitting.dispersionanalysis;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class InverterAnalysis {
+    public static void main(String[] args) {
+        // 模拟全站逆变单元的发电数据,这里用一个Map来表示每个逆变单元的发电量
+        Map<String, Double> inverterData = new HashMap<>();
+        inverterData.put("Inverter1", 950.0);
+        inverterData.put("Inverter2", 980.0);
+        inverterData.put("Inverter3", 1020.0);
+        inverterData.put("Inverter4", 940.0);
+        inverterData.put("Inverter5", 990.0);
+
+        // 时间段,以小时为单位
+        double hours = 8760.0; // 假设一年的小时数
+
+        // 计算等效发电时的平均值
+        double average = calculateAverageEquivalentOperatingHours(inverterData, hours);
+
+        // 计算等效发电时的标准差
+        double stdDeviation = calculateStandardDeviationEquivalentOperatingHours(inverterData, hours, average);
+
+        // 存储极差逆变单元的列表
+        List<String> outlierInverters = new ArrayList<>();
+
+        // 进行等效发电时分析并找出极差逆变单元
+        for (Map.Entry<String, Double> entry : inverterData.entrySet()) {
+            String inverterName = entry.getKey();
+            double inverterPower = entry.getValue();
+
+            double equivalentOperatingHours = calculateEquivalentOperatingHours(inverterPower, hours);
+
+            // 判断逆变单元的运行水平并根据枚举值进行分类
+            OperatingLevel currentLevel = determineOperatingLevel(equivalentOperatingHours, average, stdDeviation);
+
+            // 如果运行水平是差或非常差,将逆变单元添加到极差逆变单元列表中
+            if (currentLevel == OperatingLevel.POOR || currentLevel == OperatingLevel.VERY_POOR) {
+                outlierInverters.add(inverterName);
+            }
+        }
+
+        // 将极差逆变单元推送给运维人员
+        if (!outlierInverters.isEmpty()) {
+            System.out.println("需要重点关注的极差逆变单元:");
+            for (String outlier : outlierInverters) {
+                System.out.println(outlier);
+            }
+        } else {
+            System.out.println("没有发现极差逆变单元。");
+        }
+    }
+
+    // 计算等效发电时的平均值
+    private static double calculateAverageEquivalentOperatingHours(Map<String, Double> data, double hours) {
+        double sum = 0.0;
+        for (double value : data.values()) {
+            sum += calculateEquivalentOperatingHours(value, hours);
+        }
+        return sum / data.size();
+    }
+
+    // 计算等效发电时的标准差
+    private static double calculateStandardDeviationEquivalentOperatingHours(Map<String, Double> data, double hours, double average) {
+        double sum = 0.0;
+        for (double value : data.values()) {
+            double equivalentOperatingHours = calculateEquivalentOperatingHours(value, hours);
+            sum += Math.pow(equivalentOperatingHours - average, 2);
+        }
+        double variance = sum / data.size();
+        return Math.sqrt(variance);
+    }
+
+    // 计算等效发电时
+    private static double calculateEquivalentOperatingHours(double power, double hours) {
+        return (power / 1000) * hours; // 假设power是千瓦
+    }
+
+    // 根据等效发电时、平均值和标准差确定运行水平
+    private static OperatingLevel determineOperatingLevel(double equivalentOperatingHours, double average, double stdDeviation) {
+        double deviation = equivalentOperatingHours - average;
+
+        // 使用标准差的倍数来判断运行水平
+        if (deviation > 2 * stdDeviation) {
+            return OperatingLevel.EXCELLENT;
+        } else if (deviation > stdDeviation) {
+            return OperatingLevel.GOOD;
+        } else if (deviation >= -stdDeviation && deviation <= stdDeviation) {
+            return OperatingLevel.AVERAGE;
+        } else if (deviation >= -2 * stdDeviation) {
+            return OperatingLevel.POOR;
+        } else {
+            return OperatingLevel.VERY_POOR;
+        }
+    }
+}

+ 136 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/InverterAnalysis2.java

@@ -0,0 +1,136 @@
+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.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+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
+@RestController("/equivalent")
+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("/rate")
+    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;//等效发电时之和
+        for (String s : inverterIds) {
+            double dxfds = calculateEquivalentOperatingHours(endSection.get(s).getDoubleValue() - startSection.get(s).getDoubleValue(), emMap.get(inverterModelMap.get(s)));
+            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) {
+        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 "非常差";
+        }
+    }
+}

+ 7 - 1
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/InverterData.java

@@ -5,11 +5,13 @@ class InverterData {
     private String inverterId;
     private long timestamp;
     private double outputPower;
+    private double lightIntensity;
 
-    public InverterData(String inverterId, long timestamp, double outputPower) {
+    public InverterData(String inverterId, long timestamp, double outputPower, double lightIntensity) {
         this.inverterId = inverterId;
         this.timestamp = timestamp;
         this.outputPower = outputPower;
+        this.lightIntensity = lightIntensity;
     }
 
     public String getInverterId() {
@@ -23,4 +25,8 @@ class InverterData {
     public double getOutputPower() {
         return outputPower;
     }
+
+    public double getLightIntensity() {
+        return lightIntensity;
+    }
 }

+ 38 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/InverterData2.java

@@ -0,0 +1,38 @@
+package com.gyee.power.fitting.dispersionanalysis;
+
+// 逆变器数据类,包含逆变器ID、时间戳和输出功率
+class InverterData2 {
+    private String inverterId;
+    private double powerDeviation;//等效发电时、离散率、转换效率
+    private double averagePower;//平均功率
+    private String status;//状态
+    private String type;//等效发电时、离散率、转换效率
+
+    public InverterData2(String inverterId, double powerDeviation, double averagePower, String status, String type) {
+        this.inverterId = inverterId;
+        this.powerDeviation = powerDeviation;
+        this.averagePower = averagePower;
+        this.status = status;
+        this.type = type;
+    }
+
+    public String getInverterId() {
+        return inverterId;
+    }
+
+    public double getPowerDeviation() {
+        return powerDeviation;
+    }
+
+    public double getAveragePower() {
+        return averagePower;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public String getType() {
+        return type;
+    }
+}

+ 5 - 1
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/InverterPowerAnalysis.java

@@ -1,9 +1,12 @@
 package com.gyee.power.fitting.dispersionanalysis;
 
+import org.springframework.stereotype.Service;
+
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.*;
 
+@Service
 public class InverterPowerAnalysis {
 
     public static void main(String[] args) {
@@ -35,7 +38,8 @@ public class InverterPowerAnalysis {
             String inverterId = "Inverter" + i;
             long timestamp = System.currentTimeMillis();
             double outputPower = rand.nextDouble() * 1000;
-            data.add(new InverterData(inverterId, timestamp, outputPower));
+            double lightIntensity = rand.nextDouble() * 1000;
+            data.add(new InverterData(inverterId, timestamp, outputPower, lightIntensity));
         }
         return data;
     }

+ 157 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/InverterPowerAnalysis2.java

@@ -0,0 +1,157 @@
+package com.gyee.power.fitting.dispersionanalysis;
+
+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.service.impl.IvPvCurveFittingService;
+import org.apache.commons.math3.fitting.WeightedObservedPoints;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+//逆变器单位装机输出功率离散率分析
+@CrossOrigin
+@RestController("/discreteness")
+public class InverterPowerAnalysis2 {
+
+    @Resource
+    private IvPvCurveFittingService curveFittingService;
+    @Resource
+    private PolynomialCurveFitting pncf;
+
+    // 模拟生成逆变器数据
+    private static List<InverterData> generateInverterData() {
+        List<InverterData> data = new ArrayList<>();
+        Random rand = new Random();
+        for (int i = 1; i <= 10; i++) {
+            String inverterId = "Inverter" + i;
+            long timestamp = System.currentTimeMillis();
+            double outputPower = rand.nextDouble() * 1000;
+            double lightIntensity = rand.nextDouble() * 1000;
+            data.add(new InverterData(inverterId, timestamp, outputPower, lightIntensity));
+        }
+        return data;
+    }
+
+    // 计算平均功率
+    private static double calculateAveragePower(List<Double> powerData) {
+        double sum = 0.0;
+        for (Double power : powerData) {
+            sum += power;
+        }
+        return sum / powerData.size();
+    }
+
+    // 根据复杂规则分析逆变器状态
+    private static String analyzeInverterStatus(double powerDeviation, double averagePower) {
+        if (powerDeviation < 0.1 && averagePower > 800) {
+            return "运行稳定";
+        } else if (powerDeviation < 0.2 && averagePower > 600) {
+            return "运行良好";
+        } else if (powerDeviation < 0.3 && averagePower > 400) {
+            return "运行水平有待提高";
+        } else {
+            return "必须整改";
+        }
+    }
+
+    // 将数据存储到CSV文件
+    private static void saveDataToCSV(Map<String, List<Double>> historicalPowerData, String fileName) {
+        try {
+            FileWriter writer = new FileWriter(fileName);
+            writer.append("InverterId,PowerData\n");
+            for (Map.Entry<String, List<Double>> entry : historicalPowerData.entrySet()) {
+                String inverterId = entry.getKey();
+                List<Double> powerData = entry.getValue();
+                StringBuilder powerDataStr = new StringBuilder();
+                for (Double power : powerData) {
+                    powerDataStr.append(power).append(",");
+                }
+                writer.append(inverterId).append(",").append(powerDataStr.toString()).append("\n");
+            }
+            writer.flush();
+            writer.close();
+            System.out.println("数据已保存到 " + fileName);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @GetMapping("/rate")
+    private JSONObject getFileList(
+            @RequestParam(value = "station", required = true) String station,
+            @RequestParam(value = "inverters", required = true) List<String> inverters,
+            @RequestParam(value = "startdate", required = true) long startdate,
+            @RequestParam("interval") int interval,
+            @RequestParam(value = "enddate", required = true) long enddate) {
+
+        Map<String, List<PhotovoltaicInfo>> datasInfos = curveFittingService.getDatas2File1(station, startdate, enddate, interval);
+
+        /*List<PhotovoltaicInfo> 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<InverterData2> 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);
+    }
+
+    // 分析逆变器性能,包括计算离散率和平均功率
+    private InverterData2 analyzeInverterPerformance(List<PhotovoltaicInfo> infos, double[] run, String inverterId) {
+
+        List<Double> 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<Double> 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());
+    }
+}

+ 49 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/PhotovoltaicEfficiencyAnalysis.java

@@ -0,0 +1,49 @@
+package com.gyee.power.fitting.dispersionanalysis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PhotovoltaicEfficiencyAnalysis {
+    public static void main(String[] args) {
+        // 模拟全站光伏逆变单元的数据,这里用一个Map来表示每个逆变单元的发电功率和入射光能
+        Map<String, Double[]> inverterData = new HashMap<>();
+        inverterData.put("Inverter1", new Double[]{500.0, 600.0});
+        inverterData.put("Inverter2", new Double[]{550.0, 600.0});
+        inverterData.put("Inverter3", new Double[]{450.0, 600.0});
+        inverterData.put("Inverter4", new Double[]{600.0, 600.0});
+        inverterData.put("Inverter5", new Double[]{350.0, 600.0});
+
+        // 分析光伏逆变单元的运行水平
+        for (Map.Entry<String, Double[]> entry : inverterData.entrySet()) {
+            String inverterName = entry.getKey();
+            Double[] data = entry.getValue();
+            double actualOutputPower = data[0]; // 实际发电功率
+            double incidentSolarPower = data[1]; // 入射光能
+
+            double efficiency = calculatePhotovoltaicEfficiency(actualOutputPower, incidentSolarPower);
+            OperatingLevel currentLevel = determinePhotovoltaicLevel(efficiency);
+
+            // 输出每个逆变单元的运行水平
+            System.out.println(inverterName + "的运行水平是: " + currentLevel);
+        }
+    }
+
+    // 根据转换效率确定光伏运行水平
+    private static OperatingLevel determinePhotovoltaicLevel(double efficiency) {
+        if (efficiency >= 90.0) {
+            return OperatingLevel.STABLE;
+        } else if (efficiency >= 80.0) {
+            return OperatingLevel.GOOD;
+        } else if (efficiency >= 70.0) {
+            return OperatingLevel.NEEDS_IMPROVEMENT;
+        } else {
+            return OperatingLevel.MUST_CORRECT;
+        }
+    }
+
+    // 计算光伏转换效率
+    private static double calculatePhotovoltaicEfficiency(double actualOutputPower, double incidentSolarPower) {
+        // 转换为百分比
+        return (actualOutputPower / incidentSolarPower) * 100.0;
+    }
+}

+ 77 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/dispersionanalysis/PhotovoltaicEfficiencyAnalysis2.java

@@ -0,0 +1,77 @@
+package com.gyee.power.fitting.dispersionanalysis;
+
+import com.alibaba.fastjson.JSONObject;
+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.service.impl.IvPvCurveFittingService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+//光伏转换效率分析
+@Slf4j
+@CrossOrigin
+@RestController("/conversion")
+public class PhotovoltaicEfficiencyAnalysis2 {
+
+    @Resource
+    private IvPvCurveFittingService curveFittingService;
+
+    // 计算光伏转换效率
+    private static double calculatePhotovoltaicEfficiency(double actualOutputPower, double incidentSolarPower) {
+        double v = (actualOutputPower / incidentSolarPower) * 100.0;
+        if (v > 95) v = 95.0;
+        // 转换为百分比
+        return v;
+    }
+
+    @GetMapping("/efficiency")
+    private JSONObject getFileList(
+            @RequestParam(value = "station", required = true) String station,
+            @RequestParam(value = "inverters", required = true) List<String> inverters,
+            @RequestParam(value = "startdate", required = true) long startdate,
+            @RequestParam("interval") int interval,
+            @RequestParam(value = "enddate", required = true) long enddate) {
+
+        Map<String, List<PhotovoltaicInfo>> datasInfos = curveFittingService.getDatas2File1(station, startdate, enddate, interval);
+        List<PhotovoltaicInfo> bzdList = curveFittingService.standardPointCalculate1(datasInfos);
+
+        Map<String, List<PhotovoltaicInfo>> bzdInfos = curveFittingService.calculatAnalysis1(bzdList, datasInfos);
+
+        List<InverterData2> inverterData2s = new ArrayList<>();
+        // 分析光伏逆变单元的运行水平
+        datasInfos.forEach((k, v) -> {
+            double actualOutputPower = v.stream().mapToDouble(PhotovoltaicInfo::getActualP).sum();
+            double incidentSolarPower = v.stream().mapToDouble(PhotovoltaicInfo::getIdeaP).sum();
+            double sPower = v.stream().mapToDouble(PhotovoltaicInfo::getS).sum();
+            log.info(k + "逆变器转换率2:" + actualOutputPower / sPower);
+
+            double efficiency = calculatePhotovoltaicEfficiency(actualOutputPower, incidentSolarPower);
+            String currentLevel = determinePhotovoltaicLevel(efficiency);
+            inverterData2s.add(new InverterData2(k, efficiency, actualOutputPower / v.size(), currentLevel, "转换效率"));
+        });
+
+        return JsonResult.successData(ResultCode.SUCCESS, inverterData2s);
+    }
+
+    // 根据转换效率确定光伏运行水平
+    private String determinePhotovoltaicLevel(double efficiency) {
+        if (efficiency >= 90.0) {
+            return "运行稳定";
+        } else if (efficiency >= 80.0) {
+            return "运行良好";
+        } else if (efficiency >= 70.0) {
+            return "运行水平有待提高";
+        } else {
+            return "必须整改";
+        }
+    }
+}

+ 763 - 561
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/impl/IvPvCurveFittingService.java

@@ -1,561 +1,763 @@
-//package com.gyee.power.fitting.service.impl;
-//
-//import com.gyee.power.fitting.common.alg.CurrentVoltageCalc;
-//import com.gyee.power.fitting.common.alg.PolynomialCurveFitting;
-//import com.gyee.power.fitting.common.config.GyeeConfig;
-//import com.gyee.power.fitting.common.constants.Constants;
-//import com.gyee.power.fitting.common.feign.IAdapterService;
-//import com.gyee.power.fitting.common.spring.InitialRunner;
-//import com.gyee.power.fitting.common.util.DateUtils;
-//import com.gyee.power.fitting.common.util.FileUtil;
-//import com.gyee.power.fitting.common.util.PowerFittingUtil;
-//import com.gyee.power.fitting.model.Powerfittinganalysis;
-//import com.gyee.power.fitting.model.Windpowerstationtestingpoint2;
-//import com.gyee.power.fitting.model.Windturbinetestingpointai2;
-//import com.gyee.power.fitting.model.anno.AnnotationTool;
-//import com.gyee.power.fitting.model.anno.FixedVo;
-//import com.gyee.power.fitting.model.custom.FjjxbVo;
-//import com.gyee.power.fitting.model.custom.PhotovoltaicInfo;
-//import com.gyee.power.fitting.model.custom.TableTitle;
-//import com.gyee.power.fitting.model.custom.TsDoubleData;
-//import com.gyee.power.fitting.service.IWindpowerstationtestingpoint2Service;
-//import com.gyee.power.fitting.service.Windturbinetestingpointai2Service;
-//import org.apache.commons.lang3.StringUtils;
-//import org.apache.commons.math3.fitting.WeightedObservedPoints;
-//import org.springframework.stereotype.Service;
-//
-//import javax.annotation.Resource;
-//import javax.servlet.http.HttpServletResponse;
-//import java.io.File;
-//import java.math.BigDecimal;
-//import java.util.*;
-//import java.util.function.Function;
-//import java.util.stream.Collectors;
-//
-//@Service
-//public class IvPvCurveFittingService {
-//
-//    @Resource
-//    private IWindpowerstationtestingpoint2Service windpowerstationtestingpoint2Service;
-//    @Resource
-//    private Windturbinetestingpointai2Service windturbinetestingpointai2Service;
-//    @Resource
-//    private IAdapterService adpClient;
-//    @Resource
-//    private GyeeConfig config;
-//    @Resource
-//    private PolynomialCurveFitting pncf;
-//
-//    public void getDatas2File(String stationid, long start, long end) {
-//
-//        int daym = 24 * 60 * 60 * 1000;
-//
-//        //按天
-//        for (long i = start; i < end; i += daym) {
-//
-//            List<List<PhotovoltaicInfo>> datas = getDatas(stationid, i, i + daym);
-//            infos2File(datas);
-//
-//        }
-//
-//    }
-//
-//    private void infos2File(List<List<PhotovoltaicInfo>> datas) {
-//
-//        //文件第一行
-//        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
-//        String columnName = fixedVos.stream().map(FixedVo::getDes).collect(Collectors.joining(","));
-//        //遍历逆变器
-//        for (List<PhotovoltaicInfo> data : datas) {
-//            PhotovoltaicInfo info = data.get(0);
-//            String station = info.getStation();
-//            String fileName = config.getFilePathPrepare() + "gf\\" + station + "-" + info.getInverter() + "-" + DateUtils.date2StringS(new Date(info.getTime())) + ".csv";
-//            File file = new File(fileName);
-//            if (file.exists()) continue;
-//            StringBuilder sb = new StringBuilder();
-//            sb.append(columnName).append("\n");
-//            for (PhotovoltaicInfo datum : data) {
-//                sb.append(datum.getStation()).append(",").append(datum.getInverter()).append(",").append(DateUtils.date2StringL(new Date(datum.getTime())))
-//                        .append(",").append(datum.getT()).append(",").append(datum.getS()).append(",").append(datum.getI()).append(",").append(datum.getV())
-//                        .append(",").append(datum.getActualP()).append(",").append(datum.getAI()).append(",").append(datum.getAV()).append(",")
-//                        .append(datum.getBI()).append(",").append(datum.getBV()).append(",").append(datum.getCI()).append(",").append(datum.getCV())
-//                        .append("\n");
-//            }
-//            FileUtil.writeFile(fileName, sb.toString());
-//        }
-//    }
-//
-//    public List<String> getFileList(String station, List<String> nbq, long startdate, long enddate, boolean isOffline) {
-//        List<String> fileList = new ArrayList<>();
-//        //获取文件位置
-//        File file = new File(config.getFilePathPrepare() + "gf");
-//        //获取文件列表
-//        File[] files = file.listFiles();
-//        //如果文件不够,返回null
-//        for (long i = startdate; i < enddate; i += 24 * 60 * 60 * 1000) {
-//            int size = fileList.size();
-//            String s = DateUtils.date2StringS(new Date(i));
-//            for (File f : files) {
-//                if (f.getName().contains(station) && f.getName().contains(s) && jiancha(f.getName(), nbq))
-//                    fileList.add(f.getName());
-//            }
-//            if (fileList.size() == size && !isOffline) return null;
-//        }
-//        return fileList;
-//    }
-//
-//    private boolean jiancha(String name, List<String> nbq) {
-//        for (String s : nbq) {
-//            if (name.contains(s)) return true;
-//        }
-//        return false;
-//    }
-//
-//    public Map<String, Object> getTable(String s) {
-//        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
-//        List<TableTitle> collect = fixedVos.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList());
-//        Map<String, Object> tableMap = new HashMap<>();
-//        String fs = config.getFilePathPrepare() + "gf\\" + s;
-//        List<PhotovoltaicInfo> infos = file2Info(fs, false);
-//        tableMap.put("data", infos);
-//        tableMap.put("title", collect);
-//        return tableMap;
-//    }
-//
-//    private List<PhotovoltaicInfo> file2Info(String path, boolean isAll) {
-//        List<String> strings = FileUtil.readFile(path, isAll);
-//        List<PhotovoltaicInfo> infos = new ArrayList<>();
-//        for (int i = 1; i < strings.size(); i++) {
-//            String[] split = strings.get(i).split(",");
-//            PhotovoltaicInfo info = new PhotovoltaicInfo();
-//            try {
-//                info.setStation(split[0]);
-//                info.setInverter(split[1]);
-//                if (!"".equals(split[2])) {
-//                    info.setTime(DateUtils.string2DateL(split[2]).getTime());
-//                    info.setDatetime(split[2]);
-//                }
-//                info.setT(StringUtils.isBlank(split[3]) ? 0 : Double.parseDouble(split[3]));
-//                info.setS(StringUtils.isBlank(split[4]) ? 0 : Double.parseDouble(split[4]));
-//                info.setI(StringUtils.isBlank(split[5]) ? 0 : Double.parseDouble(split[5]));
-//                info.setV(StringUtils.isBlank(split[6]) ? 0 : Double.parseDouble(split[6]));
-//                info.setActualP(StringUtils.isBlank(split[7]) ? 0 : Double.parseDouble(split[7]));
-//                info.setAI(StringUtils.isBlank(split[8]) ? 0 : Double.parseDouble(split[8]));
-//                info.setAV(StringUtils.isBlank(split[9]) ? 0 : Double.parseDouble(split[9]));
-//                info.setBI(StringUtils.isBlank(split[10]) ? 0 : Double.parseDouble(split[10]));
-//                info.setBV(StringUtils.isBlank(split[11]) ? 0 : Double.parseDouble(split[11]));
-//                info.setCI(StringUtils.isBlank(split[12]) ? 0 : Double.parseDouble(split[12]));
-//                info.setCV(StringUtils.isBlank(split[13]) ? 0 : Double.parseDouble(split[13]));
-//            } catch (Exception e) {
-//                System.out.println();
-//            }
-//
-//            infos.add(info);
-//        }
-//        return infos;
-//    }
-//
-//    /**
-//     * 计算理论功率加入原列表
-//     *
-//     * @return
-//     */
-//    public Map<String, List<PhotovoltaicInfo>> calculatAnalysis(List<String> fileList) {
-//
-//        String bzcldPath = config.getFilePathPrepare() + "bzd\\标准点.csv";
-//        List<PhotovoltaicInfo> bzclds = file2Info(bzcldPath, true);
-//        Map<String, PhotovoltaicInfo> bzcldMap = bzclds.stream().collect(Collectors.toMap(PhotovoltaicInfo::getInverter, Function.identity()));
-//
-//        String fs = config.getFilePathPrepare() + "gf\\";
-//        Map<String, List<PhotovoltaicInfo>> stringListMap = new HashMap<>();
-//        for (String s : fileList) {
-//            //读取一个文件
-//            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
-//            List<PhotovoltaicInfo> theoryInfos;
-//            if (s.contains("HZJ_GDC") || s.contains("AK_GDC")) {
-//                theoryInfos = CurrentVoltageCalc.CalcTheoryPowerHZJ(infos, bzcldMap);
-//            } else {
-//                theoryInfos = CurrentVoltageCalc.CalcTheoryPower(infos, bzcldMap);
-//            }
-//            //按逆变器聚合数据
-//            if (stringListMap.containsKey(theoryInfos.get(0).getInverter())) {
-//                stringListMap.get(theoryInfos.get(0).getInverter()).addAll(theoryInfos);
-//            } else {
-//                stringListMap.put(theoryInfos.get(0).getInverter(), theoryInfos);
-//            }
-//        }
-//        return stringListMap;
-//    }
-//
-//    /**
-//     * 合并同逆变器文件
-//     *
-//     * @param fileList
-//     * @return
-//     */
-//    public Map<String, List<PhotovoltaicInfo>> mergeCalculat(List<String> fileList) {
-//
-//        String fs = config.getFilePathPrepare() + "gf\\";
-//        Map<String, List<PhotovoltaicInfo>> stringListMap = new HashMap<>();
-//        for (String s : fileList) {
-//            //读取一个文件
-//            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
-//            //按逆变器聚合数据
-//            if (stringListMap.containsKey(infos.get(0).getInverter())) {
-//                stringListMap.get(infos.get(0).getInverter()).addAll(infos);
-//            } else {
-//                stringListMap.put(infos.get(0).getInverter(), infos);
-//            }
-//        }
-//        return stringListMap;
-//    }
-//
-//    public List<Object> str2FileList(List<String> fileList) {
-//        List<Powerfittinganalysis> fileLists = new ArrayList<>();
-//        for (String s : fileList) {
-//            String[] split = s.split("-");
-//            Powerfittinganalysis fl = new Powerfittinganalysis();
-//            /*fl.setPath(s);
-//            fl.setStation(split[0]);
-//            fl.setStationcn(InitialRunner.gfstationMap.get(split[0]));
-//            fl.setWindturbine(split[1]);
-//            fl.setTime(split[2]+"年"+split[3]+"月");
-//            fl.setInterval("五分钟");*/
-//            fl.setPath(s);
-//            fl.setStation(split[0]);
-//            fl.setStationcn(split[1]);
-//            fl.setWindturbine(split[1]);
-//            fl.setTime(InitialRunner.gfstationMap.get(split[0]));
-//            fl.setInterval(split[2] + "年" + split[3] + "月");
-//            fileLists.add(fl);
-//        }
-//        List<Object> objects = PowerFittingUtil.powerDataTree(fileLists, Constants.DATA_FITTING);
-//        return objects;
-//    }
-//
-//    public List<String> getAllFileList() {
-//        //获取文件位置
-//        File file = new File(config.getFilePathPrepare() + "gf");
-//        //获取文件列表
-//        File[] files = file.listFiles();
-//        List<String> fileList = Arrays.stream(files).map(f -> f.getName()).collect(Collectors.toList());
-//        return fileList;
-//    }
-//
-//    /**
-//     * 标准点计算
-//     */
-//    public void standardPointCalculate2() {
-//        List<String> allFileList = getAllFileList();
-//        Map<String, List<PhotovoltaicInfo>> stringListMap = mergeCalculat(allFileList);
-//
-//        List<PhotovoltaicInfo> ptInfos = new ArrayList<>();
-//        for (Map.Entry<String, List<PhotovoltaicInfo>> entry : stringListMap.entrySet()) {
-//            List<PhotovoltaicInfo> value = entry.getValue();
-//            Optional<PhotovoltaicInfo> first = value.stream().sorted(Comparator.comparing(PhotovoltaicInfo::getActualP).reversed()).findFirst();
-//            ptInfos.add(first.get());
-//        }
-//
-//        //文件第一行
-//        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
-//        StringBuilder sb = new StringBuilder();
-//        String columnName = fixedVos.stream().map(FixedVo::getDes).collect(Collectors.joining(","));
-//        sb.append(columnName).append("\n");
-//        for (PhotovoltaicInfo ptInfo : ptInfos) {
-//            sb.append(ptInfo.getStation()).append(",").append(ptInfo.getInverter()).append(",")
-//                    .append(DateUtils.date2StringL(new Date(ptInfo.getTime()))).append(",")
-//                    .append(ptInfo.getT()).append(",").append(ptInfo.getS()).append(",")
-//                    .append(ptInfo.getI()).append(",").append(ptInfo.getV())
-//                    .append(",").append(ptInfo.getActualP()).append(",")
-//                    .append(ptInfo.getAI()).append(",").append(ptInfo.getAV())
-//                    .append(",").append(ptInfo.getBI()).append(",").append(ptInfo.getBV())
-//                    .append(",").append(ptInfo.getCI()).append(",").append(ptInfo.getCV())
-//                    .append("\n");
-//        }
-//        String fileName = config.getFilePathPrepare() + "bzd\\标准点.csv";
-//        File file = new File(fileName);
-//        file.delete();
-//        FileUtil.writeFile(fileName, sb.toString());
-//
-//    }
-//
-//    public List<TableTitle> getTheoryTitel() {
-//
-//        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
-//        String[] ss = {"station", "datetime", "T", "S", "actualP"};
-//        List<String> strings = Arrays.asList(ss);
-//        List<TableTitle> collect = fixedVos.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList());
-//        collect = collect.stream().filter(c -> strings.contains(c.getKey())).collect(Collectors.toList());
-//        TableTitle title = new TableTitle();
-//        title.setKey("ideaP");
-//        title.setDes("理论功率");
-//        collect.add(title);
-//
-//        return collect;
-//    }
-//
-//    /**
-//     * 获得所有文件的值
-//     *
-//     * @param fileList
-//     * @return
-//     */
-//    public List<PhotovoltaicInfo> calculatFitting(List<String> fileList) {
-//
-//        String fs = config.getFilePathPrepare() + "gf\\";
-//        List<PhotovoltaicInfo> infoList = new ArrayList<>();
-//        for (String s : fileList) {
-//            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
-//            if (infoList.size() == 0 || Objects.equals(infos.get(0).getStation(), infoList.get(0).getStation())) {
-//                infoList.addAll(infos);
-//            }
-//        }
-//
-//        return infoList;
-//    }
-//
-//    public List<double[]> oneFileFitting(List<PhotovoltaicInfo> infos) {
-//
-//        WeightedObservedPoints points = new WeightedObservedPoints();
-//        double max = 0;
-//        for (PhotovoltaicInfo info : infos) {
-//            if (info.getS() < 1) {
-//                points.add(0, 0);
-//            }
-//            points.add(info.getS(), info.getActualP());
-//            if (info.getS() > max) {
-//                max = info.getS();
-//            }
-//        }
-//        double[] result = pncf.run(points);
-//
-//        List<double[]> b = new ArrayList<>();
-//        for (int i = 0; i < max; i += 5) {
-//            double[] curve = new double[2];
-//            curve[0] = i;
-//            curve[1] = pncf.calcPoly(i, result);
-//            b.add(curve);
-//        }
-//        return b;
-//    }
-//
-//    /**
-//     * 光伏绩效榜
-//     *
-//     * @param startdate
-//     * @param enddate
-//     */
-//    public List<FjjxbVo> getPhotovoltaicPerformanceList(long startdate, long enddate) {
-//        int oneday = 24 * 60 * 60;
-//
-//        String bzcldPath = config.getFilePathPrepare() + "bzd\\标准点.csv";
-//        List<PhotovoltaicInfo> bzclds = file2Info(bzcldPath, true);
-//        Map<String, PhotovoltaicInfo> bzcldMap = bzclds.stream().collect(Collectors.toMap(PhotovoltaicInfo::getInverter, Function.identity()));
-//
-//        //获取实际发电量
-//        List<Windpowerstationtestingpoint2> rfdl = windpowerstationtestingpoint2Service.getPoints(null, "RFDL");
-//        List<FjjxbVo> infos = new ArrayList<>();
-//        //遍历逆变器
-//        for (Windpowerstationtestingpoint2 wstp : rfdl) {
-//            //场站
-//            String stationid = wstp.getWindpowerstationid();
-//
-//            List<TsDoubleData> history = adpClient.getHistorySnap(wstp.getCode(), startdate + oneday * 1000, enddate, oneday);
-//            double d = 0;
-//            for (TsDoubleData data : history) {
-//                d += data.getDoubleValue();
-//            }
-//            FjjxbVo vo = new FjjxbVo();
-//            vo.setName(InitialRunner.gfstationMap.get(stationid));
-//            vo.setSjfdl(d);
-//
-//            //理论发电量
-//            double llfdl = 0;
-//            //光照平均值
-//            double gz = 0;
-//            int i = 0;
-//            double t = 5 / 60;
-//
-//            List<List<PhotovoltaicInfo>> datas = getDatas(stationid, startdate, enddate);
-//            //遍历逆变器
-//            for (List<PhotovoltaicInfo> data : datas) {
-//
-//                if ("HZJ_GDC".equals(stationid) || "AK_GDC".equals(stationid)) {
-//                    CurrentVoltageCalc.CalcTheoryPowerHZJ(data, bzcldMap);
-//                } else {
-//                    CurrentVoltageCalc.CalcTheoryPower(data, bzcldMap);
-//                }
-//
-//                for (PhotovoltaicInfo datum : data) {
-//                    llfdl += datum.getIdeaP() * t;
-//                    gz += datum.getS();
-//                    i++;
-//                }
-//            }
-//            vo.setLlfdl(llfdl);
-//            vo.setSpeed(gz / i);
-//            vo.setFnlly(vo.getSjfdl() / vo.getLlfdl() * 100);
-//            infos.add(vo);
-//        }
-//        return infos;
-//    }
-//
-//    /**
-//     * 获取数据
-//     *
-//     * @return 逆变器,列表
-//     */
-//    public List<List<PhotovoltaicInfo>> getDatas(String stationid, long start, long end) {
-//
-//        //间隔
-//        int interval = 5 * 60;
-//        //获得测点
-//        Map<String, String> zglpoints = getPoints(stationid, "zgl");
-//        Map<String, String> adypoints = getPoints(stationid, "ady");
-//        Map<String, String> bdypoints = getPoints(stationid, "bdy");
-//        Map<String, String> cdypoints = getPoints(stationid, "cdy");
-//        Map<String, String> adlpoints = getPoints(stationid, "adl");
-//        Map<String, String> bdlpoints = getPoints(stationid, "bdl");
-//        Map<String, String> cdlpoints = getPoints(stationid, "cdl");
-//        Windpowerstationtestingpoint2 zfsPoint = InitialRunner.zfsMap.get(stationid);
-//        Windpowerstationtestingpoint2 zjwdPoint = InitialRunner.zjwdMap.get(stationid);
-//
-//        //总辐射
-//        List<TsDoubleData> zfsDatas = adpClient.getHistorySnap(zfsPoint.getCode(), start, end, interval);
-//        //组件温度
-//        List<TsDoubleData> zjwdDatas = adpClient.getHistorySnap(zjwdPoint.getCode(), start, end, interval);
-//
-//        List<List<PhotovoltaicInfo>> infosLit = new ArrayList<>();
-//        //按逆变器
-//        for (String wtid : zglpoints.keySet()) {
-//
-//            //总功率
-//            List<TsDoubleData> zglDatas = adpClient.getHistorySnap(zglpoints.get(wtid), start, end, interval);
-//
-//            //电网A相电压
-//            List<TsDoubleData> adyDatas = adpClient.getHistorySnap(adypoints.get(wtid), start, end, interval);
-//            //电网A相电流
-//            List<TsDoubleData> adlDatas = adpClient.getHistorySnap(adlpoints.get(wtid), start, end, interval);
-//
-//            List<PhotovoltaicInfo> infos = new ArrayList<>();
-//
-//            List<TsDoubleData> bdyDatas = null, cdyDatas = null, bdlDatas = null, cdlDatas = null;
-//            if ("HZJ_GDC".equals(stationid) || "AK_GDC".equals(stationid)) {
-//                //电网B相电压
-//                bdyDatas = adpClient.getHistorySnap(bdypoints.get(wtid), start, end, interval);
-//                //电网C相电压
-//                cdyDatas = adpClient.getHistorySnap(cdypoints.get(wtid), start, end, interval);
-//                //电网B相电流
-//                bdlDatas = adpClient.getHistorySnap(bdlpoints.get(wtid), start, end, interval);
-//                //电网C相电流
-//                cdlDatas = adpClient.getHistorySnap(cdlpoints.get(wtid), start, end, interval);
-//            }
-//
-//            for (int j = 0; j < zfsDatas.size(); j++) {
-//                PhotovoltaicInfo info = new PhotovoltaicInfo();
-//                info.setStation(stationid);
-//                info.setInverter(wtid);
-//                long ts = zfsDatas.get(j).getTs();
-//                info.setTime(ts);
-//                info.setDatetime(DateUtils.date2StringL(new Date(ts)));
-//
-//                info.setT(double3Decimal(zjwdDatas.get(j).getDoubleValue()));
-//                info.setS(double3Decimal(zfsDatas.get(j).getDoubleValue(), false));
-//                if ("HZJ_GDC".equals(stationid) || "AK_GDC".equals(stationid)) {
-//                    info.setAI(double3Decimal(adlDatas.get(j).getDoubleValue(), false));
-//                    info.setBI(double3Decimal(bdlDatas.get(j).getDoubleValue(), false));
-//                    info.setCI(double3Decimal(cdlDatas.get(j).getDoubleValue(), false));
-//                    info.setAV(double3Decimal(adyDatas.get(j).getDoubleValue(), true));
-//                    info.setBV(double3Decimal(bdyDatas.get(j).getDoubleValue(), true));
-//                    info.setCV(double3Decimal(cdyDatas.get(j).getDoubleValue(), true));
-//                } else {
-//                    info.setI(double3Decimal(adlDatas.get(j).getDoubleValue(), false));
-//                    info.setV(double3Decimal(adyDatas.get(j).getDoubleValue(), true));
-//                }
-//                info.setActualP(double3Decimal(zglDatas.get(j).getDoubleValue(), false));
-//                infos.add(info);
-//            }
-//            infosLit.add(infos);
-//        }
-//
-//        return infosLit;
-//    }
-//
-//    private double double3Decimal(double d) {
-//        BigDecimal bd = new BigDecimal(d);
-//        return bd.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
-//    }
-//
-//    private double double3Decimal(double d, boolean isMultFactor) {
-//        d = d < 1 ? 0 : d;
-//        if (isMultFactor) {
-//            d = d * 0.001;
-//        }
-//        return double3Decimal(d);
-//    }
-//
-//    /**
-//     * 获得测点
-//     * 逆变器,测点
-//     */
-//    private Map<String, String> getPoints(String stationid, String key) {
-//
-//        switch (key) {
-//            case "zgl":
-//                //总功率
-//                return InitialRunner.zglMap.get(stationid).stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//            case "ady":
-//                List<Windturbinetestingpointai2> adyPoints = null;
-//                if ("HZJ_GDC".equals(stationid)) {
-//                    //电网A相电压
-//                    adyPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG063");
-//                } else {
-//                    //电网A相电压
-//                    adyPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG061");
-//                }
-//                return adyPoints.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//            case "bdy":
-//                List<Windturbinetestingpointai2> bdyPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG061A");
-//                return bdyPoints.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//            case "cdy":
-//                List<Windturbinetestingpointai2> cdyPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG065");
-//                return cdyPoints.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//            case "adl":
-//                List<Windturbinetestingpointai2> adlPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG060");
-//                return adlPoints.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//            case "bdl":
-//                List<Windturbinetestingpointai2> bdlPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG062");
-//                return bdlPoints.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//            case "cdl":
-//                List<Windturbinetestingpointai2> cdlPoints = windturbinetestingpointai2Service.getPoints(stationid, null, "AIG064");
-//                return cdlPoints.stream().collect(Collectors.toMap(Windturbinetestingpointai2::getWindturbineid, Windturbinetestingpointai2::getCode));
-//        }
-//        return new HashMap<>();
-//    }
-//
-//    public int deleteFiles(List<String> fileList) {
-//        String fs = config.getFilePathPrepare() + "gf\\";
-//        List<PhotovoltaicInfo> infoList = new ArrayList<>();
-//        int count = 0;
-//        for (String s : fileList) {
-//            File file = new File(fs + s);
-//            if (file.delete()) count++;
-//        }
-//        return count;
-//    }
-//
-//    public void downFiles(List<String> strings, HttpServletResponse response) {
-//        List<File> files = path2File(strings);
-//        String path = config.getFilePathPrepare() + "zip\\" + System.currentTimeMillis() + ".zip";
-//        String s = FileUtil.zipFiles(files, new File(path));
-//        FileUtil.download(s, response);
-//    }
-//
-//    private List<File> path2File(List<String> strings) {
-//        List<File> files = new ArrayList<>();
-//        for (String string : strings) {
-//            files.add(new File(config.getFilePathPrepare() + "gf\\" + string));
-//        }
-//        return files;
-//    }
-//}
+package com.gyee.power.fitting.service.impl;
+
+import com.gyee.power.fitting.common.alg.CurrentVoltageCalc;
+import com.gyee.power.fitting.common.alg.PolynomialCurveFitting;
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.common.constants.Constants;
+import com.gyee.power.fitting.common.feign.IAdapterService;
+import com.gyee.power.fitting.common.feign.RemoteServiceBuilder;
+import com.gyee.power.fitting.common.spring.InitialRunner;
+import com.gyee.power.fitting.common.util.DateUtils;
+import com.gyee.power.fitting.common.util.FileUtil;
+import com.gyee.power.fitting.common.util.PowerFittingUtil;
+import com.gyee.power.fitting.model.*;
+import com.gyee.power.fitting.model.anno.AnnotationTool;
+import com.gyee.power.fitting.model.anno.FixedVo;
+import com.gyee.power.fitting.model.custom.FjjxbVo;
+import com.gyee.power.fitting.model.custom.PhotovoltaicInfo;
+import com.gyee.power.fitting.model.custom.TableTitle;
+import com.gyee.power.fitting.model.custom.TsDoubleData;
+import com.gyee.power.fitting.service.IWindpowerstationtestingpoint2Service;
+import com.gyee.power.fitting.service.ProBasicEquipmentPointService;
+import com.gyee.power.fitting.service.ProBasicPowerstationPointService;
+import com.gyee.power.fitting.service.Windturbinetestingpointai2Service;
+import com.gyee.power.fitting.service.custom.curve.DataScangfService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.math3.fitting.WeightedObservedPoints;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+public class IvPvCurveFittingService {
+
+    @Resource
+    private IWindpowerstationtestingpoint2Service windpowerstationtestingpoint2Service;
+    @Resource
+    private Windturbinetestingpointai2Service windturbinetestingpointai2Service;
+
+    @Resource
+    private ProBasicWeatherStationServiceImpl weatherStationService;
+
+    @Resource
+    private ProBasicEquipmentPointService proBasicEquipmentPointService;
+
+    @Resource
+    private ProBasicPowerstationPointService proBasicPowerstationPointService;
+    @Resource
+    private IAdapterService adpClient;
+
+    @Autowired
+    private RemoteServiceBuilder remoteService;
+
+    @Resource
+    private GyeeConfig config;
+    @Resource
+    private PolynomialCurveFitting pncf;
+
+    private List<FixedVo> fixedVos;
+    private Map<String, String> uniforcodes;
+
+    @Resource
+    private DataScangfService dataScangfService;
+
+    public void getDatas2File(String stationid, long start, long end, int interval) {
+
+        int daym = 24 * 60 * 60 * 1000;
+
+        //按天
+        for (long i = start; i < end; i += daym) {
+
+            List<List<PhotovoltaicInfo>> datas = getDatas(stationid, i, i + daym, interval);
+            infos2File(datas);
+        }
+    }
+
+    public Map<String, List<PhotovoltaicInfo>> getDatas2File1(String stationid, long start, long end, int interval) {
+
+        int daym = 24 * 60 * 60 * 1000;
+        Map<String, List<PhotovoltaicInfo>> wj = new HashMap<>();
+        //按天
+        for (long i = start; i < end; i += daym) {
+
+            List<List<PhotovoltaicInfo>> datas = getDatas(stationid, i, i + daym, interval);
+            for (List<PhotovoltaicInfo> data : datas) {
+                List<PhotovoltaicInfo> infos = wj.get(data.get(0).getInverter());
+                if (infos == null) {
+                    wj.put(data.get(0).getInverter(), data);
+                } else {
+                    infos.addAll(data);
+                }
+            }
+        }
+        return wj;
+    }
+
+    private void infos2File(List<List<PhotovoltaicInfo>> datas) {
+
+        //文件第一行
+        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
+        String columnName = fixedVos.stream().map(FixedVo::getDes).collect(Collectors.joining(","));
+        //遍历逆变器
+        for (List<PhotovoltaicInfo> data : datas) {
+            PhotovoltaicInfo info = data.get(0);
+            String station = info.getStation();
+            String fileName = config.getFilePathPrepare() + "gf" + File.separator + "一秒" + File.separator + station + "-" + info.getInverter() + "-" + DateUtils.date2StringS(new Date(info.getTime())) + ".csv";
+            File file = new File(fileName);
+            if (file.exists()) continue;
+            StringBuilder sb = new StringBuilder();
+            sb.append(columnName).append("\n");
+            for (PhotovoltaicInfo datum : data) {
+                sb.append(datum.getStation()).append(",").append(datum.getInverter()).append(",").append(DateUtils.date2StringL(new Date(datum.getTime())))
+                        .append(",").append(datum.getT()).append(",").append(datum.getS()).append(",").append(datum.getI()).append(",").append(datum.getV())
+                        .append(",").append(datum.getActualP()).append(",").append(datum.getAI()).append(",").append(datum.getAV()).append(",")
+                        .append(datum.getBI()).append(",").append(datum.getBV()).append(",").append(datum.getCI()).append(",").append(datum.getCV())
+                        .append("\n");
+            }
+            FileUtil.writeFile(fileName, sb.toString());
+        }
+    }
+
+    public List<String> getFileList(String station, List<String> nbq, long startdate, int interval, long enddate, boolean isOffline) {
+        List<String> fileList = new ArrayList<>();
+        File file = null;
+        //获取文件位置
+        if (interval == 1) {
+            file = new File(config.getFilePathPrepare() + "gf" + File.separator + "一秒" + File.separator);
+        } else if (interval == 1) {
+            file = new File(config.getFilePathPrepare() + "gf" + File.separator + "一秒" + File.separator);
+        }
+        //获取文件列表
+        File[] files = file.listFiles();
+        //如果文件不够,返回null
+        for (long i = startdate; i < enddate; i += 24 * 60 * 60 * 1000) {
+            int size = fileList.size();
+            String s = DateUtils.date2StringS(new Date(i));
+            for (File f : files) {
+                if (f.getName().contains(station) && f.getName().contains(s) && jiancha(f.getName(), nbq))
+                    fileList.add(f.getName());
+            }
+            if (fileList.size() == size && !isOffline) return null;
+        }
+        return fileList;
+    }
+
+    private boolean jiancha(String name, List<String> nbq) {
+        for (String s : nbq) {
+            if (name.contains(s)) return true;
+        }
+        return false;
+    }
+
+    public Map<String, Object> getTable(String s) {
+        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
+        List<TableTitle> collect = fixedVos.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList());
+        Map<String, Object> tableMap = new HashMap<>();
+        String fs = config.getFilePathPrepare() + "gf" + File.separator + s;
+        List<PhotovoltaicInfo> infos = file2Info(fs, false);
+        tableMap.put("data", infos);
+        tableMap.put("title", collect);
+        return tableMap;
+    }
+
+    private List<PhotovoltaicInfo> file2Info(String path, boolean isAll) {
+        List<String> strings = FileUtil.readFile(path, isAll);
+        List<PhotovoltaicInfo> infos = new ArrayList<>();
+        for (int i = 1; i < strings.size(); i++) {
+            String[] split = strings.get(i).split(",");
+            PhotovoltaicInfo info = new PhotovoltaicInfo();
+            try {
+                info.setStation(split[0]);
+                info.setInverter(split[1]);
+                if (!"".equals(split[2])) {
+                    info.setTime(DateUtils.string2DateL(split[2]).getTime());
+                    info.setDatetime(split[2]);
+                }
+                info.setT(StringUtils.isBlank(split[3]) ? 0 : Double.parseDouble(split[3]));
+                info.setS(StringUtils.isBlank(split[4]) ? 0 : Double.parseDouble(split[4]));
+                info.setI(StringUtils.isBlank(split[5]) ? 0 : Double.parseDouble(split[5]));
+                info.setV(StringUtils.isBlank(split[6]) ? 0 : Double.parseDouble(split[6]));
+                info.setActualP(StringUtils.isBlank(split[7]) ? 0 : Double.parseDouble(split[7]));
+                info.setAI(StringUtils.isBlank(split[8]) ? 0 : Double.parseDouble(split[8]));
+                info.setAV(StringUtils.isBlank(split[9]) ? 0 : Double.parseDouble(split[9]));
+                info.setBI(StringUtils.isBlank(split[10]) ? 0 : Double.parseDouble(split[10]));
+                info.setBV(StringUtils.isBlank(split[11]) ? 0 : Double.parseDouble(split[11]));
+                info.setCI(StringUtils.isBlank(split[12]) ? 0 : Double.parseDouble(split[12]));
+                info.setCV(StringUtils.isBlank(split[13]) ? 0 : Double.parseDouble(split[13]));
+            } catch (Exception e) {
+                System.out.println();
+            }
+
+            infos.add(info);
+        }
+        return infos;
+    }
+
+    /**
+     * 计算理论功率加入原列表
+     *
+     * @return
+     */
+    public Map<String, List<PhotovoltaicInfo>> calculatAnalysis(List<String> fileList) {
+
+        String bzcldPath = config.getFilePathPrepare() + "bzd" + File.separator + "标准点.csv";
+        List<PhotovoltaicInfo> bzclds = file2Info(bzcldPath, true);
+        Map<String, PhotovoltaicInfo> bzcldMap = bzclds.stream().collect(Collectors.toMap(PhotovoltaicInfo::getInverter, Function.identity()));
+
+        String fs = config.getFilePathPrepare() + "gf" + File.separator;
+        Map<String, List<PhotovoltaicInfo>> stringListMap = new HashMap<>();
+        for (String s : fileList) {
+            //读取一个文件
+            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
+            List<PhotovoltaicInfo> theoryInfos;
+            if (s.contains("HZJ_GDC") || s.contains("AK_GDC")) {
+                theoryInfos = CurrentVoltageCalc.CalcTheoryPowerHZJ(infos, bzcldMap);
+            } else {
+                theoryInfos = CurrentVoltageCalc.CalcTheoryPower(infos, bzcldMap);
+            }
+            //按逆变器聚合数据
+            if (stringListMap.containsKey(theoryInfos.get(0).getInverter())) {
+                stringListMap.get(theoryInfos.get(0).getInverter()).addAll(theoryInfos);
+
+            } else {
+                stringListMap.put(theoryInfos.get(0).getInverter(), theoryInfos);
+            }
+        }
+        return stringListMap;
+    }
+
+    /**
+     * 计算理论功率加入原列表
+     *
+     * @return
+     */
+    public Map<String, List<PhotovoltaicInfo>> calculatAnalysis1(List<PhotovoltaicInfo> bzdList, Map<String, List<PhotovoltaicInfo>> datasInfos) {
+
+        Map<String, PhotovoltaicInfo> bzcldMap = bzdList.stream().collect(Collectors.toMap(PhotovoltaicInfo::getInverter, Function.identity()));
+
+        Map<String, List<PhotovoltaicInfo>> stringListMap = new HashMap<>();
+
+        String s;
+        for (Map.Entry<String, List<PhotovoltaicInfo>> entry : datasInfos.entrySet()) {
+            s = entry.getKey();
+            List<PhotovoltaicInfo> theoryInfos;
+            if (s.contains("HZJ_GDC") || s.contains("AK_GDC")) {
+                theoryInfos = CurrentVoltageCalc.CalcTheoryPowerHZJ(entry.getValue(), bzcldMap);
+            } else {
+                theoryInfos = CurrentVoltageCalc.CalcTheoryPower(entry.getValue(), bzcldMap);
+            }
+            stringListMap.put(s, theoryInfos);
+        }
+        return stringListMap;
+    }
+
+    //    public Map<String, List<PhotovoltaicInfo>> calculatAnalysis1(List<List<List<PhotovoltaicInfo>>> feill) {
+    //
+    //        String bzcldPath = config.getFilePathPrepare() + "bzd"+File.separator + "标准点.csv";
+    //        List<PhotovoltaicInfo> bzclds = file2Info(bzcldPath, true);
+    //        Map<String, PhotovoltaicInfo> bzcldMap = bzclds.stream().collect(Collectors.toMap(PhotovoltaicInfo::getInverter, Function.identity()));
+    //
+    //        String fs = config.getFilePathPrepare() + "gf" +File.separator;
+    //        Map<String, List<PhotovoltaicInfo>> stringListMap = new HashMap<>();
+    //        for (String s : fileList) {
+    //            //读取一个文件
+    //            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
+    //            List<PhotovoltaicInfo> theoryInfos;
+    //            if (s.contains("HZJ_GDC") || s.contains("AK_GDC")) {
+    //                theoryInfos = CurrentVoltageCalc.CalcTheoryPowerHZJ(infos, bzcldMap);
+    //            } else {
+    //                theoryInfos = CurrentVoltageCalc.CalcTheoryPower(infos, bzcldMap);
+    //            }
+    //            //按逆变器聚合数据
+    //            if (stringListMap.containsKey(theoryInfos.get(0).getInverter())) {
+    //                stringListMap.get(theoryInfos.get(0).getInverter()).addAll(theoryInfos);
+    //
+    //            } else {
+    //                stringListMap.put(theoryInfos.get(0).getInverter(), theoryInfos);
+    //            }
+    //        }
+    //        return stringListMap;
+    //    }
+
+    /**
+     * 合并同逆变器文件
+     *
+     * @param fileList
+     * @return
+     */
+    public Map<String, List<PhotovoltaicInfo>> mergeCalculat(List<String> fileList) {
+
+        String fs = config.getFilePathPrepare() + "gf" + File.separator;
+        Map<String, List<PhotovoltaicInfo>> stringListMap = new HashMap<>();
+        for (String s : fileList) {
+            //读取一个文件
+            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
+            //按逆变器聚合数据
+            if (stringListMap.containsKey(infos.get(0).getInverter())) {
+                stringListMap.get(infos.get(0).getInverter()).addAll(infos);
+            } else {
+                stringListMap.put(infos.get(0).getInverter(), infos);
+            }
+        }
+        return stringListMap;
+    }
+
+    public List<Object> str2FileList(List<String> fileList) {
+        List<ProEconPowerFittingAnalySis> fileLists = new ArrayList<>();
+        for (String s : fileList) {
+            String[] split = s.split("-");
+            ProEconPowerFittingAnalySis fl = new ProEconPowerFittingAnalySis();
+            /*fl.setPath(s);
+            fl.setStation(split[0]);
+            fl.setStationcn(InitialRunner.gfstationMap.get(split[0]));
+            fl.setWindturbine(split[1]);
+            fl.setTime(split[2]+"年"+split[3]+"月");
+            fl.setInterval("五分钟");*/
+            fl.setPath(s);
+            fl.setStation(split[0]);
+            fl.setStationcn(split[1]);
+            //fl.setWindturbine(split[1]);
+            fl.setTime(InitialRunner.newgfstationMap.get(split[0]));
+            fl.setInterval(split[2] + "年" + split[3] + "月");
+            fileLists.add(fl);
+        }
+        List<Object> objects = PowerFittingUtil.powerDataTree(fileLists, Constants.DATA_FITTING);
+        return objects;
+    }
+
+    public List<String> getAllFileList() {
+        //获取文件位置
+        File file = new File(config.getFilePathPrepare() + "gf" + "一秒");
+        //获取文件列表
+        File[] files = file.listFiles();
+        List<String> fileList = Arrays.stream(files).map(f -> f.getName()).collect(Collectors.toList());
+        return fileList;
+    }
+
+    /**
+     * 标准点计算
+     */
+    public void standardPointCalculate2() {
+        List<String> allFileList = getAllFileList();
+        Map<String, List<PhotovoltaicInfo>> stringListMap = mergeCalculat(allFileList);
+
+        List<PhotovoltaicInfo> ptInfos = new ArrayList<>();
+        for (Map.Entry<String, List<PhotovoltaicInfo>> entry : stringListMap.entrySet()) {
+            List<PhotovoltaicInfo> value = entry.getValue();
+            Optional<PhotovoltaicInfo> first = value.stream().sorted(Comparator.comparing(PhotovoltaicInfo::getActualP).reversed()).findFirst();
+            ptInfos.add(first.get());
+        }
+
+        //文件第一行
+        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
+        StringBuilder sb = new StringBuilder();
+        String columnName = fixedVos.stream().map(FixedVo::getDes).collect(Collectors.joining(","));
+        sb.append(columnName).append("\n");
+        for (PhotovoltaicInfo ptInfo : ptInfos) {
+            sb.append(ptInfo.getStation()).append(",").append(ptInfo.getInverter()).append(",")
+                    .append(DateUtils.date2StringL(new Date(ptInfo.getTime()))).append(",")
+                    .append(ptInfo.getT()).append(",").append(ptInfo.getS()).append(",")
+                    .append(ptInfo.getI()).append(",").append(ptInfo.getV())
+                    .append(",").append(ptInfo.getActualP()).append(",")
+                    .append(ptInfo.getAI()).append(",").append(ptInfo.getAV())
+                    .append(",").append(ptInfo.getBI()).append(",").append(ptInfo.getBV())
+                    .append(",").append(ptInfo.getCI()).append(",").append(ptInfo.getCV())
+                    .append("\n");
+        }
+        String fileName = config.getFilePathPrepare() + "bzd" + File.separator + "标准点.csv";
+        File file = new File(fileName);
+        file.delete();
+        FileUtil.writeFile(fileName, sb.toString());
+
+    }
+
+    /**
+     * 标准点计算
+     *
+     * @param stringListMap
+     */
+    public List<PhotovoltaicInfo> standardPointCalculate1(Map<String, List<PhotovoltaicInfo>> stringListMap) {
+
+        List<PhotovoltaicInfo> ptInfos = new ArrayList<>();
+        for (Map.Entry<String, List<PhotovoltaicInfo>> entry : stringListMap.entrySet()) {
+            List<PhotovoltaicInfo> value = entry.getValue();
+            Optional<PhotovoltaicInfo> first = value.stream().sorted(Comparator.comparing(PhotovoltaicInfo::getActualP).reversed()).findFirst();
+            ptInfos.add(first.get());
+        }
+        return ptInfos;
+    }
+
+    public List<TableTitle> getTheoryTitel() {
+
+        List<FixedVo> fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
+        String[] ss = {"station", "datetime", "T", "S", "actualP"};
+        List<String> strings = Arrays.asList(ss);
+        List<TableTitle> collect = fixedVos.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList());
+        collect = collect.stream().filter(c -> strings.contains(c.getKey())).collect(Collectors.toList());
+        TableTitle title = new TableTitle();
+        title.setKey("ideaP");
+        title.setDes("理论功率");
+        collect.add(title);
+
+        return collect;
+    }
+
+    /**
+     * 获得所有文件的值
+     *
+     * @param fileList
+     * @return
+     */
+    public List<PhotovoltaicInfo> calculatFitting(List<String> fileList) {
+
+        String fs = config.getFilePathPrepare() + "gf" + File.separator;
+        List<PhotovoltaicInfo> infoList = new ArrayList<>();
+        for (String s : fileList) {
+            List<PhotovoltaicInfo> infos = file2Info(fs + s, true);
+            if (infoList.size() == 0 || Objects.equals(infos.get(0).getStation(), infoList.get(0).getStation())) {
+                infoList.addAll(infos);
+            }
+        }
+
+        return infoList;
+    }
+
+    public List<double[]> oneFileFitting(List<PhotovoltaicInfo> infos) {
+
+        WeightedObservedPoints points = new WeightedObservedPoints();
+        double max = 0;
+        for (PhotovoltaicInfo info : infos) {
+            if (info.getS() < 1) {
+                points.add(0, 0);
+            }
+            points.add(info.getS(), info.getActualP());
+            if (info.getS() > max) {
+                max = info.getS();
+            }
+        }
+        double[] result = pncf.run(points);
+
+        List<double[]> b = new ArrayList<>();
+        for (int i = 0; i < max; i += 5) {
+            double[] curve = new double[2];
+            curve[0] = i;
+            curve[1] = pncf.calcPoly(i, result);
+            b.add(curve);
+        }
+        return b;
+    }
+
+    /**
+     * 光伏绩效榜
+     *
+     * @param startdate
+     * @param enddate
+     */
+    public List<FjjxbVo> getPhotovoltaicPerformanceList(long startdate, long enddate, int interval) {
+        int oneday = 24 * 60 * 60;
+
+        String bzcldPath = config.getFilePathPrepare() + "bzd" + File.separator + "标准点.csv";
+        List<PhotovoltaicInfo> bzclds = file2Info(bzcldPath, true);
+        Map<String, PhotovoltaicInfo> bzcldMap = bzclds.stream().collect(Collectors.toMap(PhotovoltaicInfo::getInverter, Function.identity()));
+
+        //获取实际发电量
+        List<ProBasicPowerstationPoint> rfdl = proBasicPowerstationPointService.getzfsPoints(null, "RFDL");
+        List<FjjxbVo> infos = new ArrayList<>();
+        //遍历逆变器
+        for (ProBasicPowerstationPoint wstp : rfdl) {
+            //场站
+            String stationid = wstp.getWindpowerstationId();
+
+            List<TsDoubleData> history = remoteService.adapterfd().getHistorySnap(wstp.getNemCode(), startdate + oneday * 1000, enddate, oneday);
+            double d = 0;
+            for (TsDoubleData data : history) {
+                d += data.getDoubleValue();
+            }
+            FjjxbVo vo = new FjjxbVo();
+            vo.setName(InitialRunner.newgfstationMap.get(stationid));
+            vo.setSjfdl(d);
+
+            //理论发电量
+            double llfdl = 0;
+            //光照平均值
+            double gz = 0;
+            int i = 0;
+            double t = 5 / 60;
+
+            List<List<PhotovoltaicInfo>> datas = getDatas(stationid, startdate, enddate, interval);
+            //遍历逆变器
+            for (List<PhotovoltaicInfo> data : datas) {
+
+                if ("HZJ_GDC".equals(stationid) || "AK_GDC".equals(stationid)) {
+                    CurrentVoltageCalc.CalcTheoryPowerHZJ(data, bzcldMap);
+                } else {
+                    CurrentVoltageCalc.CalcTheoryPower(data, bzcldMap);
+                }
+
+                for (PhotovoltaicInfo datum : data) {
+                    llfdl += datum.getIdeaP() * t;
+                    gz += datum.getS();
+                    i++;
+                }
+            }
+            vo.setLlfdl(llfdl);
+            vo.setSpeed(gz / i);
+            vo.setFnlly(vo.getSjfdl() / vo.getLlfdl() * 100);
+            infos.add(vo);
+        }
+        return infos;
+    }
+
+    /**
+     * 获取数据
+     *
+     * @return 逆变器,列表
+     */
+    public List<List<PhotovoltaicInfo>> getDatas(String stationid, long start, long end, int interval) {
+        //间隔
+        interval = 5 * 60; //5分钟-300
+
+        //获得测点
+        Map<String, String> zglpoints = getPoints(stationid, "zgl");
+        Map<String, String> llglpoints = getPoints(stationid, "llgl");
+        Map<String, String> adypoints = getPoints(stationid, "ady");
+        Map<String, String> bdypoints = getPoints(stationid, "bdy");
+        Map<String, String> cdypoints = getPoints(stationid, "cdy");
+        Map<String, String> adlpoints = getPoints(stationid, "adl");
+        Map<String, String> bdlpoints = getPoints(stationid, "bdl");
+        Map<String, String> cdlpoints = getPoints(stationid, "cdl");
+
+        List<ProBasicWeatherStation> weatherStations = weatherStationService.getBaseMapper().selectList(null);
+        List<ProBasicWeatherStation> collect = weatherStations.stream().filter(c -> stationid.equals(c.getWindpowerstationId())).collect(Collectors.toList());
+
+        String station = collect.get(0).getId();
+
+        ProBasicPowerstationPoint zfsPoint = InitialRunner.newzfsMap.get(stationid);
+        ProBasicPowerstationPoint zjwdPoint = InitialRunner.newzjwdMap.get(station);
+
+        //总辐射
+        //        List<TsDoubleData> zfsDatas = adpClient.getHistorySnap(zfsPoint.getNemCode(), start, end, interval);
+
+        List<TsDoubleData> zfsDatas = remoteService.adapterfd().getHistorySnap(zfsPoint.getNemCode(), start, end, interval);
+
+        //组件温度
+        //        List<TsDoubleData> zjwdDatas = adpClient.getHistorySnap(zjwdPoint.getNemCode(), start, end, interval);
+
+        List<TsDoubleData> zjwdDatas = remoteService.adaptergf().getHistorySnap(zjwdPoint.getNemCode(), start, end, interval);
+
+        List<List<PhotovoltaicInfo>> infosLit = new ArrayList<>();
+        //按逆变器
+        for (String wtid : zglpoints.keySet()) {
+
+            //总功率
+            //            List<TsDoubleData> zglDatas = adpClient.getHistorySnap(zglpoints.get(wtid), start, end, interval);
+            List<TsDoubleData> zglDatas = remoteService.adaptergf().getHistorySnap(zglpoints.get(wtid), start, end, interval);
+            List<TsDoubleData> llglDatas = remoteService.adapterfd().getHistorySnap(llglpoints.get(wtid), start, end, interval);
+
+            //电网A相电压
+            //            List<TsDoubleData> adyDatas = adpClient.getHistorySnap(adypoints.get(wtid), start, end, interval);
+            List<TsDoubleData> adyDatas = remoteService.adaptergf().getHistorySnap(adypoints.get(wtid), start, end, interval);
+            //电网A相电流
+            //            List<TsDoubleData> adlDatas = adpClient.getHistorySnap(adlpoints.get(wtid), start, end, interval);
+            List<TsDoubleData> adlDatas = remoteService.adaptergf().getHistorySnap(adlpoints.get(wtid), start, end, interval);
+
+            List<PhotovoltaicInfo> infos = new ArrayList<>();
+
+            List<TsDoubleData> bdyDatas = null, cdyDatas = null, bdlDatas = null, cdlDatas = null;
+            if ("HZJ_GDC".equals(stationid) || "AK_GDC".equals(stationid)) {
+                //电网B相电压
+                bdyDatas = adpClient.getHistorySnap(bdypoints.get(wtid), start, end, interval);
+                //电网C相电压
+                cdyDatas = adpClient.getHistorySnap(cdypoints.get(wtid), start, end, interval);
+                //电网B相电流
+                bdlDatas = adpClient.getHistorySnap(bdlpoints.get(wtid), start, end, interval);
+                //电网C相电流
+                cdlDatas = adpClient.getHistorySnap(cdlpoints.get(wtid), start, end, interval);
+            }
+
+            for (int j = 0; j < zfsDatas.size(); j++) {
+                PhotovoltaicInfo info = new PhotovoltaicInfo();
+                info.setStation(stationid);
+                info.setInverter(wtid);
+                long ts = zfsDatas.get(j).getTs();
+                info.setTime(ts);
+                info.setDatetime(DateUtils.date2StringL(new Date(ts)));
+
+                info.setT(double3Decimal(zjwdDatas.get(j).getDoubleValue()));
+                info.setS(double3Decimal(zfsDatas.get(j).getDoubleValue(), false));
+                if ("HZJ_GDC".equals(stationid) || "AK_GDC".equals(stationid)) {
+                    info.setAI(double3Decimal(adlDatas.get(j).getDoubleValue(), false));
+                    info.setBI(double3Decimal(bdlDatas.get(j).getDoubleValue(), false));
+                    info.setCI(double3Decimal(cdlDatas.get(j).getDoubleValue(), false));
+                    info.setAV(double3Decimal(adyDatas.get(j).getDoubleValue(), true));
+                    info.setBV(double3Decimal(bdyDatas.get(j).getDoubleValue(), true));
+                    info.setCV(double3Decimal(cdyDatas.get(j).getDoubleValue(), true));
+                } else {
+                    if (adlDatas.size() >= 1) {
+                        info.setI(double3Decimal(adlDatas.get(j).getDoubleValue(), false));
+                    } else {
+                        info.setI(0);
+                    }
+                    if (adyDatas.size() >= 1) {
+                        info.setV(double3Decimal(adyDatas.get(j).getDoubleValue(), true));
+                    } else {
+                        info.setV(0);
+                    }
+                }
+                if (zglDatas.size() >= 1) {
+                    info.setActualP(double3Decimal(zglDatas.get(j).getDoubleValue(), false));
+                } else {
+                    info.setActualP(0);
+                }
+                if (llglDatas.size() >= 1) {
+                    info.setIdeaP(double3Decimal(llglDatas.get(j).getDoubleValue(), false));
+                } else {
+                    info.setIdeaP(0);
+                }
+                infos.add(info);
+            }
+            infosLit.add(infos);
+        }
+
+        return infosLit;
+    }
+
+    private double double3Decimal(double d) {
+        BigDecimal bd = new BigDecimal(d);
+        return bd.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    private double double3Decimal(double d, boolean isMultFactor) {
+        d = d < 1 ? 0 : d;
+        if (isMultFactor) {
+            d = d * 0.001;
+        }
+        return double3Decimal(d);
+    }
+
+    /**
+     * 获得测点
+     * 逆变器,测点
+     */
+    private Map<String, String> getPoints(String stationid, String key) {
+
+        switch (key) {
+            case "zgl":
+                //总功率
+                return InitialRunner.newzglMap.get(stationid).stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+            case "llgl":
+                //总功率
+                return InitialRunner.newllglMap.get(stationid).stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+
+            case "ady":
+                List<ProBasicEquipmentPoint> adyPoints = null;
+                if ("HZJ_GDC".equals(stationid)) {
+                    //电网A相电压
+                    adyPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG005");
+                } else {
+                    //电网A相电压
+                    adyPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG005");
+                }
+
+                return adyPoints.stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+            case "bdy":
+                List<ProBasicEquipmentPoint> bdyPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG008");
+                return bdyPoints.stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+            case "cdy":
+                List<ProBasicEquipmentPoint> cdyPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG011");
+                return cdyPoints.stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+            case "adl":
+                List<ProBasicEquipmentPoint> adlPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG004");
+                return adlPoints.stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+            case "bdl":
+                List<ProBasicEquipmentPoint> bdlPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG007");
+                return bdlPoints.stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+            case "cdl":
+                List<ProBasicEquipmentPoint> cdlPoints = proBasicEquipmentPointService.getPoints(stationid, null, "AIG010");
+                return cdlPoints.stream().filter(c -> !c.getNemCode().equals("INTIAL")).collect(Collectors.toMap(ProBasicEquipmentPoint::getWindturbineId, ProBasicEquipmentPoint::getNemCode));
+        }
+        return new HashMap<>();
+    }
+
+    public int deleteFiles(List<String> fileList) {
+        String fs = config.getFilePathPrepare() + "gf";
+        List<PhotovoltaicInfo> infoList = new ArrayList<>();
+        int count = 0;
+        for (String s : fileList) {
+            File file = new File(fs + s);
+            if (file.delete()) count++;
+        }
+        return count;
+    }
+
+    public void downFiles(List<String> strings, HttpServletResponse response) {
+        List<File> files = path2File(strings);
+        String path = config.getFilePathPrepare() + "zip\\" + System.currentTimeMillis() + ".zip";
+        String s = FileUtil.zipFiles(files, new File(path));
+        FileUtil.download(s, response);
+    }
+
+    private List<File> path2File(List<String> strings) {
+        List<File> files = new ArrayList<>();
+        for (String string : strings) {
+            files.add(new File(config.getFilePathPrepare() + "gf" + string));
+        }
+        return files;
+    }
+
+    public List<FixedVo> getFixedVos() {
+        if (fixedVos == null) {
+            fixedVos = AnnotationTool.getFixedVoList(PhotovoltaicInfo.class);
+            uniforcodes = fixedVos.stream().filter(fv -> fv.getUniformCode() != null).collect(Collectors.toMap(FixedVo::getDes, FixedVo::getUniformCode));
+        }
+        return fixedVos;
+    }
+
+    public Map<String, String> getUniforcodes() {
+        getFixedVos();
+        return uniforcodes;
+    }
+
+
+    public List<ProBasicEquipment> wtByWplist(String wpids) {
+        List<ProBasicEquipment> equipmentList = InitialRunner.newgfwtList.stream()
+                .filter(oe -> wpids.contains(oe.getWindpowerstationId()))
+                .sorted(Comparator.comparingInt(ProBasicEquipment::getOrderNum)) // 根据order_num字段排序
+                .collect(Collectors.toList());
+
+        return equipmentList;
+    }
+
+    /**
+     * 通过大点的key获取小散点
+     *
+     * @param yk
+     * @param wk
+     * @return
+     */
+    public List<PhotovoltaicInfo> dataOrigin(String yk, String wk) {
+        List<PhotovoltaicInfo> list = new ArrayList<>();
+
+        if (!StringUtils.isEmpty(yk)) {
+            String[] key = yk.split(",");
+            for (String k : key) {
+                list.addAll(dataScangfService.getMapYY().get(k));
+            }
+        }
+        if (!StringUtils.isEmpty(wk)) {
+            String[] kew = wk.split(",");
+            for (String k : kew) {
+                list.addAll(dataScangfService.getMapWY().get(k));
+            }
+        }
+
+        return list;
+    }
+}