diff --git a/pqs-advance/advance-api/pom.xml b/pqs-advance/advance-api/pom.xml
index eb06043eb..a5f991315 100644
--- a/pqs-advance/advance-api/pom.xml
+++ b/pqs-advance/advance-api/pom.xml
@@ -33,6 +33,12 @@
common-microservice
${project.version}
+
+
+ com.njcn
+ event-api
+ ${project.version}
+
com.sun.jna
jna
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java
index 909f41a62..b16ee6ff0 100644
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/AdvanceResponseEnum.java
@@ -28,7 +28,9 @@ public enum AdvanceResponseEnum {
USER_DATA_P_NODE_PARAMETER_ERROR("A0101","无用采用户或所有用户的完整性均不满足条件"),
- RESPONSIBILITY_PARAMETER_ERROR("A0101","调用接口程序计算失败,参数非法")
+ RESPONSIBILITY_PARAMETER_ERROR("A0101","调用接口程序计算失败,参数非法"),
+
+ EVENT_EMPTY("A0102","没有查询到未分析事件")
;
private final String code;
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/EnumEvt.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/EnumEvt.java
new file mode 100644
index 000000000..96bcc9dfa
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/enums/EnumEvt.java
@@ -0,0 +1,99 @@
+package com.njcn.advance.enums;
+
+/**
+ * @Author: Sunwei 【sunW2016@163.com】
+ * @Description: 高级分析返回结果
+ * @Date: Create in 9:02 2018/3/6
+ * @Modified By:
+ */
+public enum EnumEvt {
+ EVT_NUM("evt_num", "高级算法返回事件个数"), EVT_BUF("evt_buf", "高级算法返回数据"), QVVR_TYPE("qvvr_type", "暂降类型"), POW_A("POW_a",
+ "A相波形起始点"), POW_B("POW_b", "B相波形起始点"), POW_C("POW_c", "C相波形起始点"), SEG_T_IDX("SEG_T_idx",
+ "修正分段位置"), SEG_T_NUM("SEG_T_num", "分段数目"), SEG_RMS_T_NUM("SEG_RMS_T_num", "有效值分段数目"), SEG_RMS_T_IDX(
+ "SEG_RMS_T_idx", "有效值分段位置"), UA_MIN("ua_min", "A相电压特征值"), UB_MIN("ub_min",
+ "B相电压特征值"), UC_MIN("uc_min", "C相电压特征值"), U3_MIN("u3_min",
+ "三相电压特征值"), U_MIN_NUM("u_min_num", "特征值个数"), ORDER_MIN_IDX("order_min_idx",
+ "最小值位置"), HOLD_TIME_RMS("hold_time_rms", "有效值算法持续时间"), HOLD_TIME_DQ(
+ "hold_time_dq",
+ "dq变换算法持续时间"), VOLTAGECHANGE_VA("Voltagechange_Va",
+ "A相跳变段电压变化率"), VOLTAGECHANGE_VB("Voltagechange_Vb",
+ "B相跳变段电压变化率"), VOLTAGECHANGE_VC("Voltagechange_Vc",
+ "C相跳变段电压变化率"), ANGLE_DIFF_AP("angle_diff_ap",
+ "A相相位正跳变"), ANGLE_DIFF_BP("angle_diff_bp",
+ "B相相位正跳变"), ANGLE_DIFF_CP("angle_diff_cp",
+ "C相相位正跳变"), ANGLE_DIFF_AN("angle_diff_an",
+ "A相相位负跳变"), ANGLE_DIFF_BN("angle_diff_bn",
+ "B相相位负跳变"), ANGLE_DIFF_CN("angle_diff_cn",
+ "C相相位负跳变"), BPH_MAX_VALUE("bph_max_value",
+ "不平衡度"), QVVR_CATA_CAUSE("qvvr_cata_cause",
+ "暂降原因"), QVVR_PHASETYPE("qvvr_phasetype",
+ "暂降相别"), QVVR_CATA_TYPE("qvvr_cata_type",
+ "暂降类型"), POWER_QVVR_BEFORE_BUF("power_qvvr_before_buf",
+ "暂态前基波功率参数"),POWER_QVVR_AFTER_BUF("power_qvvr_after_buf",
+ "暂态前基波功率参数"),FUND_P("Fund_P",
+ "基波有功功率"),FUND_Q("Fund_Q",
+ "基波无功功率"),FUND_S("Fund_S",
+ "基波视在功率"),QVVR_DIRECTION_INFO("qvvr_direction_info",
+ "暂降源定位特征参数"),TRIG_TIME("trig_time",
+ "暂降触发时刻"),QVVR_BEFORE_RMS("qvvr_before_rms",
+ "暂降前基波有效值"),QVVR_BEFORE_ZK("qvvr_before_zk",
+ "暂降前基波阻抗值"),QVVR_OCCUR_RMS("qvvr_occur_rms",
+ "暂降发生时基波有效值"),QVVR_OCCUR_ZK("qvvr_occur_zk",
+ "暂降发生时基波阻抗值"),QVVR_POS_INFO("qvvr_pos_info",
+ "暂降源与监测位置关系"),QVVR_UTBL_INFO("qvvr_utbl_info",
+ "突变量参数"),ENTER("\n",
+ "回车换行"), QUOTATION("\"",
+ "双引号"), NEWLINE("\n\t",
+ "换行Tab"), TAB("\t",
+ "tab");
+ /**
+ * 字段描述
+ */
+ private String description;
+
+ /**
+ * 字段值
+ */
+ private String property;
+
+ EnumEvt(String property, String description) {
+ this.description = description;
+ this.property = property;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public static String setEvtProperty(String property) {
+ return QUOTATION.getProperty() + property + QUOTATION.getProperty() + ":";
+ }
+
+ public static String setEnter(String s, int lineNumber) {
+ return s += "," + ENTER.getProperty() + setTab(lineNumber);
+ }
+
+ public static String setClose(int lineNumber) {
+ String s = ENTER.getProperty();
+ s += setTab(lineNumber);
+ return s + "}";
+ }
+
+ public static String setTab(int count) {
+ String string = "";
+
+ for (int i = 0; i < count; i++) {
+ string += TAB.getProperty();
+ }
+
+ return string;
+ }
+
+ public static String setNewLine() {
+ return "{" + NEWLINE.getProperty();
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/FinalData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/FinalData.java
deleted file mode 100644
index fdabd4e5d..000000000
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/FinalData.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.njcn.advance.pojo.bo;
-
-/**
- * pqs
- *
- * @author cdf
- * @date 2023/6/20
- */
-public interface FinalData {
-
- /**
- * 暂降事件按开始时间归集门槛10秒
- */
- int TIME_THRESHOLD = 10;
- //分组的最大组数
- int MAX_GROUP_NUM = 1000;
- //类别数
- int MAX_CATA_NUM = 7;
- //最大事件个数
- int MAX_EVT_NUM = 1000;
- //三相故障
- int QVVR_TYPE_THREE = 9;
- //故障类型未知
- int QVVR_TYPE_UNKNOWN = 10;
- //节点不在网络拓扑中
- int QVVR_TYPE_OUTOFRANGE = -1;
- int DATA_INF = -1;
- int EVT_TYPE_NUM = 6;//故障类型数
- int MAX_PATH_NUM = 50;//最大路径数
- int NODE_NUM = -1;//输入节点数
-
- // 暂降综合评估算法
- int CLUSER_NUM = 4; // 系统中各监测点分类后的代表节点
- int MAX_LINE_NUM = 1000; // 监测点最多个数
- int MAX_STA_NUM = 120; // 支持的子系统个数
-
-
-}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QtIdxArray.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QtIdxArray.java
index 3ea0613b5..97ca3f10e 100644
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QtIdxArray.java
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QtIdxArray.java
@@ -1,6 +1,7 @@
package com.njcn.advance.pojo.bo;
-import com.njcn.advance.pojo.dto.QtIdx;
+import com.njcn.advance.pojo.dto.relevent.FinalData;
+import com.njcn.advance.pojo.dto.relevent.QtIdx;
import com.sun.jna.Structure;
import java.util.List;
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QvvrDataStruct.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QvvrDataStruct.java
index 6a9ad4d86..de454b1c7 100644
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QvvrDataStruct.java
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/QvvrDataStruct.java
@@ -1,5 +1,6 @@
package com.njcn.advance.pojo.bo;
+import com.njcn.advance.pojo.dto.relevent.FinalData;
import com.sun.jna.Structure;
import java.util.Arrays;
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/ZtpgSin.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/ZtpgSin.java
index 82b3e7711..234af5ed9 100644
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/ZtpgSin.java
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/bo/ZtpgSin.java
@@ -1,5 +1,6 @@
package com.njcn.advance.pojo.bo;
+import com.njcn.advance.pojo.dto.relevent.FinalData;
import com.sun.jna.Structure;
import java.util.Arrays;
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/BalanceInfo.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/BalanceInfo.java
index 798417c2c..7ebe66475 100644
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/BalanceInfo.java
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/BalanceInfo.java
@@ -1,5 +1,6 @@
package com.njcn.advance.pojo.dto;
+import com.njcn.advance.pojo.dto.relevent.QtIdx;
import lombok.Data;
import java.util.List;
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityGroupData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityGroupData.java
new file mode 100644
index 000000000..8d2a236fa
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityGroupData.java
@@ -0,0 +1,43 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+import lombok.Data;
+
+/**
+ * pqs
+ *
+ * @author cdf
+ * @date 2023/7/20
+ */
+@Data
+public class EntityGroupData {
+ private int idx[];
+ private int all_evt_num;
+ private int evt_in_num;
+ private int evt_out_num;
+ private int evt_res_num;
+
+ private int Matrixcata[][];
+
+ private EntityGroupEvtData in_buf[];
+ private EntityGroupEvtData out_buf[];
+ private EntityGroupEvtData res_buf[];
+ private EntityGroupEvtData grp_buf[][];
+
+ private int grp_num[];
+ private int grp_all_num;
+ private EntityGroupEvtData grp_cata_buf[][][];
+ private int grp_cata_num[][];
+
+ public EntityGroupData() {
+ idx = new int[FinalData.MAX_EVT_NUM];
+ Matrixcata = new int[FinalData.MAX_CATA_NUM][FinalData.MAX_EVT_NUM];
+ in_buf = new EntityGroupEvtData[FinalData.MAX_EVT_NUM];
+ out_buf = new EntityGroupEvtData[FinalData.MAX_EVT_NUM];
+ res_buf = new EntityGroupEvtData[FinalData.MAX_EVT_NUM];
+ grp_buf = new EntityGroupEvtData[FinalData.MAX_GROUP_NUM][FinalData.MAX_EVT_NUM];
+ grp_num = new int[FinalData.MAX_GROUP_NUM];
+ grp_cata_buf = new EntityGroupEvtData[FinalData.MAX_GROUP_NUM][FinalData.MAX_CATA_NUM
+ + 2][FinalData.MAX_EVT_NUM];
+ grp_cata_num = new int[FinalData.MAX_GROUP_NUM][FinalData.MAX_CATA_NUM + 2];
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityGroupEvtData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityGroupEvtData.java
new file mode 100644
index 000000000..c4c888941
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityGroupEvtData.java
@@ -0,0 +1,53 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+import com.njcn.advance.pojo.dto.SagEvent;
+import lombok.Data;
+
+@Data
+public class EntityGroupEvtData implements Cloneable,Comparable {
+
+ //逻辑节点序号
+ private int node;
+ //事件开始时间时标
+ private int start_time;
+ //类别
+ private int cata;
+ //标注类别
+ private int cata2;
+ //物理节点
+ private String nodePhysics;
+
+ private SagEvent sagEvent;
+
+ private String sagReason;
+
+
+ public Object objClone() {
+ try {
+ return clone();
+ } catch (CloneNotSupportedException e) {
+ return new EntityGroupEvtData(null, -1, -1, -1,null,null);
+ }
+ }
+
+ public EntityGroupEvtData(String nodePhysics, int start_time, int cata, int cata2, SagEvent sagEvent, String sagReason) {
+ this.nodePhysics = nodePhysics;
+ this.start_time = start_time;
+ this.cata = cata;
+ this.cata2 = cata2;
+ this.sagEvent = sagEvent;
+ this.sagReason = sagReason;
+ }
+
+
+ @Override
+ public int compareTo(EntityGroupEvtData obj) {
+ if(this.getStart_time() < obj.getStart_time()){
+ return -1;
+ }else if(this.getStart_time() > obj.getStart_time()){
+ return 1;
+ }
+
+ return 0;
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityLogic.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityLogic.java
new file mode 100644
index 000000000..f71da1882
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityLogic.java
@@ -0,0 +1,21 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+
+import lombok.Data;
+
+@Data
+public class EntityLogic {
+ //物理隔绝变压器策略GUID
+ private String tPIndex;
+ //变压器逻辑上节点
+ private String node_h;
+ //变压器逻辑下节点
+ private String node_l;
+ // 变压器连接方式
+ private Integer type;
+ //变压器物理上节点
+ private String nodeBefore;
+ //变压器物理下节点
+ private String nodeNext;
+
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityMtrans.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityMtrans.java
new file mode 100644
index 000000000..67550b4bd
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EntityMtrans.java
@@ -0,0 +1,71 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+import com.njcn.advance.pojo.dto.relevent.FinalData;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+public class EntityMtrans implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private int Matrixcata0[][];
+ private int Matrixcata1[][];
+ private int Mtrans[][];
+ private int possiable_path[][];
+ private int path_num;
+
+ public EntityMtrans() {
+ super();
+ Mtrans = new int[FinalData.NODE_NUM][FinalData.NODE_NUM];
+ Matrixcata0 = new int[FinalData.EVT_TYPE_NUM][FinalData.NODE_NUM];
+ Matrixcata1 = new int[FinalData.EVT_TYPE_NUM][FinalData.NODE_NUM];
+ possiable_path = new int[FinalData.MAX_PATH_NUM][FinalData.NODE_NUM + 1];
+ path_num = 0;
+ }
+
+ public int[][] getMatrixcata0() {
+ return Matrixcata0;
+ }
+
+ public void setMatrixcata0(int[][] matrixcata0) {
+ Matrixcata0 = matrixcata0;
+ }
+
+ public int[][] getMatrixcata1() {
+ return Matrixcata1;
+ }
+
+ public void setMatrixcata1(int[][] matrixcata1) {
+ Matrixcata1 = matrixcata1;
+ }
+
+ public int[][] getMtrans() {
+ return Mtrans;
+ }
+
+ public void setMtrans(int[][] mtrans) {
+ Mtrans = mtrans;
+ }
+
+ public int[][] getPossiable_path() {
+ return possiable_path;
+ }
+
+ public void setPossiable_path(int[][] possiable_path) {
+ this.possiable_path = possiable_path;
+ }
+
+ public int getPath_num() {
+ return path_num;
+ }
+
+ public void setPath_num(int path_num) {
+ this.path_num = path_num;
+ }
+
+ @Override
+ public String toString() {
+ return "EntityMtrans [Matrixcata0=" + Arrays.toString(Matrixcata0) + ", Matrixcata1="
+ + Arrays.toString(Matrixcata1) + ", Mtrans=" + Arrays.toString(Mtrans) + ", possiable_path="
+ + Arrays.toString(possiable_path) + ", path_num=" + path_num + "]";
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EventAssObj.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EventAssObj.java
new file mode 100644
index 000000000..528972e1c
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/EventAssObj.java
@@ -0,0 +1,123 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+import com.njcn.advance.pojo.dto.SagEvent;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+/*
+ *一个归一化事件包含多个事件(一对多)
+ *indexEventAss:事件关联分析表Guid
+ *time:归一化中第一个时间
+ *describe:关联事件描述
+ *bRange:是否进行范围分析
+ *indexUser:用户表Guid
+ *updateTime:更新时间
+ *state:数据状态
+ *name:关联事件名称
+ *list:属于该归一化事件的暂降事件
+ *strTime:字符串时间
+*/
+@Data
+public class EventAssObj implements Serializable {
+ private String indexEventAss;
+ private LocalDateTime time;
+ private String describe;
+ private int bRange;
+ private String indexUser;
+ private LocalDateTime updateTime = LocalDateTime.now();
+ private int state;
+ private String name;
+ private String strTime;
+ private List list;
+
+ public String getStrTime() {
+ return strTime;
+ }
+
+ public void setStrTime(String strTime) {
+ this.strTime = strTime;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getIndexEventAss() {
+ return indexEventAss;
+ }
+
+ public void setIndexEventAss(String indexEventAss) {
+ this.indexEventAss = indexEventAss;
+ }
+
+ public LocalDateTime getTime() {
+ return time;
+ }
+
+ public void setTime(LocalDateTime time) {
+ this.time = time;
+ }
+
+ public String getDescribe() {
+ return describe;
+ }
+
+ public void setDescribe(String describe) {
+ this.describe = describe;
+ }
+
+ public int getbRange() {
+ return bRange;
+ }
+
+ public void setbRange(int bRange) {
+ this.bRange = bRange;
+ }
+
+ public String getIndexUser() {
+ return indexUser;
+ }
+
+ public void setIndexUser(String indexUser) {
+ this.indexUser = indexUser;
+ }
+
+ public LocalDateTime getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(LocalDateTime updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public int getState() {
+ return state;
+ }
+
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public void setList(List list) {
+ this.list = list;
+ }
+
+ @Override
+ public String toString() {
+ return "EventAssObj [indexEventAss=" + indexEventAss + ", time=" + time + ", describe=" + describe + ", bRange="
+ + bRange + ", indexUser=" + indexUser + ", updateTime=" + updateTime + ", state=" + state + ", name="
+ + name + ", strTime=" + strTime + ", list=" + list + "]";
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/FinalData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/FinalData.java
new file mode 100644
index 000000000..1d7a025a4
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/FinalData.java
@@ -0,0 +1,25 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+public class FinalData {
+ public static final int TIME_THRESHOLD = 10;//暂降事件按开始时间归集门槛10秒
+ public static final int MAX_GROUP_NUM = 1000;//分组的最大组数
+ public static final int MAX_CATA_NUM = 7;//类别数
+ public static final int MAX_EVT_NUM = 1000;//最大事件个数
+
+ public static final int QVVR_TYPE_THREE = 9; //三相故障
+ public static final int QVVR_TYPE_UNKNOWN = 10; //故障类型未知
+ public static final int QVVR_TYPE_OUTOFRANGE = -1; //节点不在网络拓扑中
+ public static final int DATA_INF = -1;
+ public static final int EVT_TYPE_NUM = 6;//故障类型数
+ public static final int MAX_PATH_NUM = 50;//最大路径数
+ public static int NODE_NUM;//输入节点数
+
+ // 暂降综合评估算法
+ public static final int CLUSER_NUM = 4; // 系统中各监测点分类后的代表节点
+ public static final int MAX_LINE_NUM = 1000; // 监测点最多个数
+ public static final int MAX_STA_NUM = 120; // 支持的子系统个数
+
+ static {
+ NODE_NUM = -1;
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/PlantInfo.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/PlantInfo.java
new file mode 100644
index 000000000..27dfd7550
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/PlantInfo.java
@@ -0,0 +1,32 @@
+package com.njcn.advance.pojo.dto.relevent;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * pqs
+ *终端监测点名称信息
+ * nameGD:供电公司名称
+ * nameBD:变电站名称
+ * nameSubV:母线名称
+ * namePoint:监测点名称
+ * indexPoint:监测点的唯一标识
+ *
+ * 新增add
+ * xuyang
+ * 2021.05.11
+ * 监测点电压等级:monitorVoltageLevel
+ * 监测点干扰源类型终:monitorLoadType
+ */
+@Data
+public class PlantInfo implements Serializable {
+ private String indexPoint;
+ private String nameGD;
+ private String nameBD;
+ private String nameSubV;
+ private String namePoint;
+ private String monitorVoltageLevel;
+ private String monitorLoadType;
+ private String objName;
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/QtIdx.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/QtIdx.java
similarity index 94%
rename from pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/QtIdx.java
rename to pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/QtIdx.java
index f6cba8d7d..d9c002a73 100644
--- a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/QtIdx.java
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/QtIdx.java
@@ -1,4 +1,4 @@
-package com.njcn.advance.pojo.dto;
+package com.njcn.advance.pojo.dto.relevent;
import com.sun.jna.Structure;
import lombok.Data;
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/SagEvent.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/SagEvent.java
new file mode 100644
index 000000000..0b12f4a2b
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/relevent/SagEvent.java
@@ -0,0 +1,423 @@
+package com.njcn.advance.pojo.dto;
+
+import com.njcn.advance.pojo.dto.relevent.PlantInfo;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * pqs
+ *
+ * @author cdf
+ * @date 2023/7/21
+ */
+public class SagEvent implements Comparable, Serializable {
+ // 事件的唯一标识
+ private String indexEventDetail;
+
+ private Integer waveType;
+ // 暂降事件发生时间
+ private LocalDateTime sagTime;
+
+ // 暂降事件发生时间毫秒
+ private Integer msec;
+
+ // 事件描述
+ private String events;
+
+ // 持续时间
+ private Float persistTime;
+
+ // 发生暂降事件的监测点层级信息
+ private PlantInfo plantInfo;
+
+ // 拼接sagTime和msec
+ private String strTime;
+
+ // 事件发生时刻的毫秒表示
+ private Long time;
+
+ // 监测点的唯一标识
+ private String indexPoint;
+
+ // 归一化事件的GUID
+ private String indexEventAss;
+
+ // 特征幅值
+ private Float eventValue;
+
+ // 暂降原因
+ private String sagReason;
+
+ // 暂降类型
+ private String sagType;
+
+ // 暂降类型描述
+ private String sagTypeDes;
+
+ public String getSagTypeDes() {
+ return sagTypeDes;
+ }
+
+ public void setSagTypeDes(String sagTypeDes) {
+ this.sagTypeDes = sagTypeDes;
+ }
+
+ // 暂降深度
+ private String strEventValue;
+ private String strPersist;
+
+ // 事件是否经过高级算法处理(0-未处理,1-已处理,默认为0)
+ private Integer dealFlag;
+
+ // 事件是否经过高级算法处理中文描述(已处理、未处理)
+ private String dealFlagDescription;
+
+ // 录波文件是否存在(0-不存在,1-存在,默认为0)
+ private Integer fileFlag;
+
+ // 录波文件是否存在中文描述(存在、不存在)
+ private String fileFlagDescription;
+
+ // 高级算法返回dq持续时间
+ private Float dqTime;
+
+ // 高级算法处理事件个数记录
+ private Integer number;
+
+ // 归一化处理更新时间
+ private LocalDateTime dealTime;
+
+ // 高级算法的对应关系
+ private int cata;
+
+ // 第一次事件的触发时间
+ private Date firstTime;
+
+ // 第一次事件的暂降类型
+ private String firstType;
+
+ // 第一次事件的触发时间毫秒
+ private Integer firstMs;
+
+ // 第一次事件触发时间date->毫秒
+ private Long firstTimeMills;
+
+ // 暂降严重度
+ private Float severity;
+
+ // 排序方式
+ private int sortType = 0; // 初始化默认为0-按照时间排序 新增1-按暂降严重度排序 2-暂降发生时刻排序 3-先根据电压等级排序,如果相等再按照暂降幅值排序
+
+ //电压等级
+ private Double voltage;
+
+ //监测点对象名称
+ private String objName;
+
+ public String getObjName() {
+ return objName;
+ }
+
+ public void setObjName(String objName) {
+ this.objName = objName;
+ }
+
+ public Integer getWaveType() {
+ return waveType;
+ }
+
+ public void setWaveType(Integer waveType) {
+ this.waveType = waveType;
+ }
+
+ private String strVoltage;
+
+ public Double getVoltage() {
+ return voltage;
+ }
+
+ public void setVoltage(Double voltage) {
+ this.voltage = voltage;
+ }
+
+ public String getStrVoltage() {
+ return strVoltage;
+ }
+
+ public void setStrVoltage(String strVoltage) {
+ //转为double
+ strVoltage = strVoltage.toUpperCase();
+ String str = strVoltage.substring(0, strVoltage.indexOf("KV"));
+ this.voltage = Double.parseDouble(str);
+ }
+
+ public int getSortType() {
+ return sortType;
+ }
+
+ public void setSortType(int sortType) {
+ this.sortType = sortType;
+ }
+
+ public Float getSeverity() {
+ return severity;
+ }
+
+ public void setSeverity(Float severity) {
+ this.severity = severity;
+ }
+
+ public Long getFirstTimeMills() {
+ return firstTimeMills;
+ }
+
+ public void setFirstTimeMills(Long firstTimeMills) {
+ this.firstTimeMills = firstTimeMills;
+ }
+
+ public Integer getFirstMs() {
+ return firstMs;
+ }
+
+ public void setFirstMs(Integer firstMs) {
+ this.firstMs = firstMs;
+ }
+
+ public Date getFirstTime() {
+ return firstTime;
+ }
+
+ public void setFirstTime(Date firstTime) {
+ this.firstTime = firstTime;
+ }
+
+ public String getFirstType() {
+ return firstType;
+ }
+
+ public void setFirstType(String firstType) {
+ this.firstType = firstType;
+ }
+
+ public Integer getFileFlag() {
+ return fileFlag;
+ }
+
+ public void setFileFlag(Integer fileFlag) {
+ this.fileFlag = fileFlag;
+ }
+
+ public String getFileFlagDescription() {
+ return fileFlagDescription;
+ }
+
+ public void setFileFlagDescription(String fileFlagDescription) {
+ this.fileFlagDescription = fileFlagDescription;
+ }
+
+ public int getCata() {
+ return cata;
+ }
+
+ public void setCata(int cata) {
+ this.cata = cata;
+ }
+
+ public LocalDateTime getDealTime() {
+ return dealTime;
+ }
+
+ public void setDealTime(LocalDateTime dealTime) {
+ this.dealTime = dealTime;
+ }
+
+ public Float getDqTime() {
+ return dqTime;
+ }
+
+ public void setDqTime(Float dqTime) {
+ this.dqTime = dqTime;
+ }
+
+ public Integer getNumber() {
+ return number;
+ }
+
+ public void setNumber(Integer number) {
+ this.number = number;
+ }
+
+ public void setDealFlagDescription(String dealFlagDescription) {
+ this.dealFlagDescription = dealFlagDescription;
+ }
+
+ public String getDealFlagDescription() {
+ return dealFlagDescription;
+ }
+
+ public Integer getDealFlag() {
+ return dealFlag;
+ }
+
+ public void setDealFlag(Integer dealFlag) {
+ this.dealFlag = dealFlag;
+ }
+
+ public String getIndexEventDetail() {
+ return indexEventDetail;
+ }
+
+ public void setIndexEventDetail(String indexEventDetail) {
+ this.indexEventDetail = indexEventDetail;
+ }
+
+ public LocalDateTime getSagTime() {
+ return sagTime;
+ }
+
+ public void setSagTime(LocalDateTime sagTime) {
+ this.sagTime = sagTime;
+ }
+
+ public Integer getMsec() {
+ return msec;
+ }
+
+ public void setMsec(Integer msec) {
+ this.msec = msec;
+ }
+
+ public String getEvents() {
+ return events;
+ }
+
+ public void setEvents(String events) {
+ this.events = events;
+ }
+
+ public Float getPersistTime() {
+ return persistTime;
+ }
+
+ public void setPersistTime(Float persistTime) {
+ if (persistTime == null) {
+ this.persistTime = 0f;
+ return;
+ }
+
+ float f1 = (float) (Math.round(persistTime.floatValue() * 1000)) / 1000;
+ this.persistTime = new Float(f1);
+ }
+
+ public PlantInfo getPlantInfo() {
+ return plantInfo;
+ }
+
+ public void setPlantInfo(PlantInfo plantInfo) {
+ this.plantInfo = plantInfo;
+ }
+
+ public String getStrTime() {
+ return strTime;
+ }
+
+ public void setStrTime(String strTime) {
+ this.strTime = strTime;
+ }
+
+ public Long getTime() {
+ return time;
+ }
+
+ public void setTime(Long time) {
+ this.time = time;
+ }
+
+ public String getIndexPoint() {
+ return indexPoint;
+ }
+
+ public void setIndexPoint(String indexPoint) {
+ this.indexPoint = indexPoint;
+ }
+
+ public String getIndexEventAss() {
+ return indexEventAss;
+ }
+
+ public void setIndexEventAss(String indexEventAss) {
+ this.indexEventAss = indexEventAss;
+ }
+
+ public Float getEventValue() {
+ return eventValue;
+ }
+
+ public void setEventValue(Float eventValue) {
+ if (eventValue == null) {
+ this.eventValue = 0f;
+ return;
+ }
+
+ this.eventValue = eventValue;
+ }
+
+ public String getSagReason() {
+ return sagReason;
+ }
+
+ public void setSagReason(String sagReason) {
+ this.sagReason = sagReason;
+ }
+
+ public String getSagType() {
+ return sagType;
+ }
+
+ public void setSagType(String sagType) {
+ this.sagType = sagType;
+ }
+
+ public String getStrEventValue() {
+ return strEventValue;
+ }
+
+ public void setStrEventValue(String strEventValue) {
+ this.strEventValue = strEventValue;
+ }
+
+ public String getStrPersist() {
+ return strPersist;
+ }
+
+ public void setStrPersist(String strPersist) {
+ this.strPersist = strPersist;
+ }
+
+
+
+ // 根据设定规则进行排序
+ @Override
+ public int compareTo(SagEvent obj) {
+ switch (this.getSortType()) {
+ case 1:
+ return obj.getSeverity().compareTo(this.getSeverity());
+ case 2:
+ return this.getTime().compareTo(obj.getTime());
+ case 3: {
+ if (obj.getVoltage().compareTo(this.getVoltage()) != 0) {
+ return obj.getVoltage().compareTo(this.getVoltage());
+ }
+ else {
+ return this.getEventValue().compareTo(obj.getEventValue());
+ }
+ }
+ default:
+ break;
+ }
+
+ return this.getFirstTimeMills().compareTo(obj.getFirstTimeMills());
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/AnalyWave.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/AnalyWave.java
new file mode 100644
index 000000000..8f4b1ae9f
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/AnalyWave.java
@@ -0,0 +1,1152 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.CharsetUtil;
+import com.njcn.advance.utils.WaveUtils;
+import com.njcn.common.config.GeneralInfo;
+import com.njcn.common.utils.wave.BitConverter;
+import com.njcn.harmonic.utils.PubUtils;
+import com.njcn.oss.utils.FileStorageUtil;
+
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import sun.nio.ch.IOUtil;
+
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+public class AnalyWave {
+
+
+
+
+ /*****************************************
+ * 解析comtrate文件工具类
+ * author yexb根据Ww算法装换
+ *****************************************/
+ // 日志记录
+ private static final Logger logger = LoggerFactory.getLogger(AnalyWave.class);
+
+ private AnalyWaveModel.tagComtradeCfg ComtradeCfg;//cfg实体类
+ private AnalyWaveModel.tagRates RatesCfg;//cfg_采样率实体类
+ private AnalyWaveModel.tagDataValue TagDataValue;//返回数据实体类
+ private String strBinType;//结束读取cfg标志
+ private int iPush = 0;//前推周波个数(目前常见的是5个或者10个周波)
+ private float nFreq;//comtrade频率 WW 2019-11-14
+ private long nOneWaveNum = 32;//最小采样率,高级算法时候需要
+ private long nAllWaveNum = 0;//所有波形
+ private Date TimeTrige;//cfg中【波形的触发时间】、【波形的起始时间】
+
+ private static Date TimeWave;
+
+ public Date getTimeTrige() {
+ return TimeTrige;
+ }
+
+ public void setTimeTrige(Date timeTrige) {
+ TimeTrige = timeTrige;
+ }
+
+ public static Date getTimeWave() {
+ return TimeWave;
+ }
+
+ public void setTimeWave(Date timeWave) {
+ TimeWave = timeWave;
+ }
+
+ //add by sw 暂降触发时间
+ private Date firstTime;//暂降触发第一次
+ private Integer firstMs;
+
+ //add by sw获取最小采样率供其他类使用
+ public long getnOneWaveNum() {
+ return nOneWaveNum;
+ }
+
+ public AnalyWaveModel.tagRates getRatesCfg() {
+ return RatesCfg;
+ }
+
+ public Date getFirstTime() {
+ return firstTime;
+ }
+
+ public Integer getFirstMs() {
+ return firstMs;
+ }
+
+ public String startTime;
+
+ public String ms;
+
+
+ /******************************************
+ * 调用读取comtrate文件方法
+ ** ** strFilePath *** cfg文件路径
+ * *** auth *** 读取方式 null则使用本地读取方式读取
+ ******************************************/
+ public AnalyWaveModel.tagDataValue readComtrade(List temCfgList,byte[] array, int iFlag) {
+ //初始化参数
+ ComtradeCfg = new AnalyWaveModel.tagComtradeCfg();
+ RatesCfg = new AnalyWaveModel.tagRates();
+ TagDataValue = new AnalyWaveModel.tagDataValue();
+ // 读取cfg文件
+ if (!AnalyseComtradeCfg(temCfgList)) {
+ return TagDataValue;
+ }
+
+ if (!strBinType.equals("BINARY")) {
+ return TagDataValue;
+ }
+
+ //编辑数据标题 YXB2020-10-09 去除相别为N相的数据//存储数据标题
+ List tmpWaveTitle = new ArrayList<>();
+ tmpWaveTitle.add("Time");
+ for (int j = 0; j < ComtradeCfg.nAnalogNum; j++) {
+ if (ComtradeCfg.OneChannleCfg.get(j).szPhasicName.toUpperCase().equals("N")) {
+ continue;
+ } else {
+ String strUnit = "U";
+ switch (ComtradeCfg.OneChannleCfg.get(j).szUnitName.toUpperCase()) {
+ case "KV":
+ strUnit = "U";
+ break;
+ case "V":
+ strUnit = "U";
+ break;
+ case "A":
+ strUnit = "I";
+ break;
+ }
+ tmpWaveTitle.add(strUnit + ComtradeCfg.OneChannleCfg.get(j).szPhasicName.toUpperCase() + "相");
+ }
+ }
+ // 读取dat
+ /*****根据通道号计算相别** add by yexb -----Start****
+ * 1、判断是否是3的倍数,是3的倍数则是3相
+ * 2、假如不是3的倍数 ,是1的倍数则是单相
+ ********************************************************/
+ if (ComtradeCfg.nAnalogNum % 3 == 0) {
+ ComtradeCfg.nPhasic = 3;
+ } else if (ComtradeCfg.nAnalogNum % 1 == 0) {
+ ComtradeCfg.nPhasic = 1;
+ }
+ TagDataValue.setiPhasic(ComtradeCfg.nPhasic);
+
+ List> listWaveData = AnalyseComtradeDat(array, iFlag);
+ TagDataValue.setTmpWaveTitle(tmpWaveTitle);
+ TagDataValue.setListWaveData(listWaveData);
+
+ /*****根据通道号计算相别** add by yexb -----end****/
+
+ return TagDataValue;
+ }
+
+
+ /*********************************
+ * 读取cfg方法
+ * param strFilePath 文件路径
+ * return 返回bool为是否解析出错
+ * readType 1:本地磁盘 2:华为obs 3: minioss
+ **********************************/
+ private boolean AnalyseComtradeCfg(List temCfgList) {
+ Iterator iterable = temCfgList.iterator();
+ iterable.next();
+ String[] strTempArray;// 读取cfg文件
+ try {
+ nFreq = 0f;//WW 2019-11-14
+ String strFileLine = iterable.next();
+ strTempArray = strFileLine.split(",");
+
+ for (int i = 0; i < strTempArray.length; i++) {
+ switch (i) {
+ case 0:// 总个数
+ ComtradeCfg.nChannelNum = Integer.parseInt(strTempArray[i]);
+ break;
+ case 1:// 模拟量的个数
+ {
+ String str = strTempArray[i].substring(0, strTempArray[i].length() - 1);
+ ComtradeCfg.nAnalogNum = Integer.parseInt(str);
+ }
+ break;
+ case 2:// 开关量的个数
+ {
+ String str = strTempArray[i].substring(0, strTempArray[i].length() - 1);
+ ComtradeCfg.nDigitalNum = Integer.parseInt(str);
+ }
+ break;
+ }
+ }
+
+ // 从第三行到第ComtradeCfg.nChannelNum+3行是模拟量通道和数字量通道
+ for (int i = 0; i < ComtradeCfg.nChannelNum; i++) {
+ AnalyWaveModel.tagOneChannleCfg OneChannlecfg = new AnalyWaveModel.tagOneChannleCfg();
+ ComtradeCfg.OneChannleCfg.add(OneChannlecfg);
+
+ strFileLine = iterable.next();
+ strTempArray = strFileLine.split(",");
+ // 配置总共13项
+ for (int j = 0; j < strTempArray.length; j++) {
+ switch (j) {
+ case 0:// 通道序号
+ OneChannlecfg.nIndex = Integer.parseInt(strTempArray[j]);
+ break;
+ case 1:// 通道名称
+ OneChannlecfg.szChannleName = strTempArray[j];
+ break;
+ case 2:// 相位名称
+ OneChannlecfg.szPhasicName = strTempArray[j];
+ break;
+ case 3:// 监视的通道名称
+ OneChannlecfg.szMonitoredChannleName = strTempArray[j];
+ break;
+ case 4:// 通道的单位
+ OneChannlecfg.szUnitName = strTempArray[j];
+ break;
+ case 5:// 通道的系数
+ OneChannlecfg.fCoefficent = Float.parseFloat(strTempArray[j]);
+ break;
+ case 6:// 通道的偏移量
+ OneChannlecfg.fOffset = Float.parseFloat(strTempArray[j]);
+ break;
+ case 7:// 起始采样时间的偏移量
+ OneChannlecfg.fTimeOffset = Float.parseFloat(strTempArray[j]);
+ break;
+ case 8:// 采样值的最小值
+ OneChannlecfg.nMin = Integer.parseInt(strTempArray[j]);
+ break;
+ case 9:// 采样值的最大值
+ OneChannlecfg.nMax = Integer.parseInt(strTempArray[j]);
+ break;
+ case 10:// 一次变比
+ OneChannlecfg.fPrimary = Float.parseFloat(strTempArray[j]);
+ break;
+ case 11:// 二次变比
+ OneChannlecfg.fSecondary = Float.parseFloat(strTempArray[j]);
+ break;
+ case 12:// 一次值还是二次值标志
+ OneChannlecfg.szValueType = strTempArray[j];
+ break;
+ }
+ }
+ }
+ // 采样频率
+ strFileLine = iterable.next();
+ float fFreq = Float.parseFloat(strFileLine);
+ nFreq = (float) fFreq;//WW 2019-11-14
+ // 采样段数
+ strFileLine = iterable.next();
+ int nRates = Integer.parseInt(strFileLine);
+ RatesCfg.nRates = nRates;
+ // 获得每段的采样率
+ long nOffset = 0;
+ for (int i = 0; i < nRates; i++) {
+ strFileLine = iterable.next();
+ strTempArray = strFileLine.split(",");
+
+ AnalyWaveModel.tagOneRate OneRate = new AnalyWaveModel.tagOneRate();
+ RatesCfg.OneRate.add(OneRate);
+
+ for (int j = 0; j < strTempArray.length; j++) {
+
+ switch (j) {
+ case 0:// 单周波采样点数
+ OneRate.nOneSample = (int) (Float.parseFloat(strTempArray[j]) / nFreq);//WW 2019-11-14
+ break;
+ case 1:// 总点数 //这里的strTemp是一个偏移量
+ OneRate.nSampleNum = (long) (Float.parseFloat(strTempArray[j]) - nOffset);
+ nOffset = OneRate.nSampleNum;
+ break;
+ }
+ }
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS");
+ // 波形起始时间
+ strFileLine = iterable.next();
+ strFileLine = strFileLine.substring(0, strFileLine.length() - 3).replace(",", " ");
+ TimeTrige = sdf.parse(strFileLine);
+ // 暂态触发时间
+ strFileLine = iterable.next();
+ strFileLine = strFileLine.substring(0, strFileLine.length() - 3).replace(",", " ");
+ TimeWave = sdf.parse(strFileLine);
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(TimeWave);
+ firstMs = calendar.get(Calendar.MILLISECOND);
+ firstTime = calendar.getTime();
+
+ long a = TimeWave.getTime();
+ long b = TimeTrige.getTime();
+ int c = (int) (a - b);
+ if (c >= 90 && c <= 110) {
+ iPush = 100;
+ } else if (c >= 190 && c <= 210) {
+ iPush = 200;
+ }
+ // 赋值编码格式(二进制)
+ strBinType = iterable.next().toUpperCase();
+
+
+
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ logger.error("读取文件内容出错"+e.getMessage());
+ return false;
+ }finally {
+
+
+
+ }
+ return true;
+ }
+
+ /*********************************
+ * 读取dat方法
+ * param strFilePath
+ * List> 返回波形瞬时值
+ **********************************/
+ private List> AnalyseComtradeDat(byte[] array, int iFlag) {
+ float xValueAll = 0;//初始化xValue的值
+ boolean blxValue = false;//判断是否首次登陆
+
+ List> listWaveData = new ArrayList<>();//返回数据
+
+
+ try {
+
+
+
+
+ // 计算每个单独的数据块的大小 4字节的序号 4字节的时间 2字节的值
+ // 示例中的排布是 4字节的序号 4字节的时间 UA(2字节) UB(2字节) UC(2字节) IA(2字节) IB(2字节)
+ // IC(2字节)
+ int nDigSize = (ComtradeCfg.nDigitalNum % 16) > 0 ? (ComtradeCfg.nDigitalNum / 16 + 1) * 2
+ : ComtradeCfg.nDigitalNum / 16 * 2;
+ int nBlockSize = 2 * Integer.SIZE / 8 + ComtradeCfg.nAnalogNum * 2 + nDigSize;
+ int nBlockNum = array.length / nBlockSize;
+ nOneWaveNum = MinWaveSample(RatesCfg.OneRate);
+ /********************************************************
+ * iFlag == 0 高级算法的要求,采样率只能是32-128
+ * iFlag == 1 普通展示,采样率按照cfg里面最小的(大于32)
+ * iFlag == 2 App抽点要求,采样率抽点成32
+ * iFlag == 3 高级算法原始波形(大于32)
+ ********************************************************/
+ //高级算法的要求,采样率只能是32-128
+ if (iFlag == 0) {
+ if (nOneWaveNum < 32) {
+ nOneWaveNum = 32;
+ } else if (nOneWaveNum > 128) {
+ nOneWaveNum = 128;
+ }
+ }
+ //App抽点要求,采样率抽点成32
+ else if (iFlag == 2) {
+ if (nOneWaveNum < 32) {
+ nOneWaveNum = 32;
+ } else if (nOneWaveNum > 32) {
+ nOneWaveNum = 32;
+ }
+ }
+
+ int iRates = 0;
+ // 设定最小采样率
+ int nnInd = 0;
+ long nWaveNum = 0, nNum = 0;// 抽点后总共多少点数据
+ AnalyWaveModel.tagRates RateTemp = new AnalyWaveModel.tagRates();
+ for (iRates = 0; iRates < RatesCfg.nRates; iRates++) {
+ if (RatesCfg.OneRate.get(iRates).nOneSample >= 32) {
+ // 计算本段录波总共有多少波形
+ nWaveNum = RatesCfg.OneRate.get(iRates).nSampleNum / RatesCfg.OneRate.get(iRates).nOneSample;
+ nAllWaveNum += nWaveNum;
+ // 将最低采样率替换到本段录波内
+ AnalyWaveModel.tagOneRate OneTempRate = new AnalyWaveModel.tagOneRate();
+ RateTemp.OneRate.add(OneTempRate);
+ //iFlag =3 一定不进行抽点算法
+ if (iFlag != 3) {
+ //true 抽点算法(当前采样率跟统一采样率不一样则是抽点,否则是未抽点)
+ if (RatesCfg.OneRate.get(iRates).nOneSample != nOneWaveNum) {
+ RateTemp.OneRate.get(nnInd).nOneSample = nOneWaveNum;
+ // 计算本段录波按照最低采样点应该有多少录波
+ RateTemp.OneRate.get(nnInd).nSampleNum = nOneWaveNum * nWaveNum;
+ } else {
+ RateTemp.OneRate.get(nnInd).nOneSample = RatesCfg.OneRate.get(iRates).nOneSample;
+ // 计算本段录波按照最低采样点应该有多少录波
+ RateTemp.OneRate.get(nnInd).nSampleNum = RatesCfg.OneRate.get(iRates).nOneSample * nWaveNum;
+ }
+ } else {
+ RateTemp.OneRate.get(nnInd).nOneSample = RatesCfg.OneRate.get(iRates).nOneSample;
+ // 计算本段录波按照最低采样点应该有多少录波
+ RateTemp.OneRate.get(nnInd).nSampleNum = RatesCfg.OneRate.get(iRates).nOneSample * nWaveNum;
+ }
+
+ nNum += RateTemp.OneRate.get(nnInd).nSampleNum;
+ // 正常的配置中采样率
+ RatesCfg.OneRate.get(nnInd).nOneSample = RatesCfg.OneRate.get(iRates).nOneSample;
+ RatesCfg.OneRate.get(nnInd).nSampleNum = RatesCfg.OneRate.get(iRates).nSampleNum;
+ nnInd++;
+ }
+ }
+
+ long nOffSet = 0;
+ int nIndex = 0;
+ long nWaveSpan = 0;
+
+ float fValue;
+ float dfValue;//两个点之间的时间差
+ for (int i = 0; i < nBlockNum; i++) {
+ // 计算本段抽点采样间隔
+ nWaveSpan = RatesCfg.OneRate.get(nIndex).nOneSample / RateTemp.OneRate.get(nIndex).nOneSample;
+ // 判断是否进入下一段
+ if (i == RatesCfg.OneRate.get(nIndex).nSampleNum + nOffSet) {
+ nOffSet += RatesCfg.OneRate.get(nIndex).nSampleNum;
+ nIndex++;
+ if (nIndex == nnInd) {
+ break;
+ }
+ }
+ dfValue = (float) 20 / RatesCfg.OneRate.get(nIndex).nOneSample;
+ // 判断是否到了需要抽的采样点
+ if (i % nWaveSpan == 0) {
+ // 计算每个通道的值
+ List tmpWaveData = new ArrayList();//存储局部数据集合,包含了时间,A,B,C三相
+ for (int j = 0; j < ComtradeCfg.nAnalogNum; j++) {
+ //数据只有电压ABC三相数据,不展示U0、I0等数据 YXB2020-10-09 去除相别为N相的数据
+ if (ComtradeCfg.OneChannleCfg.get(j).szPhasicName.toUpperCase().equals("N")) {
+ break;
+ }
+
+ float fCoef = ComtradeCfg.OneChannleCfg.get(j).fCoefficent;
+ fValue = BitConverter.byte2ToUnsignedShort(array, i * nBlockSize + 2 * 4 + j * 2) * fCoef;
+
+ //WW 2019-11-14
+ /**************************
+ * 1、接口返回的默认是二次值
+ * 2、P是一次值 S是二次值
+ * 3、S(二次值)情况下:
+ * ①、单位为"V"时候则直接等于;
+ * ②、单位为"kV"时候需要乘以1000
+ * 4、P(一次值)情况下:
+ * ①、单位为"V"时候则直接等于;
+ * ②、单位为"kV"时候需要乘以1000
+ **************************/
+ if (ComtradeCfg.OneChannleCfg.get(j).szValueType.toUpperCase().equals("S"))//P是一次值 S是二次值
+ {
+ if (ComtradeCfg.OneChannleCfg.get(j).szUnitName.toUpperCase().equals("KV"))//判断单位是V还是kV
+ {
+ fValue = fValue * 1000.0f;
+ } else {
+ fValue = fValue;
+ }
+ } else if (ComtradeCfg.OneChannleCfg.get(j).szValueType.toUpperCase().equals("P"))//P是一次值 S是二次值
+ {
+ if (ComtradeCfg.OneChannleCfg.get(j).szUnitName.toUpperCase().equals("V"))//判断单位是V还是kV
+ {
+ if (ComtradeCfg.OneChannleCfg.get(j).fPrimary != 0.0f)//根据cfg内的变比,将一次值转换成二次值
+ {
+ fValue = fValue * ComtradeCfg.OneChannleCfg.get(j).fSecondary / ComtradeCfg.OneChannleCfg.get(j).fPrimary;
+ } else {
+ fValue = fValue;
+ }
+ } else if (ComtradeCfg.OneChannleCfg.get(j).szUnitName.toUpperCase().equals("KV"))//判断单位是V还是kV
+ {
+ if (ComtradeCfg.OneChannleCfg.get(j).fPrimary != 0.0f)//根据cfg内的变比,将一次值转换成二次值
+ {
+ fValue = fValue * 1000.0f * ComtradeCfg.OneChannleCfg.get(j).fSecondary / ComtradeCfg.OneChannleCfg.get(j).fPrimary;
+ } else {
+ fValue = fValue;
+ }
+ } else //还有可能是电流,单位是A
+ {
+ if (ComtradeCfg.OneChannleCfg.get(j).fPrimary != 0.0f)//根据cfg内的变比,将一次值转换成二次值
+ {
+ fValue = ComtradeCfg.OneChannleCfg.get(j).fSecondary / ComtradeCfg.OneChannleCfg.get(j).fPrimary;
+ } else {
+ fValue = fValue;
+ }
+ }
+ }
+
+ //ComtradeCfg.OneChannleCfg.get(j)
+
+ //xValue前移量,假如是第一次时候则需要前移
+ if (!blxValue && j == 0) {
+ xValueAll = (float) (i * 20) / RatesCfg.OneRate.get(nIndex).nOneSample - iPush;
+ blxValue = true;
+ //只增加一个xValue的值
+ tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);//增加时间值
+ } else if (j == 0) {
+ xValueAll += (float) nWaveSpan * dfValue;
+ //只增加一个xValue的值
+ tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);//增加时间值
+ }
+
+ //不同通道yValue的值都需要增加,最终成ABC三相
+ tmpWaveData.add((float) (Math.round(fValue * 100)) / 100);//每个通道的值
+ }
+ listWaveData.add(tmpWaveData);//把每个单独的值赋予到整体里面去
+ }
+ }
+ } catch (Exception e) {
+ logger.error("读取文件出错:" + e.getMessage());
+ return listWaveData;
+ }finally {
+
+ }
+
+ return listWaveData;
+ }
+
+ /*********************************
+ * 根据波形数据算出rms值数据
+ * param tmplistwave 瞬时波形数据
+ * List> 返回RMS波形
+ **********************************/
+ @SuppressWarnings("unused")
+ public List> showValidData(List> tmplistwave) {
+ List> listRms = new ArrayList<>();//返回rms的值
+
+ float fs = nOneWaveNum;
+ int nWaveNum = (int) nAllWaveNum;
+
+ int HalfTs = (int) fs;// 全波有效值 (int)fs / 2;//半波有效值
+ // 计算有效值算法
+ /*********************************
+ * modify by yexibao 2020-10-29
+ * 增加多波形算法 ---------start
+ ********************************/
+ double iWave = 0;
+ if (tmplistwave.size() > 0) {
+ //ComtradeCfg.nAnalogNum为值的个数(-1的原因是一个存的是时间)
+ iWave = Math.floor((tmplistwave.get(0).size() - 1) / ComtradeCfg.nPhasic);
+ List tmpListRms;
+ //每一项一项计算
+ for (int j = 0; j < iWave; j++) {
+ double fSumA = 0.0, fSumB = 0.0, fSumC = 0.0;
+ double fValidA = 0.0, fValidB = 0.0, fValidC = 0.0;
+ //循环原始数据
+ for (int i = 0; i < tmplistwave.size(); i++) {
+ // 当第一次循环的时候实例化,其余的获取已有的List
+ List tmpListValue = tmplistwave.get(i); //获取每一项的值
+ if (j == 0) {
+ tmpListRms = new ArrayList<>();
+ tmpListRms.add(tmpListValue.get(0));//获取时间
+ listRms.add(tmpListRms);
+ } else {
+ tmpListRms = listRms.get(i);
+ }
+
+ //包含了时间、电压(A、B、C)三相、电流(A、B、C)三相
+ if (tmpListValue.size() >= 2) {
+ //电压有效值算法,根据相别进行处理
+ switch (ComtradeCfg.nPhasic) {
+ case 1:
+ fSumA += Math.pow(tmpListValue.get(1 + ComtradeCfg.nPhasic * j), 2);
+ if (i >= HalfTs)// 计算有效值
+ {
+ List forwardListValue = tmplistwave.get(i - HalfTs);//获取前推周波的值
+ fSumA -= Math.pow(forwardListValue.get(1 + ComtradeCfg.nPhasic * j), 2);
+ }
+ fValidA = Math.sqrt(fSumA / HalfTs);
+
+ tmpListRms.add((float) fValidA);
+ listRms.set(i, tmpListRms);
+ break;
+ case 2:
+ fSumA += Math.pow(tmpListValue.get(1 + ComtradeCfg.nPhasic * j), 2);
+ fSumB += Math.pow(tmpListValue.get(2 + ComtradeCfg.nPhasic * j), 2);
+ if (i >= HalfTs)// 计算有效值
+ {
+ List forwardListValue = tmplistwave.get(i - HalfTs);//获取前推周波的值
+ fSumA -= Math.pow(forwardListValue.get(1 + ComtradeCfg.nPhasic * j), 2);
+ fSumB -= Math.pow(forwardListValue.get(2 + ComtradeCfg.nPhasic * j), 2);
+ }
+ fValidA = Math.sqrt(fSumA / HalfTs);
+ fValidB = Math.sqrt(fSumB / HalfTs);
+
+ tmpListRms.add((float) fValidA);
+ tmpListRms.add((float) fValidB);
+ listRms.set(i, tmpListRms);
+ break;
+ case 3:
+ fSumA += Math.pow(tmpListValue.get(1 + ComtradeCfg.nPhasic * j), 2);
+ fSumB += Math.pow(tmpListValue.get(2 + ComtradeCfg.nPhasic * j), 2);
+ fSumC += Math.pow(tmpListValue.get(3 + ComtradeCfg.nPhasic * j), 2);
+ if (i >= HalfTs)// 计算有效值
+ {
+ List forwardListValue = tmplistwave.get(i - HalfTs);//获取前推周波的值
+ fSumA -= Math.pow(forwardListValue.get(1 + ComtradeCfg.nPhasic * j), 2);
+ fSumB -= Math.pow(forwardListValue.get(2 + ComtradeCfg.nPhasic * j), 2);
+ fSumC -= Math.pow(forwardListValue.get(3 + ComtradeCfg.nPhasic * j), 2);
+ }
+ fValidA = Math.sqrt(fSumA / HalfTs);
+ fValidB = Math.sqrt(fSumB / HalfTs);
+ fValidC = Math.sqrt(fSumC / HalfTs);
+
+ tmpListRms.add((float) fValidA);
+ tmpListRms.add((float) fValidB);
+ tmpListRms.add((float) fValidC);
+ listRms.set(i, tmpListRms);
+ break;
+ }
+ }
+ }
+ }
+ }
+ //过滤前一个周波
+ //HalfTs表示一个周波
+ try {
+ for (int i = 0; i < HalfTs; i++) {
+ //电压有效值算法
+ List tmpListRms = new ArrayList<>();//没相具体的值
+ for (int j = 0; j < iWave; j++) {
+ if (j == 0) {
+ tmpListRms.add(listRms.get(i).get(0));//获取时间
+ }
+
+ switch (ComtradeCfg.nPhasic) {
+ case 1:
+ tmpListRms.add(listRms.get(i + HalfTs).get(1 + ComtradeCfg.nPhasic * j));
+ break;
+ case 2:
+ tmpListRms.add(listRms.get(i + HalfTs).get(1 + ComtradeCfg.nPhasic * j));
+ tmpListRms.add(listRms.get(i + HalfTs).get(2 + ComtradeCfg.nPhasic * j));
+ break;
+ case 3:
+ tmpListRms.add(listRms.get(i + HalfTs).get(1 + ComtradeCfg.nPhasic * j));
+ tmpListRms.add(listRms.get(i + HalfTs).get(2 + ComtradeCfg.nPhasic * j));
+ tmpListRms.add(listRms.get(i + HalfTs).get(3 + ComtradeCfg.nPhasic * j));
+ break;
+ }
+ }
+ listRms.set(i, tmpListRms);//重新赋值
+ }
+ } catch (Exception e) {
+ logger.error("更改收个周波值出错");
+ }
+ return listRms;
+ }
+
+ /*public static void main(String[] args) {
+ AnalyWave analyWave = new AnalyWave();
+ AnalyWaveModel.tagDataValue realWave = analyWave.readComtrade("C:\\Users\\DELL\\Desktop\\hikvision\\1_20230426_153245_471.cfg", null, 1);//获取原始波形值
+ //List> realWave = analyWave.readComtrade("C:\\Users\\Lenovo\\Desktop\\Comtrade\\waveTemp9200\\192.168.10.128\\1_20200927_135822_644.CFG", null, 0);//获取原始波形值
+ List> result1=analyWave.showValidData(realWave.getListWaveData());
+ realWave.getListWaveData();
+ *//********************************************************
+ * iFlag == 0 高级算法的要求,采样率只能是32-128
+ * iFlag == 1 普通展示,采样率按照cfg里面最小的(大于32)
+ * iFlag == 2 App抽点要求,采样率抽点成32
+ * iFlag == 3 高级算法原始波形(大于32)
+ ********************************************************//*
+ List> result = analyWave.getEigenvalue(realWave.getListWaveData(), true);
+ List> result2 = analyWave.getEigenvalue(realWave.getListWaveData(), true);
+
+ }*/
+
+ /*****************************
+ *获取暂降特征值,包含离线
+ ** ** strFilePath *** cfg文件路径
+ *** auth *** 读取方式 null则使用本地读取方式读取
+ *****************************/
+ public List> getEigenvalue(List> realWave, boolean iFlag) {
+ List> result = null;//返回值
+ if (realWave.size() > 0) {
+ //获取突变量和rms值
+ if (GetAnaylseValue(realWave)) {
+ if (listRms_Offline.size() > 0 && listTBL_Offline.size() > 0) {
+ result = GetEventValue(realWave, listTBL_Offline, listRms_Offline, (int) nOneWaveNum, iFlag);
+ if (result.size() == 3) {
+ if ((result.get(0).get(1) > 0.9 && result.get(0).get(1) < 1.1) && (result.get(1).get(1) > 0.9 && result.get(1).get(1) < 1.1) &&
+ (result.get(2).get(1) > 0.9 && result.get(2).get(1) < 1.1)) {
+ result = GetEventValue(realWave, listTBL_Offline, listRms_Offline, (int) nOneWaveNum, iFlag);
+ }
+// //第五行显示电压PU
+// //String strDes = TimeTrige.ToString("yyyy-MM-dd HH:mm:ss.fff");
+// String strDes = "";
+// if (result.get(0).get(1) <= 0.9 || result.get(1).get(1) <= 0.9 || result.get(2).get(1) <= 0.9)
+// strDes += "事件类型:暂降事件 ";
+// else if (result.get(0).get(1) <= 0.05 || result.get(1).get(1) <= 0.05 || result.get(2).get(1) <= 0.05)
+// strDes += "事件类型:中断事件 ";
+// else if (result.get(0).get(1) >= 1.1 || result.get(1).get(1) >= 1.1 || result.get(2).get(1) >= 1.1)
+// strDes += "事件类型:暂升事件 ";
+// for (int iTemp = 0; iTemp < 3; iTemp++) {
+// String strPhasic = "A相";
+// switch (iTemp) {
+// case 0:
+// strPhasic = "A相";
+// break;
+// case 1:
+// strPhasic = "B相";
+// break;
+// case 2:
+// strPhasic = "C相";
+// break;
+// }
+// String strType = "";
+// if (result.get(iTemp).get(1) <= 0.05)
+// strType = "电压中断";
+// else if (result.get(iTemp).get(1) <= 0.9)
+// strType = "电压暂降";
+// else if (result.get(iTemp).get(1) >= 1.1)
+// strType = "电压暂升";
+// if (strType != "") {
+// strDes +="暂降事件:"+ strPhasic + strType + ",运行电压:" + result.get(iTemp).get(2) + "V,残余电压:" + result.get(iTemp).get(2) +
+// "V,残余电压(百分比):" + result.get(iTemp).get(1) * 100.0f + "%,持续时间:" + result.get(iTemp).get(1) + "毫秒; ";
+// }
+// }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /*********************************
+ * 离线波形导入时获取突变量算法
+ * param tmpListWave 波形原始数据
+ **********************************/
+ private List> listRms_Offline;//离线数据RMS有效值数据
+ private List> listTBL_Offline;//离线数据突变量数据
+ private double fMinMagA = 0;
+ private double fMinMagB = 0;
+ private double fMinMagC = 0;
+
+ public Boolean GetAnaylseValue(List> realWave) {
+ boolean blFlag = true;
+ //实例化
+ listRms_Offline = new ArrayList<>();
+ listTBL_Offline = new ArrayList<>();
+
+ float fs = nOneWaveNum;
+ int nWaveNum = (int) nAllWaveNum;
+
+ // 计算有效值
+ double fSumA = 0.0, fSumB = 0.0, fSumC = 0.0;
+ double fValidA = 0.0, fValidB = 0.0, fValidC = 0.0;
+ fMinMagA = 99999;
+ fMinMagB = 99999;
+ fMinMagC = 99999;
+ double fValue = 0.0;
+ int HalfTs = (int) fs;// 全波有效值 ; (int)fs / 2;//半波有效值
+ //瞬时波形数据_瞬时
+ List tmpRealValue;
+ //获取前推周波的值_瞬时
+ List forwardRealValue;
+ //获取前推周波的值_突变量
+ List tblValue;
+ //获取前推周波的值_突变量
+ List forwardTblValue;
+
+ // 计算有效值算法
+ for (int i = 0; i < realWave.size(); i++) {
+ //获取每一项的值
+ tmpRealValue = realWave.get(i);
+ //包含了时间、A、B、C三相
+ if (tmpRealValue.size() >= 4) {
+ fSumA += Math.pow(tmpRealValue.get(1), 2);
+ fSumB += Math.pow(tmpRealValue.get(2), 2);
+ fSumC += Math.pow(tmpRealValue.get(3), 2);
+ // 计算有效值
+ List tmpRmsValue = new ArrayList<>();
+ if (i >= fs) {
+ forwardRealValue = realWave.get(i - HalfTs);
+ fSumA -= Math.pow(forwardRealValue.get(1), 2);
+ fSumB -= Math.pow(forwardRealValue.get(2), 2);
+ fSumC -= Math.pow(forwardRealValue.get(3), 2);
+ }
+ // 计算突变量值
+ List tmpTblValue = new ArrayList<>();
+ tmpTblValue.add(tmpRealValue.get(0));//获取时间
+ if (i >= HalfTs) {
+ tblValue = realWave.get(i);//获取前推周波的值
+ forwardTblValue = realWave.get(i - HalfTs);//获取前推周波的值
+ tmpTblValue.add(tblValue.get(1) - forwardTblValue.get(1));
+ tmpTblValue.add(tblValue.get(2) - forwardTblValue.get(2));
+ tmpTblValue.add(tblValue.get(3) - forwardTblValue.get(3));
+ } else {
+ tmpTblValue.add(0f);
+ tmpTblValue.add(0f);
+ tmpTblValue.add(0f);
+ }
+ fValidA = Math.sqrt(fSumA / HalfTs);
+ fValidB = Math.sqrt(fSumB / HalfTs);
+ fValidC = Math.sqrt(fSumC / HalfTs);
+
+ if (i >= fs) {
+ if (fValidA < fMinMagA) {
+ fMinMagA = fValidA;
+ }
+ if (fValidB < fMinMagB) {
+ fMinMagB = fValidB;
+ }
+ if (fValidC < fMinMagC) {
+ fMinMagC = fValidC;
+ }
+ }
+ //RMS获取
+ tmpRmsValue.add(tmpRealValue.get(0));//获取时间
+ tmpRmsValue.add((float) fValidA);
+ tmpRmsValue.add((float) fValidB);
+ tmpRmsValue.add((float) fValidC);
+ listRms_Offline.add(tmpRmsValue);
+
+ //RMS获取
+ listTBL_Offline.add(tmpTblValue);
+ }
+ }
+ return blFlag;
+ }
+
+ /*********************************
+ * 离线波形导入时获取暂降特征值的算法
+ * List> 返回暂降数据
+ **********************************/
+ private List> GetEventValue(List> realWave, List> tblWave, List> rmstWave, int nCirclePoint, boolean blFlag) {
+ //额定电压
+ float fBase = 57.74f;
+ //假如所选的是380V,那么PT变比是1:1,因此额定电压要选220
+ if (ComtradeCfg.OneChannleCfg.size() > 0) {
+ if (ComtradeCfg.OneChannleCfg.get(0).fPrimary / ComtradeCfg.OneChannleCfg.get(0).fSecondary <= 1) {
+ fBase = 220f;
+ }
+ }
+ //采样率
+ int nSJ = nCirclePoint;
+ /*********************************
+ * 0是特征幅值(残余电压百分比)
+ * 1是特征幅值(残余电压)
+ * 2额定定压(动态电压)
+ * 3是持续时间
+ **********************************/
+ List> listEventValue = new ArrayList<>();//ABC三相分析结果
+ for (int i = 0; i < 3; i++) {
+ int iDDY = 0, iGDY = 0;//低电压和郭电压标识值
+ List tmpListEventValue = new ArrayList<>();//某一项分析结果
+ iDDY = App_Disturb_DDY1(realWave, tblWave, rmstWave, nSJ, i, blFlag);
+ if (Disturb_Val == 0 && Disturb_SJ == 0) {
+ //判断A相的暂态事件类型是否为短时中断或电压暂降
+ iGDY = App_Disturb_GDY1(realWave, tblWave, rmstWave, nSJ, i, blFlag);
+ if (iGDY != 0) {
+ if (Disturb_Val != 0) {
+ if (blFlag) {
+ tmpListEventValue.add(Disturb_Val / rmstWave.get(nSJ + 2).get(i + 1));//征幅值(残余电压百分比)
+ tmpListEventValue.add(Disturb_Val);//特征幅值(残余电压)
+ tmpListEventValue.add(rmstWave.get(nSJ + 2).get(i + 1));//额定定压(动态电压)
+ } else {
+ tmpListEventValue.add(Disturb_Val / 57.74f);//征幅值(残余电压百分比)
+ tmpListEventValue.add(Disturb_Val);//特征幅值(残余电压)
+ tmpListEventValue.add(57.74f);//额定定压(动态电压)
+ }
+ }
+ } else//如果都没有找到,那么需要从曲线里面找出比较小的值来计算
+ {
+ double rate = 0f;
+ double residualVoltage = 0.f;//残余电压
+ switch (i) {
+ case 0:
+ residualVoltage = fMinMagA;
+ break;
+ case 1:
+ residualVoltage = fMinMagB;
+ break;
+ case 2:
+ residualVoltage = fMinMagC;
+ break;
+ }
+
+ if (residualVoltage != -1) {
+ rate = residualVoltage / fBase > 1 ? 1.0f : residualVoltage / fBase;
+ }
+ tmpListEventValue.add((float) rate);//征幅值(残余电压百分比)
+ tmpListEventValue.add((float) residualVoltage);//特征幅值(残余电压)
+ tmpListEventValue.add(fBase);//额定定压(动态电压)
+ }
+ } else {
+ if (Disturb_Val != 0) {
+ if (Disturb_Val != 0) {
+ if (blFlag) {
+ tmpListEventValue.add(Disturb_Val / rmstWave.get(nSJ + 2).get(i + 1));//征幅值(残余电压百分比)
+ tmpListEventValue.add(Disturb_Val);//特征幅值(残余电压)
+ tmpListEventValue.add(rmstWave.get(nSJ + 2).get(i + 1));//额定定压(动态电压)
+ } else {
+ tmpListEventValue.add(Disturb_Val / 57.74f);//征幅值(残余电压百分比)
+ tmpListEventValue.add(Disturb_Val);//特征幅值(残余电压)
+ tmpListEventValue.add(57.74f);//额定定压(动态电压)
+ }
+ }
+ }
+ }
+ tmpListEventValue.add(Disturb_SJ / nSJ * 20.0f);//持续时间
+ listEventValue.add(tmpListEventValue);
+ }
+ return listEventValue;
+ }
+
+ private float Disturb_Val = 0;//暂降幅值
+ private double Disturb_Time = 0;//持续时间
+ private float Disturb_SJ = 0;//暂态启动点号
+
+ private float Un09 = (0.90f * 57.74f);//暂降幅值90%
+ private float Un002 = (0.02f * 57.74f);//暂降幅值2%
+ private float Un110 = (1.10f * 57.74f);//暂降幅值110%
+
+ /************************************
+ *低电压的判据 包含了暂降和中断
+ * @param realWave 原始波形数据
+ * @param tblWave 突变量波形数据
+ * @param rmstWave RMS波形数据
+ * @param nCirclePoint 采样率
+ * @param nType 类别 0:A相,1:B相,2:C相
+ * @param blFlag 浮动门槛和固定门槛
+ * @return
+ *************************************/
+ private int App_Disturb_DDY1(List> realWave, List> tblWave, List> rmstWave, int nCirclePoint, int nType, boolean blFlag) {
+ Disturb_Val = 0;
+ Disturb_Time = 0;
+ Disturb_SJ = 0;
+
+ /****************************
+ * ADC 临时的突变量判据
+ * Disturb_JS_Val 事件启动点时刻的有效值
+ ****************************/
+ double temp, ADC, Disturb_JS_Val = 0;
+ int iTbl = 0;
+ long Disturb_QD = 0;
+ //nSJ就是全波的采样率,nHalfSJ是半波的采样率
+ int nSJ = nCirclePoint, nHalfSJ = nCirclePoint / 2;
+ //定义90%和20%额定电压
+ float fUN09 = Un09, fUN002 = Un002;
+ //增加浮动门槛判断
+ if (blFlag) {
+ /****************************
+ * 计算值去掉一个前一个周波后
+ * 取第二个周波的第二个有效值
+ * 第一个值是时间、A,B,C三相
+ ****************************/
+ if (rmstWave.size() > nSJ + 2) {
+ fUN09 = rmstWave.get(nSJ + 2).get(nType + 1) * 0.9f;
+ fUN002 = rmstWave.get(nSJ + 2).get(nType + 1) * 0.02f;
+ }
+ }
+ /****************************
+ * 从第二个周波开始
+ ****************************/
+ for (int i = nSJ; i < realWave.size(); i++) {
+ //获取RMS有效值
+ float rmsValue = rmstWave.get(i).get(nType + 1);
+ //电压扰动启动判别
+ if (Disturb_QD == 0) {
+ //有效值小于90%
+ if (rmsValue < fUN09) {
+ Disturb_QD = 0xff;
+ Disturb_Val = rmsValue;
+ Disturb_JS_Val = rmsValue;
+ //寻找突变点
+ for (int j = 0; j < nHalfSJ; j++) {
+ //临时的突变量
+ ADC = tblWave.get(i - nHalfSJ + j).get(nType + 1);
+ //临时的突变量小于0时候取绝对值
+ if (ADC < 0) {
+ ADC = 0 - ADC;
+ }
+ if (ADC > fUN002) {
+ Disturb_SJ += (nHalfSJ - j);
+ iTbl = (int) (i - nHalfSJ + j);
+ break;
+ }
+ }
+ }
+ }
+ //电压扰动返回判别
+ else {
+ if (rmsValue < (fUN09 + fUN002)) {
+ Disturb_SJ++;
+ if (Disturb_Val > rmsValue) {
+ Disturb_Val = rmsValue;
+ }
+ Disturb_JS_Val = rmsValue;
+ } else {
+ if (Disturb_SJ >= (nSJ + nHalfSJ)) {
+ //20%突变量标志
+ int iFlag = 0;
+ for (int j = 0; j < nHalfSJ; j++) {
+ iFlag = j;
+ //临时的突变量
+ ADC = tblWave.get(i - nHalfSJ + j).get(nType + 1);
+ //临时的突变量小于0时候取绝对值
+ if (ADC < 0) {
+ ADC = 0 - ADC;
+ }
+ if (ADC > fUN002) {
+ break;
+ }
+ }
+ Disturb_SJ -= (nHalfSJ - iFlag);
+ Disturb_Time = ((double) Disturb_SJ) * 20 / nSJ;
+ return iTbl;
+ } else {
+ Disturb_SJ++;
+ ADC = realWave.get(i).get(nType + 1);
+ if (ADC < 0) {
+ ADC = 0 - ADC;
+ }
+ temp = rmsValue - Disturb_JS_Val;
+ if (temp < 0) {
+ temp = 0 - temp;
+ }
+ if ((ADC > 100) && (temp < 0.1)) {
+ Disturb_SJ -= (nHalfSJ + 1);
+ Disturb_Time = ((double) Disturb_SJ) * 20 / nSJ + 1;
+ return iTbl;
+ }
+ }
+ Disturb_JS_Val = rmsValue;
+ }
+ }
+ }
+ return iTbl;
+ }
+
+ /************************************
+ *过电压的判据
+ * @param realWave 原始波形数据
+ * @param tblWave 突变量波形数据
+ * @param rmstWave RMS波形数据
+ * @param nCirclePoint 采样率
+ * @param nType 类别 0:A相,1:B相,2:C相
+ * @param blFlag 浮动门槛和固定门槛
+ * @return
+ *************************************/
+ private int App_Disturb_GDY1(List> realWave, List> tblWave, List> rmstWave, int nCirclePoint, int nType, boolean blFlag) {
+ Disturb_Val = 0;
+ Disturb_Time = 0;
+ Disturb_SJ = 0;
+
+ /****************************
+ * ADC 临时的突变量判据
+ * Disturb_JS_Val 事件启动点时刻的有效值
+ ****************************/
+ double temp, ADC, Disturb_JS_Val = 0;
+ int iTbl = 0;
+ long Disturb_QD = 0;
+ //nSJ就是全波的采样率,nHalfSJ是半波的采样率
+ int nSJ = nCirclePoint, nHalfSJ = nCirclePoint / 2;
+ //定义110%和20%额定电压
+ float fUN110 = Un110, fUN002 = Un002;
+ //增加浮动门槛判断
+ if (blFlag) {
+ /****************************
+ * 计算值去掉一个前一个周波后
+ * 取第二个周波的第二个有效值
+ * 第一个值是时间、A,B,C三相
+ ****************************/
+ if (rmstWave.size() > nSJ + 2) {
+ fUN110 = rmstWave.get(nSJ + 2).get(nType + 1) * 1.1f;
+ fUN002 = rmstWave.get(nSJ + 2).get(nType + 1) * 0.02f;
+ }
+ }
+ /****************************
+ * 从第二个周波开始
+ ****************************/
+ for (int i = nSJ; i < realWave.size(); i++) {
+ //获取RMS有效值
+ float rmsValue = rmstWave.get(i).get(nType + 1);
+ //电压扰动启动判别
+ if (Disturb_QD == 0) {
+ if (rmsValue > fUN110) {
+ Disturb_QD = 0xff;
+ Disturb_Val = rmsValue;
+ Disturb_JS_Val = rmsValue;
+ //寻找突变点
+ for (int j = 0; j < nHalfSJ; j++) {
+ //临时的突变量
+ ADC = tblWave.get(i - nHalfSJ + j).get(nType + 1);
+ //临时的突变量小于0时候取绝对值
+ if (ADC < 0) {
+ ADC = 0 - ADC;
+ }
+ if (ADC > fUN002) {
+ Disturb_SJ += (nHalfSJ - j);
+ iTbl = (int) (i - nHalfSJ + j);
+ break;
+ }
+ }
+ }
+ }
+ //电压扰动返回判别
+ else {
+ if (rmsValue > (fUN110 - fUN002)) {
+ Disturb_SJ++;
+ if (Disturb_Val < rmsValue) {
+ Disturb_Val = rmsValue;
+ }
+ Disturb_JS_Val = rmsValue;
+ } else {
+ if (Disturb_SJ >= (nSJ + nHalfSJ)) {
+ int iFlag = 0;
+ for (int j = 0; j < nHalfSJ; j++) {
+ iFlag = j;
+ ADC = tblWave.get(i - nHalfSJ + j).get(nType + 1);
+ if (ADC < 0) {
+ ADC = 0 - ADC;
+ }
+ if (ADC > fUN002) {
+ break;
+ }
+ }
+ Disturb_SJ -= (nHalfSJ - iFlag);
+ Disturb_Time = (double) Disturb_SJ * 20 / nSJ;
+ return iTbl;
+ } else {
+ Disturb_SJ++;
+ ADC = realWave.get(i).get(nType + 1);
+ if (ADC < 0) {
+ ADC = 0 - ADC;
+ }
+ temp = rmsValue - Disturb_JS_Val;
+ if (temp < 0) {
+ temp = 0 - temp;
+ }
+ if ((ADC > 100) && (temp < 0.1)) {
+ Disturb_SJ -= (nHalfSJ + 1);
+ Disturb_Time = Disturb_SJ * 20 / nSJ + 1;
+ return iTbl;
+ }
+ }
+ Disturb_JS_Val = rmsValue;
+ }
+ }
+ }
+ return iTbl;
+ }
+
+
+ /*********************************
+ * 获取最小采样率方法
+ * @param OneRate cfg中关于采样率参数
+ * @return 返回最小采样率
+ **********************************/
+ private long MinWaveSample(List OneRate) {
+ long nMinOneSample = OneRate.get(0).nOneSample;
+ for (int i = 0; i < OneRate.size(); i++) {
+ if (OneRate.get(i).nOneSample >= 32) {
+ if (nMinOneSample > OneRate.get(i).nOneSample) {
+ nMinOneSample = OneRate.get(i).nOneSample;
+ }
+ }
+ }
+ return nMinOneSample;
+ }
+
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/AnalyWaveModel.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/AnalyWaveModel.java
new file mode 100644
index 000000000..e9e240460
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/AnalyWaveModel.java
@@ -0,0 +1,200 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class AnalyWaveModel {
+
+ /********************************
+ * 解析Comtrate文件相关实体类
+ * @author yexb 转ww C#代码
+ **********************************/
+
+ // 模拟量通道记录类
+ public static class tagOneChannleCfg {
+ // 通道序号
+ public int nIndex;
+ // 通道名称
+ public String szChannleName;
+ // 相位名称
+ public String szPhasicName;
+ // 监视的通道名称
+ public String szMonitoredChannleName;
+ // 通道的单位
+ public String szUnitName;
+ // 通道的系数
+ public float fCoefficent;
+ // 通道的便宜量
+ public float fOffset;
+ // 起始采样时间的偏移量
+ public float fTimeOffset;
+ // 采样值的最小值
+ public int nMin;
+ // 采样值的最大值
+ public int nMax;
+ // 一次变比
+ public float fPrimary;
+ // 二次变比
+ public float fSecondary;
+ // 一次值还是二次值标志
+ public String szValueType;
+ }
+
+ // 数字量通道记录类
+ public static class tagOneChannleCfg_digital {
+ // 通道序号
+ public int nIndex;
+ // 通道名称
+ public String szChannleName;
+ // 相位名称
+ public String szPhasicName;
+ // 监视的通道名称
+ public String szMonitoredChannleName;
+ // 通道的单位
+ public int Initial;
+
+ }
+
+ // 配置文件总类
+ public static class tagComtradeCfg {
+ public int nChannelNum;
+ public int nPhasic;// 模拟量通道的个数 yexibao 2020-12-15
+ public int nAnalogNum;// 模拟量通道的个数 WW 2013-05-15
+ public int nDigitalNum;// 数字量通道的个数 WW 2013-05-15
+ public List OneChannleCfg;
+ public List OneChannleCfgDig;
+
+ public tagComtradeCfg() {
+ OneChannleCfg = new LinkedList();
+ OneChannleCfgDig = new LinkedList();
+ }
+ }
+
+ public static class tagOneRate{
+ // 1秒钟内的采样点数
+ public long nOneSample;
+ // 总采样点数
+ public long nSampleNum;
+ }
+
+ // 采样总结构
+ public static class tagRates {
+ public int nRates;
+ public List OneRate;
+
+ public tagRates() {
+ OneRate = new LinkedList();
+ }
+ }
+
+ // 采样值结构
+ public static class tagOneValue {
+ // 数据点时间
+ public String szTime;
+ // 数据点序号
+ public int nIndex;
+ // int nValueNum; WW 2013-05-15
+ // 模拟量数据个数
+ public int nAnalogValueNum;
+ // 数字量数据个数
+ public int nDigitalValueNum;
+ // 数据区
+ // float fValue[8];
+ public List fValue;// WW 2013-05-15 原来的8通道也是仅考虑了单路的情况,如果遇到多路这里会超出
+ public List DigitalValue;// WW 2013-05-15
+
+ public tagOneValue() {
+ fValue = new LinkedList();
+ DigitalValue = new LinkedList();
+ }
+ }
+
+ // 采样值总结构
+ public static class tagValue {
+ // 数据个数
+ public int nValueNum;
+ // 数据区
+ public List OneValueList;
+
+ public tagValue() {
+ OneValueList = new LinkedList();
+ }
+ }
+
+ public static class tagWave {
+ // 标识 1-二次值的事件波形 2-二次值的RMS 3-一次值的事件波形 4-一次值的RMS
+ //标识 5-二次值的事件波形 6-二次值的RMS 7-一次值的事件波形 8-一次值的RMS
+ private int type;
+ // 相别
+ private int phaseType;// 0:A相;1:B相;2:c相
+ // X坐标值
+ private int xvalue;
+ // y坐标值
+ private float yvalue;
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public int getPhaseType() {
+ return phaseType;
+ }
+
+ public void setPhaseType(int phaseType) {
+ this.phaseType = phaseType;
+ }
+
+ public int getXvalue() {
+ return xvalue;
+ }
+
+ public void setXvalue(int xvalue) {
+ this.xvalue = xvalue;
+ }
+
+ public float getYvalue() {
+ return yvalue;
+ }
+
+ public void setYvalue(float yvalue) {
+ this.yvalue = yvalue;
+ }
+ }
+ //增加返回值描述
+ public static class tagDataValue {
+ //波形对应的标题
+ private List tmpWaveTitle;
+ //波形对应的值
+ private List> listWaveData;
+ //波形对应的相别数量
+ private int iPhasic;
+
+ public List getTmpWaveTitle() {
+ return tmpWaveTitle;
+ }
+
+ public void setTmpWaveTitle(List tmpWaveTitle) {
+ this.tmpWaveTitle = tmpWaveTitle;
+ }
+
+ public List> getListWaveData() {
+ return listWaveData;
+ }
+
+ public void setListWaveData(List> listWaveData) {
+ this.listWaveData = listWaveData;
+ }
+
+ public int getiPhasic() {
+ return iPhasic;
+ }
+
+ public void setiPhasic(int iPhasic) {
+ this.iPhasic = iPhasic;
+ }
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/BackData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/BackData.java
new file mode 100644
index 000000000..bbf46f5e4
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/BackData.java
@@ -0,0 +1,94 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 输出参数
+ * qvvr_cata_cause 暂降原因(目前算法不支持,不填)
+ * qvvr_phasetype 暂降相别 1:一相 2:两相 3:三相
+ * qvvr_cata_type 暂降类型
+ * 持续时间(单位秒)
+ * hold_time_rms 有效值算法持续时间
+ * hold_time_dq dq变换算法持续时间
+ * 波形起始点(单位度)
+ * POW_a A相波形起始点
+ * POW_b B相波形起始点
+ * POW_c C相波形起始点
+ * 跳变段电压变化率(单位V/S)
+ * Voltagechange_Va A相跳变段电压变化率
+ * Voltagechange_Vb B相跳变段电压变化率
+ * Voltagechange_Vc C相跳变段电压变化率
+ * 分段信息
+ * SEG_T_num 分段数目
+ * SEG_T0_idx 原始分段位置
+ * SEG_T_idx 修正分段位置
+ * 有效值分段信息
+ * SEG_RMS_T_num 分段数目
+ * SEG_RMS_T_idx 分段位置
+ * 特征幅值(单位V)
+ * u_min_num 特征值个数
+ * ua_min A相电压特征值
+ * ub_min B相电压特征值
+ * uc_min C相电压特征值
+ * u3_min 三相电压特征值
+ * order_min_idx 最小值位置
+ * 相位跳变(单位度)
+ * angle_diff_ap A相相位正跳变
+ * angle_diff_bp B相相位正跳变
+ * angle_diff_cp C相相位正跳变
+ * angle_diff_an A相相位负跳变
+ * angle_diff_bn B相相位负跳变
+ * angle_diff_cn C相相位负跳变
+ * bph_max_value 不平衡度(单位%)
+ */
+public class BackData extends Structure {
+ public int qvvr_cata_cause[] = new int[256];
+ public int qvvr_phasetype[] = new int[256];
+ public int qvvr_cata_type[] = new int[256];
+ public float hold_time_rms;
+ public float hold_time_dq;
+ public float POW_a;
+ public float POW_b;
+ public float POW_c;
+ public float Voltagechange_Va;
+ public float Voltagechange_Vb;
+ public float Voltagechange_Vc;
+ public int SEG_T_num;
+ public int SEG_T0_idx[] = new int[256];
+ public int SEG_T_idx[] = new int[256];
+ public int SEG_RMS_T_num;
+ public int SEG_RMS_T_idx[] = new int[256];
+ public int u_min_num;
+ public float ua_min[] = new float[256];
+ public float ub_min[] = new float[256];
+ public float uc_min[] = new float[256];
+ public float u3_min[] = new float[256];
+ public int order_min_idx[] = new int[256];
+ public float angle_diff_ap[] = new float[256];
+ public float angle_diff_bp[] = new float[256];
+ public float angle_diff_cp[] = new float[256];
+ public float angle_diff_an[] = new float[256];
+ public float angle_diff_bn[] = new float[256];
+ public float angle_diff_cn[] = new float[256];
+ public float bph_max_value[] = new float[256];
+
+ public static class ByReference extends BackData implements Structure.ByReference {
+
+ }
+
+ public static class ByValue extends BackData implements Structure.ByValue {
+
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return Arrays.asList(new String[] { "qvvr_cata_cause", "qvvr_phasetype", "qvvr_cata_type", "hold_time_rms",
+ "hold_time_dq", "POW_a", "POW_b", "POW_c", "Voltagechange_Va", "Voltagechange_Vb", "Voltagechange_Vc",
+ "SEG_T_num", "SEG_T0_idx", "SEG_T_idx","SEG_RMS_T_num","SEG_RMS_T_idx", "u_min_num", "ua_min", "ub_min", "uc_min", "u3_min",
+ "order_min_idx", "angle_diff_ap", "angle_diff_bp", "angle_diff_cp", "angle_diff_an", "angle_diff_bn",
+ "angle_diff_cn", "bph_max_value" });
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/CauseStruct.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/CauseStruct.java
new file mode 100644
index 000000000..c16248b08
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/CauseStruct.java
@@ -0,0 +1,30 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CauseStruct extends Structure {
+ //最大能容纳的数据
+ public static final int MAX_SMP_DATA_LEN = 128 * 50 * 120;
+ public float smp_va[] = new float[MAX_SMP_DATA_LEN];
+ public float smp_vb[] = new float[MAX_SMP_DATA_LEN];
+ public float smp_vc[] = new float[MAX_SMP_DATA_LEN];
+ public int smp_rate;
+ public int smp_len;
+ public float threshold[] = new float[50];
+ public int cause = 0;
+ public int no_cal = 0;
+
+ public static class ByReference extends CauseStruct implements Structure.ByReference {
+ }
+
+ public static class ByValue extends CauseStruct implements Structure.ByValue {
+ }
+
+ @Override
+ protected List getFieldOrder() { // 返回值填入的顺序
+ return Arrays.asList(new String[] { "cause", "no_cal" });
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/DirectionData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/DirectionData.java
new file mode 100644
index 000000000..a4199bff2
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/DirectionData.java
@@ -0,0 +1,47 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+public class DirectionData{
+ private int trigTime[] = new int[256];
+ private float qvvrBeforeRms[] = new float[256];
+ private float qvvrBeforeZk[] = new float[256];
+ private float qvvrOccurRms[] = new float[256];
+ private float qvvrOccurZk[] = new float[256];
+ private String qvvrPosInfo[] = new String[256];
+
+ public int[] getTrigTime() {
+ return trigTime;
+ }
+ public void setTrigTime(int[] trigTime) {
+ this.trigTime = trigTime;
+ }
+ public float[] getQvvrBeforeRms() {
+ return qvvrBeforeRms;
+ }
+ public void setQvvrBeforeRms(float[] qvvrBeforeRms) {
+ this.qvvrBeforeRms = qvvrBeforeRms;
+ }
+ public float[] getQvvrBeforeZk() {
+ return qvvrBeforeZk;
+ }
+ public void setQvvrBeforeZk(float[] qvvrBeforeZk) {
+ this.qvvrBeforeZk = qvvrBeforeZk;
+ }
+ public float[] getQvvrOccurRms() {
+ return qvvrOccurRms;
+ }
+ public void setQvvrOccurRms(float[] qvvrOccurRms) {
+ this.qvvrOccurRms = qvvrOccurRms;
+ }
+ public float[] getQvvrOccurZk() {
+ return qvvrOccurZk;
+ }
+ public void setQvvrOccurZk(float[] qvvrOccurZk) {
+ this.qvvrOccurZk = qvvrOccurZk;
+ }
+ public String[] getQvvrPosInfo() {
+ return qvvrPosInfo;
+ }
+ public void setQvvrPosInfo(String[] qvvrPosInfo) {
+ this.qvvrPosInfo = qvvrPosInfo;
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/EntityAdvancedData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/EntityAdvancedData.java
new file mode 100644
index 000000000..5a554eda9
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/EntityAdvancedData.java
@@ -0,0 +1,39 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+import lombok.Data;
+
+/**
+ * @author njcn
+ * @高级算法返回数据
+ * @包含RMS值
+ * @X轴坐标
+ * @处理返回的结果
+ */
+@Data
+public class EntityAdvancedData {
+ public float smp_a[];
+ public float smp_b[];
+ public float smp_c[];
+ public float smp_x[];
+ public int smp_len;
+ public String sagReason[]; // 暂降原因描述,数据库获取
+ public String sagType[]; // 暂降类型描述,数据库获取
+ public String sagPhaseType[]; // 暂降相别 1-一相 2-两相 3-三相
+ public int backNumber = -1;
+ public BackData evt_buf[];
+ public PowerData power_before_buf[];
+ public PowerData power_after_buf[];
+ public DirectionData qvvr_direction_info[];
+ public UtblData qvvr_utbl_info[];
+
+ public EntityAdvancedData(int lengthRMS) {
+ super();
+ this.smp_a = new float[lengthRMS];
+ this.smp_b = new float[lengthRMS];
+ this.smp_c = new float[lengthRMS];
+ this.smp_x = new float[lengthRMS];
+ this.sagReason = new String[256];
+ this.sagType = new String[256];
+ this.sagPhaseType = new String[256];
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/PowerData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/PowerData.java
new file mode 100644
index 000000000..d49017a5c
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/PowerData.java
@@ -0,0 +1,27 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+public class PowerData{
+ private float fundP[] = new float[256];
+ private float fundQ[] = new float[256];
+ private float fundS[] = new float[256];
+
+ public float[] getFundP() {
+ return fundP;
+ }
+ public void setFundP(float[] fundP) {
+ this.fundP = fundP;
+ }
+ public float[] getFundQ() {
+ return fundQ;
+ }
+ public void setFundQ(float[] fundQ) {
+ this.fundQ = fundQ;
+ }
+ public float[] getFundS() {
+ return fundS;
+ }
+ public void setFundS(float[] fundS) {
+ this.fundS = fundS;
+ }
+
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/PubWaveModel.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/PubWaveModel.java
new file mode 100644
index 000000000..a43e9605f
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/PubWaveModel.java
@@ -0,0 +1,168 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class PubWaveModel {
+
+ /************************
+ * Comtrate文件相关
+ *
+ * @author Yexb
+ *
+ **************************/
+
+ // 模拟量通道记录类
+ public static class tagOneChannleCfg {
+ // 通道序号
+ public int nIndex;
+ // 通道名称
+ public String szChannleName;
+ // 相位名称
+ public String szPhasicName;
+ // 监视的通道名称
+ public String szMonitoredChannleName;
+ // 通道的单位
+ public String szUnitName;
+ // 通道的系数
+ public float fCoefficent;
+ // 通道的便宜量
+ public float fOffset;
+ // 起始采样时间的偏移量
+ public float fTimeOffset;
+ // 采样值的最小值
+ public int nMin;
+ // 采样值的最大值
+ public int nMax;
+ // 一次变比
+ public float fPrimary;
+ // 二次变比
+ public float fSecondary;
+ // 一次值还是二次值标志
+ public String szValueType;
+ }
+
+ // 数字量通道记录类
+ public static class tagOneChannleCfg_digital {
+ // 通道序号
+ public int nIndex;
+ // 通道名称
+ public String szChannleName;
+ // 相位名称
+ public String szPhasicName;
+ // 监视的通道名称
+ public String szMonitoredChannleName;
+ // 通道的单位
+ public int Initial;
+
+ }
+
+ // 配置文件总类
+ public static class tagComtradeCfg {
+ public int nChannelNum;
+ public int nAnalogNum;// 模拟量通道的个数 WW 2013-05-15
+ public int nDigitalNum;// 数字量通道的个数 WW 2013-05-15
+ public List OneChannleCfg;
+ public List OneChannleCfgDig;
+
+ public tagComtradeCfg() {
+ OneChannleCfg = new LinkedList();
+ OneChannleCfgDig = new LinkedList();
+ }
+ }
+
+ public static class tagOneRate {
+ // 1秒钟内的采样点数
+ public long nOneSample;
+ // 总采样点数
+ public long nSampleNum;
+ }
+
+ // 采样总结构
+ public static class tagRates {
+ public int nRates;
+ public List OneRate;
+
+ public tagRates() {
+ OneRate = new LinkedList();
+ }
+ }
+
+ // 采样值结构
+ public static class tagOneValue {
+ // 数据点时间
+ public String szTime;
+ // 数据点序号
+ public int nIndex;
+ // int nValueNum; WW 2013-05-15
+ // 模拟量数据个数
+ public int nAnalogValueNum;
+ // 数字量数据个数
+ public int nDigitalValueNum;
+ // 数据区
+ // float fValue[8];
+ public List fValue;// WW 2013-05-15 原来的8通道也是仅考虑了单路的情况,如果遇到多路这里会超出
+ public List DigitalValue;// WW 2013-05-15
+
+ public tagOneValue() {
+ fValue = new LinkedList();
+ DigitalValue = new LinkedList();
+ }
+ }
+
+ // 采样值总结构
+ public static class tagValue {
+ // 数据个数
+ public int nValueNum;
+ // 数据区
+ public List OneValueList;
+
+ public tagValue() {
+ OneValueList = new LinkedList();
+ }
+ }
+
+ public static class tagWave {
+ // 标识 1-二次值的事件波形 2-二次值的RMS 3-一次值的事件波形 4-一次值的RMS
+ //标识 5-二次值的事件波形 6-二次值的RMS 7-一次值的事件波形 8-一次值的RMS
+ private int type;
+ // 相别
+ private int phaseType;// 0:A相;1:B相;2:c相
+ // X坐标值
+ private float xvalue;
+ // y坐标值
+ private float yvalue;
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public int getPhaseType() {
+ return phaseType;
+ }
+
+ public void setPhaseType(int phaseType) {
+ this.phaseType = phaseType;
+ }
+
+ public float getXvalue() {
+ return xvalue;
+ }
+
+ public void setXvalue(float xvalue) {
+ this.xvalue = xvalue;
+ }
+
+ public float getYvalue() {
+ return yvalue;
+ }
+
+ public void setYvalue(float yvalue) {
+ this.yvalue = yvalue;
+ }
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/Rect.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/Rect.java
new file mode 100644
index 000000000..b7e3ed46c
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/Rect.java
@@ -0,0 +1,42 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+import com.sun.jna.Structure;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author njcn
+ * 传入参数
+ * smp_va A相电压波形数据
+ * smp_vb B相电压波形数据
+ * smp_vc C相电压波形数据
+ * smp_rate 波形采样率
+ * smp_len 每个通道波形数据个数
+ * evt_num 高级算法返回事件个数
+ * evt_buf 高级算法返回数据
+ */
+public class Rect extends Structure {
+ public static final int MAX_SMP_DATA_LEN = 128*50*120;
+ public float smp_va[] = new float[MAX_SMP_DATA_LEN];
+ public float smp_vb[] = new float[MAX_SMP_DATA_LEN];
+ public float smp_vc[] = new float[MAX_SMP_DATA_LEN];
+ public int smp_rate;
+ public int smp_len;
+ public int evt_num = -1;
+ public BackData evt_buf[] = new BackData[32];
+
+ public static class ByReference extends Rect implements Structure.ByReference {
+
+ }
+
+ public static class ByValue extends Rect implements Structure.ByValue {
+
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return Arrays.asList(new String[] { "evt_num","evt_buf" });
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/UtblData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/UtblData.java
new file mode 100644
index 000000000..a528137ba
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/UtblData.java
@@ -0,0 +1,13 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+public class UtblData{
+ private long trigTime[] = new long[1];
+
+ public long[] getTrigTime() {
+ return trigTime;
+ }
+
+ public void setTrigTime(long[] trigTime) {
+ this.trigTime = trigTime;
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/WaveData.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/WaveData.java
new file mode 100644
index 000000000..f38d25d4b
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/dto/waveAnalysis/WaveData.java
@@ -0,0 +1,296 @@
+package com.njcn.advance.pojo.dto.waveAnalysis;
+
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author hongawen
+ * @Date: 2018/12/4 10:03
+ */
+public class WaveData implements Serializable {
+ //标题数据
+ private List tmpWaveTitle = new ArrayList<>();
+
+ //瞬时波形的数据
+ List> sunData = new ArrayList<>();
+
+ //RMS波形的数据
+ List> rmsData = new ArrayList<>();
+
+ //相别个数
+ private int iPhasic = 0;
+
+ //PT变比
+ Float pt = 0.0f;
+
+ //CT变比
+ Float ct = 0.0f;
+
+ private String a="A相";
+
+ private String b="B相";
+
+ private String c="C相";
+
+ //波形采样率
+ private long nOneWaveNum = 32;
+ private Date firstTime;//暂降触发第一次
+ private Integer firstMs;
+
+
+ //发生时刻
+ String time;
+
+ //暂降类型
+ String waveType;
+
+ //严重度
+ float yzd;
+
+ //监测点名称
+ String lineName;
+
+ //暂降幅值
+ Float eventValue;
+
+ //持续时间
+ Float persistTime;
+
+ //暂降触发时间
+ private Date trigeTime;
+
+ private boolean openTri=false;
+
+ //最大最小值集合
+ private List readComtrade = new ArrayList<>();
+
+ //变电站名称
+ private String subName;
+
+
+
+ public WaveData() {
+ iPhasic = 0;
+ }
+
+ public AnalyWaveModel.tagRates getRatesCfg() {
+ return RatesCfg;
+ }
+
+ public void setRatesCfg(AnalyWaveModel.tagRates ratesCfg) {
+ RatesCfg = ratesCfg;
+ }
+
+ private AnalyWaveModel.tagRates RatesCfg;//cfg_采样率实体类
+
+ public List getReadComtrade() {
+ return readComtrade;
+ }
+
+ public void setReadComtrade(List readComtrade) {
+ this.readComtrade = readComtrade;
+ }
+
+ public List> getSunData() {
+ return sunData;
+ }
+
+ public void setSunData(List> sunData) {
+ this.sunData = sunData;
+ }
+
+ public List> getRmsData() {
+ return rmsData;
+ }
+
+ public void setRmsData(List> rmsData) {
+ this.rmsData = rmsData;
+ }
+
+ public Float getPt() {
+ return pt;
+ }
+
+ public void setPt(Float pt) {
+ this.pt = pt;
+ }
+
+ public String getTime() {
+ return time;
+ }
+
+ public void setTime(String time) {
+ this.time = time;
+ }
+
+ public String getWaveType() {
+ return waveType;
+ }
+
+ public void setWaveType(String waveType) {
+ this.waveType = waveType;
+ }
+
+ public float getYzd() {
+ return yzd;
+ }
+
+ public void setYzd(float yzd) {
+ this.yzd = yzd;
+ }
+
+ public Float getCt() {
+ return ct;
+ }
+
+ public void setCt(Float ct) {
+ this.ct = ct;
+ }
+
+ public long getnOneWaveNum() {
+ return nOneWaveNum;
+ }
+
+ public void setnOneWaveNum(long nOneWaveNum) {
+ this.nOneWaveNum = nOneWaveNum;
+ }
+
+ public Date getFirstTime() {
+ return firstTime;
+ }
+
+ public void setFirstTime(Date firstTime) {
+ this.firstTime = firstTime;
+ }
+
+ public Integer getFirstMs() {
+ return firstMs;
+ }
+
+ public void setFirstMs(Integer firstMs) {
+ this.firstMs = firstMs;
+ }
+
+ public String getLineName() {
+ return lineName;
+ }
+
+ public void setLineName(String lineName) {
+ this.lineName = lineName;
+ }
+
+ public Float getEventValue() {
+ return eventValue;
+ }
+
+ public void setEventValue(Float eventValue) {
+ this.eventValue = eventValue;
+ }
+
+ public Float getPersistTime() {
+ return persistTime;
+ }
+
+ public void setPersistTime(Float persistTime) {
+ this.persistTime = persistTime;
+ }
+
+
+ public Date getTrigeTime() {
+ return trigeTime;
+ }
+
+ public void setTrigeTime(Date trigeTime) {
+ this.trigeTime = trigeTime;
+ }
+
+ public boolean getOpenTri() {
+ return openTri;
+ }
+
+ public void setOpen(boolean open) {
+ this.openTri = open;
+ }
+
+ public List getTmpWaveTitle() {
+ return tmpWaveTitle;
+ }
+
+ public void setTmpWaveTitle(List tmpWaveTitle) {
+ this.tmpWaveTitle = tmpWaveTitle;
+ }
+
+ public String getA() {
+ return a;
+ }
+
+ public void setA(String a) {
+ this.a = a;
+ }
+
+ public String getB() {
+ return b;
+ }
+
+ public void setB(String b) {
+ this.b = b;
+ }
+
+ public String getC() {
+ return c;
+ }
+
+ public void setC(String c) {
+ this.c = c;
+ }
+
+ public String getSubName() {
+ return subName;
+ }
+
+ public void setSubName(String subName) {
+ this.subName = subName;
+ }
+
+
+ public int getiPhasic() {
+ return iPhasic;
+ }
+
+ public void setiPhasic(int iPhasic) {
+ this.iPhasic = iPhasic;
+ }
+
+ @Override
+ public String toString() {
+ return "WaveData{" +
+ "tmpWaveTitle=" + tmpWaveTitle +
+ ", sunData=" + sunData +
+ ", rmsData=" + rmsData +
+ ", iPhasic=" + iPhasic +
+ ", pt=" + pt +
+ ", ct=" + ct +
+ ", a='" + a + '\'' +
+ ", b='" + b + '\'' +
+ ", c='" + c + '\'' +
+ ", nOneWaveNum=" + nOneWaveNum +
+ ", firstTime=" + firstTime +
+ ", firstMs=" + firstMs +
+ ", RatesCfg=" + RatesCfg +
+ ", time='" + time + '\'' +
+ ", waveType='" + waveType + '\'' +
+ ", yzd=" + yzd +
+ ", lineName='" + lineName + '\'' +
+ ", eventValue=" + eventValue +
+ ", persistTime=" + persistTime +
+ ", trigeTime=" + trigeTime +
+ ", openTri=" + openTri +
+ ", readComtrade=" + readComtrade +
+ ", subName='" + subName + '\'' +
+ '}';
+ }
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/po/PqsRelevanceLog.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/po/PqsRelevanceLog.java
new file mode 100644
index 000000000..051c0337e
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/pojo/po/PqsRelevanceLog.java
@@ -0,0 +1,33 @@
+package com.njcn.advance.pojo.po;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.njcn.db.bo.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.sql.Timestamp;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@TableName("pqs_relevancy_log")
+public class PqsRelevanceLog extends BaseEntity {
+
+ /**
+ * 归一化算法时间
+ */
+ @TableId("Time_Id")
+ private LocalDateTime timeId;
+
+
+ /**
+ * 归一化算法描述
+ */
+ private String contentDes;
+
+ private Integer state;
+
+}
diff --git a/pqs-advance/advance-api/src/main/java/com/njcn/advance/utils/WaveUtils.java b/pqs-advance/advance-api/src/main/java/com/njcn/advance/utils/WaveUtils.java
new file mode 100644
index 000000000..3d971800a
--- /dev/null
+++ b/pqs-advance/advance-api/src/main/java/com/njcn/advance/utils/WaveUtils.java
@@ -0,0 +1,49 @@
+package com.njcn.advance.utils;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.CharsetUtil;
+import com.njcn.event.api.RmpEventDetailFeignClient;
+import com.njcn.oss.utils.FileStorageUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * pqs
+ * 波形操作工具类
+ * @author cdf
+ * @date 2023/8/1
+ */
+@Component
+@RequiredArgsConstructor
+@Slf4j
+public class WaveUtils {
+
+ private final FileStorageUtil fileStorageUtil;
+
+
+
+ /**
+ * 读取文件服务器波形数据
+ * @author cdf
+ * @date 2023/8/1
+ */
+ public String getFile(String filePath){
+ String temJson = null;
+ try(InputStream inputStream = fileStorageUtil.getFileStream(filePath)){
+ temJson = IoUtil.read(inputStream, CharsetUtil.UTF_8);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return temJson;
+ }
+
+
+ public static void main(String[] args) {
+
+ }
+}
diff --git a/pqs-advance/advance-boot/pom.xml b/pqs-advance/advance-boot/pom.xml
index 081b7cba7..c3e782980 100644
--- a/pqs-advance/advance-boot/pom.xml
+++ b/pqs-advance/advance-boot/pom.xml
@@ -42,21 +42,20 @@
com.njcn
pq-device-api
- 1.0.0
+ ${project.version}
compile
com.njcn
advance-api
- 1.0.0
- compile
+ ${project.version}
com.njcn
event-api
- 1.0.0
+ ${project.version}
diff --git a/pqs-advance/advance-boot/src/main/java/com/njcn/advance/controller/EventRelevantAnalysisController.java b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/controller/EventRelevantAnalysisController.java
new file mode 100644
index 000000000..1f0f03f7f
--- /dev/null
+++ b/pqs-advance/advance-boot/src/main/java/com/njcn/advance/controller/EventRelevantAnalysisController.java
@@ -0,0 +1,74 @@
+package com.njcn.advance.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.netflix.ribbon.proxy.annotation.Http;
+import com.njcn.advance.pojo.dto.BalanceInfo;
+import com.njcn.advance.pojo.param.AdvanceBaseParam;
+import com.njcn.advance.service.EventRelevantAnalysisService;
+import com.njcn.common.pojo.annotation.OperateInfo;
+import com.njcn.common.pojo.enums.common.LogEnum;
+import com.njcn.common.pojo.enums.response.CommonResponseEnum;
+import com.njcn.common.pojo.response.HttpResult;
+import com.njcn.common.utils.HttpResultUtil;
+import com.njcn.common.utils.PubUtils;
+import com.njcn.event.pojo.vo.AdvanceEventDetailVO;
+import com.njcn.web.controller.BaseController;
+import com.njcn.web.pojo.annotation.DateTimeStrValid;
+import com.njcn.web.pojo.param.BaseParam;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.DataInputStream;
+import java.net.URLDecoder;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * pqs
+ * 事件关联分析
+ *
+ * @author cdf
+ * @date 2023/6/30
+ */
+@RestController
+@RequestMapping("process")
+@Api(tags = "暂降事件关联分析")
+@RequiredArgsConstructor
+@Slf4j
+public class EventRelevantAnalysisController extends BaseController {
+
+ private final EventRelevantAnalysisService eventRelevantAnalysisService;
+
+ @GetMapping("processEvents")
+ @OperateInfo(info = LogEnum.BUSINESS_COMMON)
+ @ApiOperation("启动关联分析")
+ public HttpResult