package com.slibra.quartz.task; import cn.hutool.core.date.DateUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONWriter; import com.google.protobuf.ByteString; import com.slibra.business.domain.*; import com.slibra.business.mapper.*; import com.slibra.business.req.ChatReq; import com.slibra.business.req.ChatRequest; import com.slibra.business.req.GenerateArgs; import com.slibra.business.req.PredictorRequest; import com.slibra.business.res.ChartBasic; import com.slibra.business.res.ShowValueChartBasic; import com.slibra.business.service.ITXinyiForecastComparisonService; import com.slibra.common.DecimalUtils; import com.slibra.common.config.BigModelConfig; import com.slibra.common.constant.MyConstants; import com.slibra.common.core.domain.TXinyiDaily; import com.slibra.common.enums.BusinessEnum; import com.slibra.common.enums.DataSourceType; import com.slibra.common.utils.DateUtils; import com.slibra.common.utils.LocalDateTimeUtil; import com.slibra.common.utils.uuid.IdUtils; import com.slibra.framework.datasource.DynamicDataSourceContextHolder; import com.slibra.quartz.business.JsCsFormatData; import inference.InferenceAPIsServiceGrpc; import inference.PredictionResponse; import inference.PredictionsRequest; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.slibra.common.utils.StringUtils; import org.springframework.util.CollectionUtils; import java.io.IOException; import java.math.BigDecimal; import java.text.ParseException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static com.slibra.common.constant.MyConstants.*; import static com.slibra.common.enums.BusinessEnum.BigModelWarningTypeRemarkEnum.TWO_YC_WARNING; import static com.slibra.common.enums.BusinessEnum.WarningCategoryEnum.CS_TP_YC; /** * 定时任务调度测试 * * */ @Component("ryTask") @Slf4j public class RyTask { public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); } public void ryParams(String params) { System.out.println("执行有参方法:" + params); } public void ryNoParams() { System.out.println("执行无参方法"); } //----------------------------------------------下面是新增的方法---------------------------------------------- @Autowired private TXinyiIndustryMapper xinyiIndustryMapper; @Autowired private TXinyiRobotMapper xinyiRobotMapper; @Autowired private TXinyiNormConfigMapper xinyiNormConfigMapper; @Autowired private TXinyiWarningRecordMapper xinyiWarningRecordMapper; @Autowired private TXinyiChatRecordMapper xinyiChatRecordMapper; @Autowired private TXinyiDailyMapper xinyiDailyMapper; @Autowired private AsyncTask asyncTask; @Autowired private ITXinyiForecastComparisonService xinyiForecastComparisonService; @Autowired private BigModelConfig bigModelConfig; @Autowired private TXinyiBigTableDayMapper xinyiBigTableDayMapper; @Autowired private TXinyiBigTableMonthMapper xinyiBigTableMonthMapper; @Autowired private TXinyiBigTableHourMapper xinyiBigTableHourMapper; @Autowired private JsCsFormatData jsCsFormatData; /** 使用的是哪个环境 */ @Value("${spring.profiles.active}") private String environment; // public final static StopWatch watch = new StopWatch("task"); public static final String[] queryTags = {"信义污水厂JS_COD_Value","信义污水厂JS_PH_Value","信义污水厂JS_SS_Value","信义污水厂JS_ZL_Value","信义污水厂JS_ZA_Value","信义污水厂JS_AD_Value","信义污水厂JS_T_Value","信义污水厂进水泵房液位","信义污水厂出水瞬时流量","信义污水厂升级出水COD","信义污水厂升级出水PH","信义污水厂升级出水SS","信义污水厂升级出水TN","信义污水厂升级出水TP","信义污水厂升级出水氨氮","信义污水厂AIT202_Value","信义污水厂AIT203_Value","信义污水厂AIT207_Value","信义污水厂AIT206_Value","信义污水厂AIT209_Value","信义污水厂AIT210_Value","信义污水厂进水TDS","信义污水厂FT101_Value","信义污水厂SWCHHYHLB1_R_Value","信义污水厂SWCHHYHLB2_R_Value","信义污水厂SWCHHYHLB3_R_Value","信义污水厂SWCHHYHLB4_R_Value","信义污水厂SWCHHYHLB5_R_Value","信义污水厂SWCHHYHLB6_R_Value","信义污水厂SWCWNHLB1_R_Value","信义污水厂SWCWNHLB2_R_Value","信义污水厂SWCWNHLB3_R_Value","信义污水厂SWCWNHLB4_R_Value","信义污水厂SWCWNHLB5_R_Value","信义污水厂GFJ1_R_Value","信义污水厂GFJ2_R_Value","信义污水厂GFJ3_R_Value","信义污水厂GFJ4_R_Value","信义污水厂GFJ5_R_Value","信义污水厂GFJ6_R_Value","信义污水厂GFJ1_KQLL_Value","信义污水厂GFJ2_KQLL_Value","信义污水厂GFJ3_KQLL_Value","信义污水厂GFJ4_KQLL_Value","信义污水厂GFJ5_KQLL_Value","信义污水厂GFJ6_KQLL_Value","信义污水厂实际碳源加药量","信义污水厂除磷加药瞬时流量", "信义污水厂_除磷P04预测值_"}; /** * * 2024年6月21日14:52:05 调整逻辑: * 出水总氮 的预测:使用 (xsy1 + xsy2) /2 /0.8 做为出水总氮的结果 * */ // public static final String[] predictorArr = {"出水COD", "出水SS", "出水总磷", "出水氨氮"}; public static final String[] predictorArr = {"出水COD", "出水SS", "出水总磷", "出水氨氮", "xsy1", "xsy2", "qyxsy1", "qyxsy2", "缺氧出水氨氮1", "缺氧出水氨氮2"}; public static final String[] predictorArrSpecial = {"xsy1", "xsy2"}; /** * 定时从工业库获取数据 * * 2024年4月17日17:44:15 调整逻辑:考虑到因断电等情况导致服务断电,所以不再同步最近一小时,而是同步从上次成功的最后一条数据开始。 */ public void getIndustryData(){ log.info("进入了定时同步工业库数据的任务"); //耗时工具 // watch.start("parseJob"); // 给定时间段的起始时间和结束时间 LocalDateTime endTime = LocalDateTime.now(); // LocalDateTime startTime = endTime.plusMinutes(-60); //获取上次最后一条同步的数据的日期到 分钟维度 String lastDateHour = this.xinyiIndustryMapper.getLastMinute(); log.info("获取上次同步工业库的最后一条记录的时间是{}", lastDateHour); lastDateHour = lastDateHour + ":00"; //开始时间 LocalDateTime startTime = LocalDateTime.parse(lastDateHour.replaceAll("/", "-").replace(" ", "T")); startTime = startTime.plusMinutes(60L);//加一分钟 从上次最后一条记录的下一分钟开始 /*LocalDateTime startTime = LocalDateTime.parse("2024-02-26T00:00:00"); LocalDateTime endTime = LocalDateTime.parse("2024-02-27T00:00:00");*/ // 每个小时的时间格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 循环按小时分割 LocalDateTime currentHour = startTime; //最终获取的数据 Map needMap = new LinkedHashMap<>(); while (currentHour.isBefore(endTime)) { String begin = currentHour.format(formatter); String end = currentHour.plusMinutes(5).format(formatter); // 输出当前小时的起始时间和结束时间 System.out.println("起始时间:" + begin); System.out.println("结束时间:" + end); // 当前小时加一小时,作为下一个小时的起始时间 currentHour = currentHour.plusMinutes(5); //每个小时查询一次数据 String url = "http://10.0.0.27:4568/api/v1/khquerydata"; HashMap req = new HashMap<>(); req.put("tagNames", queryTags); req.put("startTime", begin); req.put("endTime", end); req.put("recordNumbers", 100000); String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body(); // System.out.println("body = " + body); List> list = new ArrayList<>(); //行转列数据处理 for (String queryTag : queryTags) { JSONArray array = JSON.parseObject(body).getJSONArray(queryTag); //特殊数据处理一 if(Objects.isNull(array) || array.isEmpty()){ System.out.println(queryTag + "查询到了空的数据,跳过本次循环"); continue; } int size = array.size(); //特殊数据处理二 if("0".equals(array.get(1) + "")){ System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0"); continue; } //结合至少62个数据才满足条件(有可能获取不到) /*if(size < 62){ System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环"); continue; }*/ //存放的数据集 //利用map去重 HashMap map = new LinkedHashMap<>(); for (int i = 2; i < size; i++) { // System.out.println(i + "" + array.get(i)); JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i))); //处理为空或者为0的数据 Object timeStampValue = oneRecord.get(2); if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + "")) continue; BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + ""); long timestamp = (long) timeStampValue; String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS); map.put(format, queryTag + "-" + value); } list.add(map); } Set recordTimeSet = new HashSet<>(); Map recordMap = new HashMap<>(); for (int i = 0; i < list.size(); i++) { HashMap map = list.get(i); int finalJ = i; map.forEach((k, v) ->{ TXinyiIndustry industry = null; if(!recordTimeSet.contains(k)){//第一次 industry = new TXinyiIndustry(); recordTimeSet.add(k); recordMap.put(k, industry); }else{ industry = recordMap.get(k); } industry.setTestTime(k + ":00"); //2024年4月15日11:19:52 额外增加2个字段 industry.setTestDate(k.substring(0,10)); industry.setTestHour(k.substring(0,13)); //解析值 String[] split = v.split("-"); String type = split[0]; BigDecimal value = new BigDecimal(split[1]); if ("信义污水厂JS_COD_Value".equals(type)) { industry.setJsCod(value); } else if ("信义污水厂JS_PH_Value".equals(type)) { industry.setJsPh(value); } else if ("信义污水厂JS_SS_Value".equals(type)) { // log.info("************----------真实的进水SS的值为{}\n时间为{}", value, k); industry.setJsSs(value); } else if ("信义污水厂JS_ZL_Value".equals(type)) { industry.setJsTp(value); } else if ("信义污水厂JS_ZA_Value".equals(type)) { industry.setJsTn(value); } else if ("信义污水厂JS_AD_Value".equals(type)) { industry.setJsNh3(value); } else if ("信义污水厂JS_T_Value".equals(type)) { industry.setJsSwPh(value); } else if ("信义污水厂进水泵房液位".equals(type)) { industry.setJsBfyw(value); } else if ("信义污水厂出水瞬时流量".equals(type)) { industry.setCsSlqc(value); } else if ("信义污水厂升级出水COD".equals(type)) { industry.setCsCod(value); } else if ("信义污水厂升级出水PH".equals(type)) { industry.setCsPh(value); } else if ("信义污水厂升级出水SS".equals(type)) { industry.setCsSs(value); } else if ("信义污水厂升级出水TN".equals(type)) { // log.info("************----------真实的出水总氮的值为{}\n时间为{}", value, k); // industry.setCsTn(new BigDecimal(17)); industry.setCsTn(value); } else if ("信义污水厂升级出水TP".equals(type)) { industry.setCsTp(value); } else if ("信义污水厂升级出水氨氮".equals(type)) { industry.setCsNh3(value); } else if ("信义污水厂AIT202_Value".equals(type)) { industry.setOneHyzdDo(value); } else if ("信义污水厂AIT203_Value".equals(type)) { industry.setOneHymdDo(value); } else if ("信义污水厂AIT207_Value".equals(type)) { industry.setTwoHyzdDo(value); } else if ("信义污水厂AIT206_Value".equals(type)) { industry.setTwoHymdDo(value); } else if ("信义污水厂AIT209_Value".equals(type)) { industry.setOneMlss(value); } else if ("信义污水厂AIT210_Value".equals(type)) { industry.setTwoMlss(value); } else if ("信义污水厂进水TDS".equals(type)) { industry.setJsTds(value); } else if ("信义污水厂FT101_Value".equals(type)) { industry.setJsSlq(value); } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) { industry.setNHlbOneGp(value); } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) { industry.setNHlbTwoGp(value); } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) { industry.setNHlbThreeGp(value); } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) { industry.setNHlbFourGp(value); } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) { industry.setNhlBFiveGp(value); } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) { industry.setNHlbSixGp(value); } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) { industry.setWHlbOneGp(value); } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) { industry.setWHlbTwoGp(value); } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) { industry.setWHlbThreeGp(value); } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) { industry.setWHlbFourGp(value); } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) { industry.setWHlbFiveGp(value); } else if ("信义污水厂GFJ1_R_Value".equals(type)) { industry.setFjOne(value); } else if ("信义污水厂GFJ2_R_Value".equals(type)) { industry.setFjTwo(value); } else if ("信义污水厂GFJ3_R_Value".equals(type)) { industry.setFjThree(value); } else if ("信义污水厂GFJ4_R_Value".equals(type)) { industry.setFjFour(value); } else if ("信义污水厂GFJ5_R_Value".equals(type)) { industry.setFjFive(value); } else if ("信义污水厂GFJ6_R_Value".equals(type)) { industry.setFjSix(value); } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) { industry.setKqllOne(value); } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) { industry.setKqllTwo(value); } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) { industry.setKqllThree(value); } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) { industry.setKqllFour(value); } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) { industry.setKqllFive(value); } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) { industry.setKqllSix(value); }else if ("信义污水厂实际碳源加药量".equals(type)) { industry.setSJTYJLY(value); }else if ("信义污水厂除磷加药瞬时流量".equals(type)) { industry.setCLJYSSLL(value); } else if ("信义污水厂_除磷P04预测值_".equals(type)) { industry.setCLP04YCZ(value); } //只有最后一次才执行数据库添加 if(finalJ == list.size()-1){ needMap.put(industry.getTestHour(), industry); } }); } } //保存数据 触发告警 决策 问答记录等等 needMap.forEach((k, industry) ->{ //2024年4月22日15:45:24 额外保存两个字段 数组 List extraList = new ArrayList<>(); extraList.add(industry.getOneHymdDo()); extraList.add(industry.getTwoHymdDo()); industry.setHycRjyAll(JSON.toJSONString(extraList)); extraList.clear(); extraList.add(industry.getOneHyzdDo()); extraList.add(industry.getTwoHyzdDo()); industry.setHycRjyZdAll(JSON.toJSONString(extraList)); extraList.clear(); extraList.add(industry.getOneMlss()); extraList.add(industry.getTwoMlss()); industry.setHycWnndAll(JSON.toJSONString(extraList)); //插入数据库 xinyiIndustryMapper.insertTXinyiIndustry(industry); //判断是否触发告警、接触告警、保存决策等等 // this.handleWarning(industry); //2024年5月30日18:29:20 改为异步处理 asyncTask.handleWarning(industry); }); //执行完成 测试执行时间 //计时结束 // watch.stop(); // System.out.println(watch.getLastTaskName() + " 执行耗时:" + watch.getLastTaskTimeMillis() + " ms"); } private String buildShowValueDeviceErr(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) { JSONObject result = new JSONObject(); JSONObject basic = new JSONObject(); Integer status = tXinyiWarningRecord.getStatus(); Date warningTime = tXinyiWarningRecord.getTime(); int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1; basic.put("title", tXinyiWarningRecord.getReason()); basic.put("报警时间", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime)); basic.put("报警值", DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getWarningVal(), INT_2)); basic.put("标准值", DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getDesignVal(), INT_2)); basic.put("管控值", DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getControlVal(), INT_2)); basic.put("报警次数", Math.min(count, MAX_COUNT)); if(tXinyiWarningRecord.getType() != 2) basic.put("状态", status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中"); else basic.put("状态", status == 0 ? "预警中" : "已完成"); //2024年5月27日14:04:22 额外返回2个字段 [管控值 和 告警级别] 返回的json没有数据是因为value没有值 // basic.put("管控值", tXinyiWarningRecord.getControlVal()); basic.put("告警级别", tXinyiWarningRecord.getLevel()); result.put("basic", basic); JSONObject jsData = jsCsFormatData.getJsonObject(tXinyiIndustry, normConfig);//进水数据 result.put("jsData", jsData); JSONObject csData = jsCsFormatData.getCsonObject(tXinyiIndustry, normConfig);//出水数据 result.put("csData", csData); return JSON.toJSONString(result, JSONWriter.Feature.WriteNulls); } /** * 带图形的构建展示数据 * * @param tXinyiWarningRecord * @param tXinyiIndustry * @param normConfig * @param date * @param yjHour * @param nowDate * @return */ private String buildShowValueWithCharts(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, List chartsDataList, String date, String yjHour, Date nowDate) { JSONObject result = new JSONObject(); // JSONObject basic = new JSONObject(); Integer status = tXinyiWarningRecord.getStatus(); /*Date warningTime = tXinyiWarningRecord.getTime(); String remark = tXinyiWarningRecord.getRemark(); int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1;*/ ShowValueChartBasic showValueChartBasic = new ShowValueChartBasic(); /*if("0".equals(remark)){//水质报警 showValueChartBasic.setH(ZAIXIANYIBIAO); }else if("1".equals(remark)){//生化报警 showValueChartBasic.setH(ZAIXIANYIBIAO); }else if("2".equals(remark)){//预测报错 showValueChartBasic.setH(YVCE); }else {//机器人化验室报警 showValueChartBasic.setH(LIANXUJIANCE); }*/ //通用的 // showValueBasic.setA(tXinyiWarningRecord.getReason()); //2024年6月23日17:01:30 预警时间改成当前时间 showValueChartBasic.setB(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM, nowDate)); showValueChartBasic.setC(date + " " + yjHour);//预计超标时间 showValueChartBasic.setD(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getWarningVal(), INT_2));//改成现在值 不是报警时候的值(在发现存在告警记录的时候更新) showValueChartBasic.setE(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getForecastVal(), INT_2));//改成预测值 不是报警时候的值(在发现存在告警记录的时候更新) showValueChartBasic.setF(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getControlVal(), INT_2)); showValueChartBasic.setG(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getDesignVal(), INT_2)); // showValueChartBasic.setH(Math.min(count, MAX_COUNT)); //2024年7月20日17:28:17 增加数据来源展示 String category = tXinyiWarningRecord.getCategory(); if(BusinessEnum.WarningCategoryEnum.CS_COD_YC.getCode().equals(category) || BusinessEnum.WarningCategoryEnum.CS_SS_YC.getCode().equals(category) || BusinessEnum.WarningCategoryEnum.CS_AD_YC.getCode().equals(category)) showValueChartBasic.setH(ZAIXIANYIBIAO); else showValueChartBasic.setH(LIANXUJIANCE); if(tXinyiWarningRecord.getType() != 2) showValueChartBasic.setI(status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中"); else showValueChartBasic.setI(status == 0 ? "预警中" : "已完成"); result.put("basic", showValueChartBasic); JSONObject jsData = jsCsFormatData.getJsonObject(tXinyiIndustry, normConfig);//进水数据 result.put("jsData", jsData); JSONObject csData = jsCsFormatData.getCsonObject(tXinyiIndustry, normConfig);//出水数据 result.put("csData", csData); // JSONObject chartsData = getChartsCsonObject(tXinyiIndustry, normConfig);//图表数据 因为展示不同,所以要传过来或者判断 result.put("chartsData", chartsDataList); result.put("chartsTitle", tXinyiWarningRecord.getCategory() + "数据趋势图"); return JSON.toJSONString(result, JSONWriter.Feature.WriteNulls); } private static JSONObject getJsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) { JSONObject jsData = new JSONObject(); HashMap temp1 = new HashMap<>(); BigDecimal jsSlq = tXinyiIndustry.getJsSlq(); temp1.put("value", DecimalUtils.getAbsAndScale(jsSlq, INT_2)); temp1.put("exceed", jsSlq.compareTo(normConfig.getJsslSjz()) >0); jsData.put("流量", temp1); HashMap temp2 = new HashMap<>(); BigDecimal jsCod = tXinyiIndustry.getJsCod(); temp2.put("value", DecimalUtils.getAbsAndScale(jsCod, INT_2)); temp2.put("exceed", jsCod.compareTo(normConfig.getJscodSjz()) > 0); jsData.put("COD", temp2); HashMap temp3 = new HashMap<>(); BigDecimal jsNh3 = tXinyiIndustry.getJsNh3(); temp3.put("value", DecimalUtils.getAbsAndScale(jsNh3, INT_2)); temp3.put("exceed", jsNh3.compareTo(normConfig.getJsadSjz()) > 0); jsData.put("NH3-N", temp3); HashMap temp4 = new HashMap<>(); BigDecimal jsTp = tXinyiIndustry.getJsTp(); temp4.put("value", DecimalUtils.getAbsAndScale(jsTp, INT_2)); temp4.put("exceed", jsTp.compareTo(normConfig.getJszlSjz()) > 0); jsData.put("TP", temp4); HashMap temp5 = new HashMap<>(); BigDecimal jsSs = tXinyiIndustry.getJsSs(); temp5.put("value", DecimalUtils.getAbsAndScale(jsSs, INT_2)); temp5.put("exceed", jsSs.compareTo(normConfig.getJsssSjz()) > 0); jsData.put("SS", temp5); HashMap temp6 = new HashMap<>(); BigDecimal jsTn = tXinyiIndustry.getJsTn(); temp6.put("value", DecimalUtils.getAbsAndScale(jsTn, INT_2)); temp6.put("exceed", jsTn.compareTo(normConfig.getJszdSjz()) > 0); jsData.put("TN", temp6); return jsData; } private static JSONObject getCsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) { JSONObject csData = new JSONObject(); HashMap temp1 = new HashMap<>(); BigDecimal csSlq = tXinyiIndustry.getCsSlqc(); temp1.put("value", DecimalUtils.getAbsAndScale(csSlq, INT_2)); temp1.put("exceed", false);//出水水量没有管控值 csData.put("流量", temp1); HashMap temp2 = new HashMap<>(); BigDecimal csCod = tXinyiIndustry.getCsCod(); temp2.put("value", DecimalUtils.getAbsAndScale(csCod, INT_2)); temp2.put("exceed", csCod.compareTo(normConfig.getCscodGkz()) > 0); csData.put("COD", temp2); HashMap temp3 = new HashMap<>(); BigDecimal csNh3 = tXinyiIndustry.getCsNh3(); temp3.put("value", DecimalUtils.getAbsAndScale(csNh3, INT_2)); temp3.put("exceed", csNh3.compareTo(normConfig.getCsadGkz()) > 0); csData.put("NH3-N", temp3); HashMap temp4 = new HashMap<>(); BigDecimal csTp = tXinyiIndustry.getCsTp(); temp4.put("value", DecimalUtils.getAbsAndScale(csTp, INT_2)); temp4.put("exceed", csTp.compareTo(normConfig.getCszlGkz()) > 0); csData.put("TP", temp4); HashMap temp5 = new HashMap<>(); BigDecimal csSs = tXinyiIndustry.getCsSs(); temp5.put("value", DecimalUtils.getAbsAndScale(csSs, INT_2)); temp5.put("exceed", csSs.compareTo(normConfig.getCsssGkz()) > 0); csData.put("SS", temp5); HashMap temp6 = new HashMap<>(); BigDecimal csTn = tXinyiIndustry.getCsTn(); temp6.put("value", DecimalUtils.getAbsAndScale(csTn, INT_2)); temp6.put("exceed", csTn.compareTo(normConfig.getCszzGkz()) > 0); csData.put("TN", temp6); return csData; } private void addChatRecordByDeviceErr(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) { ChatReq chatReq = new ChatReq(); //保存聊天记录 //将问答更新到数据库中 chatReq.setSessionId(IdUtils.simpleUUID()); chatReq.setType(1);//0问答 1决策 2本地 3仿真预测 chatReq.setModule(3); /*String userId = SecurityUtils.getUserId().toString(); String username = SecurityUtils.getUsername();*/ chatReq.setUserId(WARNING_DEFAULT_CREATE); String showVal = this.buildShowValueDeviceErr(tXinyiWarningRecord, tXinyiIndustry, normConfig); chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致 chatReq.setQuestion(WARNING_DEFAULT_QUESTION);//本地问题 chatReq.setAnswer(tXinyiWarningRecord.getReason() + ",请检查设备是否正常运行"); chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId())); chatReq.setCounts(1);//问答次数 chatReq.setCreateBy(WARNING_DEFAULT_CREATE); chatReq.setCreateTime(DateUtils.getNowDate()); this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq); } /** * 定时从sqlserver获取数据 */ public void sqlserverData(){ log.info("进入了定时同步SqlServer的任务"); //主库获取上次最新的同步日期 String lastTime = this.xinyiRobotMapper.selectLastTime(); log.info("上次同步的日期是{}", lastTime); //从 DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name()); List tXinyiRobots = xinyiRobotMapper.selectTXinyiRobotListByTime(lastTime); DynamicDataSourceContextHolder.clearDataSourceType(); // System.out.println(JSON.toJSONString(tXinyiRobots)); // System.out.println("-------------"); //主 List needHandleList = new ArrayList<>(); if(!CollectionUtils.isEmpty(tXinyiRobots)){ for (TXinyiRobot tXinyiRobot : tXinyiRobots) { String date = handleDate(tXinyiRobot.getVDate().replaceAll(" ", ""));//有空格 String time = handleDate(tXinyiRobot.getVTime().replaceAll(" ", ""));//有空格 tXinyiRobot.setVDate(date); tXinyiRobot.setVTime(time); tXinyiRobot.setVDateTime(date + " " + time); //处理给前端展示的字段 tXinyiRobot.setTestDate(date);//日期 tXinyiRobot.setTestHour(date + " " + time.substring(0, 2));//小时 tXinyiRobot.setTestTime(date + " " + time.substring(0, 5));//分钟 tXinyiRobot.setCreatedTime(new Date()); //2024年5月29日10:33:32 额外处理几个新增的字段 多个池子数据合并一个 List extraList = new ArrayList<>(); extraList.add(tXinyiRobot.getNo3Hlj1Jqr()); extraList.add(tXinyiRobot.getNo3Hlj2Jqr()); tXinyiRobot.setHycxsyAll(JSON.toJSONString(extraList)); extraList.clear(); extraList.add(tXinyiRobot.getNh31Jqr()); extraList.add(tXinyiRobot.getNh32Jqr()); tXinyiRobot.setQyanAll(JSON.toJSONString(extraList)); extraList.clear(); extraList.add(tXinyiRobot.getNo3Qyc1Jqr()); extraList.add(tXinyiRobot.getNo3Qyc2Jqr()); tXinyiRobot.setQyckxsyAll(JSON.toJSONString(extraList)); extraList.clear(); extraList.add(tXinyiRobot.getTpHl1Jqr()); extraList.add(tXinyiRobot.getTpHl2Jqr()); tXinyiRobot.setHyzlsyAll(JSON.toJSONString(extraList)); //按照小时填充集合 然后处理报警相关逻辑 //2024年6月17日13:32:59 因为机器人化验室数据基本几个小时的都一致 改成一小时取一次 needHandleList.add(tXinyiRobot); // this.xinyiRobotMapper.insertTXinyiRobot(tXinyiRobot); } } if(!CollectionUtils.isEmpty(needHandleList)){ List uniqueList = needHandleList.stream() .collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TXinyiRobot::getTestHour))), ArrayList::new )); if(!CollectionUtils.isEmpty(uniqueList)){ for (TXinyiRobot tXinyiRobot : uniqueList) { //判断是否添加过了(小时) String testHour = tXinyiRobot.getTestHour(); List tXinyiRobotList = this.xinyiRobotMapper.selectTXinyiRobotList(TXinyiRobot.builder().testHour(testHour).build()); if(CollectionUtils.isEmpty(tXinyiRobotList)){ this.xinyiRobotMapper.insertTXinyiRobot(tXinyiRobot); //2024年6月18日10:45:20 额外计算一下预测的准确度 asyncTask.updateForecastComparisonByRobot(tXinyiRobot); //2024年7月6日10:32:36 大宽表的数据处理 asyncTask.updateBigTableHourByRobot(tXinyiRobot); } else log.info("{}已经吧保存过了,无需重复保存***&&&···", testHour); } //2024年08月09日14:26:29 为了节省费用,测试环境关闭报警并增加手动触发报警操作 if(PROD_ENVIRONMENT.equalsIgnoreCase(environment)){ asyncTask.handleRobotWarning(uniqueList); } } } } /** * * 定时生成每日简报数据 * */ public void generateShortReport(){ log.info("进入了定时生成每日简报数据"); List dailyTwoRecords = this.xinyiDailyMapper.selectNRecords(DAILY_REPORT_COUNT_RECORD); //正常不会有这种问题 因为日报有很多条 if(CollectionUtils.isEmpty(dailyTwoRecords) || dailyTwoRecords.size() < DAILY_REPORT_COUNT_RECORD){ log.error("进入了定时生成每日简报数据 获取最新的{}条数据不足,终止", DAILY_REPORT_COUNT_RECORD); return; } //暂时不考虑因为没有填写日报 导致生成重复数据的问题(后续需要的话再添加) //处理数据 并 拼装 String queryData = buildShortReportQueryDataNew(dailyTwoRecords); // log.info("定时生成简报,组装好的请求大模型的参数为:{}", queryData); if(StringUtils.isBlank(queryData)){ log.error("无法拼装请求数据!!!!!!"); return; } String showVal = formateDateStr(dailyTwoRecords.get(0).getTestDate()) + JIAN_BAO_END; //调用模型 并保存结果 this.askBigModel(queryData, showVal); log.info("定时生成简报任务结束~~~~~~~~~~~~~~"); } /** * * 每小时发一一次预测 * */ public void predictor(){ //获取最新的6条工业科数据 List tXinyiIndustries6 = this.xinyiIndustryMapper.selectNIndustry(INT_6); List tXinyiRobots6 = this.xinyiRobotMapper.selectNRobot(INT_6); //2024年7月18日10:31:18 加个校验,只有从来没有数据的水厂才会进入下面的判断 if(CollectionUtils.isEmpty(tXinyiIndustries6) || tXinyiIndustries6.size() < INT_6 || CollectionUtils.isEmpty(tXinyiRobots6) || tXinyiRobots6.size() gyHycRjyAll = new ArrayList<>(); ArrayList gyHycRjyZdAll = new ArrayList<>(); ArrayList gyHycWnndAll = new ArrayList<>(); ArrayList rbHycRjyAll = new ArrayList<>(); ArrayList rbHycWnndAll = new ArrayList<>(); ArrayList rbYycRjyAll = new ArrayList<>(); ArrayList rbQycRjyAll = new ArrayList<>(); ArrayList rbWncjbAll = new ArrayList<>(); ArrayList rbWntjzsAll = new ArrayList<>(); ArrayList rbHfxwnndAll = new ArrayList<>(); ArrayList hyHycxsyAll = new ArrayList<>(); ArrayList hyQyanAll = new ArrayList<>(); ArrayList hyQyckxsyAll = new ArrayList<>(); ArrayList hyHyzlsyAll = new ArrayList<>(); gyHycRjyAll.add(xinyiBigTableDay.getGyOneHymdDo()); gyHycRjyAll.add(xinyiBigTableDay.getGyTwoHymdDo()); gyHycRjyZdAll.add(xinyiBigTableDay.getGyOneHyzdDo()); gyHycRjyZdAll.add(xinyiBigTableDay.getGyTwoHyzdDo()); gyHycWnndAll.add(xinyiBigTableDay.getGyOneMlss()); gyHycWnndAll.add(xinyiBigTableDay.getGyTwoMlss()); rbHycRjyAll.add(xinyiBigTableDay.getGyOneHymdDo()); rbHycRjyAll.add(xinyiBigTableDay.getGyTwoHymdDo()); rbHycWnndAll.add(xinyiBigTableDay.getRbShcHyOneMlss()); rbHycWnndAll.add(xinyiBigTableDay.getRbShcHyTwoMlss()); rbYycRjyAll.add(xinyiBigTableDay.getRbShcYyOneDo()); rbYycRjyAll.add(xinyiBigTableDay.getRbShcYyTwoDo()); rbQycRjyAll.add(xinyiBigTableDay.getRbShcQyOneDo()); rbQycRjyAll.add(xinyiBigTableDay.getRbShcQyTwoDo()); rbWncjbAll.add(xinyiBigTableDay.getRbShcHyOneSv()); rbWncjbAll.add(xinyiBigTableDay.getRbShcHyTwoSv()); rbWntjzsAll.add(xinyiBigTableDay.getRbShcHyOneSvi()); rbWntjzsAll.add(xinyiBigTableDay.getRbShcHyTwoSvi()); rbHfxwnndAll.add(xinyiBigTableDay.getRbShcHyOneMlvss()); rbHfxwnndAll.add(xinyiBigTableDay.getRbShcHyTwoMlvss()); hyHycxsyAll.add(xinyiBigTableDay.getHyNo3Hlj1Jqr()); hyHycxsyAll.add(xinyiBigTableDay.getHyNo3Hlj2Jqr()); hyQyanAll.add(xinyiBigTableDay.getHyNh31Jqr()); hyQyanAll.add(xinyiBigTableDay.getHyNh32Jqr()); hyQyckxsyAll.add(xinyiBigTableDay.getHyNo3Qyc1Jqr()); hyQyckxsyAll.add(xinyiBigTableDay.getHyNo3Qyc2Jqr()); hyHyzlsyAll.add(xinyiBigTableDay.getHyTpHl1Jqr()); hyHyzlsyAll.add(xinyiBigTableDay.getHyTpHl2Jqr()); xinyiBigTableDay.setGyHycRjyAll(formatList(gyHycRjyAll)); xinyiBigTableDay.setGyHycRjyZdAll(formatList(gyHycRjyZdAll)); xinyiBigTableDay.setGyHycWnndAll(formatList(gyHycWnndAll)); xinyiBigTableDay.setRbHycRjyAll(formatList(rbHycRjyAll)); xinyiBigTableDay.setRbHycWnndAll(formatList(rbHycWnndAll)); xinyiBigTableDay.setRbYycRjyAll(formatList(rbYycRjyAll)); xinyiBigTableDay.setRbQycRjyAll(formatList(rbQycRjyAll)); xinyiBigTableDay.setRbWncjbAll(formatList(rbWncjbAll)); xinyiBigTableDay.setRbWntjzsAll(formatList(rbWntjzsAll)); xinyiBigTableDay.setRbHfxwnndAll(formatList(rbHfxwnndAll)); xinyiBigTableDay.setHyHycxsyAll(formatList(hyHycxsyAll)); xinyiBigTableDay.setHyQyanAll(formatList(hyQyanAll)); xinyiBigTableDay.setHyQyckxsyAll(formatList(hyQyckxsyAll)); xinyiBigTableDay.setHyHyzlsyAll(formatList(hyHyzlsyAll)); this.xinyiBigTableDayMapper.insertTXinyiBigTableDay(xinyiBigTableDay); } } public String formatList(List list) { if (CollectionUtils.isEmpty(list)) { return null; } boolean isNullList = list.stream().allMatch(x -> x == null); return isNullList ? null : list.toString(); } /** * * 每个月第一天定时计算月度维度的数据 * */ public void bigModelMonthHandle(){ log.info("进入了 每个月第一天定时计算月度维度的数据 处理"); //获取上个月的第一天和最后一天(定时任务是某个月第一天开始执行的 所以减7天,肯定是上个月的数据) LocalDateTime lastMonthDateTime = LocalDateTime.now().plusDays(-7); String begin = LocalDateTimeUtil.getMonthFirst(lastMonthDateTime).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS)); String end = LocalDateTimeUtil.getMonthLast(lastMonthDateTime).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS)); //获取昨日的统计数据 TXinyiBigTableMonth xinyiBigTableMonth = this.xinyiBigTableMonthMapper.selectAvgByMonth(begin, end); //保存到插入对象 //插入到数据库 if(!Objects.isNull(xinyiBigTableMonth)){ //先把日期处理一下 处理成只要月份的 xinyiBigTableMonth.setTestDate(xinyiBigTableMonth.getTestDate().substring(0, 7)); ArrayList gyHycRjyAll = new ArrayList<>(); ArrayList gyHycRjyZdAll = new ArrayList<>(); ArrayList gyHycWnndAll = new ArrayList<>(); ArrayList rbHycRjyAll = new ArrayList<>(); ArrayList rbHycWnndAll = new ArrayList<>(); ArrayList rbYycRjyAll = new ArrayList<>(); ArrayList rbQycRjyAll = new ArrayList<>(); ArrayList rbWncjbAll = new ArrayList<>(); ArrayList rbWntjzsAll = new ArrayList<>(); ArrayList rbHfxwnndAll = new ArrayList<>(); ArrayList hyHycxsyAll = new ArrayList<>(); ArrayList hyQyanAll = new ArrayList<>(); ArrayList hyQyckxsyAll = new ArrayList<>(); ArrayList hyHyzlsyAll = new ArrayList<>(); gyHycRjyAll.add(xinyiBigTableMonth.getGyOneHymdDo()); gyHycRjyAll.add(xinyiBigTableMonth.getGyTwoHymdDo()); gyHycRjyZdAll.add(xinyiBigTableMonth.getGyOneHyzdDo()); gyHycRjyZdAll.add(xinyiBigTableMonth.getGyTwoHyzdDo()); gyHycWnndAll.add(xinyiBigTableMonth.getGyOneMlss()); gyHycWnndAll.add(xinyiBigTableMonth.getGyTwoMlss()); rbHycRjyAll.add(xinyiBigTableMonth.getGyOneHymdDo()); rbHycRjyAll.add(xinyiBigTableMonth.getGyTwoHymdDo()); rbHycWnndAll.add(xinyiBigTableMonth.getRbShcHyOneMlss()); rbHycWnndAll.add(xinyiBigTableMonth.getRbShcHyTwoMlss()); rbYycRjyAll.add(xinyiBigTableMonth.getRbShcYyOneDo()); rbYycRjyAll.add(xinyiBigTableMonth.getRbShcYyTwoDo()); rbQycRjyAll.add(xinyiBigTableMonth.getRbShcQyOneDo()); rbQycRjyAll.add(xinyiBigTableMonth.getRbShcQyTwoDo()); rbWncjbAll.add(xinyiBigTableMonth.getRbShcHyOneSv()); rbWncjbAll.add(xinyiBigTableMonth.getRbShcHyTwoSv()); rbWntjzsAll.add(xinyiBigTableMonth.getRbShcHyOneSvi()); rbWntjzsAll.add(xinyiBigTableMonth.getRbShcHyTwoSvi()); rbHfxwnndAll.add(xinyiBigTableMonth.getRbShcHyOneMlvss()); rbHfxwnndAll.add(xinyiBigTableMonth.getRbShcHyTwoMlvss()); hyHycxsyAll.add(xinyiBigTableMonth.getHyNo3Hlj1Jqr()); hyHycxsyAll.add(xinyiBigTableMonth.getHyNo3Hlj2Jqr()); hyQyanAll.add(xinyiBigTableMonth.getHyNh31Jqr()); hyQyanAll.add(xinyiBigTableMonth.getHyNh32Jqr()); hyQyckxsyAll.add(xinyiBigTableMonth.getHyNo3Qyc1Jqr()); hyQyckxsyAll.add(xinyiBigTableMonth.getHyNo3Qyc2Jqr()); hyHyzlsyAll.add(xinyiBigTableMonth.getHyTpHl1Jqr()); hyHyzlsyAll.add(xinyiBigTableMonth.getHyTpHl2Jqr()); xinyiBigTableMonth.setGyHycRjyAll(formatList(gyHycRjyAll)); xinyiBigTableMonth.setGyHycRjyZdAll(formatList(gyHycRjyZdAll)); xinyiBigTableMonth.setGyHycWnndAll(formatList(gyHycWnndAll)); xinyiBigTableMonth.setRbHycRjyAll(formatList(rbHycRjyAll)); xinyiBigTableMonth.setRbHycWnndAll(formatList(rbHycWnndAll)); xinyiBigTableMonth.setRbYycRjyAll(formatList(rbYycRjyAll)); xinyiBigTableMonth.setRbQycRjyAll(formatList(rbQycRjyAll)); xinyiBigTableMonth.setRbWncjbAll(formatList(rbWncjbAll)); xinyiBigTableMonth.setRbWntjzsAll(formatList(rbWntjzsAll)); xinyiBigTableMonth.setRbHfxwnndAll(formatList(rbHfxwnndAll)); xinyiBigTableMonth.setHyHycxsyAll(formatList(hyHycxsyAll)); xinyiBigTableMonth.setHyQyanAll(formatList(hyQyanAll)); xinyiBigTableMonth.setHyQyckxsyAll(formatList(hyQyckxsyAll)); xinyiBigTableMonth.setHyHyzlsyAll(formatList(hyHyzlsyAll)); this.xinyiBigTableMonthMapper.insertTXinyiBigTableMonth(xinyiBigTableMonth); } } private void predictorSpecial(List tXinyiIndustries6, List tXinyiRobots6) { //数据1 String result1 = getPredictor(predictorArrSpecial[0]); if(StringUtils.isBlank(result1) || "error".equals(result1)){ log.info("预测数据返回结果不符合解析条件,返回结果为{}", result1); return; } JSONObject jsonObject1 = null; try { jsonObject1 = JSON.parseObject(result1); } catch (Exception e) { log.error("[转JSON的时候]预测数据返回结果不符合解析条件,返回结果为{}", result1); return; } String hour1 = jsonObject1.getString("hour"); String pred1 = jsonObject1.getString("pred"); String date1 = jsonObject1.getString("date"); //数据2 String result2 = getPredictor(predictorArrSpecial[1]); if(StringUtils.isBlank(result2) || "error".equals(result2)){ log.info("预测数据返回结果不符合解析条件,返回结果为{}", result2); return; } JSONObject jsonObject2 = null; try { jsonObject2 = JSON.parseObject(result2); } catch (Exception e) { log.error("[转JSON的时候]预测数据返回结果不符合解析条件,返回结果为{}", result2); return; } String pred2 = jsonObject2.getString("pred"); if(StringUtils.isNotBlank(pred1) && pred1.contains(",") && StringUtils.isNotBlank(pred2) && pred2.contains(",")){ String[] split1 = pred1.split(","); String[] split2 = pred2.split(","); if(split1.length != 3 || split2.length != 3){ return; } //构建两个的平均值 String[] splitNew = new String[3]; for (int i = 0; i < split1.length; i++) { splitNew[i] = String.valueOf((Double.parseDouble(split1[i]) + Double.parseDouble(split2[i]))/2/0.8); } // log.info("取完平均值再组装的数组为{}", Arrays.toString(splitNew)); //解析数据 处理报警 调研prompt 保存等 this.handlePredictorWarningSpecialTn(splitNew, hour1, "tn", tXinyiIndustries6, tXinyiRobots6, date1); }else { log.error("预测数据返回结果为{}和{},无法正常解析", result1, result2); } } private void handlePredictorWarningSpecialTn(String[] split, String hour, String task, List tXinyiIndustries6, List tXinyiRobots6, String date) { String[] hours = hour.split(","); //2024年6月23日18:28:55 因为存在跨天问题 所以日期也是逗号拼接的 String[] dates = date.split(","); //2024年6月18日13:41:10 统一格式,否则查询不到结果 //2024年6月18日10:36:49 增加预测记录,预测准确度计算等 TXinyiForecastComparison tXinyiForecastComparison = new TXinyiForecastComparison(); tXinyiForecastComparison.setCategory(task); tXinyiForecastComparison.setForecastTimeOne(dates[0].replaceAll("-", "/") + " " + hours[0]); tXinyiForecastComparison.setForecastTimeTwo(dates[1].replaceAll("-", "/") + " " + hours[1]); tXinyiForecastComparison.setForecastTimeThree(dates[2].replaceAll("-", "/") + " " + hours[2]); tXinyiForecastComparison.setHsForecastOne(new BigDecimal(split[0])); tXinyiForecastComparison.setHsForecastTwo(new BigDecimal(split[1])); tXinyiForecastComparison.setHsForecastThree(new BigDecimal(split[2])); //2024年6月20日14:28:31 增加字段,方便查询 tXinyiForecastComparison.setRemark(DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYYMMDDHH_TS)); //防止工业库挂掉以后持续预测同一数据 //2024年6月20日14:59:23 因为预测bug 判断是否生成过了否则不生成 String remark = tXinyiForecastComparison.getRemark(); String category = tXinyiForecastComparison.getCategory(); TXinyiForecastComparison tXinyiForecastComparisonReq = new TXinyiForecastComparison(); tXinyiForecastComparisonReq.setRemark(remark); tXinyiForecastComparisonReq.setCategory(category); List tXinyiForecastComparisons = this.xinyiForecastComparisonService.selectTXinyiForecastComparisonList(tXinyiForecastComparisonReq); if(!CollectionUtils.isEmpty(tXinyiForecastComparisons)){ log.error("预测已经进行过了,无需重复运行~~~~~~~~~~~@@@@@@@,时间为{}\n类型为{}", remark, category); return; } //获取配置表 List tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null); if(CollectionUtils.isEmpty(tXinyiNormConfigs)) { log.error( "未查询到配置信息"); return; } TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0); //获取最新的工业库的数据 TXinyiIndustry tXinyiIndustry = this.xinyiIndustryMapper.selectTXinyiIndustryNewest(); List chartsDataList = new ArrayList<>(9); //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=3&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); BigDecimal cscodBzz = normConfig.getCscodBzz(); BigDecimal cscodGkz = normConfig.getCscodGkz(); //处理展示数据 for (int i = 0; i < tXinyiIndustries6.size(); i++) { TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11)); //todo 2024年6月25日10:09:24 目前就存放工业库的,后续看是否调整取化验室的 chartBasic.setVal(tXinyiIndustryTemp.getCsTn()); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(new BigDecimal(val)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cscodBzz, split, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_TN_YC.getCode(), hour, normConfig,tXinyiIndustry.getCsTn(), tXinyiIndustry, chartsDataList, date); //插入到数据库 //2024年6月21日14:18:55 如果红杉预测和跃渊预测都有数据再保存 //2024年7月8日15:15:46 逻辑调整:只要红杉的数据不为空就保存 if(Objects.isNull(tXinyiForecastComparison.getHsForecastOne()) || Objects.isNull(tXinyiForecastComparison.getHsForecastTwo()) ||Objects.isNull(tXinyiForecastComparison.getHsForecastThree())){ // || Objects.isNull(tXinyiForecastComparison.getYyForecastOne()) || Objects.isNull(tXinyiForecastComparison.getYyForecastTwo()) || Objects.isNull(tXinyiForecastComparison.getYyForecastThree())){ log.error("保存预测对比数据时,有存在不满足条件的数据,不再保存数据,数据为{}", JSON.toJSONString(tXinyiForecastComparison)); }else this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); } private void handlePredictorWarning(String[] split, String hour, String task, List tXinyiIndustries6, List tXinyiRobots6, String date) { String[] hours = hour.split(","); //2024年6月23日18:28:55 因为存在跨天问题 所以日期也是逗号拼接的 String[] dates = date.split(","); //2024年6月18日13:41:10 统一格式,否则查询不到结果 //2024年6月18日10:36:49 增加预测记录,预测准确度计算等 TXinyiForecastComparison tXinyiForecastComparison = new TXinyiForecastComparison(); //2024年7月11日17:04:11 TP改为zlsy tXinyiForecastComparison.setCategory(BusinessEnum.BigModelForecastEnum.TP.getCode().equalsIgnoreCase(task) ? BusinessEnum.BigModelForecastEnum.ZLSY.getCode() : task); tXinyiForecastComparison.setForecastTimeOne(dates[0].replaceAll("-", "/") + " " + hours[0]); tXinyiForecastComparison.setForecastTimeTwo(dates[1].replaceAll("-", "/") + " " + hours[1]); tXinyiForecastComparison.setForecastTimeThree(dates[2].replaceAll("-", "/") + " " + hours[2]); tXinyiForecastComparison.setHsForecastOne(new BigDecimal(split[0])); tXinyiForecastComparison.setHsForecastTwo(new BigDecimal(split[1])); tXinyiForecastComparison.setHsForecastThree(new BigDecimal(split[2])); //2024年6月20日14:28:31 增加字段,方便查询 tXinyiForecastComparison.setRemark(DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYYMMDDHH_TS)); //防止工业库挂掉以后持续预测同一数据 //2024年6月20日14:59:23 因为预测bug(以工业库为准,假如工业库挂了,获取的全是挂了时间段后的三小时) 判断是否生成过了否则不生成 TXinyiForecastComparison tXinyiForecastComparisonReq = new TXinyiForecastComparison(); //2024年08月20日16:24:56 因为remark存放的是当前时间,也就是每个小时的,所以都是不一样的,修复此bug // tXinyiForecastComparisonReq.setRemark(tXinyiForecastComparison.getRemark()); tXinyiForecastComparisonReq.setCategory(tXinyiForecastComparison.getCategory()); //2024年7月18日15:04:37 如果工业库挂掉以后,不管什么时刻,调用预测返回的未来三小时时间都是一样的,再增加一个查询条件 tXinyiForecastComparisonReq.setForecastTimeOne(tXinyiForecastComparison.getForecastTimeOne());//一个时刻就可以了 没必要再比较第二和第三时刻了。 List tXinyiForecastComparisons = this.xinyiForecastComparisonService.selectTXinyiForecastComparisonList(tXinyiForecastComparisonReq); if(!CollectionUtils.isEmpty(tXinyiForecastComparisons)){ log.error("预测已经进行过了,无需重复运行~~~~~~~~~~~@@@@@@@,要保存的预测数据为{}", JSON.toJSONString(tXinyiForecastComparison)); return; } //获取配置表 List tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null); if(CollectionUtils.isEmpty(tXinyiNormConfigs)) { log.error( "未查询到配置信息"); return; } TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0); //获取最新的工业库的数据 // TXinyiIndustry tXinyiIndustry = this.xinyiIndustryMapper.selectTXinyiIndustryNewest(); //2024年7月18日10:29:44 因为获取了最新的六条数据,所以无需再查询最新的数据了 TXinyiIndustry tXinyiIndustry = tXinyiIndustries6.get(0); TXinyiRobot tXinyiRobot = tXinyiRobots6.get(0); List chartsDataList = new ArrayList<>(9); if(BusinessEnum.BigModelForecastEnum.COD.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=2&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); BigDecimal cscodBzz = normConfig.getCscodBzz(); BigDecimal cscodGkz = normConfig.getCscodGkz(); //处理展示数据 for (int i = 0; i < tXinyiIndustries6.size(); i++) { TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsCod(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cscodBzz, split, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_COD_YC.getCode(), hour, normConfig, tXinyiIndustry.getCsCod(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.SS.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=5&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); BigDecimal csSSBzz = normConfig.getCsssBzz(); BigDecimal csssGkz = normConfig.getCsssGkz(); //处理展示数据 for (int i = 0; i < tXinyiIndustries6.size(); i++) { TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsSs(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(csSSBzz, split, csssGkz, BusinessEnum.WarningCategoryEnum.CS_SS_YC.getCode(), hour, normConfig, tXinyiIndustry.getCsSs(), tXinyiIndustry, chartsDataList, date); }/*else if(BusinessEnum.BigModelForecastEnum.TN.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=3&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); BigDecimal cszzBzz = normConfig.getCszzBzz(); BigDecimal cszzGkz = normConfig.getCszzGkz(); //处理展示数据 for (int i = 0; i < tXinyiIndustries6.size(); i++) { TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsTn(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_TN_YC.getCode(), hour, normConfig,tXinyiIndustry.getCsCod(), tXinyiIndustry, chartsDataList, date); }*/else if(BusinessEnum.BigModelForecastEnum.TP.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=1&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); BigDecimal cszlBzz = normConfig.getCszlBzz(); BigDecimal cszlGkz = normConfig.getCszlGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getTpRccJqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cszlBzz, split, cszlGkz, CS_TP_YC.getCode(), hour, normConfig, tXinyiRobot.getTpRccJqr(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.NH3.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=4&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); BigDecimal csadBzz = normConfig.getCsadBzz(); BigDecimal csadGkz = normConfig.getCsadGkz(); //处理展示数据 for (int i = 0; i < tXinyiIndustries6.size(); i++) { TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsNh3(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(csadBzz, split, csadGkz, BusinessEnum.WarningCategoryEnum.CS_AD_YC.getCode(), hour, normConfig, tXinyiIndustry.getCsNh3(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.XSY1.getCode().equals(task)){ //2024年6月21日14:57:02 红杉的出水总氮预测改成 不用工业库的,用化验科的两个xsy 相关指标 //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=6&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK); BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/ //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警 BigDecimal cszzBzz = normConfig.getCszzBzz(); BigDecimal cszzGkz = normConfig.getCszzGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Hlj1Jqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_XSY_1_YC.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj1Jqr(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.XSY2.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); } // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK); BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/ //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警 BigDecimal cszzBzz = normConfig.getCszzBzz(); BigDecimal cszzGkz = normConfig.getCszzGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Hlj2Jqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_XSY_2_YC.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.QYXSY1.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 /*try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); }*/ // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK); BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/ //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警 BigDecimal cszzBzz = normConfig.getCszzBzz(); BigDecimal cszzGkz = normConfig.getCszzGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Qyc1Jqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.QYCXSY_1.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.QYXSY2.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 /*try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); }*/ // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK); BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/ //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警 BigDecimal cszzBzz = normConfig.getCszzBzz(); BigDecimal cszzGkz = normConfig.getCszzGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Qyc2Jqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.QYCXSY_2.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.QYNH31.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 /*try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); }*/ // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK); BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/ //2024年09月08日11:21:25 采用出水氨氮的标准值和管控值 BigDecimal csadBzz = normConfig.getCsadBzz(); BigDecimal csadGkz = normConfig.getCsadGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNh31Jqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(csadBzz, split, csadGkz, BusinessEnum.WarningCategoryEnum.QYAD_1.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date); }else if(BusinessEnum.BigModelForecastEnum.QYNH32.getCode().equals(task)){ //同时调用跃渊的预测接口 保存记录值 /*try { String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000); if(!StringUtils.isBlank(result)){ JSONArray array = JSON.parseArray(result); tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6)); tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7)); tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8)); } } catch (Exception e) { log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage()); }*/ // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK); BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/ //2024年09月08日11:21:25 采用出水氨氮的标准值和管控值 BigDecimal csadBzz = normConfig.getCsadBzz(); BigDecimal csadGkz = normConfig.getCsadGkz(); //处理展示数据 for (int i = 0; i < tXinyiRobots6.size(); i++) { TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i); ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11)); chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNh32Jqr(), INT_2)); chartsDataList.add(chartBasic); } for (int i = 0; i < split.length; i++) { String val = split[i]; ChartBasic chartBasic = new ChartBasic(); chartBasic.setTime(hours[i]); chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2)); chartsDataList.add(chartBasic); } handleXinYiWarningsYC(csadBzz, split, csadGkz, BusinessEnum.WarningCategoryEnum.QYAD_2.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date); }else { log.error("暂未支持的类型{}", task); } //插入到数据库 //2024年6月21日14:18:55 如果红杉预测和跃渊预测都有数据再保存 //2024年7月8日15:15:46 逻辑调整:只要红杉的数据不为空就保存 if(Objects.isNull(tXinyiForecastComparison.getHsForecastOne()) || Objects.isNull(tXinyiForecastComparison.getHsForecastTwo()) ||Objects.isNull(tXinyiForecastComparison.getHsForecastThree())){ // || Objects.isNull(tXinyiForecastComparison.getYyForecastOne()) || Objects.isNull(tXinyiForecastComparison.getYyForecastTwo()) || Objects.isNull(tXinyiForecastComparison.getYyForecastThree())){ log.error("保存预测对比数据时,有存在不满足条件的数据,不再保存数据,数据为{}", JSON.toJSONString(tXinyiForecastComparison)); }else this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison); } public void handleXinYiWarningsYC(BigDecimal csBzz, String[] split, BigDecimal csGkz, String category, String hour, TXinyiNormConfig normConfig, BigDecimal currentVal, TXinyiIndustry tXinyiIndustry, List chartsDataList, String date) { BigDecimal multiply = csBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE)); TXinyiWarningRecord tXinyiWarningRecord = null; String yjHour = null; for (int i = 0, splitLength = split.length; i < splitLength; i++) { String forecast = split[i]; /*BigDecimal forecastVal = new BigDecimal("10000");*/ BigDecimal forecastVal = new BigDecimal(forecast); tXinyiWarningRecord = new TXinyiWarningRecord(); /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/ tXinyiWarningRecord.setStatus(0); tXinyiWarningRecord.setType(2); tXinyiWarningRecord.setCategory(category); tXinyiWarningRecord.setWarningVal(currentVal);//当前值 tXinyiWarningRecord.setForecastVal(forecastVal); tXinyiWarningRecord.setDesignVal(csBzz); tXinyiWarningRecord.setControlVal(csGkz); tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE); tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate()); tXinyiWarningRecord.setRemark(TWO_YC_WARNING.getCode()); //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口 if (Objects.isNull(forecastVal)) { tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING_YC); tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE); } else if (forecastVal.compareTo(multiply) > 0) {//一级 tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING_YC); tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE); } else if (forecastVal.compareTo(csBzz) >= 0 && forecastVal.compareTo(multiply) <= 0) {//二级 tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING_YC); tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO); } else if (!Objects.isNull(csGkz) && forecastVal.compareTo(csGkz) > 0) { tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING_YC); tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE); } else { tXinyiWarningRecord = null;//这种的无需处理 } if (!Objects.isNull(tXinyiWarningRecord)) { log.info("预测报警中出现了超标的情况,循环可以退出了"); yjHour = hour.split(",")[i]; date = date.split(",")[i];//2024年6月23日18:34:49 日期也是多个了 //预计超标时间 不是当前值,是预测超标的时间。 try { tXinyiWarningRecord.setTime(DateUtils.parseDate(date + " " + yjHour, DateUtils.YYYY_MM_DD_HH)); } catch (ParseException e) { log.error("处理语句的预计超标时间是,异常,异常信息为{}", e.getMessage()); } break; } } //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭) List tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(2).category(category).warningStatus(0).build()); if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息 if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){ log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords)); for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) { xinyiWarningRecord.setStatus(2); Date nowDate = DateUtils.getNowDate(); xinyiWarningRecord.setOffTime(nowDate); xinyiWarningRecord.setUpdateTime(nowDate); xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE); this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord); } } }else{//有告警信息 //2024年6月27日10:45:49 列表的预警时间和showval里的预警时间保持一致(用同一个,否则可能有一分钟左右的误差) Date nowDate = DateUtils.getNowDate(); if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录 //2024年7月15日11:06:16 因为只有一个告警记录,但是如果一直报警,现在报警时间取的是更新时间,兼容第一次报警处理 tXinyiWarningRecord.setUpdateTime(nowDate); //保存到数据库中 this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord); if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){ //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的 this.addChatRecordByDeviceErr(tXinyiWarningRecord, tXinyiIndustry, normConfig); }else { //继续调用大模型prompt try { this.askBigModelForYC(tXinyiWarningRecord, tXinyiIndustry, normConfig, chartsDataList, date, yjHour, nowDate); } catch (Exception e) { log.error("预测完成调用大模型获取解决方案时异常,异常信息为{}", JSON.toJSONString(e)); } } }else{ log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category); for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的 if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){ //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的 this.addChatRecordByDeviceErr(tXinyiWarningRecord, tXinyiIndustry, normConfig); }else { //2024年6月25日11:32:13 预测的相对特殊:因为前端不展示次数,所以这里把 超标时间+现在值+预测值更新一下 xinyiWarningRecord.setForecastVal(tXinyiWarningRecord.getForecastVal()); xinyiWarningRecord.setWarningVal(currentVal); xinyiWarningRecord.setTime(tXinyiWarningRecord.getTime()); xinyiWarningRecord.setUpdateTime(nowDate); xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE); //2024年7月15日11:07:33 报警的级别也要重新计算并更新 xinyiWarningRecord.setLevel(tXinyiWarningRecord.getLevel()); //2024年7月31日09:20:47 报警的原因(超标还是超管控也需要更新) xinyiWarningRecord.setReason(tXinyiWarningRecord.getReason()); //更新数据库 this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord); //继续调用决策 try { this.askBigModelForYC(xinyiWarningRecord, tXinyiIndustry, normConfig, chartsDataList, date, yjHour, nowDate); } catch (Exception e) { log.error("预测完成调用大模型获取解决方案时异常,异常信息为{}", JSON.toJSONString(e)); } } } } } } private void askBigModelForYC(TXinyiWarningRecord xinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, List chartsDataList, String date, String yjHour, Date nowDate) { log.info("预测进入了后台接口调⽤⼤模型获取问答结果处理(预测)"); StringBuilder sb = new StringBuilder(); String sessionId = IdUtils.simpleUUID(); ChatReq chatReq = new ChatReq(); // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型 String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址 int counts = 1;//默认是第一次 //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录 List historyDates = new ArrayList<>(); //构建问题(替换提示词中的占位符) /*String shWarningPrompt = YC_WARNING_PROMPT; shWarningPrompt =shWarningPrompt.replace("#{0}", xinyiWarningRecord.getReason()); shWarningPrompt =shWarningPrompt.replace("#{1}", String.valueOf(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getDesignVal(), INT_2))); shWarningPrompt =shWarningPrompt.replace("#{2}", String.valueOf(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getWarningVal(), INT_2))); shWarningPrompt =shWarningPrompt.replace("#{3}", String.valueOf(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getForecastVal(), INT_2)));*/ StringBuilder prompt = new StringBuilder(YC_WARNING_PROMPT_1); if(CS_TP_YC.getCode().equalsIgnoreCase(xinyiWarningRecord.getCategory())){ log.info("进入了需要特殊处理的预警:二沉池正磷酸盐"); prompt.append(xinyiWarningRecord.getReason()); prompt.append(YC_WARNING_PROMPT_2).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getDesignVal(), INT_2)); prompt.append(YC_WARNING_PROMPT_3).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getWarningVal(), INT_2)); prompt.append(YC_WARNING_PROMPT_4).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getForecastVal(), INT_2)); prompt.append(YC_WARNING_PROMPT_6); //查询最近7天的二沉池正磷酸盐数据 List> list = this.xinyiRobotMapper.selectAvg7Datas(); if(!CollectionUtils.isEmpty(list)){ for (int i = 0; i < list.size(); i++) { HashMap map = list.get(i); prompt.append(map.get("DATE")).append(":").append(DecimalUtils.getAbsAndScale(new BigDecimal(map.get("VAL").toString()), INT_2)).append(YC_WARNING_PROMPT_UNIT_MG_L); if(i < list.size() -1)//不是最后一条 prompt.append(","); } } prompt.append(YC_WARNING_PROMPT_7); //查询最近7天的进水总磷数据 List tXinyiDailies = this.xinyiDailyMapper.selectNRecords(7); if(!CollectionUtils.isEmpty(tXinyiDailies)){ for (int i = 0; i < tXinyiDailies.size(); i++) { TXinyiDaily tXinyiDaily = tXinyiDailies.get(i); prompt.append(tXinyiDaily.getTestDate()).append(":").append(DecimalUtils.getAbsAndScale(tXinyiDaily.getJsTp(), INT_2)).append(YC_WARNING_PROMPT_UNIT_MG_L); if(i < tXinyiDailies.size() -1)//不是最后一条 prompt.append(","); } } prompt.append(YC_WARNING_PROMPT_8); }else{// prompt.append(xinyiWarningRecord.getReason()); prompt.append(YC_WARNING_PROMPT_2).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getDesignVal(), INT_2)); prompt.append(YC_WARNING_PROMPT_3).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getWarningVal(), INT_2)); prompt.append(YC_WARNING_PROMPT_4).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getForecastVal(), INT_2)); prompt.append(YC_WARNING_PROMPT_5); } historyDates.add(prompt.toString()); // 获取输出流 ManagedChannel channel = null; try { channel = ManagedChannelBuilder.forAddress(bigModelConfig.getIp(), bigModelConfig.getPort()) .usePlaintext() .build(); InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel); // String dataJson = "{\"bot_id\":\"721\",\"exp_id\":\"721\",\"session_id\":\"" + sessionId + "\",\"use_rag\":\"true\",\"prompt\":\"你是⼀个资深⽔务领域专家,能回答各种⽔务相关问题\",\"history_dia\":" + JSON.toJSONString(historyDates) + ",\"generate_args\":{\"max_new_tokens\":2048,\"max_length\":4096,\"num_beams\":1,\"do_sample\":true,\"top_p\":0.7,\"temperature\":0.95},\"extra\":{ \"ip_address\": \"" + ipAddr + "\" },\"strengthen\":" + (true) + "}"; //2024年6月27日10:51:47 优化:不再手动拼接JSON字符串 String dataJson = buildBigModelReqForChat(sessionId, historyDates); // log.info("请求大模型的问答参数为{}", dataJson); PredictionsRequest request = PredictionsRequest.newBuilder() .setModelName("slibra_bot") .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理 .putInput("data", ByteString.copyFrom(dataJson, "utf-8")) .buildPartial(); Iterator predictions = stub.streamPredictions(request); //将结果记录到问答表 while (predictions.hasNext()) { String responseStr = predictions.next().getPrediction().toStringUtf8(); // log.info("大模型问答返回的原始结果为{}", responseStr); responseStr = JSON.parseObject(responseStr).getString("message"); if("complete".equals(responseStr)){ log.info("结尾语句并且是非JSON,无需处理"); }else{ sb.append(responseStr); } } //将问答更新到数据库中 chatReq.setSessionId(sessionId); chatReq.setType(1);//0问答 1决策 2本地 3仿真预测 预测报警这里也算是决策 仿真预测是在调用仿真那里使用的 chatReq.setModule(3);//0专家问答 1智能工单 2智能体助手 3告警 4简报 String showVal = this.buildShowValueWithCharts(xinyiWarningRecord, tXinyiIndustry, normConfig, chartsDataList, date, yjHour, nowDate); chatReq.setShowVal(showVal); chatReq.setQuestion(prompt.toString()); chatReq.setAnswer(sb.toString()); chatReq.setWarningId(String.valueOf(xinyiWarningRecord.getId())); chatReq.setCounts(counts);//问答次数 chatReq.setUserId(WARNING_DEFAULT_CREATE); chatReq.setCreateBy(WARNING_DEFAULT_CREATE); chatReq.setCreateTime(DateUtils.getNowDate()); this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq); } catch (IOException e) { throw new RuntimeException(e); } finally { // 关闭输出流 channel.shutdown(); } } private String buildBigModelReqForChat(String sessionId, List historyDates) { ChatRequest chatRequest = new ChatRequest(); chatRequest.setSessionId(sessionId); chatRequest.setHistoryDia(historyDates); //2024年7月5日13:24:10 temperature做区分 GenerateArgs generateArgs = new GenerateArgs(); generateArgs.setTemperature(bigModelConfig.getTemperature()); chatRequest.setGenerateArgs(generateArgs); Map extra = new HashMap<>(); // extra.put("ip_address", IpUtils.getIpAddr()); extra.put("ip_address", null); chatRequest.setExtra(extra); chatRequest.setStrengthen(true); return JSON.toJSONString(chatRequest); } public String getPredictor(String type){ // 获取输出流 ManagedChannel channel = null; try { channel = ManagedChannelBuilder.forAddress(bigModelConfig.getIp(), bigModelConfig.getPort()) .usePlaintext() .build(); InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel); // String dataJson = "{\"bot_id\":\"b00001\",\"exp_id\":\"721\",\"norm\":\"" + type + "\",\"session_id\":\" " + IdUtils.simpleUUID() + " \",\"extra\":{}}"; //2024年6月27日13:23:25 优化:改成非拼接JSON字符串 String dataJson = buildBigModelReqForPredictor(type); // log.info("请求大模型的预测的参数为{}", dataJson); PredictionsRequest request = PredictionsRequest.newBuilder() .setModelName("slibra_bot") .putInput("method", ByteString.copyFrom("predictor", "utf-8"))//推理 .putInput("data", ByteString.copyFrom(dataJson, "utf-8")) .buildPartial(); /*Iterator predictions = stub.streamPredictions(request); //将结果记录到问答表 String responseStr = predictions.next().getPrediction().toStringUtf8(); log.info("大模型的预测的返回结果为{}", responseStr);*/ //2024年6月21日11:46:36 改成非流式输出 PredictionResponse predictions = stub.predictions(request); String responseStr = predictions.getPrediction().toStringUtf8(); log.info("调用TFT预测大模型返回的原始结果为{}", responseStr); // return JSON.parseObject(responseStr).getString("pred"); return responseStr; } catch (IOException e) { throw new RuntimeException(e); } finally { assert channel != null; channel.shutdown(); } } private static String buildBigModelReqForPredictor(String type) { PredictorRequest predictorRequest = new PredictorRequest(); predictorRequest.setNorm(type); predictorRequest.setSessionId(IdUtils.simpleUUID()); return JSON.toJSONString(predictorRequest); } /** * * 2022/01/01 转成2022年01月01日 数据 * @param testDate * @return */ private String formateDateStr(String testDate) { if(StringUtils.isBlank(testDate)) return ""; if(!testDate.contains("/")) return testDate; String[] split = testDate.split("/"); return split[0] + "年" + split[1] + "月" + split[2] + "日"; } private void askBigModel(String question, String showVal) { log.info("进入了后台接口调⽤⼤模型获取问答结果处理"); StringBuilder sb = new StringBuilder(); String sessionId = IdUtils.simpleUUID(); ChatReq chatReq = new ChatReq(); // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型 String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址 int counts = 1;//默认是第一次 //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录 List historyDates = new ArrayList<>(); historyDates.add(question); // 获取输出流 ManagedChannel channel = null; try { channel = ManagedChannelBuilder.forAddress(bigModelConfig.getIp(), bigModelConfig.getPort()) .usePlaintext() .build(); InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel); // String dataJson = "{\"bot_id\":\"721\",\"exp_id\":\"721\",\"session_id\":\"" + sessionId + "\",\"use_rag\":\"true\",\"prompt\":\"你是⼀个资深⽔务领域专家,能回答各种⽔务相关问题\",\"history_dia\":" + JSON.toJSONString(historyDates) + ",\"generate_args\":{\"max_new_tokens\":2048,\"max_length\":4096,\"num_beams\":1,\"do_sample\":true,\"top_p\":0.7,\"temperature\":0.95},\"extra\":{ \"ip_address\": \"" + ipAddr + "\" },\"strengthen\":" + (true) + "}"; //2024年6月27日10:51:47 优化:不再手动拼接JSON字符串 String dataJson = buildBigModelReqForChat(sessionId, historyDates); // log.info("请求大模型的问答参数为{}", dataJson); PredictionsRequest request = PredictionsRequest.newBuilder() .setModelName("slibra_bot") .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理 .putInput("data", ByteString.copyFrom(dataJson, "utf-8")) .buildPartial(); Iterator predictions = stub.streamPredictions(request); //将结果记录到问答表 while (predictions.hasNext()) { String responseStr = predictions.next().getPrediction().toStringUtf8(); // log.info("大模型问答返回的原始结果为{}", responseStr); responseStr = JSON.parseObject(responseStr).getString("message"); if("complete".equals(responseStr)){ System.out.println("结尾语句并且是非JSON,无需处理"); //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端 /*outputStream.write(responseStr.getBytes()); outputStream.flush();*/ }else{ sb.append(responseStr); } } //将问答更新到数据库中 chatReq.setSessionId(sessionId); chatReq.setType(2);//0问答 1决策 2本地 3仿真预测 chatReq.setModule(4);//0专家问答 1智能工单 2智能体助手 3告警 4简报 chatReq.setShowVal(showVal); chatReq.setQuestion(question); chatReq.setAnswer(sb.toString()); chatReq.setCounts(counts);//问答次数 chatReq.setUserId(WARNING_DEFAULT_CREATE); chatReq.setCreateBy(WARNING_DEFAULT_CREATE); chatReq.setCreateTime(DateUtils.getNowDate()); this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq); } catch (IOException e) { throw new RuntimeException(e); } finally { // 关闭输出流 channel.shutdown(); } } /** * @param dailyTwoRecords * @return */ @Deprecated private String buildShortReportQueryData(List dailyTwoRecords) { //查询配置信息 List tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null); if(CollectionUtils.isEmpty(tXinyiNormConfigs)) return null; TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0); //获取数据 TXinyiDaily yesterdayData = dailyTwoRecords.get(0); TXinyiDaily beforeYesterdayData = dailyTwoRecords.get(1); String originStr = JIAN_BAO_PROMPT; String yesterdayStr = yesterdayData.getTestDate().substring(5).replace("/", "月") + "日"; String beforeYesterdayStr = beforeYesterdayData.getTestDate().substring(5).replace("/", "月") + "日"; originStr = originStr.replace("#{0}", yesterdayStr); originStr = originStr.replace("#{1}", beforeYesterdayStr); originStr = originStr.replace("#{2}", String.valueOf(yesterdayData.getJsCod())); originStr = originStr.replace("#{3}", String.valueOf(yesterdayData.getJsTn())); originStr = originStr.replace("#{4}", String.valueOf(yesterdayData.getJsTp())); originStr = originStr.replace("#{5}", String.valueOf(yesterdayData.getJsNh3())); originStr = originStr.replace("#{6}", String.valueOf(yesterdayData.getJsSs())); originStr = originStr.replace("#{7}", String.valueOf(yesterdayData.getJSL())); originStr = originStr.replace("#{8}", String.valueOf(yesterdayData.getCsCod())); originStr = originStr.replace("#{9}", String.valueOf(yesterdayData.getCsTn())); originStr = originStr.replace("#{10}", String.valueOf(yesterdayData.getCsTp())); originStr = originStr.replace("#{11}", String.valueOf(yesterdayData.getCsNh3())); originStr = originStr.replace("#{12}", String.valueOf(yesterdayData.getCsSs())); originStr = originStr.replace("#{13}", String.valueOf(yesterdayData.getCSL())); originStr = originStr.replace("#{14}", String.valueOf(beforeYesterdayData.getJsCod())); originStr = originStr.replace("#{15}", String.valueOf(beforeYesterdayData.getJsTn())); originStr = originStr.replace("#{16}", String.valueOf(beforeYesterdayData.getJsTp())); originStr = originStr.replace("#{17}", String.valueOf(beforeYesterdayData.getJsNh3())); originStr = originStr.replace("#{18}", String.valueOf(beforeYesterdayData.getJsSs())); originStr = originStr.replace("#{19}", String.valueOf(beforeYesterdayData.getJSL())); originStr = originStr.replace("#{20}", String.valueOf(beforeYesterdayData.getCsCod())); originStr = originStr.replace("#{21}", String.valueOf(beforeYesterdayData.getCsTn())); originStr = originStr.replace("#{22}", String.valueOf(beforeYesterdayData.getCsTp())); originStr = originStr.replace("#{23}", String.valueOf(beforeYesterdayData.getCsNh3())); originStr = originStr.replace("#{24}", String.valueOf(beforeYesterdayData.getCsSs())); originStr = originStr.replace("#{25}", String.valueOf(beforeYesterdayData.getCSL())); originStr = originStr.replace("#{26}", String.valueOf(normConfig.getJscodSjz())); originStr = originStr.replace("#{27}", String.valueOf(normConfig.getJszdSjz())); originStr = originStr.replace("#{28}", String.valueOf(normConfig.getJszlSjz())); originStr = originStr.replace("#{29}", String.valueOf(normConfig.getJsadSjz())); originStr = originStr.replace("#{30}", String.valueOf(normConfig.getJsssSjz())); originStr = originStr.replace("#{31}", String.valueOf(normConfig.getCscodBzz())); originStr = originStr.replace("#{32}", String.valueOf(normConfig.getCszzBzz())); originStr = originStr.replace("#{33}", String.valueOf(normConfig.getCszlBzz())); originStr = originStr.replace("#{34}", String.valueOf(normConfig.getCsadBzz())); originStr = originStr.replace("#{35}", String.valueOf(normConfig.getCsssBzz())); return originStr; } //2024年6月23日19:58:21 简报生成的prompt调整。 private String buildShortReportQueryDataNew(List dailyTwoRecords) { //查询配置信息 List tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null); if(CollectionUtils.isEmpty(tXinyiNormConfigs)) return null; TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0); //获取数据 TXinyiDaily yesterdayData = dailyTwoRecords.get(0); // String originStr = SHORT_REPORT_BEGIN.replace("#{0}", yesterdayData.getTestDate()); StringBuilder sb = new StringBuilder(SHORT_REPORT_BEGIN_1); sb.append(yesterdayData.getTestDate()); sb.append(SHORT_REPORT_BEGIN_2); for (TXinyiDaily dailyTwoRecord : dailyTwoRecords) { sb.append(formateDateStr(dailyTwoRecord.getTestDate())).append("进出水质数据:\n"); sb.append("进水:\n"); sb.append("进水COD").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsCod(), 2)).append("mg/L、"); sb.append("进水总氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsTn(), 2)).append("mg/L、"); sb.append("进水总磷").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsTp(), 2)).append("mg/L、"); sb.append("进水氨氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsNh3(), 2)).append("mg/L、"); sb.append("进水SS").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsSs(), 2)).append("mg/L、"); sb.append("进水水量").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJSL(), 2)).append("m³/d").append(";\n"); sb.append("出水:\n"); sb.append("出水COD").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsCod(), 2)).append("mg/L、"); sb.append("出水总氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsTn(), 2)).append("mg/L、"); sb.append("出水总磷").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsTp(), 2)).append("mg/L、"); sb.append("出水氨氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsNh3(), 2)).append("mg/L、"); sb.append("出水SS").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsSs(), 2)).append("mg/L、"); sb.append("出水水量").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCSL(), 2)).append("m³/d").append("。\n"); } sb.append(SHORT_REPORT_END); sb.append("进水COD:").append(DecimalUtils.getAbsAndScale(normConfig.getJscodSjz(), 2)).append("mg/L、"); sb.append("进水总氮:").append(DecimalUtils.getAbsAndScale(normConfig.getJszdSjz(), 2)).append("mg/L、"); sb.append("进水总磷:").append(DecimalUtils.getAbsAndScale(normConfig.getJszlSjz(), 2)).append("mg/L、"); sb.append("进水氨氮:").append(DecimalUtils.getAbsAndScale(normConfig.getJsadSjz(), 2)).append("mg/L、"); sb.append("进水SS:").append(DecimalUtils.getAbsAndScale(normConfig.getJsssSjz(), 2)).append("mg/L、"); sb.append("出水COD:").append(DecimalUtils.getAbsAndScale(normConfig.getCscodBzz(), 2)).append("mg/L、"); sb.append("出水总氮:").append(DecimalUtils.getAbsAndScale(normConfig.getCszzBzz(), 2)).append("mg/L、"); sb.append("出水总磷:").append(DecimalUtils.getAbsAndScale(normConfig.getCszlBzz(), 2)).append("mg/L、"); sb.append("出水氨氮:").append(DecimalUtils.getAbsAndScale(normConfig.getCsadBzz(), 2)).append("mg/L、"); sb.append("出水SS:").append(DecimalUtils.getAbsAndScale(normConfig.getCsssBzz(), 2)).append("mg/L").append("。"); return sb.toString(); } public static String handleDate(String str){ StringBuilder sb = new StringBuilder(); if(str.contains(" ")){//包含空格 就是年月日时分秒了 String[] split = str.split(" "); addBeforeZero(sb, split[0], "/"); sb.append(" "); addBeforeZero(sb, split[1], ":"); }else{ if(str.contains("/")){//年月日 addBeforeZero(sb, str, "/"); }else if(str.contains(":")){//时分秒 addBeforeZero(sb, str, ":"); }else { sb.append(str); } } return sb.toString(); } public static StringBuilder addBeforeZero(StringBuilder sb, String str, String tag){ String[] split = str.split(tag); int length = split.length; for (int i = 0; i < length; i++) { String value = split[i]; Integer intValue = Integer.parseInt(value); if(intValue < 10 && value.length() == 1){////防止有正确的情况 额外再补充字符串 sb.append(0).append(value); }else{ sb.append(value); } if(i < length-1){ sb.append(tag); } } return sb; } public static void main(String[] args) throws ParseException, InterruptedException { /*LocalDateTime endTime = LocalDateTime.now(); System.out.println("endTime = " + endTime); endTime = endTime.plusMinutes(60); System.out.println("endTime = " + endTime);*/ /*String str = "2024/04/15 09:55"; System.out.println(str); System.out.println(str.substring(0,10)); System.out.println(str.substring(0,13));*/ /*String str = "2024/04/18 08:00"; str = str + ":00"; System.out.println(str); LocalDateTime startTime = LocalDateTime.parse(str.replaceAll("/", "-").replace(" ", "T")); System.out.println(startTime.plusMinutes(1L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));*/ /*ArrayList objects = new ArrayList<>(); objects.add(1); objects.add(2); objects.add(3); System.out.println(objects); objects.clear(); System.out.println(objects); // test(); Date date = new Date(); System.out.println(DateUtils.differentHoursByMillisecond(date, date)); HashMap map = new HashMap<>(); map.put("a", null); map.put("b", "ab"); map.put("c", ""); map.put("d", '1'); System.out.println(JSON.toJSONString(map, JSONWriter.Feature.WriteNulls)); TXinyiIndustry tXinyiIndustry = new TXinyiIndustry(); System.out.println(JSON.toJSONString(tXinyiIndustry, JSONWriter.Feature.WriteNulls));*/ /*String s = "2022/01/01".substring(5).replace("/", "月") + "日"; System.out.println("s = " + s); // System.out.println(new BigDecimal("1").compareTo(null));//空指针 要判断 System.out.println("2022/01/01 10".substring(11)); String date = DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH); System.out.println("date = " + date); System.out.println(HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=2&time=" + date, INT_10));*/ System.out.println("2024-06-18 14".replaceAll("-", "/")); String[] splitNew = new String[3]; splitNew[0] = "0"; splitNew[1] = "1"; splitNew[2] = "2"; System.out.println(Arrays.toString(splitNew)); System.out.println(DateUtils.parseDate("2024-06-25 10", DateUtils.YYYY_MM_DD_HH)); String yesterdayStr = LocalDateTimeUtil.getCurrentDate().plusDays(-1).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS));//昨天 System.out.println(yesterdayStr); TimeUnit.MILLISECONDS.sleep(INT_10000); System.out.println("2024/07/07 12".substring(0, 7)); } //测试工业库 没小时保存一条记录是否可行 public static void test() { // 每个小时的时间格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime startTime = LocalDateTime.parse("2024-05-18T00:00:00"); LocalDateTime endTime = LocalDateTime.now(); // 循环按小时分割 LocalDateTime currentHour = startTime; //最终获取的数据 Map needMap = new LinkedHashMap<>(); while (currentHour.isBefore(endTime)) { String begin = currentHour.format(formatter); String end = currentHour.plusMinutes(5).format(formatter); // 输出当前小时的起始时间和结束时间 System.out.println("起始时间:" + begin); System.out.println("结束时间:" + end); // 当前小时加一小时,作为下一个小时的起始时间 currentHour = currentHour.plusMinutes(5); //每个小时查询一次数据 String url = "http://10.0.0.27:4568/api/v1/khquerydata"; HashMap req = new HashMap<>(); req.put("tagNames", queryTags); req.put("startTime", begin); req.put("endTime", end); req.put("recordNumbers", 100000); String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body(); // System.out.println("body = " + body); List> list = new ArrayList<>(); //行转列数据处理 for (String queryTag : queryTags) { JSONArray array = JSON.parseObject(body).getJSONArray(queryTag); //特殊数据处理一 if(Objects.isNull(array) || array.isEmpty()){ System.out.println(queryTag + "查询到了空的数据,跳过本次循环"); continue; } int size = array.size(); //特殊数据处理二 if("0".equals(array.get(1) + "")){ System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0"); continue; } //结合至少62个数据才满足条件(有可能获取不到) /*if(size < 62){ System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环"); continue; }*/ //存放的数据集 //利用map去重 HashMap map = new LinkedHashMap<>(); for (int i = 2; i < size; i++) { // System.out.println(i + "" + array.get(i)); JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i))); //处理为空或者为0的数据 Object timeStampValue = oneRecord.get(2); if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + "")) continue; BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + ""); long timestamp = (long) timeStampValue; String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS); map.put(format, queryTag + "-" + value); } list.add(map); } Set recordTimeSet = new HashSet<>(); Map recordMap = new HashMap<>(); for (int i = 0; i < list.size(); i++) { HashMap map = list.get(i); int finalJ = i; map.forEach((k, v) ->{ TXinyiIndustry industry = null; if(!recordTimeSet.contains(k)){//第一次 industry = new TXinyiIndustry(); recordTimeSet.add(k); recordMap.put(k, industry); }else{ industry = recordMap.get(k); } industry.setTestTime(k + ":00"); //2024年4月15日11:19:52 额外增加2个字段 industry.setTestDate(k.substring(0,10)); industry.setTestHour(k.substring(0,13)); //解析值 String[] split = v.split("-"); String type = split[0]; BigDecimal value = new BigDecimal(split[1]); if ("信义污水厂JS_COD_Value".equals(type)) { industry.setJsCod(value); } else if ("信义污水厂JS_PH_Value".equals(type)) { industry.setJsPh(value); } else if ("信义污水厂JS_SS_Value".equals(type)) { industry.setJsSs(value); } else if ("信义污水厂JS_ZL_Value".equals(type)) { industry.setJsTp(value); } else if ("信义污水厂JS_ZA_Value".equals(type)) { industry.setJsTn(value); } else if ("信义污水厂JS_AD_Value".equals(type)) { industry.setJsNh3(value); } else if ("信义污水厂JS_T_Value".equals(type)) { industry.setJsSwPh(value); } else if ("信义污水厂进水泵房液位".equals(type)) { industry.setJsBfyw(value); } else if ("信义污水厂出水瞬时流量".equals(type)) { industry.setCsSlqc(value); } else if ("信义污水厂升级出水COD".equals(type)) { industry.setCsCod(value); } else if ("信义污水厂升级出水PH".equals(type)) { industry.setCsPh(value); } else if ("信义污水厂升级出水SS".equals(type)) { industry.setCsSs(value); } else if ("信义污水厂升级出水TN".equals(type)) { industry.setCsTn(value); } else if ("信义污水厂升级出水TP".equals(type)) { industry.setCsTp(value); } else if ("信义污水厂升级出水氨氮".equals(type)) { industry.setCsNh3(value); } else if ("信义污水厂AIT202_Value".equals(type)) { industry.setOneHyzdDo(value); } else if ("信义污水厂AIT203_Value".equals(type)) { industry.setOneHymdDo(value); } else if ("信义污水厂AIT207_Value".equals(type)) { industry.setTwoHyzdDo(value); } else if ("信义污水厂AIT206_Value".equals(type)) { industry.setTwoHymdDo(value); } else if ("信义污水厂AIT209_Value".equals(type)) { industry.setOneMlss(value); } else if ("信义污水厂AIT210_Value".equals(type)) { industry.setTwoMlss(value); } else if ("信义污水厂进水TDS".equals(type)) { industry.setJsTds(value); } else if ("信义污水厂FT101_Value".equals(type)) { industry.setJsSlq(value); } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) { industry.setNHlbOneGp(value); } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) { industry.setNHlbTwoGp(value); } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) { industry.setNHlbThreeGp(value); } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) { industry.setNHlbFourGp(value); } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) { industry.setNhlBFiveGp(value); } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) { industry.setNHlbSixGp(value); } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) { industry.setWHlbOneGp(value); } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) { industry.setWHlbTwoGp(value); } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) { industry.setWHlbThreeGp(value); } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) { industry.setWHlbFourGp(value); } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) { industry.setWHlbFiveGp(value); } else if ("信义污水厂GFJ1_R_Value".equals(type)) { industry.setFjOne(value); } else if ("信义污水厂GFJ2_R_Value".equals(type)) { industry.setFjTwo(value); } else if ("信义污水厂GFJ3_R_Value".equals(type)) { industry.setFjThree(value); } else if ("信义污水厂GFJ4_R_Value".equals(type)) { industry.setFjFour(value); } else if ("信义污水厂GFJ5_R_Value".equals(type)) { industry.setFjFive(value); } else if ("信义污水厂GFJ6_R_Value".equals(type)) { industry.setFjSix(value); } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) { industry.setKqllOne(value); } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) { industry.setKqllTwo(value); } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) { industry.setKqllThree(value); } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) { industry.setKqllFour(value); } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) { industry.setKqllFive(value); } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) { industry.setKqllSix(value); }else if ("信义污水厂实际碳源加药量".equals(type)) { industry.setSJTYJLY(value); }else if ("信义污水厂除磷加药瞬时流量".equals(type)) { industry.setCLJYSSLL(value); } else if ("信义污水厂_除磷P04预测值_".equals(type)) { industry.setCLP04YCZ(value); } //只有最后一次才执行数据库添加 if(finalJ == list.size()-1){ needMap.put(industry.getTestHour(), industry); } }); } } //保存数据 触发告警 决策 问答记录等等 needMap.forEach((k, industry) ->{ System.out.println(JSON.toJSONString(industry)); }); } }