|
|
@@ -6,10 +6,7 @@ import com.gyee.runeconomy.dto.result.PowerPointData;
|
|
|
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
|
|
|
/**
|
|
|
* 数据预处理算法
|
|
|
@@ -40,7 +37,7 @@ public class PowerProcessALG {
|
|
|
*/
|
|
|
public static List<PowerPointData> dataProcess(List<PowerPointData> list, Map<Double, Double> map,
|
|
|
Double maxs, Double mins, Double maxp, Double minp, Boolean isfbw,
|
|
|
- Boolean isfhl, Boolean isbw, Boolean istj, Boolean isglpc, Boolean isqfh, Integer qfhdj){
|
|
|
+ Boolean isfhl, Boolean isbw, Boolean istj, Boolean isglpc, Boolean isqfh, Integer qfhdj) {
|
|
|
String timeBW = DateUtil.format(new Date(0), DATE_TIME_PATTERN);
|
|
|
List<PowerPointData> tempei = new ArrayList<>();
|
|
|
List<PowerPointData> tempqf = new ArrayList<>();
|
|
|
@@ -49,7 +46,7 @@ public class PowerProcessALG {
|
|
|
for (PowerPointData item : list) {
|
|
|
int filter = 0;
|
|
|
int fjstatus = 0;
|
|
|
- if (timeBW == DateUtil.format(new Date(0), DATE_TIME_PATTERN)){
|
|
|
+ if (timeBW == DateUtil.format(new Date(0), DATE_TIME_PATTERN)) {
|
|
|
timeBW = item.getTime();
|
|
|
}
|
|
|
// 过滤非并网值 风机状态不等于2
|
|
|
@@ -144,123 +141,139 @@ public class PowerProcessALG {
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 数据预处理
|
|
|
+ *
|
|
|
+ * @param list 预处理的数据
|
|
|
+ * @param map 风速对应的保证功率
|
|
|
+ * @param maxs 最大风速
|
|
|
+ * @param mins 最小风速
|
|
|
+ * @param maxp 最大功率
|
|
|
+ * @param minp 最小功率
|
|
|
+ * @param isfbw 是否并网
|
|
|
+ * @param isfhl 是否合理值
|
|
|
+ * @param isbw 并网后10分钟
|
|
|
+ * @param istj 停机前10分钟
|
|
|
+ * @param isglpc 功率曲线偏差
|
|
|
+ * @param isqfh 是否欠符合
|
|
|
+ * @param qfhdj 欠符合等级
|
|
|
+ * @return
|
|
|
+ */
|
|
|
|
|
|
- public static List<PowerPointData> dataProcess11(List<PowerPointData> list, Map<Double, Double> map,
|
|
|
- Double maxs, Double mins, Double maxp, Double minp, Boolean isfbw,
|
|
|
- Boolean isfhl, Boolean isbw, Boolean istj, Boolean isglpc, Boolean isqfh, Integer qfhdj) {
|
|
|
+ public static List<PowerPointData> dataProcess11(
|
|
|
+ List<PowerPointData> list, Map<Double, Double> map,
|
|
|
+ Double maxs, Double mins, Double maxp, Double minp, Boolean isfbw,
|
|
|
+ Boolean isfhl, Boolean isbw, Boolean istj, Boolean isglpc, Boolean isqfh, Integer qfhdj) {
|
|
|
|
|
|
if (list == null || list.isEmpty()) return list;
|
|
|
|
|
|
- // 并网起点时间(第一次遇到并网或者从非并网->并网时初始化)
|
|
|
- String gridStartTime = null;
|
|
|
+ // ---------- 设置 ----------
|
|
|
+ String gridStartTime = null; // 并网参考点(第一次并网或从非并网->并网时设置)
|
|
|
+ // tempei: 并网期间索引队列(用于停机前10分钟回溯)
|
|
|
+ Deque<Integer> tempeiIndex = new LinkedList<>();
|
|
|
+ // tempqf: 欠发期间索引队列(用于欠发5分钟回溯)
|
|
|
+ Deque<Integer> tempqfIndex = new LinkedList<>();
|
|
|
|
|
|
- // 用索引保存 tempei / tempqf 窗口,避免存对象引用导致连带修改
|
|
|
- List<Integer> tempeiIndex = new ArrayList<>();
|
|
|
- List<Integer> tempqfIndex = new ArrayList<>();
|
|
|
+ // 为了追踪每条数据为什么被过滤,记录原因(仅用于调试打印)
|
|
|
+ Map<Integer, String> filterReasons = new HashMap<>();
|
|
|
+
|
|
|
+ // 容忍度:在 map key 查找最近风速的容差(单位 m/s),可以按需要调整
|
|
|
+ final double SPEED_TOLERANCE = 0.05;
|
|
|
|
|
|
- // 遍历原始列表,按业务条件判断 filter(最终写回到每个 item 中)
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
|
PowerPointData item = list.get(i);
|
|
|
- int filter = 0; // 0 保留,1 过滤
|
|
|
+ int filter = 0; // 0 keep, 1 filtered
|
|
|
+ String reason = null;
|
|
|
|
|
|
String currentTime = item.getTime();
|
|
|
double speed = item.getSpeed();
|
|
|
double power = item.getPower();
|
|
|
- int mxzt = item.getMxzt();
|
|
|
+ int mxzt = item.getMxzt(); // 风机状态,2=并网
|
|
|
|
|
|
- // 状态判断
|
|
|
- boolean isGrid = (mxzt == 2); // 并网
|
|
|
- boolean isNonGrid = !isGrid; // 非并网
|
|
|
+ boolean isGrid = (mxzt == 2);
|
|
|
+ boolean isNonGrid = !isGrid;
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 1) 过滤非并网值(如果开关 isfbw 为 true)
|
|
|
- // 原逻辑中非并网要被过滤
|
|
|
- // ---------------------------
|
|
|
- if (isfbw != null && isfbw && isNonGrid) {
|
|
|
+ // ---------- 0. 边界保护 ----------
|
|
|
+ if (currentTime == null) {
|
|
|
+ // 无时间信息,过滤并记录原因
|
|
|
filter = 1;
|
|
|
- // 标记:当发生非并网事件时,我们需要把之前记录的 tempeiIndex (并网期间的索引)标记为停机前10分钟过滤
|
|
|
- // 这里的处理会在 istj 分支统一处理(以保持行为一致),但保留当前行为:非并网条目本身也被过滤
|
|
|
- }
|
|
|
-
|
|
|
- // ---------------------------
|
|
|
- // 2) 若发现是并网且 gridStartTime 未初始化,则初始化(第一次并网或刚开始的数据)
|
|
|
- // 这样能保证“第一条并网数据不会被误过滤”
|
|
|
- // ---------------------------
|
|
|
- if (isGrid && gridStartTime == null) {
|
|
|
- gridStartTime = currentTime;
|
|
|
- // 不对当前 item 做并网后 10 分钟过滤(作为起点)
|
|
|
- // 注意:如果你想只在从非并网->并网才初始化,可以改为在 isNonGrid->isGrid 的过渡时初始化
|
|
|
+ reason = "no_time";
|
|
|
+ item.setFilter(filter);
|
|
|
+ filterReasons.put(i, reason);
|
|
|
+ System.out.println("Index " + i + " filtered: " + reason);
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 3) 风速功率范围过滤(按mins/maxs/minp/maxp)
|
|
|
- // ---------------------------
|
|
|
+ // ---------- 1. 风速/功率范围过滤(尽早做) ----------
|
|
|
if (!Double.isNaN(speed) && !Double.isNaN(power)) {
|
|
|
if ((mins != null && speed < mins) || (maxs != null && speed > maxs)
|
|
|
|| (minp != null && power < minp) || (maxp != null && power > maxp)) {
|
|
|
filter = 1;
|
|
|
+ reason = "out_of_range";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 4) 过滤非合理值(并网状态下功率小于等于 minp 或速度 < 0) - 保持与你原逻辑一致
|
|
|
- // ---------------------------
|
|
|
- if (filter == 0 && isfhl != null && isfhl) {
|
|
|
- // 如果速度 < 0 且功率 <= minp 则认为不合理(参考原逻辑)
|
|
|
- if (speed < 0 && !Double.isNaN(power) && minp != null && power <= minp) {
|
|
|
- filter = 1;
|
|
|
- }
|
|
|
+ // ---------- 2. 修正并网起点(当从非并网 -> 并网时设置) ----------
|
|
|
+ // 如果 gridStartTime 还没设置,我们尽量在真正的过渡(非并网->并网)时设置它,
|
|
|
+ // 但为了兼容你的数据(如果整个序列从并网开始),我们也可以在首次并网时设置。
|
|
|
+ if (isGrid && gridStartTime == null) {
|
|
|
+ // 首次遇到并网(或序列从并网开始)时初始化为该时刻(作为并网基准)
|
|
|
+ gridStartTime = currentTime;
|
|
|
+ // 不将该时刻误判为并网后十分钟
|
|
|
+ // 备注:如果你想严格只在 "非并网->并网" 过渡时初始化,请替换为状态机检测
|
|
|
}
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 5) 并网后 10 分钟过滤(isbw 开关)
|
|
|
- // 注意:gridStartTime 必须有效(非 null),getTimeDiff 返回 -1 时不做过滤
|
|
|
- // ---------------------------
|
|
|
+ // ---------- 3. 非并网过滤(isfbw) ----------
|
|
|
+ // isfbw=true 表示 "过滤非并网点"(只保留 mxzt==2)
|
|
|
+ if (isfbw != null && isfbw && isNonGrid) {
|
|
|
+ filter = 1;
|
|
|
+ reason = appendReason(reason, "non_grid");
|
|
|
+ }
|
|
|
+
|
|
|
+ // ---------- 4. 并网后10分钟过滤(isbw) ----------
|
|
|
if (filter == 0 && isbw != null && isbw && gridStartTime != null) {
|
|
|
int diff = getTimeDiff(currentTime, gridStartTime);
|
|
|
if (diff >= 0 && diff <= 10) {
|
|
|
filter = 1;
|
|
|
+ reason = appendReason(reason, "post_grid_within_10min");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 6) 停机前 10 分钟过滤(istj 开关)
|
|
|
- // 语义:当检测到非并网(isNonGrid)时,将之前记录的并网期间最近的若干条(最多覆盖10分钟窗口)标记为过滤
|
|
|
- // 我们通过 tempeiIndex 在并网期间保存索引;一旦发现非并网 -> 标记这些索引
|
|
|
- // ---------------------------
|
|
|
+ // ---------- 5. 停机前10分钟回溯标记(istj) ----------
|
|
|
if (istj != null && istj) {
|
|
|
if (isNonGrid) {
|
|
|
- // 发生非并网事件:把 tempeiIndex 中的候选项都标记为过滤
|
|
|
+ // 发生非并网事件:将 tempeiIndex 中的并网点都标记为过滤(停机前10分钟)
|
|
|
for (Integer idx : tempeiIndex) {
|
|
|
if (idx >= 0 && idx < list.size()) {
|
|
|
- list.get(idx).setFilter(1);
|
|
|
+ PowerPointData prev = list.get(idx);
|
|
|
+ prev.setFilter(1);
|
|
|
+ // 记录原因(覆盖原有 reason 可能)
|
|
|
+ filterReasons.put(idx, appendReason(filterReasons.get(idx), "pre_shutdown_10min"));
|
|
|
}
|
|
|
}
|
|
|
- // 清空窗口
|
|
|
tempeiIndex.clear();
|
|
|
+ // 当前非并网点自身通常也会被过滤(见上面的 non_grid)
|
|
|
} else {
|
|
|
- // 当前仍为并网:维护 tempeiIndex,使其只保存最近不超过 10 分钟的并网索引
|
|
|
- if (!tempeiIndex.isEmpty()) {
|
|
|
- int firstIdx = tempeiIndex.get(0);
|
|
|
+ // 当前仍为并网:维护 tempeiIndex(保存最近不超过 10 分钟的并网索引)
|
|
|
+ // 移除过旧的索引(超过 10 分钟)
|
|
|
+ while (!tempeiIndex.isEmpty()) {
|
|
|
+ int firstIdx = tempeiIndex.peekFirst();
|
|
|
String firstTime = list.get(firstIdx).getTime();
|
|
|
- int diff = getTimeDiff(firstTime, currentTime);
|
|
|
- if (diff >= 0 && diff >= 10) {
|
|
|
- // 超过 10 分钟,则移除最旧的(可以循环移除,但原逻辑是单次检查)
|
|
|
- tempeiIndex.remove(0);
|
|
|
+ int d = getTimeDiff(firstTime, currentTime);
|
|
|
+ if (d >= 0 && d >= 10) {
|
|
|
+ tempeiIndex.pollFirst();
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- // 添加当前并网索引到窗口头(保持与原逻辑一致的顺序)
|
|
|
- tempeiIndex.add(i);
|
|
|
+ // 将当前并网点加入队列末尾(表示最新)
|
|
|
+ tempeiIndex.addLast(i);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 7) 欠发过滤(isqfh 开关 + qfhdj 等级判断)
|
|
|
- // 逻辑:如果当前点满足欠发条件 -> 过滤,并把 tempqfIndex 中的索引标记为过滤
|
|
|
- // ---------------------------
|
|
|
+ // ---------- 6. 欠发逻辑(isqfh)及回溯5分钟(tempqfIndex) ----------
|
|
|
boolean needQF = false;
|
|
|
if (filter == 0 && isqfh != null && isqfh) {
|
|
|
- // qfzt 为设备点的欠发状态等级
|
|
|
int qfzt = item.getQfzt();
|
|
|
if (!Double.isNaN(speed)) {
|
|
|
if (speed >= 6 && speed < 12.5 && qfhdj != null && qfhdj < qfzt) {
|
|
|
@@ -270,66 +283,137 @@ public class PowerProcessALG {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
if (needQF) {
|
|
|
+ // 标记当前点
|
|
|
filter = 1;
|
|
|
+ reason = appendReason(reason, "under_generation_detected");
|
|
|
+ // 回溯标记 tempqfIndex 里最近 5 分钟的数据为过滤
|
|
|
for (Integer idx : tempqfIndex) {
|
|
|
if (idx >= 0 && idx < list.size()) {
|
|
|
list.get(idx).setFilter(1);
|
|
|
+ filterReasons.put(idx, appendReason(filterReasons.get(idx), "pre_under_gen_5min"));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 更新 tempqfIndex:保持一个 5 分钟窗口(与原逻辑相同)
|
|
|
- if (!tempqfIndex.isEmpty()) {
|
|
|
- int firstIdx = tempqfIndex.get(0);
|
|
|
+ // 维护 tempqfIndex(保持最近不超过 5 分钟)
|
|
|
+ while (!tempqfIndex.isEmpty()) {
|
|
|
+ int firstIdx = tempqfIndex.peekFirst();
|
|
|
String firstTime = list.get(firstIdx).getTime();
|
|
|
- int diff = getTimeDiff(firstTime, currentTime);
|
|
|
- if (diff >= 0 && diff >= 5) {
|
|
|
- tempqfIndex.remove(0);
|
|
|
+ int d = getTimeDiff(firstTime, currentTime);
|
|
|
+ if (d >= 0 && d >= 5) {
|
|
|
+ tempqfIndex.pollFirst();
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- // 将当前索引放到 tempqfIndex 的头部(和你原来 add(0, item) 的语义对应)
|
|
|
- tempqfIndex.add(0, i);
|
|
|
-
|
|
|
- // ---------------------------
|
|
|
- // 8) 功率曲线偏差(isglpc 开关)
|
|
|
- // 使用 map 提供的保证功率(map.get(speed))和 map.get(24.0) 作为最大保证功率
|
|
|
- // ---------------------------
|
|
|
- if (filter == 0 && isglpc != null && isglpc && map != null && map.containsKey(speed)) {
|
|
|
- Double guaranteePower = map.get(speed);
|
|
|
- Double maxGuarantee = map.get(24.0);
|
|
|
- if (guaranteePower != null && guaranteePower > 0 && !Double.isNaN(power) && power > 0) {
|
|
|
- double k = power / guaranteePower; // 实际功率 / 保证功率(注意:与你原 k 定义可换)
|
|
|
- // 按你原始逻辑规则决定阈值(此处保留原来的判断条件)
|
|
|
- if (k < 0.95 && maxGuarantee != null && maxGuarantee <= guaranteePower) filter = 1;
|
|
|
- if (k < 0.9 && maxGuarantee != null && maxGuarantee > guaranteePower) filter = 1;
|
|
|
- if (k < 0.85 && speed < 6 && speed > 4) filter = 1;
|
|
|
- if (k < 0.9 && speed <= 4 && speed > 3.5) filter = 1;
|
|
|
+ // 将当前索引放到 tempqfIndex 尾部
|
|
|
+ tempqfIndex.addLast(i);
|
|
|
+
|
|
|
+ // ---------- 7. 功率曲线偏差(isglpc) - 使用最近的 map key ----------
|
|
|
+ if (filter == 0 && isglpc != null && isglpc && map != null && !map.isEmpty()) {
|
|
|
+ Double key = findNearestMapKey(map, speed, SPEED_TOLERANCE);
|
|
|
+ if (key != null) {
|
|
|
+ Double guaranteePower = map.get(key);
|
|
|
+ Double maxGuarantee = map.get(24.0);
|
|
|
+ if (guaranteePower != null && guaranteePower > 0 && !Double.isNaN(power) && power > 0) {
|
|
|
+ double k = power / guaranteePower; // 实际/保证
|
|
|
+ // 阈值逻辑保留并以 k 判定
|
|
|
+ if (k < 0.95 && maxGuarantee != null && maxGuarantee <= guaranteePower) {
|
|
|
+ filter = 1;
|
|
|
+ reason = appendReason(reason, "curve_dev_k_lt_0.95");
|
|
|
+ } else if (k < 0.9 && maxGuarantee != null && maxGuarantee > guaranteePower) {
|
|
|
+ filter = 1;
|
|
|
+ reason = appendReason(reason, "curve_dev_k_lt_0.9");
|
|
|
+ } else if (k < 0.85 && speed < 6 && speed > 4) {
|
|
|
+ filter = 1;
|
|
|
+ reason = appendReason(reason, "curve_dev_k_lt_0.85_speed_4_6");
|
|
|
+ } else if (k < 0.9 && speed <= 4 && speed > 3.5) {
|
|
|
+ filter = 1;
|
|
|
+ reason = appendReason(reason, "curve_dev_k_lt_0.9_speed_3.5_4");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // power<=0 or guaranteePower invalid -> optional filter, 这里不强制
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 未找到合适的风速 key:你可以选择把它视作不可判断(不过滤),或者做备选处理
|
|
|
+ // 目前我们不因为找不到 key 就过滤(保持宽松)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ---------------------------
|
|
|
- // 9) 最终设置当前项的 filter(0 或 1)
|
|
|
- // ---------------------------
|
|
|
+ // ---------- 8. 非合理值过滤(isfhl) - 你原始条件是速度 < 0 且功率 <= minp
|
|
|
+ // 此外,如果 qfzt 明确表示异常(非 0),也可认为是不合理点(此处不强制,但我提供注释)
|
|
|
+ if (filter == 0 && isfhl != null && isfhl) {
|
|
|
+ // 保留原始:速度 < 0 && power <= minp
|
|
|
+ if (speed < 0 && !Double.isNaN(power) && minp != null && power <= minp) {
|
|
|
+ filter = 1;
|
|
|
+ reason = appendReason(reason, "not_reasonable_speed_power");
|
|
|
+ }
|
|
|
+ // 如果你希望 qfzt>0 一定被当作不合理点可以打开下面注释:
|
|
|
+ // if (item.getQfzt() > 0) { filter = 1; reason = appendReason(reason, "qfzt_nonzero"); }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ---------- 9. 设置并输出结果 ----------
|
|
|
item.setFilter(filter);
|
|
|
+ if (filter == 1) {
|
|
|
+ if (reason == null) reason = "generic_filtered";
|
|
|
+ filterReasons.put(i, reason);
|
|
|
+ // 输出调试信息(你可以改为日志)
|
|
|
+// System.out.println("Index " + i + " filtered: " + reason + " (time=" + currentTime + ", speed=" + speed + ", power=" + power + ", mxzt=" + mxzt + ", qfzt=" + item.getQfzt() + ")");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 注意:tempeiIndex/tempqfIndex 的维护在循环各自分支里完成(tempei 在 istj 分支中)
|
|
|
+ // tempqfIndex 已在上面维护
|
|
|
+ // tempeiIndex 的维护若未启用 istj 则不会改变
|
|
|
}
|
|
|
|
|
|
- // 返回原 list(对象被按需修改 filter 字段;但没有把对象引用放到临时集合中造成额外污染)
|
|
|
+ // (可选) 将 filterReasons 结果打印为汇总,便于检查
|
|
|
+ // System.out.println("filterReasons summary: " + filterReasons);
|
|
|
+
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 将新 reason 附加到旧 reason 上(用逗号分隔)
|
|
|
+ */
|
|
|
+ private static String appendReason(String oldReason, String newReason) {
|
|
|
+ if (oldReason == null || oldReason.isEmpty()) return newReason;
|
|
|
+ if (newReason == null || newReason.isEmpty()) return oldReason;
|
|
|
+ return oldReason + "," + newReason;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在 map 的 key(风速)中查找与 targetSpeed 最接近的 key(绝对差 <= tolerance)
|
|
|
+ * 如果找不到合适 key,返回 null
|
|
|
+ */
|
|
|
+ private static Double findNearestMapKey(Map<Double, Double> map, double targetSpeed, double tolerance) {
|
|
|
+ if (map == null || map.isEmpty()) return null;
|
|
|
+ Double bestKey = null;
|
|
|
+ double bestDiff = Double.MAX_VALUE;
|
|
|
+ for (Double k : map.keySet()) {
|
|
|
+ double d = Math.abs(k - targetSpeed);
|
|
|
+ if (d < bestDiff) {
|
|
|
+ bestDiff = d;
|
|
|
+ bestKey = k;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (bestKey == null) return null;
|
|
|
+ return (bestDiff <= tolerance) ? bestKey : null;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 按照给定风俗功率过滤
|
|
|
+ *
|
|
|
* @param list
|
|
|
- * @param maxs 最大风速
|
|
|
- * @param mins 最小风速
|
|
|
- * @param maxp 最大功率
|
|
|
- * @param minp 最小风速
|
|
|
+ * @param maxs 最大风速
|
|
|
+ * @param mins 最小风速
|
|
|
+ * @param maxp 最大功率
|
|
|
+ * @param minp 最小风速
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessPS(List<PowerPointData> list, Double maxs, Double mins, Double maxp, Double minp){
|
|
|
+ public static List<PowerPointData> dataProcessPS(List<PowerPointData> list, Double maxs, Double mins, Double maxp, Double minp) {
|
|
|
//TODO 数据过滤 // 0正常,1过滤掉
|
|
|
for (PowerPointData item : list) {
|
|
|
int filter = 0;
|
|
|
@@ -346,10 +430,11 @@ public class PowerProcessALG {
|
|
|
|
|
|
/**
|
|
|
* 过滤非并网值
|
|
|
+ *
|
|
|
* @param list
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessFBW(List<PowerPointData> list){
|
|
|
+ public static List<PowerPointData> dataProcessFBW(List<PowerPointData> list) {
|
|
|
//TODO 数据过滤 // 0正常,1过滤掉
|
|
|
for (PowerPointData item : list) {
|
|
|
int filter = 0;
|
|
|
@@ -366,10 +451,11 @@ public class PowerProcessALG {
|
|
|
|
|
|
/**
|
|
|
* 过滤非合理值
|
|
|
+ *
|
|
|
* @param list
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessFHLZ(List<PowerPointData> list){
|
|
|
+ public static List<PowerPointData> dataProcessFHLZ(List<PowerPointData> list) {
|
|
|
//TODO 数据过滤 // 0正常,1过滤掉
|
|
|
for (PowerPointData item : list) {
|
|
|
int filter = 0;
|
|
|
@@ -386,20 +472,21 @@ public class PowerProcessALG {
|
|
|
|
|
|
/**
|
|
|
* 过滤并网后几分钟内数据
|
|
|
+ *
|
|
|
* @param list
|
|
|
- * @param minute 分钟
|
|
|
+ * @param minute 分钟
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessBWH(List<PowerPointData> list, int minute){
|
|
|
+ public static List<PowerPointData> dataProcessBWH(List<PowerPointData> list, int minute) {
|
|
|
String timeBW = DateUtil.format(new Date(0), DATE_TIME_PATTERN);
|
|
|
//TODO 数据过滤 // 0正常,1过滤掉
|
|
|
for (PowerPointData item : list) {
|
|
|
int filter = 0;
|
|
|
- if (timeBW == DateUtil.format(new Date(0), DATE_TIME_PATTERN)){
|
|
|
+ if (timeBW == DateUtil.format(new Date(0), DATE_TIME_PATTERN)) {
|
|
|
timeBW = item.getTime();
|
|
|
}
|
|
|
// 过滤并网后十分钟
|
|
|
- if (filter == 0 && getTimeDiff(item.getTime(), timeBW) <= minute){
|
|
|
+ if (filter == 0 && getTimeDiff(item.getTime(), timeBW) <= minute) {
|
|
|
filter = 1;
|
|
|
}
|
|
|
|
|
|
@@ -413,10 +500,10 @@ public class PowerProcessALG {
|
|
|
/**
|
|
|
* 过滤停机前几分钟内数据
|
|
|
* @param list
|
|
|
- * @param minute 分钟
|
|
|
+ * @param minute 分钟
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessTJQ(List<PowerPointData> list, int minute){
|
|
|
+ public static List<PowerPointData> dataProcessTJQ(List<PowerPointData> list, int minute) {
|
|
|
String timeBW = DateUtil.format(new Date(0), DATE_TIME_PATTERN);
|
|
|
List<PowerPointData> tempei = new ArrayList<>();
|
|
|
|
|
|
@@ -424,7 +511,7 @@ public class PowerProcessALG {
|
|
|
for (PowerPointData item : list) {
|
|
|
int filter = 0;
|
|
|
int fjstatus = 0;
|
|
|
- if (timeBW == DateUtil.format(new Date(0), DATE_TIME_PATTERN)){
|
|
|
+ if (timeBW == DateUtil.format(new Date(0), DATE_TIME_PATTERN)) {
|
|
|
timeBW = item.getTime();
|
|
|
}
|
|
|
if (filter == 0 && item.getMxzt() != 2) {
|
|
|
@@ -462,7 +549,7 @@ public class PowerProcessALG {
|
|
|
* @param map 风速对应的保证功率
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessQXPC(List<PowerPointData> list, Map<Double, Double> map){
|
|
|
+ public static List<PowerPointData> dataProcessQXPC(List<PowerPointData> list, Map<Double, Double> map) {
|
|
|
//TODO 数据过滤 // 0正常,1过滤掉
|
|
|
for (PowerPointData item : list) {
|
|
|
if (map.containsKey(item.getSpeed())) {
|
|
|
@@ -502,7 +589,7 @@ public class PowerProcessALG {
|
|
|
* @param qfhdj 签发等级
|
|
|
* @return
|
|
|
*/
|
|
|
- public static List<PowerPointData> dataProcessQF(List<PowerPointData> list, int qfhdj){
|
|
|
+ public static List<PowerPointData> dataProcessQF(List<PowerPointData> list, int qfhdj) {
|
|
|
List<PowerPointData> tempqf = new ArrayList<>();
|
|
|
//TODO 数据过滤 // 0正常,1过滤掉
|
|
|
for (PowerPointData item : list) {
|
|
|
@@ -547,16 +634,19 @@ public class PowerProcessALG {
|
|
|
//
|
|
|
// return diff;
|
|
|
// }
|
|
|
- // ---------- 时间差工具(请替换原有实现) ----------
|
|
|
+
|
|
|
+ /**
|
|
|
+ * getTimeDiff: 计算两个时间字符串差(分钟)
|
|
|
+ * 返回 -1 表示无法计算(null 或解析失败)
|
|
|
+ */
|
|
|
public static int getTimeDiff(String oldTime, String newTime) {
|
|
|
if (oldTime == null || newTime == null) return -1;
|
|
|
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
try {
|
|
|
- long OTime = df.parse(oldTime).getTime();
|
|
|
- long NTime = df.parse(newTime).getTime();
|
|
|
- return (int) (Math.abs(NTime - OTime) / 1000 / 60);
|
|
|
+ long t1 = df.parse(oldTime).getTime();
|
|
|
+ long t2 = df.parse(newTime).getTime();
|
|
|
+ return (int) (Math.abs(t2 - t1) / 1000 / 60);
|
|
|
} catch (ParseException e) {
|
|
|
- // 解析失败视为无法比较
|
|
|
return -1;
|
|
|
}
|
|
|
}
|