全业务考评 1 vuosi sitten
vanhempi
commit
c194b9e6c7
19 muutettua tiedostoa jossa 914 lisäystä ja 42 poistoa
  1. 10 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/GyeeConfig.java
  2. 16 2
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/InitialRunner.java
  3. 32 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/FileUtil.java
  4. 60 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/agc/AgcDeviateController.java
  5. 64 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/agc/PowerPredictionController.java
  6. 21 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/newfj/ProEconPowerWindInfoController.java
  7. 11 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/AgcDeviateMapper.java
  8. 16 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/ProEconPowerWindInfoMapper.java
  9. 92 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/AgcDeviateModel.java
  10. 42 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/ProEconPowerWindInfo.java
  11. 6 32
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AgcDeviateConfig.java
  12. 9 2
      power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerPointData.java
  13. 30 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/service/ProEconPowerWindInfoService.java
  14. 245 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/agc/AgcDeviateService.java
  15. 109 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/agc/FileService.java
  16. 58 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/agc/PowerPredictionService.java
  17. 7 6
      power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/windresource/AvgSpeedInfoService.java
  18. 66 0
      power-fitting-JN/src/main/java/com.gyee.power.fitting/service/impl/ProEconPowerWindInfoServiceImpl.java
  19. 20 0
      power-fitting-JN/src/main/resources/mapper/ProEconPowerWindInfoMapper.xml

+ 10 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/config/GyeeConfig.java

@@ -36,6 +36,8 @@ public class GyeeConfig {
     private String filePathProcess;
     /** 数据拟合保存路径(拟合后的数据) **/
     private String filePathFitting;
+    /** 配置文件路径 **/
+    private String filePathPower;
     /** 数据压缩下载 **/
     private String filePathDownload;
     /** 功率曲线拟合测点 **/
@@ -91,4 +93,12 @@ public class GyeeConfig {
 
         return codes;
     }
+
+    public String getFilePathPower() {
+        return jarF.getParentFile().getAbsolutePath() + File.separator + filePathPower;
+    }
+
+    public void setFilePathPower(String filePathPower) {
+        this.filePathPower = filePathPower;
+    }
 }

+ 16 - 2
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/spring/InitialRunner.java

@@ -1,14 +1,16 @@
 package com.gyee.power.fitting.common.spring;
 
+import com.alibaba.fastjson.JSON;
 import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.common.util.FileUtil;
 import com.gyee.power.fitting.model.*;
+import com.gyee.power.fitting.model.agc.AgcDeviateConfig;
 import com.gyee.power.fitting.service.*;
 import com.gyee.power.fitting.service.impl.NewIvPvCurveFittingService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.core.annotation.Order;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -116,6 +118,7 @@ public class InitialRunner implements CommandLineRunner {
     /** key: NG01_01, speed, power**/
     public static Map<String, Map<Double, Double>> zsllglMap = new HashMap<>();
 
+    public static Map<String, AgcDeviateConfig> powerPreMap = new HashMap<>();
 
 
 
@@ -332,6 +335,7 @@ public class InitialRunner implements CommandLineRunner {
     public void cacheNewStation() {
         List<ProBasicPowerstation> stations = proBasicPowerstationService.list();
         wpNewList = stations.stream().filter(f -> f.getId().contains("FDC")).collect(Collectors.toList());
+        gfwpNewList = stations.stream().filter(f -> f.getId().contains("GDC")).collect(Collectors.toList());
         wpNewList.forEach(obj -> {
             List<ProBasicEquipment> wts =proBasicEquipmentService.list().stream().filter(w -> w.getWindpowerstationId().equals(obj.getId())).collect(Collectors.toList());;
             stationNewMap.put(obj.getId(), obj.getName());
@@ -443,6 +447,16 @@ public class InitialRunner implements CommandLineRunner {
     }
 
 
-
+    /**
+     * 功率预测相关测点
+     */
+    private void cacheFGL(){
+        String str = FileUtil.getStringFromFile(config.getFilePathPower() + "fgl_info.json");
+        AgcDeviateConfig[] object = JSON.parseObject(str, AgcDeviateConfig[].class);
+        for (AgcDeviateConfig conf : object){
+            powerPreMap.put(conf.getId(), conf);
+        }
+        log.info("自功率预测相关测点数据缓存完成");
+    }
 
 }

+ 32 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/common/util/FileUtil.java

@@ -253,4 +253,36 @@ public class FileUtil {
         return zipFile.getAbsolutePath();
     }
 
+    /**
+     * 从文件中获取字符串
+     *
+     * @param path 路径
+     * @return 字符串
+     */
+    public static String getStringFromFile(String path) {
+        BufferedReader bufferedReader = null;
+        File file = new File(path);
+        if (!file.exists()) {
+            return "";
+        }
+        try {
+            bufferedReader = new BufferedReader(new FileReader(file));
+            StringBuilder sb = new StringBuilder();
+            String s = null;
+            while ((s = bufferedReader.readLine()) != null) {
+                sb.append(s);
+            }
+            return sb.toString();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                assert bufferedReader != null;
+                bufferedReader.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return "";
+    }
 }

+ 60 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/agc/AgcDeviateController.java

@@ -0,0 +1,60 @@
+package com.gyee.power.fitting.controller.agc;
+
+import com.gyee.power.fitting.common.config.GyeeConfig;
+import com.gyee.power.fitting.model.agc.AgcDeviateTag;
+import com.gyee.power.fitting.service.custom.agc.AgcDeviateService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+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;
+import java.util.stream.Collectors;
+
+/**
+ * 获取各个场站AGC偏差分析数据
+ */
+@RestController
+@RequestMapping("/agc")
+public class AgcDeviateController {
+    @Resource
+    private AgcDeviateService agcDeviateService;
+    @Resource
+    private GyeeConfig gyeeConfig;
+
+    /**
+     * 获取偏差信息
+     *
+     * @param startTs  开始时间
+     * @param endTs    结束时间
+     * @param id       场站id
+     * @param interval 时间间隔
+     * @return
+     */
+    @GetMapping("/deviate")
+    public Map<String, AgcDeviateTag> getData(@RequestParam(value = "startTs") long startTs,
+                                              @RequestParam(value = "endTs") long endTs,
+                                              @RequestParam(value = "id") String id,
+                                              @RequestParam(value = "interval", defaultValue = "60", required = false) int interval) {
+        List<AgcDeviateTag> ls = new ArrayList<>();
+        if (gyeeConfig.isOffLine()) {
+            ls = agcDeviateService.getAgcDeviateTagsOffline(id, startTs, endTs, interval);
+        } else {
+            ls = agcDeviateService.getAgcDeviateTags(id, startTs, endTs, interval);
+        }
+        return ls.stream().collect(Collectors.toMap(AgcDeviateTag::getName, f -> f));
+    }
+
+    /**
+     * 获取配置
+     *
+     * @return
+     */
+    @GetMapping("/config")
+    public Object getAgcConifg() {
+        return agcDeviateService.getConfig();
+    }
+}

+ 64 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/agc/PowerPredictionController.java

@@ -0,0 +1,64 @@
+package com.gyee.power.fitting.controller.agc;
+
+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.common.spring.InitialRunner;
+import com.gyee.power.fitting.common.util.DateUtil;
+import com.gyee.power.fitting.service.custom.agc.PowerPredictionService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+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;
+
+/**
+ * @author gyee
+ * 功率预测接口
+ */
+@RestController
+@RequestMapping("/power/prediction")
+public class PowerPredictionController {
+
+    @Resource
+    private PowerPredictionService predictionService;
+
+    /**
+     * 查询调度名称
+     * @returnv
+     */
+    @GetMapping("config")
+    public JSONObject getConfig(){
+        List<Object> list = new ArrayList<>();
+        InitialRunner.powerPreMap.forEach((k, v) -> {
+            Map<String, String> map = new HashMap<>();
+            map.put("id", k);
+            map.put("name", v.getTitle());
+            list.add(map);
+        });
+        return JsonResult.successData(ResultCode.SUCCESS, list);
+    }
+
+
+    /**
+     * 查询功率预测数据及实际功率
+     * @param id   调度id,场站
+     * @param st
+     * @param et
+     * @param interval  功率预测数据默认15分钟一条数据  900s
+     * @return
+     */
+    @GetMapping("data")
+    public JSONObject getPredictionData(String id, String st, String et,
+                                             @RequestParam(value = "interval", defaultValue = "900", required = false) int interval){
+        long startTime = DateUtil.parseStrtoDate(st, DateUtil.DATE_PATTERN).getTime();
+        long endTime = DateUtil.addDays(DateUtil.parseStrtoDate(et, DateUtil.DATE_PATTERN), 1).getTime();
+        Map<String, Object> map = predictionService.getPredictionData(id, startTime, endTime, interval);
+        return JsonResult.successData(ResultCode.SUCCESS, map);
+    }
+}

+ 21 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/controller/newfj/ProEconPowerWindInfoController.java

@@ -0,0 +1,21 @@
+package com.gyee.power.fitting.controller.newfj;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author wang
+ * @since 2023-10-12
+ */
+@RestController
+@RequestMapping("/proEconPowerWindInfo")
+public class ProEconPowerWindInfoController {
+
+}
+

+ 11 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/AgcDeviateMapper.java

@@ -0,0 +1,11 @@
+package com.gyee.power.fitting.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.power.fitting.model.AgcDeviateModel;
+import org.apache.ibatis.annotations.Mapper;
+
+
+@Mapper
+public interface AgcDeviateMapper extends BaseMapper<AgcDeviateModel> {
+
+}

+ 16 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/mapper/ProEconPowerWindInfoMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.power.fitting.mapper;
+
+import com.gyee.power.fitting.model.ProEconPowerWindInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author wang
+ * @since 2023-10-12
+ */
+public interface ProEconPowerWindInfoMapper extends BaseMapper<ProEconPowerWindInfo> {
+
+}

+ 92 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/AgcDeviateModel.java

@@ -0,0 +1,92 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+
+@TableName("controlsettings")
+public class AgcDeviateModel extends Model<AgcDeviateModel> {
+    /**
+     * 唯一ID
+     */
+    @Id
+    @Column(name = "ID")
+    private String id;
+    /**
+     * key
+     */
+    @Column(name = "KEY")
+    private String key;
+    /**
+     * 时间戳
+     */
+    @Column(name = "TIMESTAMP")
+    private Long timestamp;
+    /**
+     * 说明,描述
+     */
+    @Column(name = "DESCRIPTION")
+    private String description;
+    /**
+     * 值
+     */
+    @Column(name = "VALUE")
+    private String value;
+
+    /**
+     * 是否是备份
+     */
+    @Column(name = "BACKUP")
+    private boolean backup;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public boolean getBackup() {
+        return backup;
+    }
+
+    public void setBackup(boolean backup) {
+        this.backup = backup;
+    }
+
+}

+ 42 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/ProEconPowerWindInfo.java

@@ -0,0 +1,42 @@
+package com.gyee.power.fitting.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author wang
+ * @since 2023-10-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("pro_econ_power_wind_info")
+public class ProEconPowerWindInfo extends Model<ProEconPowerWindInfo> {
+
+    private static final long serialVersionUID=1L;
+
+    private String id;
+
+    private String station;
+
+    private String windturbineId;
+
+    private String time;
+
+    private double avgspeed;
+
+    private double mrxs;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 6 - 32
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/agc/AgcDeviateConfig.java

@@ -1,5 +1,8 @@
 package com.gyee.power.fitting.model.agc;
 
+import lombok.Data;
+
+@Data
 public class AgcDeviateConfig {
 
     private String id;
@@ -12,37 +15,8 @@ public class AgcDeviateConfig {
      */
     private String title;
 
-    private AiPoints[] aiPoints;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public float getInstalledCapacity() {
-        return installedCapacity;
-    }
+    private AiPoints power;
 
-    public void setInstalledCapacity(float installedCapacity) {
-        this.installedCapacity = installedCapacity;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public AiPoints[] getAiPoints() {
-        return aiPoints;
-    }
+    private AiPoints[] aiPoints;
 
-    public void setAiPoints(AiPoints[] aiPoints) {
-        this.aiPoints = aiPoints;
-    }
-}
+  }

+ 9 - 2
power-fitting-JN/src/main/java/com.gyee.power.fitting/model/custom/PowerPointData.java

@@ -3,6 +3,8 @@ package com.gyee.power.fitting.model.custom;
 import com.gyee.power.fitting.model.anno.Desc;
 import lombok.Data;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.text.DecimalFormat;
 
 /**
@@ -32,8 +34,13 @@ public class PowerPointData {
             this.yp2 = Double.valueOf(df.format(Double.valueOf(str[12])));
             this.yp3 = Double.valueOf(df.format(Double.valueOf(str[13])));
         }
-        if (isFilter)
-            this.filter = Integer.valueOf(str[str.length - 1]);
+        if (isFilter){
+            BigDecimal bd = new BigDecimal(str[str.length - 1]);
+            bd = bd.setScale(2, RoundingMode.HALF_UP);
+            this.filter =  bd.doubleValue()>0 ? 1 :0;
+        }
+
+
     }
 
     //时间

+ 30 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/ProEconPowerWindInfoService.java

@@ -0,0 +1,30 @@
+package com.gyee.power.fitting.service;
+
+import com.gyee.power.fitting.model.ProEconPowerWindInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author wang
+ * @since 2023-10-12
+ */
+public interface ProEconPowerWindInfoService extends IService<ProEconPowerWindInfo> {
+    /**
+     * 通过风机ID和日期查询
+     * @param wtId
+     * @param dates
+     * @return
+     */
+    List<ProEconPowerWindInfo> selectListByWtIdAndTime(String wtId, List<String> dates);
+
+
+    void insertBatch(List<ProEconPowerWindInfo> list);
+
+    void deleteBatch(String wtId, List<String> dates);
+
+}

+ 245 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/agc/AgcDeviateService.java

@@ -0,0 +1,245 @@
+package com.gyee.power.fitting.service.custom.agc;
+
+import com.alibaba.fastjson.TypeReference;
+import com.gyee.power.fitting.common.feign.IDataAdapter;
+import com.gyee.power.fitting.mapper.AgcDeviateMapper;
+import com.gyee.power.fitting.model.agc.AgcDeviateConfig;
+import com.gyee.power.fitting.model.agc.AgcDeviateTag;
+import com.gyee.power.fitting.model.agc.AiPoints;
+import com.gyee.power.fitting.model.agc.PointData;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 读取数据库配置文件
+ */
+@Order(0)
+@Component
+public class AgcDeviateService {
+
+    /**
+     * 是否是离线版本
+     */
+    private boolean isOffline;
+
+    /**
+     * 离线数据保存路径
+     */
+    private String filePathPower = "data\\power\\";
+    /**
+     * 文件读写
+     */
+    private FileService fileService;
+
+    private Map<String, List<String>> files;
+
+
+    /**
+     * AGC信息缓存
+     */
+    private Map<String, AgcDeviateConfig> agcDeviateConfigMap= null;
+
+    @Resource
+    private IDataAdapter iDataAdapter;
+
+
+//    public AgcDeviateService(AgcDeviateMapper agcDeviateMapper1, FileService fs, Environment env) {
+//        this.agcDeviateMapper = agcDeviateMapper;
+//        fileService = fs;
+//        agcDeviateConfigMap = new HashMap<>();
+//
+//        isOffline = Boolean.TRUE.equals(env.getProperty("gyee.offline", boolean.class));
+//        filePathPower = env.getProperty("gyee.file-path-power");
+//
+//        AgcDeviateConfig[] adcs = null;
+//        if (isOffline) {
+//            adcs = fileService.getFromFile(filePathPower + "agc_info_net.json", AgcDeviateConfig[].class);
+//            initFiles();
+//        } else {
+//            AgcDeviateModel adm = agcDeviateMapper.selectById("agc_info_net");
+//            adcs = JSON.parseObject(adm.getValue(), AgcDeviateConfig[].class);
+//        }
+//        for (AgcDeviateConfig adc : adcs) {
+//            agcDeviateConfigMap.put(adc.getId(), adc);
+//        }
+//    }
+
+    private void initFiles() {
+        files = new HashMap<>();
+        File f = new File(filePathPower);
+        File[] fs = f.listFiles();
+        for (File v : fs) {
+            if (v.isDirectory()) {
+                continue;
+            }
+            String[] nm = v.getName().split(",");
+            if (nm.length < 1) {
+                continue;
+            }
+            String name = nm[0];
+            if (!files.containsKey(name)) {
+                files.put(name, new ArrayList<>());
+            }
+            files.get(name).add(v.getPath());
+        }
+    }
+
+    /**
+     * 获取agc曲线偏差分析需要的数据
+     *
+     * @param id       场站ID
+     * @param startTs  开始时间戳
+     * @param endTs    结束时间戳
+     * @param interval 数据时间间隔
+     * @return 分析数据
+     */
+    public List<AgcDeviateTag> getAgcDeviateTags(String id, long startTs, long endTs, int interval) {
+        List<AgcDeviateTag> ladt = new ArrayList<>();
+        List<AiPoints> laps = getAiPoints(id);
+        if (laps == null) {
+            return ladt;
+        }
+        for (AiPoints ap : laps) {
+            AgcDeviateTag adt = new AgcDeviateTag();
+            adt.setName(ap.getName());
+            List<PointData> lpd = getPointData(ap, startTs, endTs, interval);
+            adt.setValues(lpd);
+            ladt.add(adt);
+        }
+        // 上限下限
+        List<AgcDeviateTag> upperLowerLimits = getUpperLowerLimits(ladt, id);
+        ladt.addAll(upperLowerLimits);
+        return ladt;
+    }
+
+    private List<PointData> getPointData(AiPoints ap, long startTs, long endTs, int interval) {
+        List<PointData> lpds = null;
+        if (ap.getTag().contains(",")) {
+            lpds = getMultiple(ap, startTs, endTs, interval);
+        } else {
+            lpds = iDataAdapter.getSnapValuesByKey(ap.getTag(), startTs, endTs, interval);
+        }
+        if (ap.getMultiplier() != 1) {
+            for (PointData pd : lpds) {
+                pd.setDoubleValue(pd.getDoubleValue() * ap.getMultiplier());
+            }
+        }
+        return lpds;
+    }
+
+    /**
+     * 获取多个标签点数值
+     */
+    private List<PointData> getMultiple(AiPoints ap, long startTs, long endTs, int interval) {
+        String[] tags = ap.getTag().split(",");
+        boolean isFirst = true;
+        List<PointData> lpd = new ArrayList<>();
+        for (String tag : tags) {
+            if (tag.equals("")) {
+                continue;
+            }
+            List<PointData> vals = iDataAdapter.getSnapValuesByKey(tag, startTs, endTs, interval);
+            for (int i = 0; i < vals.size(); ++i) {
+                if (isFirst) {
+                    lpd.addAll(vals);
+                    isFirst = false;
+                    break;
+                } else {
+                    PointData pd = lpd.get(i);
+                    pd.setDoubleValue(vals.get(i).getDoubleValue() + pd.getDoubleValue());
+                }
+            }
+        }
+        return lpd;
+    }
+
+    /**
+     * 获取上限下限
+     */
+    private List<AgcDeviateTag> getUpperLowerLimits(List<AgcDeviateTag> ladt, String id) {
+        // 装机容量
+        double capacity = getCapacity(id);
+        // 偏差
+        double deviation = capacity * 0.03;
+        // 有功设定
+        Optional<AgcDeviateTag> agcLimit = ladt.stream().filter(ad -> ad.getName().equals("有功设定限值")).findFirst();
+
+        List<AgcDeviateTag> la = new ArrayList<>();
+        if (!agcLimit.isPresent()) {
+            return la;
+        }
+        AgcDeviateTag adtUper = new AgcDeviateTag();
+        adtUper.setName("偏差上限");
+        adtUper.setValues(new ArrayList<>());
+        AgcDeviateTag adtLimt = new AgcDeviateTag();
+        adtLimt.setName("偏差下限");
+        adtLimt.setValues(new ArrayList<>());
+
+        for (PointData pd : agcLimit.get().getValues()) {
+            long ts = pd.getTs();
+            PointData pdUper = new PointData();
+            pdUper.setTs(ts);
+            pdUper.setDoubleValue(pd.getDoubleValue() + deviation);
+            PointData pdLimt = new PointData();
+            pdLimt.setTs(ts);
+            pdLimt.setDoubleValue(pd.getDoubleValue() - deviation);
+            adtUper.getValues().add(pdUper);
+            adtLimt.getValues().add(pdLimt);
+        }
+        la.add(adtUper);
+        la.add(adtLimt);
+        return la;
+    }
+
+
+    /**
+     * 根据ID获取agc配置信息
+     *
+     * @param id 场站ID
+     * @return 配置信息
+     */
+    private List<AiPoints> getAiPoints(String id) {
+        if (!agcDeviateConfigMap.containsKey(id)) {
+            return null;
+        }
+        AiPoints[] aiPoints = agcDeviateConfigMap.get(id).getAiPoints();
+        return Arrays.stream(aiPoints).filter(ap -> ap.getName().contains("功") && !ap.getName().contains("预测")).collect(Collectors.toList());
+    }
+
+    private double getCapacity(String id) {
+        if (!agcDeviateConfigMap.containsKey(id)) {
+            return 0;
+        }
+        return agcDeviateConfigMap.get(id).getInstalledCapacity();
+    }
+
+    /**
+     * 获取配置
+     *
+     * @return
+     */
+    public Object getConfig() {
+        return agcDeviateConfigMap;
+    }
+
+    public List<AgcDeviateTag> getAgcDeviateTagsOffline(String id, long startTs, long endTs, int interval) {
+        if (!files.containsKey(id)) {
+            return new ArrayList<>();
+        }
+        List<String> ls = files.get(id);
+
+        if (ls == null) {
+            return new ArrayList<>();
+        }
+
+        int ran = (int) (Math.random() * ls.size());
+        return fileService.getFromFile(ls.get(ran), new TypeReference<List<AgcDeviateTag>>() {
+        });
+    }
+}

+ 109 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/agc/FileService.java

@@ -0,0 +1,109 @@
+package com.gyee.power.fitting.service.custom.agc;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.lang.reflect.Type;
+
+/**
+ * 配置文件读取
+ *
+ * @author xysn
+ */
+@Component
+public class FileService {
+    /**
+     * 从json格式文件中获取对象
+     *
+     * @param path 文件路径
+     * @param type 对象类型
+     * @param <T>  泛型
+     * @return 返回对象
+     */
+    public <T> T getFromFile(String path, Type type) {
+        String str = getStringFormFile(path);
+        return JSON.parseObject(str, type);
+    }
+
+    /**
+     * 从json格式文件中获取对象
+     *
+     * @param path 文件路径
+     * @param type 对象类型
+     * @param <T>  泛型
+     * @return 返回对象
+     */
+    public <T> T getFromFile(String path, TypeReference<T> type) {
+        String str = getStringFormFile(path);
+        return JSON.parseObject(str, type);
+    }
+
+    /**
+     * 从文件中获取字符串
+     *
+     * @param path 路径
+     * @return 字符串
+     */
+    public String getStringFormFile(String path) {
+        BufferedReader bufferedReader = null;
+        File file = new File(path);
+        if (!file.exists()) {
+            return "";
+        }
+        try {
+            bufferedReader = new BufferedReader(new FileReader(file));
+            StringBuilder sb = new StringBuilder();
+            String s = null;
+            while ((s = bufferedReader.readLine()) != null) {
+                sb.append(s);
+            }
+            return sb.toString();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                assert bufferedReader != null;
+                bufferedReader.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 保存对象到文件中
+     *
+     * @param path 文件路径
+     * @param obj  要保存的对象
+     * @return 是否保存成功
+     */
+    public boolean saveObjectToFile(String path, Object obj) {
+        BufferedWriter bufferedWriter = null;
+        try {
+            File file = new File(path);
+            bufferedWriter = new BufferedWriter(new FileWriter(file));
+            String str = "";
+            if (obj instanceof String) {
+                str = obj.toString();
+            } else {
+                str = JSON.toJSONString(obj);
+            }
+            bufferedWriter.write(str);
+            bufferedWriter.flush();
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                assert bufferedWriter != null;
+                bufferedWriter.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return false;
+    }
+}

+ 58 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/agc/PowerPredictionService.java

@@ -0,0 +1,58 @@
+package com.gyee.power.fitting.service.custom.agc;
+
+import com.gyee.power.fitting.common.feign.RemoteServiceBuilder;
+import com.gyee.power.fitting.common.spring.InitialRunner;
+import com.gyee.power.fitting.common.util.DateUtil;
+import com.gyee.power.fitting.model.custom.TsDoubleData;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author gyee
+ */
+@Service
+public class PowerPredictionService {
+
+    @Resource
+    private RemoteServiceBuilder remoteService;
+
+
+    public Map<String, Object> getPredictionData(String id, long st, long et, int interval) {
+        Map<String, Object> result = new HashMap<>();
+
+        //时间
+        List<String> time = new ArrayList<>();
+        //实际功率,等间隔
+        List<Double> sjgl = new ArrayList<>();
+        String sjglPoint = InitialRunner.powerPreMap.get(id).getPower().getTag();
+        List<TsDoubleData> data = remoteService.adapterfd().getHistorySnap(sjglPoint, st, et, interval);
+        for (TsDoubleData ts : data){
+            time.add(DateUtil.format(ts.getTs(), DateUtil.DATE_TIME_PATTERN));
+            sjgl.add(new BigDecimal(ts.getDoubleValue()).setScale(2, BigDecimal.ROUND_FLOOR).doubleValue());
+        }
+
+        //短期功率
+//        List<Double> dqgl = new ArrayList<>();
+//        AiPoints[] aiPoints = InitialRunner.powerPreMap.get(id).getAiPoints();
+//        List<String> fglPoint = Arrays.stream(aiPoints).filter(f -> f.getType() == 1).map(m -> m.getTag()).collect(Collectors.toList());
+//        for (long s = st; s <= et; s += (interval * 1000)){
+//            JSONObject json = remoteService.adapter().getHistorySection(tagNames, s);
+//            for (String point : fglPoint){
+//                double value = json.getJSONObject(point).getDoubleValue("doubleValue");
+//                dqgl.add(new BigDecimal(value).setScale(2, BigDecimal.ROUND_FLOOR).doubleValue());
+//            }
+//        }
+//
+//        result.put("time", time);
+//        result.put("sjgl", sjgl);
+//        result.put("dqyugl", dqgl);
+
+        return result;
+    }
+}

+ 7 - 6
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/custom/windresource/AvgSpeedInfoService.java

@@ -6,8 +6,8 @@ import com.gyee.power.fitting.common.util.DateUtil;
 import com.gyee.power.fitting.common.util.FileUtil;
 import com.gyee.power.fitting.model.*;
 import com.gyee.power.fitting.model.custom.PowerPointData;
-import com.gyee.power.fitting.service.PowerwindinfoService;
 import com.gyee.power.fitting.service.ProEconPowerFittingAnalySisService;
+import com.gyee.power.fitting.service.ProEconPowerWindInfoService;
 import lombok.val;
 import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
@@ -22,8 +22,9 @@ import java.util.stream.Collectors;
 @Service
 public class AvgSpeedInfoService {
 
+
     @Resource
-    private PowerwindinfoService windInfoService;
+    private ProEconPowerWindInfoService windInfoService;
     @Resource
     private ProEconPowerFittingAnalySisService powerService;
 
@@ -40,13 +41,13 @@ public class AvgSpeedInfoService {
 
         for (ProEconPowerFittingAnalySis obj : listObj){
             TreeMap<String, Object> map = new TreeMap<>();
-            List<Powerwindinfo> currentList = new ArrayList<>();
+            List<ProEconPowerWindInfo> currentList = new ArrayList<>();
             List<PowerPointData> ls = csvParse(obj);
             Map<String, List<PowerPointData>> collect = ls.stream().collect(Collectors.groupingBy(PowerPointData::getTime));
             collect.forEach((k, v) -> {
-                Powerwindinfo info = new Powerwindinfo();
+                ProEconPowerWindInfo info = new ProEconPowerWindInfo();
                 info.setStation(obj.getStation());
-                info.setWindturbine(obj.getWindturbineId());
+                info.setWindturbineId(obj.getWindturbineId());
                 info.setTime(DateUtil.format(k, DateUtil.DATE_PATTERN));
                 double speed = v.stream().mapToDouble(PowerPointData::getSpeed).average().getAsDouble();
                 //毛容系数=生产电量(MWh)/ (风机容量MW * 总时间(h))
@@ -62,7 +63,7 @@ public class AvgSpeedInfoService {
 
             //同期数据
             List<String> preDate = dates.stream().map(f -> DateUtil.getLastYearCurrentDate(f, DateUtil.DATE_PATTERN)).collect(Collectors.toList());
-            List<Powerwindinfo> preList = windInfoService.selectListByWtIdAndTime(obj.getWindturbineId(), preDate);
+            List<ProEconPowerWindInfo> preList = windInfoService.selectListByWtIdAndTime(obj.getWindturbineId(), preDate);
 
             map.put("wtId", obj.getWindturbineId());
             map.put("currentData", currentList);

+ 66 - 0
power-fitting-JN/src/main/java/com.gyee.power.fitting/service/impl/ProEconPowerWindInfoServiceImpl.java

@@ -0,0 +1,66 @@
+package com.gyee.power.fitting.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.gyee.power.fitting.common.base.ExcludeQueryWrapper;
+import com.gyee.power.fitting.common.util.CollectUtil;
+import com.gyee.power.fitting.common.util.SnowFlakeUtil;
+import com.gyee.power.fitting.model.ProEconPowerWindInfo;
+import com.gyee.power.fitting.mapper.ProEconPowerWindInfoMapper;
+import com.gyee.power.fitting.service.ProEconPowerWindInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author wang
+ * @since 2023-10-12
+ */
+@Service
+public class ProEconPowerWindInfoServiceImpl extends ServiceImpl<ProEconPowerWindInfoMapper, ProEconPowerWindInfo> implements ProEconPowerWindInfoService {
+
+    @Override
+    public List<ProEconPowerWindInfo> selectListByWtIdAndTime(String wtId, List<String> dates) {
+        ExcludeQueryWrapper<ProEconPowerWindInfo> wrapper = new ExcludeQueryWrapper<>();
+        wrapper.eq("windturbine_id", wtId)
+                .in("time", dates);
+        try{
+            return baseMapper.selectList(wrapper);
+        } catch (Exception e){
+            log.error("PowerwindinfoServiceImpl--selectListByWtIdAndTime", e);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    @Override
+    public void insertBatch(List<ProEconPowerWindInfo> list) {
+        list.forEach(item -> item.setId(SnowFlakeUtil.generateId()));
+        try{
+            if (list.size() > 1000){
+                List<List<ProEconPowerWindInfo>> coll = CollectUtil.groupListByQty(list, 1000);
+                coll.forEach(ls -> saveBatch(ls));
+            } else {
+                saveBatch(list);
+            }
+        }catch (Exception e){
+            log.error("PowerwindinfoServiceImpl--insertBatch", e);
+        }
+    }
+
+    @Override
+    public void deleteBatch(String wtId, List<String> dates) {
+        QueryWrapper<ProEconPowerWindInfo> wrapper = new QueryWrapper<>();
+        wrapper.eq("windturbine_id", wtId);
+        wrapper.in("time", dates);
+        try{
+            baseMapper.delete(wrapper);
+        }catch (Exception e){
+            log.error("PowerwindinfoServiceImpl--deleteBatch", e);
+        }
+    }
+}

+ 20 - 0
power-fitting-JN/src/main/resources/mapper/ProEconPowerWindInfoMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.gyee.power.fitting.mapper.ProEconPowerWindInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.gyee.power.fitting.model.ProEconPowerWindInfo">
+        <id column="id" property="id" />
+        <result column="station" property="station" />
+        <result column="windturbineid" property="windturbineid" />
+        <result column="time" property="time" />
+        <result column="avgspeed" property="avgspeed" />
+        <result column="mrxs" property="mrxs" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, station, windturbineid, time, avgspeed, mrxs
+    </sql>
+
+</mapper>