|
|
@@ -1,11 +1,13 @@
|
|
|
package com.shkpr.service.warncore.bizhandler;
|
|
|
|
|
|
+import com.global.base.tools.CastUtil;
|
|
|
import com.global.base.tools.FastJsonUtil;
|
|
|
import com.shkpr.service.warncore.commtools.CommTool;
|
|
|
import com.shkpr.service.warncore.commtools.TimeTool;
|
|
|
import com.shkpr.service.warncore.components.locks.CountDownLatchEx;
|
|
|
import com.shkpr.service.warncore.components.locks.OrdWarnPlanLockMgr;
|
|
|
import com.shkpr.service.warncore.constants.CommFieldStatus;
|
|
|
+import com.shkpr.service.warncore.constants.FrequencyUnit;
|
|
|
import com.shkpr.service.warncore.dbdao.DBMgrProxy;
|
|
|
import com.shkpr.service.warncore.dbdao.services.intef.OrdWarnPlanInfoDBService;
|
|
|
import com.shkpr.service.warncore.dbdao.services.intef.OrdWarnPlanRulesDBService;
|
|
|
@@ -93,20 +95,30 @@ public class SiteDataHandler {
|
|
|
|
|
|
private ResponseCode handlerDataFun(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules){
|
|
|
ResponseCode code = ResponseCode.RESULT_NORMAL;
|
|
|
- String step = "Start To Pre Analysis";
|
|
|
+ String step = "Start to pre analysis.";
|
|
|
if (getWarnPlanInfoDBService().existsLineEx(OrdWarnPlanInfoTable.R_INFO.TABLE
|
|
|
, new HashMap<String, Object>(){{put(OrdWarnPlanInfoTable.R_INFO.STATUS, CommFieldStatus.ENABLE);
|
|
|
put(OrdWarnPlanInfoTable.R_INFO.UNIQUE_ID, planDetail.getUid());
|
|
|
put(OrdWarnPlanInfoTable.R_INFO.VERSION, planDetail.getVersion());
|
|
|
}}, null, "") <= 0){
|
|
|
- step = "Plan Is Changed,Do Analysis Next Time";
|
|
|
+ step = "Plan is changed,do analysis next time";
|
|
|
code = ResponseCode.RESULT_BAD;
|
|
|
}
|
|
|
|
|
|
+ boolean doForTodayBefore = false;//是否只分析今日之前的数据
|
|
|
final long curUTCTm = TimeTool.getCurMsUTC();
|
|
|
- final int curClock = (int)((curUTCTm/1000/60/60%24+8)%24);
|
|
|
- final String curDate = TimeTool.convertUTC2DateStr(curUTCTm, TimeTool.YEAR_MONTH_DAY_FORMAT);
|
|
|
+ int curClock = (int)((curUTCTm/1000/60/60%24+8)%24);
|
|
|
long queryBeginUTC = 0L, queryEndUTC = 0L, conditionMinUTC = 0L;
|
|
|
+ final String curDate = TimeTool.convertUTC2DateStr(curUTCTm, TimeTool.YEAR_MONTH_DAY_FORMAT);
|
|
|
+ if (FrequencyUnit.MIN.equals(planDetail.getFrequencyUnit())){//以分钟为单位进行分析
|
|
|
+ }else{//以小时或其他单位进行分析
|
|
|
+ curClock = curClock - 1;
|
|
|
+ if (curClock < 0){
|
|
|
+ curClock = 23;
|
|
|
+ doForTodayBefore = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
|
|
|
do {
|
|
|
if (code != ResponseCode.RESULT_NORMAL)
|
|
|
@@ -118,30 +130,53 @@ public class SiteDataHandler {
|
|
|
conditionMinUTC = TimeTool.convertDateStr2UTC(String.format("%s %2d:00:00", curDate, rules.get(i).getStart()));
|
|
|
if (curClock >= rules.get(i).getStart() && curClock <= rules.get(i).getEnd()){
|
|
|
findStartClock = rules.get(i).getStart();
|
|
|
- queryEndUTC = Math.min(curUTCTm, TimeTool.convertDateStr2UTC(String.format("%s %2d:59:59", curDate, rules.get(i).getEnd())));
|
|
|
+ if (FrequencyUnit.MIN.equals(planDetail.getFrequencyUnit())){//以分钟为单位进行分析
|
|
|
+ queryEndUTC = Math.min(curUTCTm
|
|
|
+ , TimeTool.convertDateStr2UTC(String.format("%s %2d:59:59", curDate, rules.get(i).getEnd())));
|
|
|
+ }else {//以小时或其他单位进行分析
|
|
|
+ queryEndUTC = Math.min(TimeTool.convertDateStr2UTC(String.format("%s %2d:59:59", curDate, curClock))
|
|
|
+ , TimeTool.convertDateStr2UTC(String.format("%s %2d:59:59", curDate, rules.get(i).getEnd())));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
if (findStartClock < 0){
|
|
|
- step = "Not In Time Range,Do Analysis Next Time";
|
|
|
+ step = "Not in time range,do analysis next time";
|
|
|
code = ResponseCode.RESULT_BAD;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- findStartClock = findStartClock-1;
|
|
|
- for (int i=rules.size()-1;i>=0;i--){
|
|
|
- if (findStartClock < 0)
|
|
|
- break;
|
|
|
- if (findStartClock == rules.get(i).getEnd())
|
|
|
- findStartClock = rules.get(i).getStart()-1;
|
|
|
+ if (doForTodayBefore){//只分析昨日23:00:00-23:59:59的数据
|
|
|
+ conditionMinUTC = conditionMinUTC - TimeTool.MS_ONE_DAY;//针对昨日:触发规则列表中第一个时段的起始时刻
|
|
|
+ queryBeginUTC = TimeTool.getTodayBeginUTC()-TimeTool.MS_ONE_HOUR;
|
|
|
+ queryEndUTC = TimeTool.getTodayBeginUTC()-TimeTool.MS_ONE_SEC;
|
|
|
+ }else {
|
|
|
+ findStartClock = findStartClock-1;
|
|
|
+ for (int i=rules.size()-1;i>=0;i--){
|
|
|
+ if (findStartClock < 0)
|
|
|
+ break;
|
|
|
+ if (findStartClock == rules.get(i).getEnd())
|
|
|
+ findStartClock = rules.get(i).getStart()-1;
|
|
|
+ }
|
|
|
+ queryBeginUTC = TimeTool.convertDateStr2UTC(String.format("%s %2d:00:00", curDate, findStartClock+1));
|
|
|
}
|
|
|
- queryBeginUTC = TimeTool.convertDateStr2UTC(String.format("%s %2d:00:00", curDate, findStartClock+1));
|
|
|
|
|
|
if (thisStepTempRes.getLastCompareSampleTime() <= 0L //从未分析过则重新计数
|
|
|
|| thisStepTempRes.getLastCompareSampleTime() < queryBeginUTC){//样本跨了时段则重新计数
|
|
|
thisStepTempRes.resetData();
|
|
|
}else if (thisStepTempRes.getLastCompareSampleTime() >= queryBeginUTC){
|
|
|
- queryBeginUTC = thisStepTempRes.getLastCompareSampleTime() + 1000L;
|
|
|
+ if (FrequencyUnit.MIN.equals(planDetail.getFrequencyUnit())) {//以分钟为单位进行分析
|
|
|
+ queryBeginUTC = thisStepTempRes.getLastCompareSampleTime() + TimeTool.MS_ONE_SEC;
|
|
|
+ }else {//以小时或其他单位进行分析
|
|
|
+ queryBeginUTC = thisStepTempRes.getLastCompareSampleTime() + TimeTool.MS_ONE_HOUR;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (queryBeginUTC > queryEndUTC){
|
|
|
+ step = "Time is invalid,do analysis next time";
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
}
|
|
|
+ thisStepTempRes.setDoForTodayBefore(doForTodayBefore);
|
|
|
thisStepTempRes.setQueryBeginUTC(queryBeginUTC);
|
|
|
thisStepTempRes.setQueryEndUTC(queryEndUTC);
|
|
|
thisStepTempRes.setConditionMinUTC(conditionMinUTC);
|
|
|
@@ -150,7 +185,7 @@ public class SiteDataHandler {
|
|
|
thisStepTempRes.setDayTriggerTimes(0);
|
|
|
if (planDetail.getDayTriggerUpperTimes() > 0
|
|
|
&& thisStepTempRes.getDayTriggerTimes() >= planDetail.getDayTriggerUpperTimes()){//触发事件达到最大个数
|
|
|
- step = "Event Arrive Max Limit,Stop Analysis For Today";
|
|
|
+ step = "Event arrive at max limit,stop analysis for today";
|
|
|
code = ResponseCode.RESULT_BAD;
|
|
|
break;
|
|
|
}
|
|
|
@@ -163,7 +198,7 @@ public class SiteDataHandler {
|
|
|
if (planDetail.getItemKey().endsWith("miss")){//数据缺失
|
|
|
|
|
|
}else if (planDetail.getItemKey().endsWith("swo")){//小时水量
|
|
|
-
|
|
|
+ return analysisDataForWO(planDetail, rules, thisStepTempRes);
|
|
|
}else {
|
|
|
if ("set".equals(planDetail.getDoPickWay())){//时段曲线
|
|
|
return analysisDataBySet(planDetail, rules, thisStepTempRes);
|
|
|
@@ -173,10 +208,50 @@ public class SiteDataHandler {
|
|
|
return code;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 原始值匹配规则条件
|
|
|
+ * @param originValue
|
|
|
+ * @param condition
|
|
|
+ * @return -1: 未知错误;0 -- 未匹配;1 -- 已匹配
|
|
|
+ */
|
|
|
+ private int matchedToRuleItem(String originValue, OrdWarnRuleCondition condition){
|
|
|
+ if (StringUtils.isEmpty(originValue))
|
|
|
+ return 0;
|
|
|
+ int matched = -1;
|
|
|
+ try {
|
|
|
+ int nRes = CommTool.compareFloat(originValue, condition.getThreshold());
|
|
|
+ if (nRes == 0){
|
|
|
+ if ("!=".equals(condition.getMethod())){
|
|
|
+ matched = 0;
|
|
|
+ }else if (condition.getMethod().contains("=")){
|
|
|
+ matched = 1;
|
|
|
+ }else
|
|
|
+ matched = 0;
|
|
|
+ }else if (nRes > 0){
|
|
|
+ if ("!=".equals(condition.getMethod())){
|
|
|
+ matched = 1;
|
|
|
+ }else if (condition.getMethod().contains(">")){
|
|
|
+ matched = 1;
|
|
|
+ }else
|
|
|
+ matched = 0;
|
|
|
+ }else {
|
|
|
+ if ("!=".equals(condition.getMethod())){
|
|
|
+ matched = 1;
|
|
|
+ }else if (condition.getMethod().contains("<")){
|
|
|
+ matched = 1;
|
|
|
+ }else
|
|
|
+ matched = 0;
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ matched = -1;
|
|
|
+ }
|
|
|
+ return matched;
|
|
|
+ }
|
|
|
+
|
|
|
//处理时段样本数据
|
|
|
private ResponseCode analysisDataBySet(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
|
|
|
ResponseCode code = ResponseCode.RESULT_NORMAL;
|
|
|
- String step = "Start To Deep Analysis";
|
|
|
+ String step = "Start to deep analysis";
|
|
|
long curTime = TimeTool.getCurMsUTC();
|
|
|
final String siteId = rules.get(0).getObjId();
|
|
|
SiteSampleDataResult siteSampleData = null;
|
|
|
@@ -195,32 +270,40 @@ public class SiteDataHandler {
|
|
|
}catch (Exception e){}
|
|
|
|
|
|
if (siteSampleData == null){
|
|
|
- step = String.format("Get Site Sample Data Failed");
|
|
|
+ step = String.format("Get site sample data failed");
|
|
|
code = ResponseCode.RESULT_BAD;
|
|
|
break;
|
|
|
}
|
|
|
if (CommTool.listSize(siteSampleData.getData()) <= 0
|
|
|
|| CommTool.listSize(siteSampleData.getData().get(0).getRecords()) <= 0){
|
|
|
- step = String.format("Get Site Sample Data Empty");
|
|
|
+ step = String.format("Get site sample data empty");
|
|
|
code = ResponseCode.RESULT_BAD;
|
|
|
break;
|
|
|
}
|
|
|
+ //要求getRecords()中的数据为按time升序排列
|
|
|
+ Collections.sort(siteSampleData.getData().get(0).getRecords(), new Comparator<SiteSampleGroupItem>() {
|
|
|
+ @Override
|
|
|
+ public int compare(SiteSampleGroupItem o1, SiteSampleGroupItem o2) {
|
|
|
+ return Long.compare(o1.getTime(),o2.getTime());//按时间升序排列
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
for (SiteSampleGroupItem sampleItem:siteSampleData.getData().get(0).getRecords()){
|
|
|
- if (sampleItem.getTime() <= 0L || CommTool.listSize(sampleItem.getFields()) <= 0)
|
|
|
+ long sampleRecordTm = sampleItem.getTime();
|
|
|
+ if (sampleRecordTm <= 0L || CommTool.listSize(sampleItem.getFields()) <= 0)
|
|
|
continue;
|
|
|
if (planDetail.getDayTriggerUpperTimes() > 0
|
|
|
&& thisTempStep.getDayTriggerTimes() >= planDetail.getDayTriggerUpperTimes()){
|
|
|
- step = String.format("Event Arrive Max Limit");
|
|
|
+ step = String.format("Event arrive at max limit");
|
|
|
code = ResponseCode.RESULT_BAD;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
boolean matched = false;
|
|
|
OrdWarnPlanRules findRule = null;
|
|
|
- int dataClock = (int)((sampleItem.getTime()/1000/60/60%24+8)%24);
|
|
|
+ int sampleRecordClock = (int)((sampleRecordTm/1000/60/60%24+8)%24);
|
|
|
for (OrdWarnPlanRules ruleItem:rules){
|
|
|
- if (dataClock <= ruleItem.getEnd() && dataClock >= ruleItem.getStart()){
|
|
|
+ if (sampleRecordClock <= ruleItem.getEnd() && sampleRecordClock >= ruleItem.getStart()){
|
|
|
findRule = ruleItem;
|
|
|
break;
|
|
|
}
|
|
|
@@ -229,50 +312,27 @@ public class SiteDataHandler {
|
|
|
continue;
|
|
|
for (OrdWarnRuleCondition condition:findRule.getConditions()){
|
|
|
String originValue = "";
|
|
|
+ String backTag = condition.getFormat().substring(condition.getFormat().lastIndexOf("@")+1);
|
|
|
for (KeyValue kv:sampleItem.getFields()){
|
|
|
- if (condition.getTag().equals(kv.getKey())){
|
|
|
+ if (backTag.equals(kv.getKey())){
|
|
|
originValue = kv.getValue();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- if (StringUtils.isEmpty(originValue))
|
|
|
- matched = matched || false;
|
|
|
- else {
|
|
|
- try {
|
|
|
- int nRes = CommTool.compareFloat(originValue, condition.getThreshold());
|
|
|
- if (nRes == 0){
|
|
|
- if ("!=".equals(condition.getMethod())){
|
|
|
- matched = (matched || false);
|
|
|
- }else if (condition.getMethod().contains("=")){
|
|
|
- matched = (matched || true);
|
|
|
- }else
|
|
|
- matched = (matched || false);
|
|
|
- }else if (nRes > 0){
|
|
|
- if ("!=".equals(condition.getMethod())){
|
|
|
- matched = (matched || true);
|
|
|
- }else if (condition.getMethod().contains(">")){
|
|
|
- matched = (matched || true);
|
|
|
- }else
|
|
|
- matched = (matched || false);
|
|
|
- }else {
|
|
|
- if ("!=".equals(condition.getMethod())){
|
|
|
- matched = (matched || true);
|
|
|
- }else if (condition.getMethod().contains("<")){
|
|
|
- matched = (matched || true);
|
|
|
- }else
|
|
|
- matched = (matched || false);
|
|
|
- }
|
|
|
- }catch (Exception e){
|
|
|
- step = String.format("Compare Value Exception Error");
|
|
|
- code = ResponseCode.RESULT_BAD;
|
|
|
- }
|
|
|
+ int pkRes = matchedToRuleItem(originValue, condition);
|
|
|
+ if (pkRes == -1){
|
|
|
+ step = String.format("Compare value exception error");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }else {
|
|
|
+ matched = matched || (pkRes==1?true:false);
|
|
|
}
|
|
|
}
|
|
|
- if (code == ResponseCode.RESULT_BAD){
|
|
|
+ if (code != ResponseCode.RESULT_NORMAL)
|
|
|
break;
|
|
|
- }
|
|
|
+
|
|
|
if (!matched){//本次没有匹配成功
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(0);
|
|
|
thisTempStep.setFirstMatchSampleTime(0L);
|
|
|
thisTempStep.setLastEventId("");
|
|
|
@@ -281,57 +341,59 @@ public class SiteDataHandler {
|
|
|
}//本次匹配成功进入下一步
|
|
|
|
|
|
if (thisTempStep.getLastCompareSampleResult() <= 0){//上一次没有匹配成功
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
- thisTempStep.setFirstMatchSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
continue;
|
|
|
}//上一次匹配成功了进入下一步
|
|
|
|
|
|
- long diffMatch = sampleItem.getTime()-thisTempStep.getLastCompareSampleTime();//两个最近匹配样本之间的采集时间差(单位:毫秒)
|
|
|
- if (diffMatch > planDetail.getThresholdPeriod()*TimeTool.MS_ONE_MIN){//两个最近匹配样本间缺失的数据太多、或跨了天、或跨了时段,可认为重新计数
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold()*TimeTool.MS_ONE_MIN;//触发预警事件的最小时长(单位:毫秒)
|
|
|
+ long diffMatch = sampleRecordTm-thisTempStep.getLastCompareSampleTime();//两个最近匹配样本之间的采集时间差(单位:毫秒)
|
|
|
+ if (diffMatch > triggerEventPeriodSwitch){//两个最近匹配样本间缺失的数据太多、或跨了天、或跨了时段,可认为重新计数
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
- thisTempStep.setFirstMatchSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastEventId("");
|
|
|
thisTempStep.setLastEventTime(0L);
|
|
|
continue;
|
|
|
}//两个最近匹配样本间隔很近,可认为是持续匹配,则进入下一步
|
|
|
|
|
|
if (thisTempStep.getLastCompareSampleTime() < thisTempStep.getConditionMinUTC()){//上一个匹配样本是非当前天的,可认为重新计数
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
- thisTempStep.setFirstMatchSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastEventId("");
|
|
|
thisTempStep.setLastEventTime(0L);
|
|
|
continue;
|
|
|
}//上一个匹配样本是当天的,则进入下一步
|
|
|
|
|
|
- long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:(sampleItem.getTime()-thisTempStep.getFirstMatchSampleTime());//样本匹配的持续时长(单位:毫秒)
|
|
|
+ long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:(sampleRecordTm-thisTempStep.getFirstMatchSampleTime());//样本匹配的持续时长(单位:毫秒)
|
|
|
if (StringUtils.isEmpty(thisTempStep.getLastEventId())){//之前无预警事件
|
|
|
- if (matchLen < planDetail.getThresholdPeriod()*TimeTool.MS_ONE_MIN){//还得持续等待,达不到触发事件的累计时长
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ if (matchLen < triggerEventPeriodSwitch){//还得持续等待,达不到触发事件的累计时长
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
if (thisTempStep.getFirstMatchSampleTime() <= 0)
|
|
|
- thisTempStep.setFirstMatchSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
}else {//触发一个新的事件
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
thisTempStep.setLastEventId("新事件ID");
|
|
|
thisTempStep.setLastEventTime(curTime);
|
|
|
thisTempStep.setLastEventAction(1);
|
|
|
thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ //[!!!]do not change the FirstMatchSampleTime[!!!]
|
|
|
}
|
|
|
}else {//之前有预警事件
|
|
|
if (thisTempStep.getLastEventAction() >= 2){//之前的预警事件已处理,则可认为进行重新计数
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
- thisTempStep.setFirstMatchSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastEventId("");
|
|
|
thisTempStep.setLastEventTime(0L);
|
|
|
}else {//之前的预警事件未处理,则更新预警事件的样本截止时刻
|
|
|
- thisTempStep.setLastCompareSampleTime(sampleItem.getTime());
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
thisTempStep.setLastCompareSampleResult(1);
|
|
|
- eventId2NewEndUTC.put(thisTempStep.getLastEventId(), sampleItem.getTime());
|
|
|
+ eventId2NewEndUTC.put(thisTempStep.getLastEventId(), sampleRecordTm);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -339,8 +401,187 @@ public class SiteDataHandler {
|
|
|
return code;
|
|
|
}
|
|
|
|
|
|
- //处理时段差值数据
|
|
|
- private void handleDataByDiff(){
|
|
|
+ //处理时段的用水量
|
|
|
+ private ResponseCode analysisDataForWO(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
|
|
|
+ ResponseCode code = ResponseCode.RESULT_NORMAL;
|
|
|
+ String step = "Start to deep analysis";
|
|
|
+ long curTime = TimeTool.getCurMsUTC();
|
|
|
+ final String siteId = rules.get(0).getObjId();
|
|
|
+ SiteStatsDataResult siteStatsData = null;
|
|
|
+ Map<String, Long> eventId2NewEndUTC = new HashMap<>();//需要更新预警事件的样本截止时间
|
|
|
+ List<Long> tagTime = new ArrayList<>();//每个整点时刻,用于查询站点的统计数据
|
|
|
+ long tmpStepToStep = thisTempStep.getQueryBeginUTC();
|
|
|
+ do {
|
|
|
+ tagTime.add(tmpStepToStep);
|
|
|
+ tmpStepToStep += TimeTool.MS_ONE_HOUR;
|
|
|
+ }while (tmpStepToStep < thisTempStep.getQueryEndUTC());
|
|
|
|
|
|
+ do {
|
|
|
+ if (siteStatsData == null){
|
|
|
+ step = String.format("Get site stats data failed");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (CommTool.listSize(siteStatsData.getData()) <= 0){
|
|
|
+ step = String.format("Get site stats data empty");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ //要求getReport()中的数据为按tag升序排列,注:tag为每个整点时刻的UTC时间
|
|
|
+ Collections.sort(siteStatsData.getData(), new Comparator<SiteStatsDataItem>() {
|
|
|
+ @Override
|
|
|
+ public int compare(SiteStatsDataItem o1, SiteStatsDataItem o2) {
|
|
|
+ return o1.getTag().compareTo(o2.getTag());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (SiteStatsDataItem sampleItem:siteStatsData.getData()){
|
|
|
+ long sampleRecordTm = CastUtil.castLong(sampleItem.getTag(), 0L);
|
|
|
+ if (sampleRecordTm <= 0L
|
|
|
+ || sampleItem.getCode() != 0
|
|
|
+ || CommTool.listSize(sampleItem.getReport()) <= 0)
|
|
|
+ continue;
|
|
|
+ if (planDetail.getDayTriggerUpperTimes() > 0
|
|
|
+ && thisTempStep.getDayTriggerTimes() >= planDetail.getDayTriggerUpperTimes()){
|
|
|
+ step = String.format("Event arrive at max limit");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean matched = false;
|
|
|
+ OrdWarnPlanRules findRule = null;
|
|
|
+ int sampleRecordClock = (int)((sampleRecordTm/1000/60/60%24+8)%24);
|
|
|
+ for (OrdWarnPlanRules ruleItem:rules){
|
|
|
+ if (sampleRecordClock <= ruleItem.getEnd() && sampleRecordClock >= ruleItem.getStart()){
|
|
|
+ findRule = ruleItem;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (findRule == null)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ for (OrdWarnRuleCondition condition:findRule.getConditions()){
|
|
|
+ String originValue = "";
|
|
|
+ String backTag = condition.getFormat().substring(condition.getFormat().lastIndexOf("@")+1);
|
|
|
+ for (KeyValue kv:sampleItem.getReport()){
|
|
|
+ if (backTag.equals(kv.getKey())){
|
|
|
+ originValue = kv.getValue();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int pkRes = matchedToRuleItem(originValue, condition);
|
|
|
+ if (pkRes == -1){
|
|
|
+ step = String.format("Compare value exception error");
|
|
|
+ code = ResponseCode.RESULT_BAD;
|
|
|
+ break;
|
|
|
+ }else {
|
|
|
+ matched = matched || (pkRes==1?true:false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (code != ResponseCode.RESULT_NORMAL)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (!matched){//本次没有匹配成功
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(0);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(0L);
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ continue;
|
|
|
+ }//本次匹配成功进入下一步
|
|
|
+
|
|
|
+ long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold();//触发预警事件的最小时长(单位:小时)
|
|
|
+ if (thisTempStep.getLastCompareSampleResult() <= 0){//上一次没有匹配成功
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }//上一次匹配成功了进入下一步
|
|
|
+
|
|
|
+ long diffMatch = (sampleRecordTm-thisTempStep.getLastCompareSampleTime())/TimeTool.MS_ONE_HOUR;//两个最近匹配样本之间的采集时间差(单位:小时)
|
|
|
+ if (diffMatch > triggerEventPeriodSwitch){//两个最近匹配样本间缺失的数据太多、或跨了天、或跨了时段,可认为重新计数
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ }else {
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }//两个最近匹配样本间隔很近,可认为是持续匹配,则进入下一步
|
|
|
+
|
|
|
+ if (thisTempStep.getLastCompareSampleTime() < thisTempStep.getConditionMinUTC()){//上一个匹配样本是非当前天的,可认为重新计数
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ }else {
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }//上一个匹配样本是当天的,则进入下一步
|
|
|
+
|
|
|
+ long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_HOUR);//样本匹配的持续时长(单位:小时)
|
|
|
+ if (StringUtils.isEmpty(thisTempStep.getLastEventId())){//之前无预警事件
|
|
|
+ if (matchLen < triggerEventPeriodSwitch){//还得持续等待,达不到触发事件的累计时长
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ if (thisTempStep.getFirstMatchSampleTime() <= 0){
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//补充触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {//触发一个新的事件
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ //[!!!]do not change the FirstMatchSampleTime[!!!]
|
|
|
+ }
|
|
|
+ }else {//之前有预警事件
|
|
|
+ if (thisTempStep.getLastEventAction() >= 2){//之前的预警事件已处理,则可认为进行重新计数
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
|
|
|
+ if (triggerEventPeriodSwitch <= 1){//触发事件
|
|
|
+ thisTempStep.setLastEventId("新事件ID");
|
|
|
+ thisTempStep.setLastEventTime(curTime);
|
|
|
+ thisTempStep.setLastEventAction(1);
|
|
|
+ thisTempStep.setDayTriggerTimes(thisTempStep.getDayTriggerTimes()+1);
|
|
|
+ }else {
|
|
|
+ thisTempStep.setLastEventId("");
|
|
|
+ thisTempStep.setLastEventTime(0L);
|
|
|
+ }
|
|
|
+ }else {//之前的预警事件未处理,则更新预警事件的样本截止时刻
|
|
|
+ thisTempStep.setLastCompareSampleTime(sampleRecordTm);
|
|
|
+ thisTempStep.setLastCompareSampleResult(1);
|
|
|
+ eventId2NewEndUTC.put(thisTempStep.getLastEventId(), sampleRecordTm);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }while (false);
|
|
|
+ return code;
|
|
|
}
|
|
|
}
|