Selaa lähdekoodia

feat(ucp): 新增限电损失计算功能

- 在 TurbineInfoMin 类中添加 xdfdl 字段,用于存储限电损失
- 修改 calcTurbinePjfsPjglKyglLlglMin 方法,增加限电损失计算逻辑
- 优化风速和功率数据的处理方式,提高计算准确性
-调整状态数据的获取方式,使用 snapData 替代 rawData- 重构 calcRealtimeTurbineXd 方法,增加限电状态判断逻辑
xushili 1 vuosi sitten
vanhempi
commit
5e7f6ac4bc

+ 123 - 57
ruoyi-admin/src/main/java/com/ruoyi/web/controller/JavaFunctionJobHandler.java

@@ -1,10 +1,15 @@
 package com.ruoyi.web.controller;
 
-import cn.hutool.core.collection.*;
-import cn.hutool.core.date.*;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DateRange;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.text.StrBuilder;
 import cn.hutool.core.thread.ThreadUtil;
-import cn.hutool.core.util.*;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ruoyi.quartz.handler.IJobHandler;
@@ -28,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @Service
 public class JavaFunctionJobHandler extends IJobHandler {
@@ -345,44 +351,42 @@ public class JavaFunctionJobHandler extends IJobHandler {
                 Double v = CalcCache.fitcoef.get(tbId).get(fsList.get(i).getValue());
                 if (v == null) v = 0.0;
                 v = v - glList.get(i).getValue();
-                //                double v2 = v > 0 ? v : 0;
-                double v2 = v;
                 switch ((int) collectZt.get(i).getValue()) {
                     //计划检修损失:
                     case 6:
                         //检修
-                        jxss += v2;
+                        jxss += v;
                         break;
                     case 1:
                         //手动停机
-                        sdtj += v2;
+                        sdtj += v;
                         break;
                     //非计划检修损失:
                     case 4:
                         //故障
-                        gzss += v2;
+                        gzss += v;
                         break;
                     case 0:
                         //待机
-                        djss += v2;
+                        djss += v;
                         break;
                     //性能损失:
                     case 2:
                         //性能
-                        xnss += v2;
+                        xnss += v;
                         break;
                     case 3:
                         //发电降出力
-                        fdjcl += v2;
+                        fdjcl += v;
                         break;
                     //限电损失:
                     case 8:
                         //限电降出力
-                        xdjcl += v2;
+                        xdjcl += v;
                         break;
                     case 9:
                         //限电停机
-                        xdtj += v2;
+                        xdtj += v;
                         break;
                 }
             }
@@ -1043,11 +1047,11 @@ public class JavaFunctionJobHandler extends IJobHandler {
             infoDay.setSlss(0.0);
             infoDay.setDjss(loss.get("djss"));
             infoDay.setGzss(loss.get("gzss"));
-            if (infoDay.getRfdl() == 0) {
-                infoDay.setXnss(0.0);
-            } else {
-                infoDay.setXnss(loss.get("xnss"));
-            }
+            //if (infoDay.getRfdl() == 0) {
+            //    infoDay.setXnss(0.0);
+            //} else {
+            //    infoDay.setXnss(loss.get("xnss"));
+            //}
             infoDay.setLlfdl(infoDay.getRfdl() + infoDay.getJhjxss() + infoDay.getFjhjxss() + infoDay.getXdss() + infoDay.getSlss() + infoDay.getXnss());
             infoDays.add(infoDay);
         }));
@@ -1449,11 +1453,11 @@ public class JavaFunctionJobHandler extends IJobHandler {
             infoDay.setSlss(0.0);
             infoDay.setDjss(loss.get("djss"));
             infoDay.setGzss(loss.get("gzss"));
-            if (infoDay.getRfdl() == 0) {
-                infoDay.setXnss(0.0);
-            } else {
-                infoDay.setXnss(loss.get("xnss"));
-            }
+            //if (infoDay.getRfdl() == 0) {
+            //    infoDay.setXnss(0.0);
+            //} else {
+            //    infoDay.setXnss(loss.get("xnss"));
+            //}
             infoDay.setLlfdl(infoDay.getRfdl() + infoDay.getJhjxss() + infoDay.getFjhjxss() +
                     infoDay.getXdss() + infoDay.getSlss() + infoDay.getXnss());
             infoDays.add(infoDay);
@@ -1545,6 +1549,55 @@ public class JavaFunctionJobHandler extends IJobHandler {
         return turbineZt;
     }
 
+    public void calcStationXdTest(Date date, String stId) {
+        DateTime end = DateUtil.beginOfDay(date);
+        DateTime start = DateUtil.offsetDay(end, -1);
+        //AGC
+        List<PointInfo> entityAgc = getEntity("AGC002", "booster");
+        entityAgc = filterPointInfo(entityAgc, stId, PointInfo::getStationId);
+        getSnapDataByEntity(entityAgc, start, end, 15);
+        PointInfo agcInfo = entityAgc.get(0);
+        //出线
+        List<PointInfo> entityCx = getEntity("AGC001", "booster");
+        entityCx = filterPointInfo(entityCx, stId, PointInfo::getStationId);
+        getSnapDataByEntity(entityCx, start, end, 15);
+        PointInfo cxInfo = entityCx.get(0);
+        //状态
+        List<PointInfo> turbineZt = calcTurbineDizt(start, end, 15);
+        turbineZt = filterPointInfo(turbineZt, stId, PointInfo::getStationId);
+        List<PointInfo> turbineAizt = calcTurbineAizt(start, end, 15);
+        turbineAizt = filterPointInfo(turbineAizt, stId, PointInfo::getStationId);
+        turbineZt.addAll(turbineAizt);
+        Map<String, PointInfo> ztMap = turbineZt.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
+        //风速
+        List<PointInfo> entityFs = getEntity("AI066", "turbine");
+        entityFs = filterPointInfo(entityFs, stId, PointInfo::getStationId);
+        Map<String, PointInfo> fsMap = entityFs.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
+        Map<String, List<PointData>> pdsZsglMap = new HashMap<>();
+        ztMap.forEach((wtId, zt) -> {
+            List<PointData> peek = fsMap.get(wtId).getPointDatas().stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(
+                    pd.getValue() > 25 ? 25.0 : pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
+            fsMap.get(wtId).setPointDatas(peek);
+            List<PointData> zsglSnap = fsMap.get(wtId).getPointDatas().stream().map(pd -> {
+                Double v = CalcCache.fitcoef.get(wtId).get(pd.getValue());
+                return new PointData(pd.getTs(), v == null ? 0 : v);
+            }).collect(Collectors.toList());
+            pdsZsglMap.put(wtId, zsglSnap);
+        });
+        //风机风速、功率->场站风速、功率
+        List<PointData> firstZsgl = new ArrayList<>();
+        for (int i = 0; i < agcInfo.getPointDatas().size(); i++) {
+            int finalI = i;
+            long ts = start.getTime() + finalI * 15000L;
+            double v3 = pdsZsglMap.values().stream().mapToDouble(pds -> pds.get(finalI).getValue()).sum();
+            firstZsgl.add(new PointData(ts, v3));
+        }
+        List<PointData> czxd = calcStationXd2(agcInfo, cxInfo.getPointDatas(), firstZsgl);
+        for (PointData pd : czxd) {
+            System.out.println(DateUtil.formatDateTime(new Date(pd.getTs())) + "," + pd.getValue());
+        }
+    }
+
     public List<PointData> calcTurbineSimpleZt(Date start, Date end, Integer interval, String tbId) {
         List<PointInfo> turbineZt = calcTurbineDizt(start, end, interval, tbId);
         List<PointInfo> turbineAizt = calcTurbineAizt(start, end, interval, tbId);
@@ -2140,6 +2193,11 @@ public class JavaFunctionJobHandler extends IJobHandler {
         }
     }
 
+    public Map<String, PointInfo> getSnapDataByEntity(List<PointInfo> entitys, URI uri, Date start, Date end, int interval, Function<PointInfo, String> function) {
+        getSnapDataByEntity(entitys, uri, start, end, interval);
+        return entitys.stream().collect(Collectors.toMap(function, Function.identity()));
+    }
+
     public void getSnapDataByEntity(List<PointInfo> entity, URI uri, Date start, Date end, int interval) {
         for (PointInfo info : entity) {
             getSnapDataByEntity(info, uri, start, end, interval);
@@ -3234,22 +3292,23 @@ public class JavaFunctionJobHandler extends IJobHandler {
                 Map<String, List<PointData>> collectYlzsgd = entityYlzsgd.stream().collect(Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas));
                 String ybj = "GJNY_SXGS_XZ_F_WT_0013_EQ,GJNY_SXGS_XZ_F_WT_0023_EQ,GJNY_SXGS_XZ_F_WT_0027_EQ,GJNY_SXGS_XZ_F_WT_0034_EQ,GJNY_SXGS_XZ_F_WT_0044_EQ,GJNY_SXGS_XZ_F_WT_0060_EQ,GJNY_SXGS_XZ_F_WT_0062_EQ,GJNY_SXGS_FSG_F_WT_0005_EQ,GJNY_SXGS_FSG_F_WT_0006_EQ,GJNY_SXGS_FSG_F_WT_0038_EQ,GJNY_SXGS_FSG_F_WT_0039_EQ,GJNY_SXGS_ZZ_F_WT_0008_EQ,GJNY_SXGS_ZZ_F_WT_0015_EQ,GJNY_SXGS_ZZ_F_WT_0022_EQ,GJNY_SXGS_ZZ_F_WT_0046_EQ,GJNY_SXGS_ZZ_F_WT_0049_EQ,GJNY_SXGS_CSL_F_WT_0003_EQ,GJNY_SXGS_CSL_F_WT_0012_EQ,GJNY_SXGS_CSL_F_WT_0023_EQ,GJNY_SXGS_JSL_F_WT_0002_EQ,GJNY_SXGS_JSL_F_WT_0003_EQ,GJNY_SXGS_JSL_F_WT_0028_EQ,GJNY_SXGS_JSL_F_WT_0047_EQ,GJNY_SXGS_JSL_F_WT_0070_EQ,GJNY_SXGS_JSL_F_WT_0094_EQ,GJNY_SXGS_LJS_F_WT_0002_EQ,GJNY_SXGS_LJS_F_WT_0011_EQ,GJNY_SXGS_LJS_F_WT_0030_EQ,GJNY_SXGS_LJS_F_WT_0033_EQ";
                 ztMap.forEach((wtId, ztInfo) -> {
-                    if(ybj.contains(wtId)) return;
+                    if (ybj.contains(wtId)) return;
                     List<PointData> fss = fsMap.get(wtId).getPointDatas();
                     List<PointData> gls = glMap.get(wtId);
+                    List<PointData> zsgls = pdsZsglMap.get(wtId);
                     //叶轮转速给定
                     List<PointData> ylzsgds = collectYlzsgd.get(wtId);
-                    calcRealtimeTurbineXd(ztInfo, gls.get(0), fss.get(fss.size() - 1), ylzsgds.get(0));
+                    calcRealtimeTurbineXd(ztInfo, gls.get(0), fss.get(fss.size() - 1), ylzsgds.get(0), zsgls.get(zsgls.size() - 1));
                 });
             }
         });
 
         Map<String, String> entityMxzt = getEntityMap("MXZT", "turbine");
-        Map<String, String>  entityQfzt = getEntityMap("SSQFZT", "turbine");
+        Map<String, String> entityQfzt = getEntityMap("SSQFZT", "turbine");
 
-        List<PointData> qfztDataList = entityFs.stream().map(qfzt->{
+        List<PointData> qfztDataList = entityFs.stream().map(qfzt -> {
             String wtId = qfzt.getTurbineId();
-            PointData data = qfzt.getPointDatas().get(qfzt.getPointDatas().size()-1);
+            PointData data = qfzt.getPointDatas().get(qfzt.getPointDatas().size() - 1);
             data.setTs(date.getTime());
             data.setTagName(entityQfzt.get(wtId));
             data.setDoubleValue(calcQfzt(glMap.get(wtId).get(0).getValue(), CalcCache.fitcoef.get(wtId).get(data.getValue())));
@@ -3264,7 +3323,7 @@ public class JavaFunctionJobHandler extends IJobHandler {
             return data;
         }).collect(Collectors.toList());
         if (isOnMin) {
-            List<PointData> czztDatas = xdPdMap.values().stream().peek(pd->pd.setTs(date.getTime())).collect(Collectors.toList());
+            List<PointData> czztDatas = xdPdMap.values().stream().peek(pd -> pd.setTs(date.getTime())).collect(Collectors.toList());
             adapter.writeHistoryBatch(taosUri(), czztDatas);
             adapter.writeHistoryBatch(taosUri(), dataList);
             adapter.writeHistoryBatch(taosUri(), qfztDataList);
@@ -3793,7 +3852,7 @@ public class JavaFunctionJobHandler extends IJobHandler {
         }
     }
 
-    public void calcRealtimeTurbineXd(PointInfo ztInfo, PointData gl, PointData fs, PointData ylzsgd) {
+    public void calcRealtimeTurbineXd(PointInfo ztInfo, PointData gl, PointData fs, PointData ylzsgd, PointData zsgl) {
         Map<String, EquipmentModel> map = equipmentModelService.map();
         Double capacity = map.get(ztInfo.getSpare()).getPowerProduction();
         PointData zt = ztInfo.getPointDatas().get(0);
@@ -3805,6 +3864,9 @@ public class JavaFunctionJobHandler extends IJobHandler {
             if (ylzsgd.getValue() != 0 && ylzsgd.getValue() < 17.3) {//降出力
                 zt.setDoubleValue(8.0);
             }
+            if (calcQfzt(gl.getValue(), zsgl.getValue()) >= 3) {
+                zt.setDoubleValue(8.0);
+            }
         }
     }
 
@@ -4317,17 +4379,20 @@ public class JavaFunctionJobHandler extends IJobHandler {
         return entity.stream().collect(Collectors.toMap(function, Function.identity()));
     }
 
-    public void calcTurbinePjfsPjglKyglLlglMin(Date date, int granularity) {
-        date = DateUtil.beginOfMinute(date);
-        DateTime start = DateUtil.offsetMinute(date, -granularity);
+    public void calcTurbinePjfsPjglKyglLlglMin(Date time) {
+        DateTime date = DateUtil.beginOfMinute(time);
+        int i = Math.floorDiv(date.minute(), 15) * 15;
+        date.setMinutes(i);
+        DateTime start = DateUtil.offsetMinute(date, -15);
         //风速
         List<PointInfo> entityFs = getEntity("AI066", "turbine");
-        Map<String, PointInfo> rawMapFs = getRawDataByEntity(entityFs, goldenUri(), start, date, PointInfo::getTurbineId);
+        Map<String, PointInfo> rawMapFs = getSnapDataByEntity(entityFs, goldenUri(), start, date, 15, PointInfo::getTurbineId);
         //功率
         List<PointInfo> entityGl = getEntity("AI114", "turbine");
-        Map<String, PointInfo> rawMapGl = getRawDataByEntity(entityGl, goldenUri(), start, date, PointInfo::getTurbineId);
+        Map<String, PointInfo> rawMapGl = getSnapDataByEntity(entityGl, goldenUri(), start, date, 15, PointInfo::getTurbineId);
+        //状态
         List<PointInfo> entityZt = getEntity("MXZT", "turbine");
-        Map<String, PointInfo> rawMapZt = getRawDataByEntity(entityZt, goldenUri(), start, date, PointInfo::getTurbineId);
+        Map<String, PointInfo> rawMapZt = getSnapDataByEntity(entityZt, taosUri(), start, date, 15, PointInfo::getTurbineId);
 
         List<TurbineInfoMin> mins = getTurbineinfoByMin(date, entityFs);
         for (TurbineInfoMin min : mins) {
@@ -4336,22 +4401,23 @@ public class JavaFunctionJobHandler extends IJobHandler {
             List<PointData> ztDatas = rawMapZt.get(tbId).getPointDatas();
             ztDatas = doublePointDatasFull(2, ztDatas, start.getTime(), date.getTime(), 1);
             Map<Long, Double> ztMap = ztDatas.stream().collect(Collectors.toMap(PointData::getTs, PointData::getValue));
-            double pjfs = fsDatas.stream().mapToDouble(PointData::getValue).average().orElse(0.0);
-            fsDatas = fsDatas.stream().peek(pd -> pd.setDoubleValue(pd.getValue() >= 23 ? 23 : pd.getValue() < 0 ? 0 : NumberUtil.round(pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
-            for (PointData fsData : fsDatas) {
-                if (fsData.getValue() > 3 && CalcCache.llgl.get(tbId).get(fsData.getValue()) == null) {
-                    System.out.println();
-                }
-            }
-            double llgl = fsDatas.stream().mapToDouble(pd -> pd.getValue() <= 3 ? 0d : CalcCache.llgl.get(tbId).get(pd.getValue())).average().orElse(0.0);
-            double kygl = fsDatas.stream().filter(pd -> ztMap.get(pd.getTs()) != 4 || ztMap.get(pd.getTs()) != 6)
-                    .mapToDouble(pd -> CalcCache.fitcoef.get(tbId).get(pd.getValue())).average().orElse(0.0);
-            double sjgl = rawMapGl.get(tbId).getPointDatas().stream().mapToDouble(PointData::getValue).average().orElse(0.0);
+            double pjfs = fsDatas.stream().mapToDouble(PointData::getValue).average().orElse(0);
+            fsDatas = fsDatas.stream().peek(pd -> pd.setDoubleValue(pd.getValue() >= 23 ? 23.0 : pd.getValue() < 0 ? 0 :
+                    NumberUtil.round(pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
+            double llgl = fsDatas.stream().mapToDouble(pd -> CalcCache.fitcoef.get(tbId).get(pd.getValue())).sum();
+            llgl = llgl / 60;
+            List<PointData> kyFsDatas = fsDatas.stream().filter(pd -> ztMap.get(pd.getTs()) != 4 || ztMap.get(pd.getTs()) != 6).collect(Collectors.toList());
+            double kygl = kyFsDatas.stream().mapToDouble(pd -> CalcCache.fitcoef.get(tbId).get(pd.getValue())).sum();
+            kygl = kygl / 60;
+            List<PointData> xdFsDatas = fsDatas.stream().filter(pd -> ztMap.get(pd.getTs()) == 8).collect(Collectors.toList());
+            double xdfdl = xdFsDatas.stream().mapToDouble(pd -> CalcCache.fitcoef.get(tbId).get(pd.getValue())).sum();
+            xdfdl = xdfdl / 240;
+            double sjgl = rawMapGl.get(tbId).getPointDatas().stream().mapToDouble(PointData::getValue).sum();
+            sjgl = sjgl / 60;
 
-            double v = llgl * 0.9;
-            if (kygl > v) kygl = v;
             if (kygl < sjgl) kygl = sjgl;
             if (llgl < sjgl) llgl = sjgl * 1.0005;
+            min.setXdfdl(xdfdl);
             min.setPjfs(pjfs);
             min.setPjgl(sjgl);
             min.setLlgl(llgl);
@@ -5806,7 +5872,7 @@ public class JavaFunctionJobHandler extends IJobHandler {
             examin2.setDeviceType("station");
             examin2.setTime(hps.get(0).getTime());
             examin2.setSiteId(stId);
-            examin2.setExaminScore(calcQAll(minDqList, hps, capacity,dtlMap));
+            examin2.setExaminScore(calcQAll(minDqList, hps, capacity, dtlMap));
             peList.add(examin2);
         });
         //短期准确率
@@ -5839,7 +5905,7 @@ public class JavaFunctionJobHandler extends IJobHandler {
             examin2.setDeviceType("station");
             examin2.setTime(minsKy.get(0).getRecordDate());
             examin2.setSiteId(stId);
-            calcKydlFilter(examin2,minsKy, capacity, dtlMap);
+            calcKydlFilter(examin2, minsKy, capacity, dtlMap);
             peList.add(examin2);
         });
         predictExamin2Service.saveBatch(peList);
@@ -5872,7 +5938,7 @@ public class JavaFunctionJobHandler extends IJobHandler {
             RealtimePredict predict = rps.get(i);
             List<Double> doubles = dtlMap.get(predict.getTime());
             //限电免考核
-            if(calcXdRate(doubles)>0.5) continue;
+            if (calcXdRate(doubles) > 0.5) continue;
             double Pi_n = predict.getPredictPower();
             double Pi_r = Pi_rs.get(i);
             //免考核
@@ -6001,13 +6067,13 @@ public class JavaFunctionJobHandler extends IJobHandler {
      * 可用电量计算过滤
      */
     public void calcKydlFilter(PredictExamin2 examin2, List<StationInfoMin> mins, double capacity, Map<DateTime, List<Double>> dtlMap) {
-        double actualPower=0, availablePower=0;
+        double actualPower = 0, availablePower = 0;
         for (StationInfoMin min : mins) {
             List<Double> doubles = dtlMap.get(min.getRecordDate());
             //限电
-            if(calcXdRate(doubles)>0.6) continue;
-            actualPower+=min.getKygl()/4;
-            availablePower+=min.getKygl()/4;
+            if (calcXdRate(doubles) > 0.6) continue;
+            actualPower += min.getKygl() / 4;
+            availablePower += min.getKygl() / 4;
         }
         double accuracy = calcKydlAccuracy(actualPower, availablePower, capacity);
         double penalty = calcKydlPenalty(accuracy, capacity);
@@ -6015,7 +6081,7 @@ public class JavaFunctionJobHandler extends IJobHandler {
         double sum = mins.stream().mapToDouble(StationInfoMin::getRfdl).sum();
         double sum1 = mins.stream().mapToDouble(StationInfoMin::getKygl).sum();
         examin2.setAccuracyRate2(sum);
-        examin2.setAccuracyRate3(sum1/4);
+        examin2.setAccuracyRate3(sum1 / 4);
         examin2.setExaminScore(penalty);
     }
 

+ 2 - 0
universal-computing-platform/src/main/java/com/ruoyi/ucp/entity/TurbineInfoMin.java

@@ -46,4 +46,6 @@ public class TurbineInfoMin implements Serializable {
     private Double dqycgl;
 
     private Double cdqycgl;
+
+    private Double xdfdl;
 }