package com.gyee.healthmodel.service; import com.gyee.common.contant.ContantXk; import com.gyee.common.model.PointData; import com.gyee.healthmodel.init.CacheContext; import com.gyee.healthmodel.model.auto.*; import com.gyee.healthmodel.model.vo.AlarmCustomType; import com.gyee.healthmodel.model.vo.AlarmStatVo; import com.gyee.healthmodel.model.vo.StatusDetailValue; import com.gyee.healthmodel.service.auto.*; import com.gyee.healthmodel.util.*; import com.gyee.healthmodel.vo.healthsystem.HealthExpression; import com.gyee.healthmodel.vo.healthsystem.ResultVo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.Map.Entry; @Service public class HealthJudgeService { private static Logger logger = LoggerFactory.getLogger(HealthJudgeService.class); @Resource private IProEconHealthSystemService proEconHealthSystemService; @Resource private IProEconHealthSystemSubService proEconHealthSystemSubService; @Resource private IProEconStateJudgmentDayService proEconStateJudgmentDayService; @Resource private IProEconStateJudgmentRealService proEconStateJudgmentRealService; @Resource private HealthInitialService healthInitialService; @Resource private HealthFactoryService healthFactoryService; private final double judgescore = 80; @Resource private IProBasicEquipmentPointService proBasicEquipmentPointsService; IRealTimeDataBaseUtil realApiUtil = RealTimeDataBaseFactory.createRealTimeDataBase(); @Resource private AlarmHistoryService alarmHistoryService; public void changeHealthModelValue() throws Exception { healthInitialService.healthChangeInitial();// 初始化函数算法模型数据 List codels = new ArrayList(); codels.add(ContantXk.JKZT002); codels.add(ContantXk.JKZT003); codels.add(ContantXk.JKZT004); codels.add(ContantXk.JKZT005); List pols = new ArrayList<>(); for (ProBasicEquipment wt : CacheContext.wtls) { if (wt.getWindpowerstationId().contains("FDC")) { ProEconStateJudgmentReal po = new ProEconStateJudgmentReal(); po.setId(com.gyee.common.model.StringUtils.getUUID()); po.setWpId(wt.getWindpowerstationId()); po.setWtId(wt.getId()); StringBuilder statejudgment = new StringBuilder(); double fjzt = 0; double score = 100; ProBasicEquipmentPoint ai = proBasicEquipmentPointsService.getEquipmentPoint(wt.getId(), ContantXk.MXZT); PointData point = realApiUtil.getRealData(ai); if (StringUtils.notEmp(point)) { if (point.getPointValueInDouble() == StatusDetailValue.GZ.getCode()) { fjzt = StatusDetailValue.GZ.getCode(); } if (point.getPointValueInDouble() == StatusDetailValue.JX.getCode()) { fjzt = StatusDetailValue.JX.getCode(); } } // String[] points = new String[codels.size()]; List points = new ArrayList<>(); for (int i = 0; i < codels.size(); i++) { if (CacheContext.wtpAimap.containsKey(wt.getId())) { Map wtmap = CacheContext.wtpAimap.get(wt.getId()); // 判断是否包含该统一编码 if (wtmap.containsKey(codels.get(i))) { ProBasicEquipmentPoint temp = wtmap.get(codels.get(i)); points.add(temp.getNemCode()); } } } ProBasicEquipmentPoint fjjkzf = proBasicEquipmentPointsService.getEquipmentPoint(wt.getId(), ContantXk.JKZT100); List ssvalues = realApiUtil.getRealData(points); PointData fjjkzfpoint = new PointData(); fjjkzfpoint.setEdnaId(fjjkzf.getNemCode()); fjjkzfpoint.setPointTime(new BigDecimal(new Date().getTime()).divide(new BigDecimal(1000), 0, RoundingMode.HALF_EVEN).longValue()); double clxzt = 0.0; double fdjzt = 0.0; double bjzt = 0.0; double zkzt = 0.0; if (ssvalues.size() == 4) { clxzt = ssvalues.get(0).getPointValueInDouble(); fdjzt = ssvalues.get(1).getPointValueInDouble(); bjzt = ssvalues.get(2).getPointValueInDouble(); zkzt = ssvalues.get(3).getPointValueInDouble(); } // 出现故障状态,直接降到10分 差 if (fjzt ==StatusDetailValue.GZ.getCode() || fjzt ==StatusDetailValue.JX.getCode()) { score = 9.0; statejudgment.append("1-"); } else { statejudgment.append("0-"); } if(clxzt==4 || fdjzt==4 || bjzt==4 || zkzt==4) { score=setScoreValue(score); statejudgment.append("1-"); }else if(clxzt==3 || fdjzt==3 || bjzt==3 || zkzt==3) { score=setScoreValue(score); statejudgment.append("1-"); }else { statejudgment.append("0-"); } Map xnmap=HealthInitialService.djpgchagemap; if (xnmap.containsKey(wt.getId())) { double djpgscore = xnmap.get(wt.getId()); if (djpgscore < 60) { score=setScoreValue(score); statejudgment.append("1-"); }else { statejudgment.append("0-"); } } else { statejudgment.append("0-"); } Map xfpdmap=HealthInitialService.xfpdchagemap; if(xfpdmap.containsKey(wt.getId())) { double xfqrqc =xfpdmap.get(wt.getId()); //小风曲线偏差 if (xfqrqc > 5) { score=setScoreValue(score); statejudgment.append("1-"); } else { statejudgment.append("0-"); } }else { statejudgment.append("0-"); } Map clpdmap=HealthInitialService.clpdchagemap; if(clpdmap.containsKey(wt.getId())) { double zcclqc =clpdmap.get(wt.getId()); //正常出力曲线偏差 if (zcclqc > 5) { score=setScoreValue(score); statejudgment.append("1-"); } else { statejudgment.append("0-"); } }else { statejudgment.append("0-"); } Map dfpdmap=HealthInitialService.dfpdchagemap; if(dfpdmap.containsKey(wt.getId())) { double dfqrqc =dfpdmap.get(wt.getId()); //大风曲线偏差 if (dfqrqc > 5) { score=setScoreValue(score); statejudgment.append("1-"); } else { statejudgment.append("0-"); } }else { statejudgment.append("0-"); } po.setStateJudgment(String.valueOf(statejudgment.substring(0, statejudgment.length() - 1))); pols.add(po); fjjkzfpoint.setPointValueInDouble(score); realApiUtil.updatePoint(fjjkzfpoint); } } proEconStateJudgmentRealService.deleteProEconStateJudgmentReal(); if (!pols.isEmpty()) { proEconStateJudgmentRealService.saveOrUpdateBatch(pols); // for (ProEconStateJudgmentReal po : pols) { // proEconStateJudgmentRealService.insertStatejudgmentrecord(po); // } } System.out.println("结束健康模型分数计算!"); } private double setScoreValue(double score) { if (score >= 90) { score = score - 12.0; } else if (score < 90 && score >= 60) { score = score -9; } else if (score < 60 && score >= 30) { score = score -6; } else if (score < 30 && score >= 10) { score = score -3; } else { score = 9.0; } return score; } public void healthJudge() throws Exception { ScriptJava sj = new ScriptJava(); healthInitialService.healthInitial();// 初始化函数算法模型数据 Map maps = new HashMap<>(); Map> hsmap = new HashMap<>(); Map hcmap = new HashMap<>(); Map parmarsmap = new HashMap<>(); for (HcEnum e : HcEnum.values()) { hcmap.put(e.getName(), e); } List hsls = proEconHealthSystemService.queryHealthSystem(); Map> map = proEconHealthSystemSubService.queryHealthSystemSubMap(); if (!hsls.isEmpty()) { for (ProEconHealthSystem hs : hsls) { if (map.containsKey(hs.getId())) { List subls = map.get(hs.getId()); if (!subls.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append(hs.getWpId()).append("_").append(hs.getModelId()); if (!hsmap.containsKey(String.valueOf(sb))) { hsmap.put(String.valueOf(sb), subls); } } } } } proEconStateJudgmentDayService.deleteProEconStateJudgmentDay(); List polist = new ArrayList<>(); for (ProBasicEquipment wt : CacheContext.wtls) { if (wt.getWindpowerstationId().contains("FDC")) { StringBuilder sb = new StringBuilder(); sb.append(wt.getWindpowerstationId()).append("_").append(wt.getModelId()); if (hsmap.containsKey(String.valueOf(sb))) { List subls = hsmap.get(String.valueOf(sb)); if (!subls.isEmpty()) { List descls = new ArrayList<>(); List formulals = new ArrayList<>(); double score = 100; for (ProEconHealthSystemSub sub : subls) { if (StringUtils.notEmp(sub.getFormula())) { HealthExpression healthExpression = HealthAnalyzer.getHealthExpression(sub.getFormula()); ArrayList ucs = healthExpression.getAllUniformCodes(); judgeParams(hcmap, parmarsmap, wt, ucs); } Object obj = sj.getCalValue(sub.getFormula(), parmarsmap); if (obj instanceof Boolean) { boolean value = Boolean.valueOf(String.valueOf(obj)); if (value) { descls.add(sub.getName()); formulals.add(sub.getFormula()); double tempscore = null != sub.getFormulaScore() ? sub.getFormulaScore() : 0.0; score = score - tempscore; } } } ProEconStateJudgmentDay po = new ProEconStateJudgmentDay(); po.setWpId(wt.getWindpowerstationId()); po.setWtId(wt.getId()); Calendar c = Calendar.getInstance(); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); po.setRecordDate(c.getTime()); StringBuilder sb2 = new StringBuilder(); if (!descls.isEmpty()) { for (String str : descls) { sb2.append(str).append(","); } String st = String.valueOf(sb2); po.setStateJudgment(st.substring(0, st.length() - 1)); } StringBuilder sb3 = new StringBuilder(); if (!formulals.isEmpty()) { for (String str : formulals) { sb3.append(str).append(","); } String st = String.valueOf(sb3); po.setFormulas(st.substring(0, st.length() - 1)); } sb3 = new StringBuilder(); if (!descls.isEmpty()) { for (String str : descls) { sb3.append(str).append(","); } String st = String.valueOf(sb3); po.setFormulasText(st.substring(0, st.length() - 1)); } po.setScore(score); polist.add(po); //proEconStateJudgmentDayService.insertStatejudgmentrecord(po); logger.debug("完成风机" + po.getWtId() + "_规则" + po.getStateJudgment() + "_分数" + po.getScore()); } } } } if (polist != null && polist.size() > 0) { Collections.sort(polist, new Comparator() { @Override public int compare(ProEconStateJudgmentDay o1, ProEconStateJudgmentDay o2) { // 从小到大 return o1.getScore().compareTo(o2.getScore()); } }); for (int i = 0; i < polist.size(); i++) { ProEconStateJudgmentDay po = polist.get(i); Boolean isHave = false; // Boolean isHave = wobugeqsService // .isQueryThreeDayWobugeqs(po.getWtId()); List parts = relevancePartTopThree(CacheContext.wtmap.get(po.getWtId())); int size = parts.size(); if (size > 0) { if (size == 3) { if (parts.get(0) != null) { po.setTop1(parts.get(0)); } else { po.setTop1(null); } if (parts.get(1) != null) { po.setTop2(parts.get(1)); } else { po.setTop2(null); } if (parts.get(2) != null) { po.setTop3(parts.get(2)); } else { po.setTop3(null); } } else if (size == 2) { if (parts.get(0) != null) { po.setTop1(parts.get(0)); } else { po.setTop1(null); } if (parts.get(1) != null) { po.setTop2(parts.get(1)); } else { po.setTop2(null); } po.setTop3(null); } else if (size == 1) { if (parts.get(0) != null) { po.setTop1(parts.get(0)); } else { po.setTop1(null); } po.setTop2(null); po.setTop3(null); } } if (StringUtils.empty(po.getTop1())) { po.setTop1("风速突变"); po.setTop2("发电机轴A损坏或碳刷室温度过高"); po.setTop3("单机发电机V2绕组温度传感器异常值"); } if (isHave == true) { po.setJudgmentDescribe("此风机近期有故障记录,故不在推荐范围之内!"); } else if (po.getScore() <= judgescore) { if (maps.containsKey(po.getWpId())) { int temp = maps.get(po.getWpId()) + 1; if (StringUtils.notEmp(po.getTop1())) { po.setJudgmentDescribe("健康报告达到推荐级别,推荐检修!"); maps.put(po.getWpId(), 1); }else if (temp > 1) { po.setJudgmentDescribe("设备健康情况不良,但推荐等级偏低,还需继续观察!"); } else { po.setJudgmentDescribe("健康报告达到推荐级别,推荐检修!"); } maps.put(po.getWpId(), temp); } else { po.setJudgmentDescribe("健康报告达到推荐级别,推荐检修!"); maps.put(po.getWpId(), 1); } //po.setJudgmentDescribe("健康报告达到推荐级别,推荐检修!"); } else { po.setJudgmentDescribe("健康指标未达到推荐级别,不予推荐!"); } // proEconStateJudgmentDayService.save(po); } proEconStateJudgmentDayService.saveOrUpdateBatch(polist); } } /** * 关联部件前三名新 * * @param wt * @return */ private List relevancePartTopThree(ProBasicEquipment wt) { Calendar c = Calendar.getInstance(); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); c.add(Calendar.DAY_OF_MONTH, -1); Date date = c.getTime(); c.add(Calendar.DAY_OF_MONTH, -1); Date endDate = c.getTime(); c.add(Calendar.DAY_OF_MONTH, -15); Date beginDate = c.getTime(); Map map = new HashMap(); List resultList = new ArrayList(); List voList = findArsubs(wt.getWindpowerstationId(), wt.getModelId()); for (ProEconAlarmRule arv : voList) { String temp = findAlarmcount(wt.getId(),arv.getStationId(),arv.getModelId(),arv.getId(), beginDate, endDate); Double countsum = Double.parseDouble(temp); Double benchmark = countsum / 3; String yestodayTemp =findAlarmcount(wt.getId(),arv.getStationId(),arv.getModelId(),arv.getId(), date, date); Double yestodayCount =Double.valueOf(yestodayTemp); Double deviation = 0.0; if (benchmark != 0) { deviation = (double) (Math.abs((yestodayCount - benchmark)) / benchmark); } else if (yestodayCount > 0) { deviation = 1.0; } ResultVo vo = new ResultVo(); vo.setBenchmark(benchmark); vo.setDeviation(deviation); vo.setYestodayCount(yestodayCount); map.put(arv.getName(), vo); } // 这里将map.entrySet()转换成list List> list = new ArrayList>((Collection>) map.entrySet()); // 然后通过比较器来实现排序 Collections.sort(list, new Comparator>() { @Override public int compare(Entry o1, Entry o2) { return (o2.getValue().getDeviation()).compareTo(o1.getValue().getDeviation()); } }); for (int i = 0; i < list.size(); i++) { // boolean isContent = isContent(list.get(i).getValue()); // if (isContent) { if (resultList.size() < 3) { resultList.add(list.get(i).getKey()); } else { break; } // } else { // continue; // } } return resultList; } /*** * 是否满足自定义偏差规则 * */ @SuppressWarnings("unused") private Boolean isContent(ResultVo vo) { boolean result = false; Double yestodayCount = vo.getYestodayCount();// 实际 Double benchmark = vo.getBenchmark();// 基准 int bresult = new Double(benchmark).intValue(); int bit = ("" + bresult).length(); if (bit == 1) { switch (bresult) { case 0: result = yestodayCount >= 1.0 ? true : false; break; case 1: result = yestodayCount >= 2.0 ? true : false; break; case 2: result = yestodayCount >= 3.0 ? true : false; break; case 3: result = yestodayCount >= 5.0 ? true : false; break; case 4: result = yestodayCount >= 6.0 ? true : false; break; case 5: result = yestodayCount >= 7.5 ? true : false; break; case 6: result = yestodayCount >= 9.0 ? true : false; break; case 7: result = yestodayCount >= 10.5 ? true : false; break; case 8: result = yestodayCount >= 12.0 ? true : false; break; case 9: result = yestodayCount >= 13.5 ? true : false; break; default: break; } } else if (bit == 2) { Integer firstDigit = getFirstDigit(bresult); if (firstDigit == 1) { result = yestodayCount >= bresult * 1.1 ? true : false; } else if (firstDigit == 2) { result = yestodayCount >= bresult * 1.05 ? true : false; } else if (firstDigit == 3 || firstDigit == 4) { result = yestodayCount >= bresult * 1.03 ? true : false; } else if (firstDigit == 5 || firstDigit == 6 || firstDigit == 7 || firstDigit == 8 || firstDigit == 9) { result = yestodayCount >= bresult * 1.03 ? true : false; } else { result = false; } } else { Integer firstDigit = getFirstDigit(bresult); if (firstDigit == 1) { result = yestodayCount >= bresult * 1.01 ? true : false; } else if (firstDigit == 2) { result = yestodayCount >= bresult * 1.005 ? true : false; } else if (firstDigit == 3 || firstDigit == 4) { result = yestodayCount >= bresult * 1.003 ? true : false; } else if (firstDigit == 5 || firstDigit == 6 || firstDigit == 7 || firstDigit == 8 || firstDigit == 9) { result = yestodayCount >= bresult * 1.003 ? true : false; } else { result = false; } } return result; } /** * 获取数字的最高位数字 * * @return */ private int getFirstDigit(int number) { number = Math.abs(number); if (number < 10) { return number; } return getFirstDigit((number - (number % 10)) / 10); } /** * 查询指定时间区间内的规则报警次数 * * @param stationId * @param modelId * @param alarmIds * @param beginDate * @param endDate * @return */ private String findAlarmcount(String wtId,String stationId, String modelId,String alarmIds, Date beginDate, Date endDate) { String result = "0.0"; if(StringUtils.notEmp(stationId) && StringUtils.notEmp(modelId) && StringUtils.notEmp(modelId)) { List pressureList =new ArrayList<>(); if(StringUtils.notEmp(stationId) && stationId.contains("FDC")) { String deviceType= AlarmCustomType.WT.getCode(); pressureList = alarmHistoryService.findCtFeatureStat(wtId,stationId,modelId, beginDate, endDate,null,deviceType,alarmIds,"m"); }else if(StringUtils.notEmp(stationId) && stationId.contains("GDC")) { String deviceType= AlarmCustomType.IN.getCode(); pressureList = alarmHistoryService.findCtFeatureStat(wtId,stationId,modelId, beginDate, endDate,null,deviceType,alarmIds,"m"); } if(!pressureList.isEmpty()) { AlarmStatVo vo=pressureList.get(0); StringBuilder sb=new StringBuilder(); sb.append(vo.getCount()); result = String.valueOf(sb); } } return result; } /** * 查询单个风场型号的特征规则 * * @param modelid * @param staionid * @return */ private List findArsubs(String staionid, String modelid) { List voList =new ArrayList<>(); if (StringUtils.notEmp(modelid) && StringUtils.notEmp(staionid)) { StringBuilder sb=new StringBuilder(); sb.append(staionid).append("_").append(modelid); if(CacheContext.alarmRulesModelMap.containsKey(String.valueOf(sb))) { voList=CacheContext.alarmRulesModelMap.get(String.valueOf(sb)); } return voList; } return new ArrayList<>(); } @SuppressWarnings("unused") private void saveData(List jkfxorder) { for (ProEconStateJudgmentDay vo : jkfxorder) { proEconStateJudgmentDayService.insertProEconStateJudgmentDay(vo); } } private List containList(List list, List zlist) { for (ProEconStateJudgmentDay statejudgmentrecordVo : list) { zlist.add(statejudgmentrecordVo); } return zlist; } private List removeDuplicate(List list) { for (int i = 0; i < list.size() - 1; i++) { for (int j = list.size() - 1; j > i; j--) { if (list.get(i).getFormulas().equals(list.get(j).getFormulas()) && list.get(i).getWtId().equals(list.get(j).getWtId()) && list.get(i).getRecordDate().equals(list.get(j).getRecordDate())) { list.remove(j); } } } return list; } private void judgeParams(Map hcmap, Map parmarsmap, ProBasicEquipment wt, ArrayList ucs) throws Exception { Calendar c = Calendar.getInstance(); c.set(Calendar.HOUR_OF_DAY, 0); c.set(Calendar.MINUTE, 0); c.set(Calendar.SECOND, 0); if (!ucs.isEmpty()) { for (String str : ucs) { if (hcmap.containsKey(str)) { HcEnum hc = hcmap.get(str); Object obj = healthFactoryService.judegeHealth(hc, wt, c); if (obj instanceof Boolean) { parmarsmap.put(str, Boolean.valueOf(String.valueOf(obj))); } else if (obj instanceof Double) { parmarsmap.put(str, Double.valueOf(String.valueOf(obj))); } else if (obj instanceof Integer) { parmarsmap.put(str, Integer.valueOf(String.valueOf(obj))); } } } } } }