Browse Source

五损状态时间计算--故障算法优化,故障计算速度优化

xushili 1 year ago
parent
commit
b78de2fa68

+ 10 - 0
common/data/src/main/java/com/gyee/gaia/common/data/windturbine/Powerstation.java

@@ -257,6 +257,8 @@ public class Powerstation implements Serializable {
      */
     private Integer stationNumber;
 
+    private String code;
+
     public String getId() {
         return id;
     }
@@ -641,6 +643,14 @@ public class Powerstation implements Serializable {
         this.stationNumber = stationNumber;
     }
 
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
     @Override
     public String toString() {
         return "Powerstation{" +

+ 3 - 0
state/cause/build.gradle

@@ -45,3 +45,6 @@ dependencies {
     implementation("cn.hutool:hutool-all:5.8.18")
 }
 
+test {
+    useJUnitPlatform()
+}

+ 1 - 1
state/cause/src/main/java/com/gyee/gaia/cause/adapter/ShardingApi.java

@@ -18,5 +18,5 @@ public interface ShardingApi {
             @PathVariable(value = "endtime") String endtime,
             @PathVariable(value = "stationid") String stationid,
             @PathVariable(value = "keyword") String keyWord,
-            @PathVariable(value = "messagetype") int messagetype);
+            @PathVariable(value = "messagetype") Integer messagetype);
 }

+ 2 - 0
state/cause/src/main/java/com/gyee/gaia/cause/config/AppConfig.java

@@ -4,6 +4,7 @@ import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;
 
+import java.util.HashMap;
 import java.util.Map;
 
 
@@ -24,6 +25,7 @@ public class AppConfig {
 
     public Map<String, Long> getLongTime() {
         if(longTime==null){
+            longTime = new HashMap<>();
             time.forEach((k,v)->{
                 longTime.put(k, (v * 1000L));
             });

+ 6 - 4
state/cause/src/main/java/com/gyee/gaia/cause/job/CauseJobHandler.java

@@ -19,6 +19,8 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.sql.Timestamp;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -51,15 +53,15 @@ public class CauseJobHandler implements ApplicationRunner {
         QueryWrapper<StateCause> scWrapper = new QueryWrapper<>();
         scWrapper.select("max(end_time)");
         Map<String, Object> map = stateCauseService.getMap(scWrapper);
-        long max=0;
+        Date max;
         if (map != null && map.size()>0) {
-            max = (long)map.get("max");
+            max = (Date)map.get("max");
         }else {
-            max = DateUtil.yesterday().getTime();
+            max = DateUtil.yesterday();
         }
 
         //CalculateService calculateService = new CalculateService();
-        calculateService.refresh(max, System.currentTimeMillis());
+        calculateService.refresh(max.getTime(), System.currentTimeMillis());
         calculateService.calculate();
 
     }

+ 98 - 26
state/cause/src/main/java/com/gyee/gaia/cause/service/CalculateService.java

@@ -36,7 +36,9 @@ public class CalculateService {
      * 设备id,状态点列表
      */
     private final Map<String, List<PointData>> stateDatas=new HashMap<>();
-    Map<Double, String> stateMap;
+    private Map<Double, String> stateMap;
+    private Map<String, List<FaultInfo>> fjGzMap;
+    private Map<String, List<FaultInfo>> syzGzMap;
 
     public void refresh(long starttime, long endtime){
         log.info("刷新测点值!");
@@ -44,7 +46,24 @@ public class CalculateService {
             List<PointData> rawByKey = adapterApi.getRawByKey(v.getCode(), starttime, endtime);
             stateDatas.put(k, rawByKey);
         });
+
         stateMap = CacheContext.stateMap;
+
+        log.info("加载风机故障");
+        String startStr = DateTime.of(starttime - 30 * 60 * 1000).toStringDefaultTimeZone();
+        String endStr = DateTime.of(endtime).toStringDefaultTimeZone();
+        List<FaultInfo> fjGz = shardingApi.getFaultInfoList("FJ", startStr, endStr, null, null, null);
+        fjGzMap = fjGz.stream().collect(Collectors.groupingBy(FaultInfo::getWindturbineId));
+
+        log.info("加载升压站故障");
+        List<FaultInfo> syzGz = shardingApi.getFaultInfoList("SYZ", "2023-05-10", "2023-05-13", null, null, null);
+        syzGzMap = syzGz.stream().filter(fi -> fi.getAlertText().contains("位状态"))
+                .map(fi -> {
+                    fi.setConfirmPerson(fi.getAlertText().substring(fi.getAlertText().indexOf("--")));
+                    fi.setAlertText(fi.getAlertText().substring(0, fi.getAlertText().indexOf("--")));
+                    return fi;
+                })
+                .collect(Collectors.groupingBy(FaultInfo::getStationId));
     }
 
     //风机的8种原始状态:0-停机、 1-上电、2-待机、3-启动、4-并网、5-故障、6-维护、 7-离线
@@ -92,7 +111,7 @@ public class CalculateService {
                         stateCauseList.add(cause);
                     }
                 }else if(advanceState==6){
-                    if(isHasFaultEvent(thingId,advanceTime,ts)){
+                    if(hasFaultEvent(thingId,advanceTime,ts)){
                         //故障
                         StateCause cause = new StateCause(thingId2StationId(thingId),thingId, stateMap.get(5.0),
                                 new Date(advanceTime),new Date(ts), stateMap.get(6.0),stateMap.get(doubleValue),ts -advanceTime);
@@ -128,7 +147,7 @@ public class CalculateService {
      * 判断限停
      */
     private boolean judgmentStop(String thingId, long start, long end) {
-        if(isHasFaultEvent(thingId,start,end)) return false;
+        if(hasFaultEvent(thingId,start,end)) return false;
         Booststation boostStation = thingId2BoostStation(thingId);
         TestingPoint apsTp = CacheContext.pointMapMap.get("active-power-set").get(boostStation.getId());
         List<PointData> apsRbk = adapterApi.getValuesByKey(apsTp.getCode(), start, end,30);
@@ -169,11 +188,11 @@ public class CalculateService {
     }
 
     /**
-     * 计算风电场当前时刻限电台数
+     * 计算风电场当前时刻限电台数--大于3返回优化计算速度
      */
     private int electricityRationCount(String stationid, long start, long end) {
         int count = 0;
-        for (Equipment equipment : CacheContext.stationMap.get(stationid)) {
+        for (Equipment equipment : CacheContext.stationEquipMap.get(stationid)) {
             //满发功率和满发最小风速
             ModelPower modelPower = CacheContext.fullSpeeds.get(equipment.getModelId());
             //并网时间内的风速列表
@@ -187,7 +206,7 @@ public class CalculateService {
             List<PointData> activePowerPdl = adapterApi.getValuesByKey(activePowerStr, start, end,30);
             if(bladeAnglePdl.size()<speedPdl.size()||activePowerPdl.size()<speedPdl.size()) continue;
 
-            int incount = 0;
+            double incount = 0;
             for (int i = 0; i < speedPdl.size(); i++) {
                 //风速小于11并且桨叶角度大于2
                 if (speedPdl.get(i).getDoubleValue() <= modelPower.getSpeed() && bladeAnglePdl.get(i).getDoubleValue() > 2) {
@@ -198,7 +217,7 @@ public class CalculateService {
                 }
             }
             if(incount/speedPdl.size()>0.5) count++;
-
+            if(count>3) return count;
         }
         return count;
     }
@@ -206,24 +225,66 @@ public class CalculateService {
     /**
      * 判断30分钟内是否有故障
      */
-    private boolean isHasFaultEvent(String thingId, long start, long end) {
-        String stationid = thingId2StationId(thingId);
+    private boolean hasFaultEvent(String thingId, long start, long end) {
+        List<FaultInfo> fjInfos = fjGzMap.get(CacheContext.equipMap.get(thingId).getCode());
+        fjInfos=fjInfos==null?null:fjInfos.stream().filter(fi->timeBetweenBefore30(fi.getFaultTime().getTime(),start,end)).collect(Collectors.toList());
+
+        if(fjInfos!=null&&fjInfos.size()>0){
+            Map<String, List<FaultInfo>> map = fjInfos.stream().collect(Collectors.groupingBy(FaultInfo::getAlertText));
+            //判断当前故障是触发还是解除
+            for (List<FaultInfo> value : map.values()) {
+                if(value.get(0).getMessageType()==1) return true;
+            }
+        }else {
+            String stationid = thingId2StationId(thingId);
+            List<FaultInfo> syzInfos = syzGzMap.get(CacheContext.stationMap.get(stationid).getCode());
+            syzInfos=syzInfos==null?null:syzInfos.stream().filter(fi->timeBetweenBefore30(fi.getFaultTime().getTime(),start,end)).collect(Collectors.toList());
+            if(syzInfos!=null&&syzInfos.size()>0){
+                Map<String, List<FaultInfo>> map = syzInfos.stream().collect(Collectors.groupingBy(FaultInfo::getAlertText));
+                //判断当前故障是分位状态
+                for (List<FaultInfo> value : map.values()) {
+                    if(value.get(0).getConfirmPerson().equals("--分位状态")) return true;
+                }
+            }
+        }
+        return false;
+
+        /*String stationid = thingId2StationId(thingId);
         String startStr = DateTime.of(start - 30 * 60 * 1000).toStringDefaultTimeZone();
         String endStr = DateTime.of(end).toStringDefaultTimeZone();
-        List<FaultInfo> fj = shardingApi.getFaultInfoList("FJ", startStr, endStr, stationid, null,1);
-        List<FaultInfo> collect = fj.stream().filter(fi -> thingId.equals(fi.getWindturbineId())).collect(Collectors.toList());
+        List<FaultInfo> fj = shardingApi.getFaultInfoList("FJ", startStr, endStr, CacheContext.stationMap.get(stationid).getCode(), null,null);
+        List<FaultInfo> collect = fj.stream().filter(fi -> Objects.equals(CacheContext.equipMap.get(thingId).getCode(),fi.getWindturbineId())).collect(Collectors.toList());
         if(collect.isEmpty()){
-            List<FaultInfo> infos = shardingApi.getFaultInfoList("SYZ", startStr, endStr, stationid, "位状态", 1);
-            if(infos.isEmpty()){
-                return false;
-            }else {
-                System.out.println("SYZ"+infos.get(0).getAlertText());
+            List<FaultInfo> infos = shardingApi.getFaultInfoList("SYZ", startStr, endStr, CacheContext.stationMap.get(stationid).getCode(), null, null);
+            if(infos.size()>0){
+                infos = infos.stream().filter(fi -> fi.getAlertText().contains("位状态")).collect(Collectors.toList());
+                if(infos.isEmpty()) return false;
+
+                Map<String, List<FaultInfo>> map = infos.stream().map(fi -> {
+                    fi.setConfirmPerson(fi.getAlertText().substring(fi.getAlertText().indexOf("--")));
+                    fi.setAlertText(fi.getAlertText().substring(0, fi.getAlertText().indexOf("--")));
+                    return fi;
+                }).collect(Collectors.groupingBy(FaultInfo::getAlertText));
+
+                for (List<FaultInfo> value : map.values()) {
+                    //判断当前故障是分位状态
+                    if(value.get(0).getConfirmPerson().equals("--分位状态")) return true;
+                }
             }
             //return !infos.isEmpty();
         }else {
-            System.out.println("FJ"+collect.get(0).getAlertText());
+            Map<String, List<FaultInfo>> map = collect.stream().collect(Collectors.groupingBy(FaultInfo::getAlertText));
+            //判断当前故障是触发还是解除
+            for (List<FaultInfo> value : map.values()) {
+                if(value.get(0).getMessageType()==1) return true;
+            }
         }
-        return true;
+        return false;*/
+    }
+
+    private boolean timeBetweenBefore30(long time, long start, long end) {
+        start = start - 30 * 60 * 1000;
+        return time >= start && time <= end;
     }
 
     /**
@@ -254,7 +315,7 @@ public class CalculateService {
         });
         int size = stationState.get(0).size();
 
-        int k = 0;
+        double k = 0;
         for (int i = 0; i < size; i++) {
             int finalI = i;
             boolean b = stationState.stream().filter(pds -> pds.get(finalI).getDoubleValue() == starteventstate).count() == stationState.size();
@@ -321,7 +382,7 @@ public class CalculateService {
         //是否限电
         boolean isElectricityRation = false;
         //限电开始时间
-        long t1 = 0;
+        long ts1 = 0;
 
         long ts;
         double speedPd;
@@ -341,19 +402,19 @@ public class CalculateService {
             if (speedPd <= modelPower.getSpeed() && bladeAnglePd > 2) {
                 //限电首次时间
                 if(!isElectricityRation){
-                    t1 = ts;
+                    ts1 = ts;
                 }
                 isElectricityRation = true;
                 //风速大于11并且有功功率小于满发功率减100
             } else if (speedPd > modelPower.getSpeed() && activePowerPd < modelPower.getTheoryPower()-100) {
                 //限电首次时间
                 if(!isElectricityRation){
-                    t1 = ts;
+                    ts1 = ts;
                 }
                 isElectricityRation = true;
             }else if(isElectricityRation){
                 //记录限电
-                llm.put(t1, ts);
+                llm.put(ts1, ts);
                 /*StateCause cause;
                 if(i==speedList.size()-1) {
                     cause = new StateCause(thingId2StationId(equipment), equipment, stateMap.get(8.0),
@@ -367,24 +428,35 @@ public class CalculateService {
             }
         }
         //限电跳变处理
-        long t0 = Long.MAX_VALUE;
+        long t0 = 0;
+        long t1 = 0;
         long tstart = 0;
         long tend = 0;
         LinkedHashMap<Long, Long> llm2 = new LinkedHashMap<>();
         //限电列表key2-key1小于3分钟,记录为一个限电,大于3分钟,记录为另一个限电
         for (Map.Entry<Long, Long> entry : llm.entrySet()) {
+            if(t0==0) {
+                t0 = entry.getKey();
+                tstart = entry.getKey();
+                tend=llm.get(t0);
+                continue;
+            }
             t1 = entry.getKey();
             if (t1 - t0 < appConfig.getLongTime().get("ration")) {
-                tend = llm.get(t0);
+                tend = llm.get(t1);
             }else {
                 //3分钟内的限电忽略
-                if(t0!=Long.MAX_VALUE&&(tend-tstart)>appConfig.getLongTime().get("ration-min")){
+                if(tend-tstart>appConfig.getLongTime().get("ration-min")){
                     llm2.put(tstart, tend);
                 }
+                tend = llm.get(t1);
                 tstart = t1;
             }
             t0 = t1;
         }
+        if(tend-tstart>appConfig.getLongTime().get("ration-min")){
+            llm2.put(tstart, tend);
+        }
         return llm2;
     }
 }

+ 13 - 2
state/cause/src/main/java/com/gyee/gaia/init/CacheContext.java

@@ -6,8 +6,10 @@ import com.gyee.gaia.common.data.point.TestingPoint;
 import com.gyee.gaia.common.data.power.ModelPower;
 import com.gyee.gaia.common.data.windturbine.Booststation;
 import com.gyee.gaia.common.data.windturbine.Equipment;
+import com.gyee.gaia.common.data.windturbine.Powerstation;
 import com.gyee.gaia.dao.sql.Windturbine.IBooststationService;
 import com.gyee.gaia.dao.sql.Windturbine.IEquipmentService;
+import com.gyee.gaia.dao.sql.Windturbine.IPowerstationService;
 import com.gyee.gaia.dao.sql.point.ITestingPointService;
 import com.gyee.gaia.dao.sql.power.IModelPowerService;
 import lombok.extern.slf4j.Slf4j;
@@ -37,6 +39,8 @@ public class CacheContext implements ApplicationRunner {
     @Resource
     private IBooststationService booststationService;
     @Resource
+    private IPowerstationService powerstationService;
+    @Resource
     private AppConfig appConfig;
 
     public static Map<String, ModelPower> fullSpeeds;
@@ -50,13 +54,17 @@ public class CacheContext implements ApplicationRunner {
      */
     public static Map<String,Equipment> equipMap;
     /**
+     * 场站id,Powerstation
+     */
+    public static Map<String, Powerstation> stationMap;
+    /**
      * 期次,升压站信息
      */
     public static Map<String,Booststation> boostStationMap=new HashMap<>();
     /**
      * 风场,风机
      */
-    public static Map<String,List<Equipment>> stationMap;
+    public static Map<String,List<Equipment>> stationEquipMap;
 
     @Override
     public void run(ApplicationArguments args) throws Exception {
@@ -106,7 +114,7 @@ public class CacheContext implements ApplicationRunner {
         log.info("加载风机!");
         List<Equipment> emList = equipmentService.list();
         equipMap =emList.stream().collect(Collectors.toMap(Equipment::getId, Function.identity()));
-        stationMap=emList.stream().collect(Collectors.groupingBy(Equipment::getWindpowerstationId));
+        stationEquipMap =emList.stream().collect(Collectors.groupingBy(Equipment::getWindpowerstationId));
 
         log.info("加载升压站信息!");
         List<Booststation> bsList = booststationService.list();
@@ -115,5 +123,8 @@ public class CacheContext implements ApplicationRunner {
                 boostStationMap.put(pj, bs);
             }
         }
+        log.info("加载风场信息!");
+        List<Powerstation> stationList = powerstationService.list();
+        stationMap = stationList.stream().collect(Collectors.toMap(Powerstation::getId, Function.identity()));
     }
 }

+ 1 - 1
state/cause/src/main/resources/bootstrap.yaml

@@ -1,5 +1,5 @@
 server:
-  port: 8321
+  port: 8022
 
 spring:
   application:

+ 44 - 7
state/cause/src/test/resources/bootstrap.yaml

@@ -1,5 +1,5 @@
 server:
-  port: 8022
+  port: 8321
 
 spring:
   application:
@@ -20,15 +20,13 @@ spring:
         # 共享配置
         shared-configs:
           - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
-  jpa:
-    show-sql: false
   cache:
     type: SIMPLE
   datasource:
     driver-class-name: org.postgresql.Driver
-    url: jdbc:postgresql://192.168.10.18:5432/nx_dev
-    username: gdprod
-    password: gyee123
+    url: jdbc:postgresql://192.168.1.67:5432/gyee
+    username: gyee
+    password: Gyee@2023!@#
     type: com.alibaba.druid.pool.DruidDataSource
     druid:
       max-active: 20
@@ -47,6 +45,32 @@ spring:
 
 meter:
   stations: MHS_FDC,NSS_FDC
+  adapter-url: http://192.168.10.18:8011
+  sharding-url: http://192.168.10.18:8075
+  time:
+    #小于多长时间的故障不计算在内,单位秒
+    fault-min: 180
+    #限电跳变,2次限电间隔多长时间认为是同一次限电,单位秒
+    ration: 180
+    #小于多长时间的限电不计算在内,单位秒
+    ration-min: 180
+  uniformcode:
+    #8种状态
+    state8: FJZT8
+    #桨叶角度
+    blade-angle: AI082
+    #功率-有功功率
+    active-power: AI130
+    #风速
+    speed: AI022
+  uniformcode-boost:
+    #有功设定限值
+    active-power-set: BTYGSDXZ
+    #理论功率
+    apparent-power: BTLLGL
+    #实发有功
+    output-power: BTSFYG
+
 
 mybatis-plus:
   typeAliasesPackage: com.gyee.gaia.meter.entity
@@ -79,4 +103,17 @@ mybatis-plus:
     #配置JdbcTypeForNull, oracle数据库必须配置
     jdbc-type-for-null: 'null'
     callSettersOnNulls: true
-    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+xxl:
+  job:
+    admin:
+      addresses: http://192.168.10.18:8080/xxl-job-admin
+    accessToken:
+    executor:
+      appname: meter
+      address:
+      ip:
+      port: 9021
+      logpath: d:/xxl-job/meter/logs
+      logretentiondays: 30