Kaynağa Gözat

五损状态计算之限电状态

xushili 1 yıl önce
ebeveyn
işleme
64fc2a57af

+ 151 - 0
common/data/src/main/java/com/gyee/gaia/common/data/point/UniformCode.java

@@ -0,0 +1,151 @@
+package com.gyee.gaia.common.data.point;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 统一编码表			设备类型:风电/光伏	测点类型:遥测/遥信/计算	
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-05-05
+ */
+@TableName("pro_econ_uniform_code")
+public class UniformCode implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 编号
+     */
+    private String id;
+
+    /**
+     * 编码
+     */
+    private String nemCode;
+
+    /**
+     * 说明
+     */
+    private String description;
+
+    /**
+     * 设备类型
+     */
+    private String equipmentType;
+
+    /**
+     * 测点类型
+     */
+    private String pointType;
+
+    /**
+     * 备用1
+     */
+    private String spare1;
+
+    /**
+     * 备用2
+     */
+    private String spare2;
+
+    /**
+     * 备用3
+     */
+    private String spare3;
+
+    /**
+     * 备用4
+     */
+    private String spare4;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getNemCode() {
+        return nemCode;
+    }
+
+    public void setNemCode(String nemCode) {
+        this.nemCode = nemCode;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getEquipmentType() {
+        return equipmentType;
+    }
+
+    public void setEquipmentType(String equipmentType) {
+        this.equipmentType = equipmentType;
+    }
+
+    public String getPointType() {
+        return pointType;
+    }
+
+    public void setPointType(String pointType) {
+        this.pointType = pointType;
+    }
+
+    public String getSpare1() {
+        return spare1;
+    }
+
+    public void setSpare1(String spare1) {
+        this.spare1 = spare1;
+    }
+
+    public String getSpare2() {
+        return spare2;
+    }
+
+    public void setSpare2(String spare2) {
+        this.spare2 = spare2;
+    }
+
+    public String getSpare3() {
+        return spare3;
+    }
+
+    public void setSpare3(String spare3) {
+        this.spare3 = spare3;
+    }
+
+    public String getSpare4() {
+        return spare4;
+    }
+
+    public void setSpare4(String spare4) {
+        this.spare4 = spare4;
+    }
+
+    @Override
+    public String toString() {
+        return "UniformCode{" +
+            "id = " + id +
+            ", nemCode = " + nemCode +
+            ", description = " + description +
+            ", equipmentType = " + equipmentType +
+            ", pointType = " + pointType +
+            ", spare1 = " + spare1 +
+            ", spare2 = " + spare2 +
+            ", spare3 = " + spare3 +
+            ", spare4 = " + spare4 +
+        "}";
+    }
+}

+ 12 - 13
common/data/src/main/java/com/gyee/gaia/common/data/power/ModelPower.java

@@ -3,7 +3,6 @@ package com.gyee.gaia.common.data.power;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 import java.io.Serializable;
-import java.math.BigDecimal;
 
 /**
  * <p>
@@ -31,24 +30,24 @@ public class ModelPower implements Serializable {
     /**
      * 风速/光照度
      */
-    private BigDecimal speed;
+    private Double speed;
 
     /**
      * 稳态功率(相当于理论)
      */
-    private BigDecimal theoryPower;
+    private Double theoryPower;
 
     /**
      * 动态功率(保证功率)
      */
-    private BigDecimal ensurePower;
+    private Double ensurePower;
 
     /**
      * 场站编号
      */
     private String windpowerstationId;
 
-    private BigDecimal fullSpeed;
+    private Double fullSpeed;
 
     public String getId() {
         return id;
@@ -66,27 +65,27 @@ public class ModelPower implements Serializable {
         this.modelId = modelId;
     }
 
-    public BigDecimal getSpeed() {
+    public Double getSpeed() {
         return speed;
     }
 
-    public void setSpeed(BigDecimal speed) {
+    public void setSpeed(Double speed) {
         this.speed = speed;
     }
 
-    public BigDecimal getTheoryPower() {
+    public Double getTheoryPower() {
         return theoryPower;
     }
 
-    public void setTheoryPower(BigDecimal theoryPower) {
+    public void setTheoryPower(Double theoryPower) {
         this.theoryPower = theoryPower;
     }
 
-    public BigDecimal getEnsurePower() {
+    public Double getEnsurePower() {
         return ensurePower;
     }
 
-    public void setEnsurePower(BigDecimal ensurePower) {
+    public void setEnsurePower(Double ensurePower) {
         this.ensurePower = ensurePower;
     }
 
@@ -98,11 +97,11 @@ public class ModelPower implements Serializable {
         this.windpowerstationId = windpowerstationId;
     }
 
-    public BigDecimal getFullSpeed() {
+    public Double getFullSpeed() {
         return fullSpeed;
     }
 
-    public void setFullSpeed(BigDecimal fullSpeed) {
+    public void setFullSpeed(Double fullSpeed) {
         this.fullSpeed = fullSpeed;
     }
 

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

@@ -14,6 +14,9 @@ public class AppConfig {
 
     //场站范围
     private String stations;
+    /**
+     * 统一编码名,统一编码
+     */
     private Map<String, String> uniformcode;
 
 

+ 7 - 7
state/cause/src/main/java/com/gyee/gaia/cause/entity/StateCause.java

@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 
 import java.io.Serializable;
-import java.time.LocalDateTime;
+import java.util.Date;
 
 /**
  * <p>
@@ -41,12 +41,12 @@ public class StateCause implements Serializable {
     /**
      * 开始时间
      */
-    private LocalDateTime startTime;
+    private Date startTime;
 
     /**
      * 结束时间
      */
-    private LocalDateTime endTime;
+    private Date endTime;
 
     /**
      * 事前状态
@@ -97,19 +97,19 @@ public class StateCause implements Serializable {
         this.event = event;
     }
 
-    public LocalDateTime getStartTime() {
+    public Date getStartTime() {
         return startTime;
     }
 
-    public void setStartTime(LocalDateTime startTime) {
+    public void setStartTime(Date startTime) {
         this.startTime = startTime;
     }
 
-    public LocalDateTime getEndTime() {
+    public Date getEndTime() {
         return endTime;
     }
 
-    public void setEndTime(LocalDateTime endTime) {
+    public void setEndTime(Date endTime) {
         this.endTime = endTime;
     }
 

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

@@ -38,11 +38,14 @@ public class CauseJobHandler implements ApplicationRunner {
 
     @XxlJob("WindCauseJobHandler")
     public ReturnT<String> windCauseJobHandler() {
+        //String command = XxlJobHelper.getJobParam();
+        //Map<String, String> map = JSON.parseObject(command, Map.class);
         return new ReturnT(SUCCESS_CODE, "调度成功111");
     }
 
     @Override
     public void run(ApplicationArguments args) throws Exception {
+        //获取最新更新时间
         QueryWrapper<StateCause> scWrapper = new QueryWrapper<>();
         scWrapper.select("max(end_time)");
         Map<String, Object> map = stateCauseService.getMap(scWrapper);
@@ -53,13 +56,9 @@ public class CauseJobHandler implements ApplicationRunner {
         Object max = map.get("max");
         if (max == null) max = DateUtil.yesterday().getTime();
 
-        Map<TestingPoint, List<PointData>> value = calculateService.getValue(CacheContext.state8Point, (long) max, System.currentTimeMillis());
-        calculateService.calculate(value);
-        //String command = XxlJobHelper.getJobParam();
-        //Map<String, String> map = JSON.parseObject(command, Map.class);
-        QueryWrapper<TestingPoint> wrapper = new QueryWrapper<>();
-        wrapper.eq("uniform_code", "FJZT8");
-        List<TestingPoint> list = testingPointService.list(wrapper);
+        CalculateService calculateService = new CalculateService();
+        calculateService.refresh((long) max, System.currentTimeMillis());
+        calculateService.calculate();
 
     }
 }

+ 130 - 15
state/cause/src/main/java/com/gyee/gaia/cause/service/CalculateService.java

@@ -2,35 +2,150 @@ package com.gyee.gaia.cause.service;
 
 import com.gyee.gaia.cause.adapter.AdapterApi;
 import com.gyee.gaia.cause.entity.PointData;
-import com.gyee.gaia.common.data.point.TestingPoint;
+import com.gyee.gaia.cause.entity.StateCause;
+import com.gyee.gaia.common.data.power.ModelPower;
+import com.gyee.gaia.init.CacheContext;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class CalculateService {
 
     @Resource
     private AdapterApi adapterApi;
+    @Resource
+    private IStateCauseService stateCauseService;
 
-    public Map<TestingPoint, List<PointData>> getValue(List<TestingPoint> points, long starttime, long endtime) {
-        Map<TestingPoint, List<PointData>> keyDatas = new HashMap<>();
-        for (TestingPoint point : points) {
-            List<PointData> rawByKey = adapterApi.getRawByKey(point.getCode(), starttime, endtime);
-            keyDatas.put(point, rawByKey);
-        }
-        return keyDatas;
+    private Map<String,Map<String, List<PointData>>> pointDatas;
+
+    public void refresh(long starttime, long endtime){
+        log.info("刷新测点值!");
+        CacheContext.pointsMap.forEach((ucname,pointList)->{
+            pointList.forEach(point->{
+                List<PointData> rawByKey = adapterApi.getRawByKey(point.getCode(), starttime, endtime);
+                Map<String, List<PointData>> tppdl = new HashMap<>();
+                tppdl.put(point.getCode(), rawByKey);
+                pointDatas.put(ucname, tppdl);
+            });
+        });
     }
 
-    public void calculate(Map<TestingPoint, List<PointData>> value) {
-        for (Map.Entry<TestingPoint, List<PointData>> entry : value.entrySet()) {
+    //风机的8种原始状态:0-停机、 1-上电、2-待机、3-启动、4-并网、5-故障、6-维护、 7-离线
+    public void calculate() {
+        List<StateCause> stateCauseList = new ArrayList<>();
+        pointDatas.get("风机8种状态").forEach((key,value)->{
             //事前状态
-            double advanceState = -1;
-            for (PointData pointData : entry.getValue()) {
+            double advanceState = value.get(0).getDoubleValue();
+            //事前时间
+            long advanceTime = value.get(0).getTs();
+
+            double doubleValue;
+            long ts;
+            for (PointData pointData : value) {
+                ts = pointData.getTs();
+                doubleValue = pointData.getDoubleValue();
+
+                if(doubleValue ==1||doubleValue==3) continue;
+                if(doubleValue ==advanceState) continue;
+
+                //判断事前状态
+                if(advanceState==4){
+                    //计算限电
+                    calcElectricityRation(stateCauseList,key,advanceTime,ts,doubleValue);
+                }else if(advanceState==0){
+                    StateCause cause = new StateCause();
+                    cause.setStationId(CacheContext.equipPointsMap.get(key).getWindpowerstationId());
+                    cause.setEquipmentId(CacheContext.equipPointsMap.get(key).getId());
+                    cause.setEvent("停机");
+                    cause.setStartTime(new Date(advanceTime));
+                    cause.setEndTime(new Date(ts));
+                    cause.setAdvanceState("停机");
+                    cause.setAfterState(CacheContext.stateMap.get(doubleValue));
+                    cause.setTime(ts -advanceTime);
+                    stateCauseList.add(cause);
+                }else if(advanceState==2){
+                    StateCause cause = new StateCause();
+                    cause.setStationId(CacheContext.equipPointsMap.get(key).getWindpowerstationId());
+                    cause.setEquipmentId(CacheContext.equipPointsMap.get(key).getId());
+                    cause.setEvent("待机");
+                    cause.setStartTime(new Date(advanceTime));
+                    cause.setEndTime(new Date(ts));
+                    cause.setAdvanceState("待机");
+                    cause.setAfterState(CacheContext.stateMap.get(doubleValue));
+                    cause.setTime(ts -advanceTime);
+                    stateCauseList.add(cause);
+                }
+
+                advanceState = doubleValue;
+                advanceTime = ts;
+            }
+        });
+        stateCauseService.saveBatch(stateCauseList);
+    }
+
+    /**
+     *
+     *
+     * @param stateCauseList
+     * @param equipment 设备id
+     * @param start 并网开始时间
+     * @param end 并网结束时间
+     * @param endeventstate 事后状态
+     * @return
+     */
+    private void calcElectricityRation(List<StateCause> stateCauseList, String equipment, long start, long end, double endeventstate) {
+        //满发功率和最小风速
+        ModelPower modelPower = CacheContext.fullSpeeds.get(CacheContext.equipPointsMap.get(equipment).getModelId());
+        //并网时间内的风速列表
+        List<PointData> speedList = pointDatas.get("风速").get(equipment).stream()
+                .filter(pointData -> pointData.getTs() >= start || pointData.getTs() < end).collect(Collectors.toList());
+        //是否限电
+        boolean isElectricityRation = false;
+        //限电开始时间
+        long t1 = 0;
+
+        for (PointData data : speedList) {
+            long ts = data.getTs();
+            //TODO 当前时间戳的桨叶角度
+            PointData bladeAnglePd = pointDatas.get("桨叶1角度").get(equipment).stream().filter(pointData -> pointData.getTs() <= ts).findFirst().get();
+            //TODO 当前时间戳的有功功率
+            PointData powerPd = pointDatas.get("有功功率").get(equipment).stream().filter(pointData -> pointData.getTs() <= ts).findFirst().get();
 
+            //风速小于11并且桨叶角度大于2
+            if (data.getDoubleValue() <= modelPower.getSpeed() && bladeAnglePd.getDoubleValue() > 2) {
+                //限电首次时间
+                if(!isElectricityRation){
+                    t1 = ts;
+                }
+                isElectricityRation = true;
+            //风速大于11并且有功功率小于满发功率减100
+            } else if (data.getDoubleValue() > modelPower.getSpeed() && powerPd.getDoubleValue() < modelPower.getTheoryPower()-100) {
+                //限电首次时间
+                if(!isElectricityRation){
+                    t1 = ts;
+                }
+                isElectricityRation = true;
+            }else if(isElectricityRation){
+                StateCause cause = new StateCause();
+                cause.setStationId(CacheContext.equipPointsMap.get(equipment).getWindpowerstationId());
+                cause.setEquipmentId(equipment);
+                cause.setEvent("限电");
+                cause.setStartTime(new Date(t1));
+                cause.setEndTime(new Date(ts));
+                cause.setAdvanceState("并网");
+                if(data==speedList.get(speedList.size()-1)){
+                    cause.setAfterState(CacheContext.stateMap.get(endeventstate));
+                }else {
+                    cause.setAfterState("并网");
+                }
+                cause.setTime(ts - t1);
+                stateCauseList.add(cause);
+                isElectricityRation = false;
             }
         }
     }

+ 40 - 7
state/cause/src/main/java/com/gyee/gaia/init/CacheContext.java

@@ -1,12 +1,16 @@
 package com.gyee.gaia.init;
 
-
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.gyee.gaia.cause.config.AppConfig;
 import com.gyee.gaia.common.data.point.TestingPoint;
+import com.gyee.gaia.common.data.point.UniformCode;
 import com.gyee.gaia.common.data.power.ModelPower;
+import com.gyee.gaia.common.data.windturbine.Equipment;
+import com.gyee.gaia.dao.sql.Windturbine.IEquipmentService;
 import com.gyee.gaia.dao.sql.point.ITestingPointService;
+import com.gyee.gaia.dao.sql.point.IUniformCodeService;
 import com.gyee.gaia.dao.sql.power.IModelPowerService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
@@ -19,32 +23,48 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Order(1)
+@Slf4j
 @Component
 public class CacheContext implements CommandLineRunner {
 
     @Resource
     private ITestingPointService testingPointService;
     @Resource
-    private AppConfig appConfig;
+    IUniformCodeService uniformCodeService;
     @Resource
     private IModelPowerService modelPowerService;
+    @Resource
+    private IEquipmentService equipmentService;
 
-    public static List<TestingPoint> state8Point;
     public static Map<String, ModelPower> fullSpeeds;
     public static Map<Double, String> stateMap;
+    /**
+     * 统一编码描述,测点列表
+     */
+    public static Map<String,List<TestingPoint>> pointsMap;
+    /**
+     * 风机号,TestingPoint
+     */
+    public static Map<String,Equipment> equipPointsMap;
 
     @Override
     public void run(String... args) throws Exception {
-        String state8 = appConfig.getUniformcode().get("state8");
-        QueryWrapper<TestingPoint> tpWrapper = new QueryWrapper<>();
-        tpWrapper.eq("uniformcode", state8);
-        state8Point = testingPointService.list(tpWrapper);
+        log.info("加载统一编码!");
+        QueryWrapper<UniformCode> ucWrapper = new QueryWrapper<>();
+        ucWrapper.eq("spare1", "计算五损");
+        List<UniformCode> uniformCodeList = uniformCodeService.list(ucWrapper);
+        Map<String, String> uniformCodeMap = uniformCodeList.stream().collect(Collectors.toMap(UniformCode::getDescription, UniformCode::getNemCode));
+
+        log.info("加载状态测点!");
+        loadPoints(uniformCodeMap);
 
+        log.info("加载机型满发最低风速!");
         QueryWrapper<ModelPower> mpWrapper = new QueryWrapper<>();
         mpWrapper.isNotNull("full_speed");
         List<ModelPower> mpList = modelPowerService.list(mpWrapper);
         fullSpeeds = mpList.stream().collect(Collectors.toMap(ModelPower::getModelId, Function.identity()));
 
+        log.info("加载状态说明!");
         stateMap = new HashMap<>();
         stateMap.put(0.0, "停机");
         stateMap.put(1.0, "上电");
@@ -54,5 +74,18 @@ public class CacheContext implements CommandLineRunner {
         stateMap.put(5.0, "故障");
         stateMap.put(6.0, "维护");
         stateMap.put(7.0, "离线");
+
+        log.info("加载风机!");
+        List<Equipment> emList = equipmentService.list();
+        equipPointsMap=emList.stream().collect(Collectors.toMap(Equipment::getId, Function.identity()));
+    }
+
+    private void loadPoints(Map<String, String> uniformcode) {
+        uniformcode.forEach((k,v)->{
+            QueryWrapper<TestingPoint> tpWrapper = new QueryWrapper<>();
+            tpWrapper.eq("thing_type","windturbine").eq("uniform_code", v);
+            List<TestingPoint> list = testingPointService.list(tpWrapper);
+            pointsMap.put(k, list);
+        });
     }
 }

+ 6 - 0
state/cause/src/main/resources/bootstrap.yaml

@@ -47,7 +47,12 @@ meter:
   stations: MHS_FDC,NSS_FDC
   adapter-url: http://192.168.10.18:8011
   uniformcode:
+    #8种状态
     state8: FJZT8
+    #桨叶角度
+    blade-angle: AI082
+    #功率-有功功率
+    active-power: AI130
 
 mybatis-plus:
   typeAliasesPackage: com.gyee.gaia.meter.entity
@@ -80,6 +85,7 @@ mybatis-plus:
     #配置JdbcTypeForNull, oracle数据库必须配置
     jdbc-type-for-null: 'null'
     callSettersOnNulls: true
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 
 xxl:
   job:

+ 16 - 0
timeseries/dao-interface/src/main/java/com/gyee/gaia/dao/point/UniformCodeMapper.java

@@ -0,0 +1,16 @@
+package com.gyee.gaia.dao.point;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.gaia.common.data.point.UniformCode;
+
+/**
+ * <p>
+ * 统一编码表			设备类型:风电/光伏	测点类型:遥测/遥信/计算	 Mapper 接口
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-05-05
+ */
+public interface UniformCodeMapper extends BaseMapper<UniformCode> {
+
+}

+ 16 - 0
timeseries/dao-sql/src/main/java/com/gyee/gaia/dao/sql/point/IUniformCodeService.java

@@ -0,0 +1,16 @@
+package com.gyee.gaia.dao.sql.point;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.gyee.gaia.common.data.point.UniformCode;
+
+/**
+ * <p>
+ * 统一编码表			设备类型:风电/光伏	测点类型:遥测/遥信/计算	 服务类
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-05-05
+ */
+public interface IUniformCodeService extends IService<UniformCode> {
+
+}

+ 2 - 1
timeseries/dao-sql/src/main/java/com/gyee/gaia/dao/sql/point/TestingPointServiceImpl.java

@@ -1,8 +1,9 @@
-package com.gyee.gaia.dao.sql.point;
+package com.gyee.gaia.dao.sql.point.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.gyee.gaia.common.data.point.TestingPoint;
 import com.gyee.gaia.dao.point.TestingPointMapper;
+import com.gyee.gaia.dao.sql.point.ITestingPointService;
 import org.springframework.stereotype.Service;
 
 /**

+ 20 - 0
timeseries/dao-sql/src/main/java/com/gyee/gaia/dao/sql/point/impl/UniformCodeServiceImpl.java

@@ -0,0 +1,20 @@
+package com.gyee.gaia.dao.sql.point.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gyee.gaia.common.data.point.UniformCode;
+import com.gyee.gaia.dao.point.UniformCodeMapper;
+import com.gyee.gaia.dao.sql.point.IUniformCodeService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 统一编码表			设备类型:风电/光伏	测点类型:遥测/遥信/计算	 服务实现类
+ * </p>
+ *
+ * @author gfhd
+ * @since 2023-05-05
+ */
+@Service
+public class UniformCodeServiceImpl extends ServiceImpl<UniformCodeMapper, UniformCode> implements IUniformCodeService {
+
+}