|
@@ -1,7 +1,9 @@
|
|
|
package com.persagy.netty.collect;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
|
|
@@ -12,8 +14,8 @@ import org.springframework.stereotype.Component;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.googlecode.aviator.AviatorEvaluator;
|
|
|
import com.googlecode.aviator.Expression;
|
|
|
-import com.persagy.cache.CurrentDataCache;
|
|
|
import com.persagy.constant.CommonConst;
|
|
|
+import com.persagy.constant.ExtraCommonConstant;
|
|
|
import com.persagy.entity.ReturnAlarmDefine;
|
|
|
import com.persagy.init.InitReturnAlarmConfig;
|
|
|
|
|
@@ -38,34 +40,38 @@ public class ReturnDifferentAlarm {
|
|
|
/** 从左到右:项目,时间,表号,功能号,值 */
|
|
|
public static final String COMMAND = "({};1;report;{};123;{};1;{};{})";
|
|
|
|
|
|
+ public static final List<String> tempIot = new ArrayList<String>();
|
|
|
+
|
|
|
+ public static volatile int COUNT = 0;
|
|
|
+
|
|
|
@Autowired
|
|
|
private IotCollectNettyClient iotCollectNettyClient;
|
|
|
|
|
|
/**
|
|
|
- * 启动后 延时 10s触发,以5s的间隔时间触发控返不一致的信息点实时数据写入
|
|
|
+ * 启动后 延时 10s触发,以10s的间隔时间触发控返不一致的信息点实时数据写入
|
|
|
*
|
|
|
- * 每5s的间隔,代表着人为抑制了5s的持续性报警
|
|
|
+ * 每10s的间隔,代表着人为抑制了5s的持续性报警
|
|
|
*
|
|
|
* @throws Exception
|
|
|
* @date 2021年12月9日 下午8:11:36
|
|
|
*/
|
|
|
- @Scheduled(initialDelay = 10 * 1000, fixedRate = 5 * 1000)
|
|
|
+ @Scheduled(initialDelay = 10 * 1000, fixedRate = 10 * 1000)
|
|
|
public void returnDifferentAlarm() throws Exception {
|
|
|
- if (InitReturnAlarmConfig.alarmCode2Alarm.size() == 0) {
|
|
|
+ if (InitReturnAlarmConfig.ibmsCode2AlarmResult.size() == 0) {
|
|
|
return;
|
|
|
}
|
|
|
String now = DateUtil.date().toString("yyyyMMddHHmmss");
|
|
|
|
|
|
// 根据数据,拼接出指令信息,发送入库
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
- Set<String> alarmCodes = InitReturnAlarmConfig.alarmCode2IsAlarm.keySet();
|
|
|
+ Set<String> alarmCodes = InitReturnAlarmConfig.ibmsCode2AlarmResult.keySet();
|
|
|
for (String alarmCode : alarmCodes) {
|
|
|
- Integer isAlarm = InitReturnAlarmConfig.alarmCode2IsAlarm.get(alarmCode);
|
|
|
+ Integer isAlarm = InitReturnAlarmConfig.ibmsCode2AlarmResult.get(alarmCode);
|
|
|
if (isAlarm != null && isAlarm != -1) {
|
|
|
- ReturnAlarmDefine alarmDefine = InitReturnAlarmConfig.alarmCode2Alarm.get(alarmCode);
|
|
|
+ JSONObject alarmDefine = InitReturnAlarmConfig.ibmsCode2AlarmData.get(alarmCode);
|
|
|
// 0-正常,1-报警
|
|
|
BigDecimal dataValue = new BigDecimal(isAlarm);
|
|
|
- String command = StrUtil.format(COMMAND, alarmDefine.getBuilding(), now, alarmDefine.getAlarmInfo().getMeter(), alarmDefine.getAlarmInfo().getFuncid(), dataValue.toPlainString());
|
|
|
+ String command = StrUtil.format(COMMAND, CommonConst.building, now, alarmDefine.getString("meter"), alarmDefine.getInteger("funcid"), dataValue.toPlainString());
|
|
|
sb.append(command).append("&");
|
|
|
}
|
|
|
}
|
|
@@ -85,16 +91,42 @@ public class ReturnDifferentAlarm {
|
|
|
* {"data":"20211209150133;10346;903;1.0","type":"pointset"}
|
|
|
* {"data":"20211209155421;CW20379;902;0.0","type":"iot"}
|
|
|
*
|
|
|
+ * 实际iot数据接的会很快,所以这里需要加一下锁,防止设备类加载过于缓慢的时候,丢失iot数据,只要这里能够抢到一次锁,后续就不需要了
|
|
|
+ *
|
|
|
* @param message
|
|
|
* @date 2021年12月9日 下午3:54:35
|
|
|
*/
|
|
|
public void putMsg(String message) {
|
|
|
- if (InitReturnAlarmConfig.infoCode2Alarm.size() == 0) {
|
|
|
+ if (InitReturnAlarmConfig.alarmEnable && InitReturnAlarmConfig.controlCode2AlarmDefine.size() == 0) {
|
|
|
+ tempIot.add(message);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- Set<String> infoCodes = InitReturnAlarmConfig.infoCode2Alarm.keySet();
|
|
|
- Set<String> returnCodes = InitReturnAlarmConfig.returnCode2Alarm.keySet();
|
|
|
+ // 当设备类数据加载完成的时候,这里补充加载一次iot数据
|
|
|
+ if (tempIot.size() != 0) {
|
|
|
+ synchronized (ExtraCommonConstant.sync) {
|
|
|
+ if (tempIot.size() != 0) {
|
|
|
+ for (String iot : tempIot) {
|
|
|
+ if (StrUtil.isNotBlank(iot)) {
|
|
|
+ this.parseMessage(iot);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tempIot.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.parseMessage(message);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * iot数据解析
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ * @date 2021年12月14日 下午10:44:46
|
|
|
+ */
|
|
|
+ private void parseMessage(String message) {
|
|
|
try {
|
|
|
// 解析此条iot数据详情
|
|
|
JSONObject messageObj = JSONObject.parseObject(message);
|
|
@@ -107,30 +139,30 @@ public class ReturnDifferentAlarm {
|
|
|
BigDecimal dataValue = new BigDecimal(split[3]);
|
|
|
|
|
|
// 根据表号和功能号判断是否需要进行控返不一致的报警验证
|
|
|
- ReturnAlarmDefine returnAlarmDefine = null;
|
|
|
- String code = InitReturnAlarmConfig.meterFunid2Code.get(CurrentDataCache.getKey(meter, funcid));
|
|
|
- if (infoCodes.contains(code) && CommonConst.IOT_PONINTSET_TYPE.equals(type)) {
|
|
|
- returnAlarmDefine = InitReturnAlarmConfig.infoCode2Alarm.get(code);
|
|
|
+ ReturnAlarmDefine controlAlarmDefine = InitReturnAlarmConfig.controlCode2AlarmDefine.get(ExtraCommonConstant.getKey(meter, funcid));
|
|
|
+ ReturnAlarmDefine returnAlarmDefine = InitReturnAlarmConfig.returnCode2AlarmDefine.get(ExtraCommonConstant.getKey(meter, funcid));
|
|
|
+ if (controlAlarmDefine == null && returnAlarmDefine == null) {
|
|
|
+ return; // 为空,说明不是要进行判断的iot数据
|
|
|
+ }
|
|
|
+ if (controlAlarmDefine != null && CommonConst.IOT_PONINTSET_TYPE.equals(type)) {
|
|
|
// 防止频繁的控制,导致无法进入2分钟后的逻辑判断,这里如果值相同的话,取上一次的上报时间使用
|
|
|
- BigDecimal oldValue = returnAlarmDefine.getSetInfo().getDataValue();
|
|
|
+ BigDecimal oldValue = controlAlarmDefine.getControlInfo().getDataValue();
|
|
|
if (oldValue == null || dataValue.compareTo(oldValue) != 0) {
|
|
|
- returnAlarmDefine.getSetInfo().setDataTime(dataTime);
|
|
|
- returnAlarmDefine.getSetInfo().setDataValue(dataValue);
|
|
|
+ controlAlarmDefine.getControlInfo().setDataTime(dataTime);
|
|
|
+ controlAlarmDefine.getControlInfo().setDataValue(dataValue);
|
|
|
}
|
|
|
- } else if (returnCodes.contains(code) && CommonConst.IOT_IOT_TYPE.equals(type)) {
|
|
|
- returnAlarmDefine = InitReturnAlarmConfig.returnCode2Alarm.get(code);
|
|
|
+ // 正常数据下,判断此条数据,是否会影响控返不一致的报警信息点
|
|
|
+ log.info("需要进行控返不一致判断的iot数据:{}", message);
|
|
|
+ this.returnAlarmHandler(controlAlarmDefine);
|
|
|
+ } else if (returnAlarmDefine != null && CommonConst.IOT_IOT_TYPE.equals(type)) {
|
|
|
returnAlarmDefine.getReturnInfo().setDataTime(dataTime);
|
|
|
returnAlarmDefine.getReturnInfo().setDataValue(dataValue);
|
|
|
+ // 正常数据下,判断此条数据,是否会影响控返不一致的报警信息点
|
|
|
+ log.info("需要进行控返不一致判断的iot数据:{}", message);
|
|
|
+ this.returnAlarmHandler(returnAlarmDefine);
|
|
|
+ } else {
|
|
|
+ return; // 未知的iot数据
|
|
|
}
|
|
|
-
|
|
|
- if (returnAlarmDefine == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- log.info("需要进行控返不一致判断的iot数据:{}", message);
|
|
|
-
|
|
|
- // 正常数据下,判断此条数据,是否会影响控返不一致的报警信息点
|
|
|
- this.returnAlarmHandler(returnAlarmDefine);
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
log.error("控返不一致的报警,逻辑处理异常", e);
|
|
@@ -153,17 +185,20 @@ public class ReturnDifferentAlarm {
|
|
|
* @date 2021年12月9日 下午5:29:37
|
|
|
*/
|
|
|
private void returnAlarmHandler(ReturnAlarmDefine returnAlarmDefine) {
|
|
|
- String setTimeStr = returnAlarmDefine.getSetInfo().getDataTime();
|
|
|
+ // 报警结果key
|
|
|
+ String alarmKey = ExtraCommonConstant.getKey(returnAlarmDefine.getAlarmInfo().getMeter(), returnAlarmDefine.getAlarmInfo().getFuncid()+"");
|
|
|
+
|
|
|
+ String setTimeStr = returnAlarmDefine.getControlInfo().getDataTime();
|
|
|
String returnTimeStr = returnAlarmDefine.getReturnInfo().getDataTime();
|
|
|
if (!StrUtil.isAllNotBlank(setTimeStr, returnTimeStr)) {
|
|
|
- InitReturnAlarmConfig.alarmCode2IsAlarm.put(returnAlarmDefine.getAlarmInfo().getInfoCode(), -1);
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, -1);
|
|
|
return;
|
|
|
}
|
|
|
long setTime = Long.valueOf(setTimeStr);
|
|
|
long returnTime = Long.valueOf(returnTimeStr);
|
|
|
if (setTime > returnTime) {
|
|
|
// 新的指令和旧的iot数据,无论是否满足报警定义都不做任何处理,等待最新的iot数据上传后在做判断
|
|
|
- InitReturnAlarmConfig.alarmCode2IsAlarm.put(returnAlarmDefine.getAlarmInfo().getInfoCode(), -1);
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, -1);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -176,8 +211,8 @@ public class ReturnDifferentAlarm {
|
|
|
Expression triggerExp = AviatorEvaluator.compile(alarmCondition, true);
|
|
|
|
|
|
// 判断实际是否应该产生报警
|
|
|
- String infoCode = returnAlarmDefine.getSetInfo().getInfoCode();
|
|
|
- BigDecimal infoValue = returnAlarmDefine.getSetInfo().getDataValue() == null ? null : returnAlarmDefine.getSetInfo().getDataValue();
|
|
|
+ String infoCode = returnAlarmDefine.getControlInfo().getInfoCode();
|
|
|
+ BigDecimal infoValue = returnAlarmDefine.getControlInfo().getDataValue() == null ? null : returnAlarmDefine.getControlInfo().getDataValue();
|
|
|
String returnCode = returnAlarmDefine.getReturnInfo().getInfoCode();
|
|
|
BigDecimal returnValue = returnAlarmDefine.getReturnInfo().getDataValue() == null ? null : returnAlarmDefine.getReturnInfo().getDataValue();
|
|
|
|
|
@@ -186,18 +221,41 @@ public class ReturnDifferentAlarm {
|
|
|
paramMap.put(returnCode, returnValue);
|
|
|
Boolean triggerResult = (Boolean) triggerExp.execute(paramMap);
|
|
|
|
|
|
+ Integer count = InitReturnAlarmConfig.alarmCount.get(alarmKey);
|
|
|
// 旧的指令和新的iot数据
|
|
|
if (!newest) {
|
|
|
// 不是2分钟后上传上来的iot数据,这里不做任何处理
|
|
|
- InitReturnAlarmConfig.alarmCode2IsAlarm.put(returnAlarmDefine.getAlarmInfo().getInfoCode(), -1);
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, -1);
|
|
|
} else if (BooleanUtil.isTrue(triggerResult)) {
|
|
|
// 满足报警条件,产生报警
|
|
|
- InitReturnAlarmConfig.alarmCode2IsAlarm.put(returnAlarmDefine.getAlarmInfo().getInfoCode(), 1);
|
|
|
+ if (!returnAlarmDefine.isAlarmStatus()) {
|
|
|
+ // 如果之前没有报警
|
|
|
+ if (count == null) {
|
|
|
+ InitReturnAlarmConfig.alarmCount.put(alarmKey, 1);
|
|
|
+ } else {
|
|
|
+ InitReturnAlarmConfig.alarmCount.put(alarmKey, ++count);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 这里一定时报警状态
|
|
|
+ returnAlarmDefine.setAlarmStatus(true);
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, 1);
|
|
|
} else if (BooleanUtil.isFalse(triggerResult)) {
|
|
|
- // 不满足报警条件,如果已报警,则需恢复
|
|
|
- InitReturnAlarmConfig.alarmCode2IsAlarm.put(returnAlarmDefine.getAlarmInfo().getInfoCode(), 0);
|
|
|
+ // 不满足报警条件,判断是否报警数归零,不归零的话,不能设置为正常状态
|
|
|
+ if (returnAlarmDefine.isAlarmStatus()) {
|
|
|
+ // 之前报警了
|
|
|
+ count--;
|
|
|
+ if (count < 1) {
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, 0);
|
|
|
+ }
|
|
|
+ InitReturnAlarmConfig.alarmCount.put(alarmKey, count < 1 ? 0 : count);
|
|
|
+ }
|
|
|
+ // 如果之前未报警,且当前也不存在报警,可以设置为 0
|
|
|
+ Integer isAlarm = InitReturnAlarmConfig.ibmsCode2AlarmResult.get(alarmKey);
|
|
|
+ if (isAlarm != 1) {
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, 0);
|
|
|
+ }
|
|
|
} else {
|
|
|
- InitReturnAlarmConfig.alarmCode2IsAlarm.put(returnAlarmDefine.getAlarmInfo().getInfoCode(), -1);
|
|
|
+ InitReturnAlarmConfig.ibmsCode2AlarmResult.put(alarmKey, -1);
|
|
|
}
|
|
|
}
|
|
|
|