浏览代码

增加报警判断模块

chenwen 1 年之前
父节点
当前提交
58bb1d21cf

+ 96 - 2
src/main/java/com/hb/proj/gather/business/DataAlarmDetector.java

@@ -1,9 +1,18 @@
 package com.hb.proj.gather.business;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.StringUtils;
+
 import com.hb.proj.gather.model.AlarmDefineVO;
+import com.hb.proj.gather.model.AlarmExpress;
+import com.hb.proj.gather.model.AlarmLogVO;
+import com.hb.proj.gather.model.SingleInsertPO;
+import com.hb.proj.utils.JacksonUtils;
+
+import cn.hutool.core.date.DateUtil;
 
 /**
  * 数据报警检测
@@ -12,11 +21,96 @@ import com.hb.proj.gather.model.AlarmDefineVO;
  */
 public class DataAlarmDetector {
 
-	
-	public static void detect(List<AlarmDefineVO> alarms,Map<String,Float> singleData) {
+	/**
+	 * mappingDatas  的key为  param_id
+	 */
+	public static List<AlarmLogVO> detect(String wellId,Map<String,SingleInsertPO> mappingDatas) {
+		List<AlarmDefineVO>  alarms=DataTransConfig.getAlarmDefines(wellId);
+		if(alarms==null||alarms.size()==0) {
+			return null;
+		}
 		
+		List<AlarmLogVO> almlogs=new ArrayList<>(); 
+		SingleInsertPO singlePO=null;  //需要报警的数据对象
+		List<AlarmExpress>   exps=null;
 		for(AlarmDefineVO  alarm : alarms) {
+			if(StringUtils.isBlank(alarm.getAlarmExpress())){
+				continue;
+			}
+			exps=JacksonUtils.getList2(alarm.getAlarmExpress(), AlarmExpress.class);
+			singlePO=detect(exps,mappingDatas);
+			if(singlePO==null) {
+				continue;
+			}
+			almlogs.add(buildAlarmLog(alarm,singlePO));
+		}
+		return almlogs;
+	}
+	
+	
+	/**
+	 * 需要报警时会返回对应数据对象(单值报警数据对象本身,组合报警最后一个条件对应的数据对象)
+	 * @param exps
+	 * @param mappingDatas
+	 * @return
+	 */
+	public static SingleInsertPO detect(List<AlarmExpress>   exps,Map<String,SingleInsertPO> mappingDatas) {
+		SingleInsertPO  singlePO=null;
+		for(AlarmExpress exp : exps) {
+			if(!mappingDatas.containsKey(exp.getParam())) {
+				return null;
+			}
+			singlePO=mappingDatas.get(exp.getParam());
+					
+			if(!needAlarm(exp,singlePO)) {  //一个条件不满足则整个不满足,不需要后续判断
+				return null;
+			}
+		}
+		
+		return singlePO;
+	}
+	
+	
+	private static  boolean needAlarm(AlarmExpress exp,SingleInsertPO  singlePO) {
+		try {
+			if(">".equals(exp.getSymbol())) {
+				return singlePO.getDisVal().doubleValue()>exp.getVal().doubleValue();
+			}
+			else if(">=".equals(exp.getSymbol())) {
+				return singlePO.getDisVal().doubleValue()>=exp.getVal().doubleValue();
+			}
+			else if("=".equals(exp.getSymbol())) {
+				return singlePO.getDisVal().doubleValue()==exp.getVal().doubleValue();
+			}
+			else if("<".equals(exp.getSymbol())) {
+				return singlePO.getDisVal().doubleValue()<exp.getVal().doubleValue();
+			}
+			else if("<=".equals(exp.getSymbol())) {
+				return singlePO.getDisVal().doubleValue()<=exp.getVal().doubleValue();
+			}
+			else if("!=".equals(exp.getSymbol())) {
+				return singlePO.getDisVal().doubleValue()!=exp.getVal().doubleValue();
+			}
 			
+			return false;
+		}
+		catch(Exception e) {
+			e.printStackTrace();
+			return false;
 		}
+		
+	}
+	
+	/**
+	 * 构建报警日志内容
+	 */
+	private static AlarmLogVO buildAlarmLog(AlarmDefineVO  alarm,SingleInsertPO singlePO) {
+		AlarmLogVO alarmlg=new AlarmLogVO(alarm.getAlarmDesc(),alarm.getAlarmSource(),DateUtil.format(singlePO.getGatherTime(), "yyyyMMddHHmmss"));
+		alarmlg.setParamName(alarm.getParamName());
+		alarmlg.setAlarmMode(alarm.getAlarmMode());
+		alarmlg.setParamCode(alarm.getParamCode());
+		//redisAlarms.put(alarm.getParamCode(),JacksonUtils.getJSON(alarmlg));
+		return alarmlg;
 	}
+	
 }

+ 9 - 3
src/main/java/com/hb/proj/gather/business/DataTransConfig.java

@@ -1,5 +1,6 @@
 package com.hb.proj.gather.business;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -62,11 +63,16 @@ public class DataTransConfig {
 		return configerParam.get(serialParamCode);
 	}
 	
-	public static List<AlarmDefineVO> getAlarmDefines(String serialNum) {
+	public static List<AlarmDefineVO> getAlarmDefines(String wellId) {
 		if(configerAlarm==null) {
 			configerAlarm=configService.loadAlarmDefines();
 		}
-		
-		return null;
+		List<AlarmDefineVO>  rtnAlarms=new ArrayList<>();
+		for(String almkey : configerAlarm.keySet()) {
+			if(almkey.startsWith(wellId)) {
+				rtnAlarms.add(configerAlarm.get(almkey));
+			}
+		}
+		return rtnAlarms;
 	}
 }

+ 33 - 11
src/main/java/com/hb/proj/gather/business/DataTransRepSingleTask.java

@@ -1,6 +1,5 @@
 package com.hb.proj.gather.business;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -8,11 +7,13 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.hb.proj.gather.model.AlarmLogVO;
 import com.hb.proj.gather.model.SingleCombPO;
 import com.hb.proj.gather.model.SingleInsertPO;
 import com.hb.proj.gather.model.WellParamVO;
 import com.hb.proj.gather.rep.GatherDataRepService;
 import com.hb.proj.gather.rep.RedisRepComponent;
+import com.hb.proj.utils.JacksonUtils;
 import com.hb.xframework.util.ApplicationContextUtils;
 
 /**
@@ -37,29 +38,45 @@ public class DataTransRepSingleTask implements Runnable{
 			logger.info("开始单值数据转换处理{}",singleCombPO.getDevSerial());
 			Map<String,Float>  gatherDatas=singleCombPO.getGatherDatas();
 			WellParamVO paramConfig=null;
-			List<SingleInsertPO> insPOs=new ArrayList<>(gatherDatas.size());
+			//List<SingleInsertPO> insPOs=new ArrayList<>(gatherDatas.size());
 			SingleInsertPO insPOItm=null;
+			
+			Map<String,Float> redisDatas=new HashMap<>(gatherDatas.size()); //进入redis的数据
+			Map<String,SingleInsertPO> mappingDatas=new HashMap<>(gatherDatas.size());  //入库及报警判断用数据
+			
 			for(String pcode : gatherDatas.keySet()) {
 				paramConfig=DataTransConfig.get(singleCombPO.getDevSerial()+"_"+pcode);
 				if(paramConfig==null) {
-					logger.info("未找到参数配置{}_{}",singleCombPO.getDevSerial(),pcode);
+					logger.warn("未找到参数配置{}_{}",singleCombPO.getDevSerial(),pcode);
 					continue;
 				}
 				insPOItm=new SingleInsertPO(pcode,paramConfig.getParamId(),gatherDatas.get(pcode),singleCombPO.getGatherTime());
 				DataTransUtils.transSingle(insPOItm, paramConfig);
-				insPOs.add(insPOItm);
+				
+				redisDatas.put(insPOItm.getParamCode(), insPOItm.getDataVal());
+				mappingDatas.put(insPOItm.getWellParam(), insPOItm);
+				
+				//insPOs.add(insPOItm);
+			
+			}
 			
+			if(paramConfig==null) {
+				logger.warn("设备{}未关联任何井,取消后续操",singleCombPO.getDevSerial());
+				return;
 			}
 			
-			logger.info("单值数据转换完:{}",insPOs.size());
+			List<AlarmLogVO>  almlogs=DataAlarmDetector.detect(paramConfig.getWellId(), mappingDatas);
 			
 			RedisRepComponent repRedis=ApplicationContextUtils.getBean("redisRepComponent", RedisRepComponent.class);
+			repRedis.put(paramConfig.getWellId(), redisDatas);
 			
-			repRedis.put(paramConfig.getWellId(), buildRedisDatas(insPOs));
+			repRedis.put(paramConfig.getWellId(), buildRedisAlarm(almlogs));
 			
 			GatherDataRepService repService=ApplicationContextUtils.getBean("gatherDataRepService", GatherDataRepService.class);
+			repService.save(mappingDatas.values());  //入库
+			repService.saveAlarm(almlogs);
 			
-			repService.save(insPOs);  //入库
+			logger.info("单值数据转换、报警、入库完成:{}",gatherDatas.size());
 		}
 		catch(Exception e) {
 			e.printStackTrace();
@@ -69,11 +86,16 @@ public class DataTransRepSingleTask implements Runnable{
 	}
 	
 	
-	private Map<String,Float> buildRedisDatas(List<SingleInsertPO> insPOs) {
-		Map<String,Float> rtn=new HashMap<>(insPOs.size());
-		for(SingleInsertPO po : insPOs) {
-			rtn.put(po.getParamCode(), po.getDataVal());
+	private Map<String,String> buildRedisAlarm(List<AlarmLogVO>  almlogs){
+		Map<String,String>  rtn=new HashMap<String,String>();
+		if(almlogs==null||almlogs.size()==0) {
+			return rtn;
 		}
+		
+		for(AlarmLogVO  almlog  : almlogs) {
+			rtn.put(almlog.getParamCode(), JacksonUtils.getJSON(almlog));
+		}
+		
 		return rtn;
 	}
 

+ 17 - 1
src/main/java/com/hb/proj/gather/business/DataTransUtils.java

@@ -1,8 +1,11 @@
 package com.hb.proj.gather.business;
 
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.StringUtils;
+
 import com.hb.proj.gather.model.DiagramPO;
 import com.hb.proj.gather.model.SingleInsertPO;
 import com.hb.proj.gather.model.WellParamVO;
@@ -14,12 +17,25 @@ import com.hb.proj.gather.model.WellParamVO;
  */
 public class DataTransUtils {
 	
+	public static DecimalFormat df=new DecimalFormat("0.000");
+	
 	public static void transSingle(SingleInsertPO  singleInsPO,WellParamVO  wp) {
 		Float data=transSingle(singleInsPO.getDataVal(),wp.getCalibrateA(),wp.getCalibrateB(),wp.getCalibrateC(),wp.getGatInsScale());
 		singleInsPO.setDataVal(data);
+		singleInsPO.setDisVal(trans2Disp(data,wp.getDisInsScale(),wp.getDisplayFormat()));
 	}
 	
-	
+	//入库值转显示值并格式化
+	public static Float trans2Disp(Float data,Double dispUnitScale,String fmt) {
+		if(data==null) {
+			return null;
+		}
+		double scale=dispUnitScale!=null?dispUnitScale:1;
+		if(StringUtils.isNotBlank(fmt)) {
+			df.applyPattern(fmt);
+		}
+		return Float.parseFloat(df.format(data*scale));
+	}
 	
 	public static Float transSingle(Float data,Double calA,Double calB,Double calC,Double unitScale) {
 		if(calA==null) {

+ 10 - 0
src/main/java/com/hb/proj/gather/model/AlarmDefineVO.java

@@ -4,6 +4,8 @@ public class AlarmDefineVO extends AlarmDefinePO {
 
 	private String paramCode;
 	
+	private String paramName;
+	
 	private String wellId;
 
 	public String getParamCode() {
@@ -22,5 +24,13 @@ public class AlarmDefineVO extends AlarmDefinePO {
 		this.wellId = wellId;
 	}
 
+	public String getParamName() {
+		return paramName;
+	}
+
+	public void setParamName(String paramName) {
+		this.paramName = paramName;
+	}
+
 	
 }

+ 49 - 0
src/main/java/com/hb/proj/gather/model/AlarmExpress.java

@@ -0,0 +1,49 @@
+package com.hb.proj.gather.model;
+
+/**
+ * 报警表达式
+ * @author cwen
+ *
+ */
+public class AlarmExpress {
+
+	private String label;
+	
+	private String param;
+	
+	private String symbol;
+	
+	private Double  val;
+
+	public String getLabel() {
+		return label;
+	}
+
+	public void setLabel(String label) {
+		this.label = label;
+	}
+
+	public String getParam() {
+		return param;
+	}
+
+	public void setParam(String param) {
+		this.param = param;
+	}
+
+	public String getSymbol() {
+		return symbol;
+	}
+
+	public void setSymbol(String symbol) {
+		this.symbol = symbol;
+	}
+
+	public Double getVal() {
+		return val;
+	}
+
+	public void setVal(Double val) {
+		this.val = val;
+	}
+}

+ 89 - 0
src/main/java/com/hb/proj/gather/model/AlarmLogVO.java

@@ -0,0 +1,89 @@
+package com.hb.proj.gather.model;
+
+import java.util.Date;
+
+public class AlarmLogVO {
+
+	private String alarmDesc;
+	
+	private String alarmSource;
+	
+	private Date  alarmTime;
+	
+	private String alarmHolder;
+	
+	private String paramName;
+	
+	private String paramCode;
+	
+	private String alarmMode;
+	
+	public AlarmLogVO() {
+		this.alarmTime=new Date();
+	}
+	
+	public AlarmLogVO(String alarmDesc,String alarmSource,String alarmHolder) {
+		this.alarmDesc=alarmDesc;
+		this.alarmSource=alarmSource;
+		this.alarmHolder=alarmHolder;
+		this.alarmTime=new Date();
+	}
+
+	public String getAlarmDesc() {
+		return alarmDesc;
+	}
+
+	public void setAlarmDesc(String alarmDesc) {
+		this.alarmDesc = alarmDesc;
+	}
+
+	public String getAlarmSource() {
+		return alarmSource;
+	}
+
+	public void setAlarmSource(String alarmSource) {
+		this.alarmSource = alarmSource;
+	}
+
+	public Date getAlarmTime() {
+		return alarmTime;
+	}
+
+	public void setAlarmTime(Date alarmTime) {
+		this.alarmTime = alarmTime;
+	}
+
+	public String getAlarmHolder() {
+		return alarmHolder;
+	}
+
+	public void setAlarmHolder(String alarmHolder) {
+		this.alarmHolder = alarmHolder;
+	}
+
+	public String getParamName() {
+		return paramName;
+	}
+
+	public void setParamName(String paramName) {
+		this.paramName = paramName;
+	}
+
+	public String getAlarmMode() {
+		return alarmMode;
+	}
+
+	public void setAlarmMode(String alarmMode) {
+		this.alarmMode = alarmMode;
+	}
+
+	public String getParamCode() {
+		return paramCode;
+	}
+
+	public void setParamCode(String paramCode) {
+		this.paramCode = paramCode;
+	}
+	
+	
+}

+ 11 - 1
src/main/java/com/hb/proj/gather/model/SingleInsertPO.java

@@ -13,7 +13,9 @@ public class SingleInsertPO {
 
 	private String wellParam;
 	
-	private Float  dataVal;
+	private Float  dataVal;   //标定后,转为入库单位的值
+	
+	private Float  disVal;  //可以显示的值(转显示单位+显示格式化)
 	
 	private Date gatherTime;
 	
@@ -60,4 +62,12 @@ public class SingleInsertPO {
 	public void setParamCode(String paramCode) {
 		this.paramCode = paramCode;
 	}
+
+	public Float getDisVal() {
+		return disVal;
+	}
+
+	public void setDisVal(Float disVal) {
+		this.disVal = disVal;
+	}
 }

+ 38 - 4
src/main/java/com/hb/proj/gather/rep/GatherDataRepService.java

@@ -1,14 +1,17 @@
 package com.hb.proj.gather.rep;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import com.hb.proj.gather.model.AlarmLogVO;
 import com.hb.proj.gather.model.DiagramPO;
 import com.hb.proj.gather.model.SingleInsertPO;
 import com.hb.xframework.dao.core.SpringJdbcDAO;
+import com.hb.xframework.dao.util.UUIDHexGenerator;
 
 /**
  * 采集程序数据持久化
@@ -21,11 +24,25 @@ public class GatherDataRepService {
 	@Autowired
 	private SpringJdbcDAO  dao;
 	
+	/**
+	 * 报警日志记录入库
+	 * @param almlogs
+	 */
+	public void saveAlarm(List<AlarmLogVO>  almlogs) {
+		if(almlogs==null||almlogs.size()==0) {
+			return;
+		}
+		String sql="""
+				insert into tzl_alarm_log(record_id,alarm_time,alarm_desc,alarm_holder,alarm_source) values(?,?,?,?,?)
+				""";
+		dao.getJdbcTemplate().batchUpdate(sql, buildAlarmBatchParams(almlogs));
+	}
+	
 	/**
 	 * 单值采集数据入库
 	 * @param singleInPOs
 	 */
-	public void save(List<SingleInsertPO>  singleInPOs) {
+	public void save(Collection<SingleInsertPO>  singleInPOs) {
 		if(singleInPOs==null||singleInPOs.size()==0) {
 			return;
 		}
@@ -44,8 +61,7 @@ public class GatherDataRepService {
 				insert into tzl_gather_data_multi(well_param,gather_time,data_val1,data_val2) values(?,?,?,?)
 				""";
 		
-		String disp=list2Str(diagramPO.getDisps());
-		dao.exeUpdate(sql, diagramPO.getWellParam(),diagramPO.getGatherTime(),disp,list2Str(diagramPO.getOths()));
+		dao.exeUpdate(sql, diagramPO.getWellParam(),diagramPO.getGatherTime(),list2Str(diagramPO.getDisps()),list2Str(diagramPO.getOths()));
 	}
 	
 	private String list2Str(List<Float>  datas) {
@@ -61,7 +77,7 @@ public class GatherDataRepService {
 	 * @param singleInPOs
 	 * @return
 	 */
-	private List<Object[]>  buildBatchParams(List<SingleInsertPO>  singleInPOs){
+	private List<Object[]>  buildBatchParams(Collection<SingleInsertPO>  singleInPOs){
 		
 		List<Object[]>  params=new ArrayList<>(singleInPOs.size());
 		
@@ -72,4 +88,22 @@ public class GatherDataRepService {
 		
 		return params;
 	}
+	
+	/**
+	 * 构建报警日志批量入库参数
+	 * @return
+	 */
+	private List<Object[]> buildAlarmBatchParams(List<AlarmLogVO>  almlogs){
+
+		List<Object[]>  params=new ArrayList<>(almlogs.size());
+		
+		UUIDHexGenerator  uuid=UUIDHexGenerator.getInstance();
+		
+		for(AlarmLogVO vo : almlogs) {
+			
+			params.add(new Object[] {uuid.generate(),vo.getAlarmTime(),vo.getAlarmDesc(),vo.getAlarmHolder(),vo.getAlarmSource()});
+		}
+		
+		return params;
+	}
 }

+ 2 - 2
src/main/java/com/hb/proj/gather/rep/RedisRepComponent.java

@@ -22,8 +22,8 @@ public class RedisRepComponent {
 	 * @param wellId
 	 * @param datas
 	 */
-	public void put(String wellId,Map<String,Float> datas) {
-		HashOperations<String, String, Float>  ops=redisTemplate.opsForHash();
+	public void put(String wellId,Map<String,? extends Object> datas) {
+		HashOperations<String, String, Object>  ops=redisTemplate.opsForHash();
 		ops.putAll(wellId, datas);
 	}
 }

+ 3 - 2
src/main/java/com/hb/proj/gather/rep/WellConfigService.java

@@ -33,7 +33,7 @@ public class WellConfigService {
 				select 
 				(select device_code from tzl_gather_device d where d.well_id=wp.well_id and d.del_if=false limit 1) device_code,
 				param_id,well_id,param_code,gat_ins_scale,gat_ins_scale2,calibrate_a,calibrate_b,calibrate_c, 
-				calibrate_a2,calibrate_b2,calibrate_c2
+				calibrate_a2,calibrate_b2,calibrate_c2,display_format,dis_ins_scale
 				from tzl_well_param wp
 				where del_if=false
 				""";
@@ -67,7 +67,8 @@ public class WellConfigService {
 		String sql="""
 				select 
 				am.alarm_source,am.alarm_desc,am.alarm_express,am.alarm_mode,ifnull(wp.param_code,'comb_alarm') param_code,
-				ifnull(wp.well_id,am.alarm_source) well_id
+				ifnull(wp.well_id,am.alarm_source) well_id,
+				ifnull(wp.param_name,'') param_name
 				from tzl_alarm am
 				left join tzl_well_param wp on am.alarm_source=wp.param_id and wp.del_if=false
 				where am.del_if=false and am.using_if=true

+ 14 - 0
src/main/java/com/hb/proj/utils/JacksonUtils.java

@@ -1,10 +1,12 @@
 package com.hb.proj.utils;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
 
 public class JacksonUtils {
 
@@ -31,6 +33,18 @@ public class JacksonUtils {
     	
     }
     
+    public static <T> List<T>  getList2(String json,Class<T> cls){
+    	try {
+    		CollectionType listType =
+    				mapper.getTypeFactory().constructCollectionType(ArrayList.class, cls);
+    		return mapper.readValue(json,listType);
+    	}
+    	catch(Exception e) {
+    		throw new RuntimeException("jackson参数转换出错");
+    	}
+    	
+    }
+    
     public static List<Map<String,Object>>  getMaps(String json){
     	try {
     		return mapper.readValue(json, new TypeReference<List<Map<String,Object>>>() {});