RyTask.java 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575
  1. package com.slibra.quartz.task;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.http.HttpRequest;
  4. import com.alibaba.fastjson2.JSON;
  5. import com.alibaba.fastjson2.JSONArray;
  6. import com.alibaba.fastjson2.JSONObject;
  7. import com.alibaba.fastjson2.JSONWriter;
  8. import com.google.protobuf.ByteString;
  9. import com.slibra.business.domain.*;
  10. import com.slibra.business.mapper.*;
  11. import com.slibra.business.req.ChatReq;
  12. import com.slibra.business.req.DecisionReq;
  13. import com.slibra.common.constant.MyConstants;
  14. import com.slibra.common.enums.BusinessEnum;
  15. import com.slibra.common.enums.DataSourceType;
  16. import com.slibra.common.utils.DateUtils;
  17. import com.slibra.common.utils.ip.IpUtils;
  18. import com.slibra.common.utils.uuid.IdUtils;
  19. import com.slibra.framework.datasource.DynamicDataSourceContextHolder;
  20. import inference.InferenceAPIsServiceGrpc;
  21. import inference.PredictionResponse;
  22. import inference.PredictionsRequest;
  23. import io.grpc.ManagedChannel;
  24. import io.grpc.ManagedChannelBuilder;
  25. import lombok.extern.slf4j.Slf4j;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.stereotype.Component;
  28. import com.slibra.common.utils.StringUtils;
  29. import org.springframework.util.CollectionUtils;
  30. import java.io.IOException;
  31. import java.math.BigDecimal;
  32. import java.math.RoundingMode;
  33. import java.time.LocalDateTime;
  34. import java.time.format.DateTimeFormatter;
  35. import java.util.*;
  36. import static com.slibra.common.constant.MyConstants.*;
  37. /**
  38. * 定时任务调度测试
  39. *
  40. *
  41. */
  42. @Component("ryTask")
  43. @Slf4j
  44. public class RyTask
  45. {
  46. public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
  47. {
  48. System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
  49. }
  50. public void ryParams(String params)
  51. {
  52. System.out.println("执行有参方法:" + params);
  53. }
  54. public void ryNoParams()
  55. {
  56. System.out.println("执行无参方法");
  57. }
  58. //----------------------------------------------下面是新增的方法----------------------------------------------
  59. @Autowired
  60. private TXinyiIndustryMapper xinyiIndustryMapper;
  61. @Autowired
  62. private TXinyiRobotMapper xinyiRobotMapper;
  63. @Autowired
  64. private TXinyiNormConfigMapper xinyiNormConfigMapper;
  65. @Autowired
  66. private TXinyiWarningRecordMapper xinyiWarningRecordMapper;
  67. @Autowired
  68. private TXinyiChatRecordMapper xinyiChatRecordMapper;
  69. @Autowired
  70. private TXinyiDailyMapper xinyiDailyMapper;
  71. // public final static StopWatch watch = new StopWatch("task");
  72. 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预测值_"};
  73. /**
  74. * 定时从工业库获取数据
  75. *
  76. * 2024年4月17日17:44:15 调整逻辑:考虑到因断电等情况导致服务断电,所以不再同步最近一小时,而是同步从上次成功的最后一条数据开始。
  77. */
  78. public void getIndustryData(){
  79. log.info("进入了定时同步工业库数据的任务");
  80. //耗时工具
  81. // watch.start("parseJob");
  82. // 给定时间段的起始时间和结束时间
  83. LocalDateTime endTime = LocalDateTime.now();
  84. // LocalDateTime startTime = endTime.plusMinutes(-60);
  85. //获取上次最后一条同步的数据的日期到 分钟维度
  86. String lastDateHour = this.xinyiIndustryMapper.getLastMinute();
  87. log.info("获取上次同步工业库的最后一条记录的时间是{}", lastDateHour);
  88. lastDateHour = lastDateHour + ":00";
  89. //开始时间
  90. LocalDateTime startTime = LocalDateTime.parse(lastDateHour.replaceAll("/", "-").replace(" ", "T"));
  91. startTime = startTime.plusMinutes(60L);//加一分钟 从上次最后一条记录的下一分钟开始
  92. /*LocalDateTime startTime = LocalDateTime.parse("2024-02-26T00:00:00");
  93. LocalDateTime endTime = LocalDateTime.parse("2024-02-27T00:00:00");*/
  94. // 每个小时的时间格式
  95. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  96. // 循环按小时分割
  97. LocalDateTime currentHour = startTime;
  98. //最终获取的数据
  99. Map<String, TXinyiIndustry> needMap = new LinkedHashMap<>();
  100. while (currentHour.isBefore(endTime)) {
  101. String begin = currentHour.format(formatter);
  102. String end = currentHour.plusMinutes(5).format(formatter);
  103. // 输出当前小时的起始时间和结束时间
  104. System.out.println("起始时间:" + begin);
  105. System.out.println("结束时间:" + end);
  106. // 当前小时加一小时,作为下一个小时的起始时间
  107. currentHour = currentHour.plusMinutes(5);
  108. //每个小时查询一次数据
  109. String url = "http://10.0.0.27:4568/api/v1/khquerydata";
  110. HashMap<String, Object> req = new HashMap<>();
  111. req.put("tagNames", queryTags);
  112. req.put("startTime", begin);
  113. req.put("endTime", end);
  114. req.put("recordNumbers", 100000);
  115. String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body();
  116. // System.out.println("body = " + body);
  117. List<HashMap<String, String>> list = new ArrayList<>();
  118. //行转列数据处理
  119. for (String queryTag : queryTags) {
  120. JSONArray array = JSON.parseObject(body).getJSONArray(queryTag);
  121. //特殊数据处理一
  122. if(Objects.isNull(array) || array.isEmpty()){
  123. System.out.println(queryTag + "查询到了空的数据,跳过本次循环");
  124. continue;
  125. }
  126. int size = array.size();
  127. //特殊数据处理二
  128. if("0".equals(array.get(1) + "")){
  129. System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0");
  130. continue;
  131. }
  132. //结合至少62个数据才满足条件(有可能获取不到)
  133. /*if(size < 62){
  134. System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环");
  135. continue;
  136. }*/
  137. //存放的数据集
  138. //利用map去重
  139. HashMap<String, String> map = new LinkedHashMap<>();
  140. for (int i = 2; i < size; i++) {
  141. // System.out.println(i + "" + array.get(i));
  142. JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i)));
  143. //处理为空或者为0的数据
  144. Object timeStampValue = oneRecord.get(2);
  145. if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + ""))
  146. continue;
  147. BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + "");
  148. long timestamp = (long) timeStampValue;
  149. String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS);
  150. map.put(format, queryTag + "-" + value);
  151. }
  152. list.add(map);
  153. }
  154. Set<String> recordTimeSet = new HashSet<>();
  155. Map<String, TXinyiIndustry> recordMap = new HashMap<>();
  156. for (int i = 0; i < list.size(); i++) {
  157. HashMap<String, String> map = list.get(i);
  158. int finalJ = i;
  159. map.forEach((k, v) ->{
  160. TXinyiIndustry industry = null;
  161. if(!recordTimeSet.contains(k)){//第一次
  162. industry = new TXinyiIndustry();
  163. recordTimeSet.add(k);
  164. recordMap.put(k, industry);
  165. }else{
  166. industry = recordMap.get(k);
  167. }
  168. industry.setTestTime(k + ":00");
  169. //2024年4月15日11:19:52 额外增加2个字段
  170. industry.setTestDate(k.substring(0,10));
  171. industry.setTestHour(k.substring(0,13));
  172. //解析值
  173. String[] split = v.split("-");
  174. String type = split[0];
  175. BigDecimal value = new BigDecimal(split[1]);
  176. if ("信义污水厂JS_COD_Value".equals(type)) {
  177. industry.setJsCod(value);
  178. } else if ("信义污水厂JS_PH_Value".equals(type)) {
  179. industry.setJsPh(value);
  180. } else if ("信义污水厂JS_SS_Value".equals(type)) {
  181. industry.setJsSs(value);
  182. } else if ("信义污水厂JS_ZL_Value".equals(type)) {
  183. industry.setJsTp(value);
  184. } else if ("信义污水厂JS_ZA_Value".equals(type)) {
  185. industry.setJsTn(value);
  186. } else if ("信义污水厂JS_AD_Value".equals(type)) {
  187. industry.setJsNh3(value);
  188. } else if ("信义污水厂JS_T_Value".equals(type)) {
  189. industry.setJsSwPh(value);
  190. } else if ("信义污水厂进水泵房液位".equals(type)) {
  191. industry.setJsBfyw(value);
  192. } else if ("信义污水厂出水瞬时流量".equals(type)) {
  193. industry.setCsSlqc(value);
  194. } else if ("信义污水厂升级出水COD".equals(type)) {
  195. industry.setCsCod(value);
  196. } else if ("信义污水厂升级出水PH".equals(type)) {
  197. industry.setCsPh(value);
  198. } else if ("信义污水厂升级出水SS".equals(type)) {
  199. industry.setCsSs(value);
  200. } else if ("信义污水厂升级出水TN".equals(type)) {
  201. industry.setCsTn(value);
  202. } else if ("信义污水厂升级出水TP".equals(type)) {
  203. industry.setCsTp(value);
  204. } else if ("信义污水厂升级出水氨氮".equals(type)) {
  205. industry.setCsNh3(value);
  206. } else if ("信义污水厂AIT202_Value".equals(type)) {
  207. industry.setOneHyzdDo(value);
  208. } else if ("信义污水厂AIT203_Value".equals(type)) {
  209. industry.setOneHymdDo(value);
  210. } else if ("信义污水厂AIT207_Value".equals(type)) {
  211. industry.setTwoHyzdDo(value);
  212. } else if ("信义污水厂AIT206_Value".equals(type)) {
  213. industry.setTwoHymdDo(value);
  214. } else if ("信义污水厂AIT209_Value".equals(type)) {
  215. industry.setOneMlss(value);
  216. } else if ("信义污水厂AIT210_Value".equals(type)) {
  217. industry.setTwoMlss(value);
  218. } else if ("信义污水厂进水TDS".equals(type)) {
  219. industry.setJsTds(value);
  220. } else if ("信义污水厂FT101_Value".equals(type)) {
  221. industry.setJsSlq(value);
  222. } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) {
  223. industry.setNHlbOneGp(value);
  224. } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) {
  225. industry.setNHlbTwoGp(value);
  226. } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) {
  227. industry.setNHlbThreeGp(value);
  228. } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) {
  229. industry.setNHlbFourGp(value);
  230. } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) {
  231. industry.setNhlBFiveGp(value);
  232. } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) {
  233. industry.setNHlbSixGp(value);
  234. } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) {
  235. industry.setWHlbOneGp(value);
  236. } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) {
  237. industry.setWHlbTwoGp(value);
  238. } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) {
  239. industry.setWHlbThreeGp(value);
  240. } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) {
  241. industry.setWHlbFourGp(value);
  242. } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) {
  243. industry.setWHlbFiveGp(value);
  244. } else if ("信义污水厂GFJ1_R_Value".equals(type)) {
  245. industry.setFjOne(value);
  246. } else if ("信义污水厂GFJ2_R_Value".equals(type)) {
  247. industry.setFjTwo(value);
  248. } else if ("信义污水厂GFJ3_R_Value".equals(type)) {
  249. industry.setFjThree(value);
  250. } else if ("信义污水厂GFJ4_R_Value".equals(type)) {
  251. industry.setFjFour(value);
  252. } else if ("信义污水厂GFJ5_R_Value".equals(type)) {
  253. industry.setFjFive(value);
  254. } else if ("信义污水厂GFJ6_R_Value".equals(type)) {
  255. industry.setFjSix(value);
  256. } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) {
  257. industry.setKqllOne(value);
  258. } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) {
  259. industry.setKqllTwo(value);
  260. } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) {
  261. industry.setKqllThree(value);
  262. } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) {
  263. industry.setKqllFour(value);
  264. } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) {
  265. industry.setKqllFive(value);
  266. } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) {
  267. industry.setKqllSix(value);
  268. }else if ("信义污水厂实际碳源加药量".equals(type)) {
  269. industry.setSJTYJLY(value);
  270. }else if ("信义污水厂除磷加药瞬时流量".equals(type)) {
  271. industry.setCLJYSSLL(value);
  272. } else if ("信义污水厂_除磷P04预测值_".equals(type)) {
  273. industry.setCLP04YCZ(value);
  274. }
  275. //只有最后一次才执行数据库添加
  276. if(finalJ == list.size()-1){
  277. needMap.put(industry.getTestHour(), industry);
  278. }
  279. });
  280. }
  281. }
  282. //保存数据 触发告警 决策 问答记录等等
  283. needMap.forEach((k, industry) ->{
  284. //2024年4月22日15:45:24 额外保存两个字段 数组
  285. List<BigDecimal> extraList = new ArrayList<>();
  286. extraList.add(industry.getOneHymdDo());
  287. extraList.add(industry.getTwoHymdDo());
  288. industry.setHycRjyAll(JSON.toJSONString(extraList));
  289. extraList.clear();
  290. extraList.add(industry.getOneHyzdDo());
  291. extraList.add(industry.getTwoHyzdDo());
  292. industry.setHycRjyZdAll(JSON.toJSONString(extraList));
  293. extraList.clear();
  294. extraList.add(industry.getOneMlss());
  295. extraList.add(industry.getTwoMlss());
  296. industry.setHycWnndAll(JSON.toJSONString(extraList));
  297. //插入数据库
  298. xinyiIndustryMapper.insertTXinyiIndustry(industry);
  299. //判断是否触发告警、接触告警、保存决策等等
  300. this.handleWarning(industry);
  301. });
  302. //执行完成 测试执行时间
  303. //计时结束
  304. // watch.stop();
  305. // System.out.println(watch.getLastTaskName() + " 执行耗时:" + watch.getLastTaskTimeMillis() + " ms");
  306. }
  307. private void handleWarning(TXinyiIndustry tXinyiIndustry) {
  308. log.info("进入了定时任务保存工业库数据并触发报警操作");
  309. //获取配置表
  310. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  311. if(CollectionUtils.isEmpty(tXinyiNormConfigs))
  312. throw new RuntimeException("未查询到配置信息");
  313. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  314. //水质报警
  315. this.handleSZWarning(tXinyiIndustry, normConfig);
  316. //2024年5月28日14:14:26 下面是新增的 生化报警处理
  317. this.handleSHWarning(tXinyiIndustry, normConfig);
  318. }
  319. private void handleSHWarning(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  320. //判断对应指标是否报警 然后调研大模型获取决策信息
  321. BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  322. //内回流比报警
  323. BigDecimal nhlbSjz = normConfig.getNhlbSjz();//400
  324. BigDecimal nhlbnkSxz = normConfig.getNhlbnkSxz();//360
  325. BigDecimal nhlbqdsl = normConfig.getNHLBQDSL();
  326. BigDecimal nhlbdsjll = normConfig.getNHLBDSJLL();
  327. BigDecimal nhlbgzxl = normConfig.getNHLBGZXL();
  328. if(!Objects.isNull(jsSlq) && !Objects.isNull(nhlbnkSxz) && !Objects.isNull(nhlbqdsl)
  329. && !Objects.isNull(nhlbdsjll) && !Objects.isNull(nhlbgzxl)){
  330. BigDecimal divide = nhlbqdsl.multiply(nhlbdsjll).multiply(nhlbgzxl).divide(jsSlq, 4, RoundingMode.HALF_UP);
  331. if(!Objects.isNull(nhlbSjz)){
  332. handleXinYiWarningsSH(nhlbSjz, divide, nhlbnkSxz, BusinessEnum.WarningCategoryEnum.NHLB.getCode(), tXinyiIndustry, normConfig);
  333. }
  334. }
  335. //外回流比报警
  336. BigDecimal whlbqdsl = normConfig.getWHLBQDSL();
  337. BigDecimal whlbdsjll = normConfig.getWHLBDSJLL();
  338. BigDecimal whlbgzxl = normConfig.getWHLBGZXL();
  339. BigDecimal whlbnkXxz = normConfig.getWhlbnkXxz();
  340. BigDecimal whlbSjz = normConfig.getWhlbSjz();
  341. if(!Objects.isNull(whlbqdsl) && !Objects.isNull(whlbdsjll) && !Objects.isNull(whlbgzxl)){
  342. BigDecimal divide = whlbqdsl.multiply(whlbdsjll).multiply(whlbgzxl).divide(jsSlq, 4, RoundingMode.HALF_UP);
  343. if(!Objects.isNull(whlbSjz)){
  344. handleXinYiWarningsSH(whlbSjz, divide, whlbnkXxz, BusinessEnum.WarningCategoryEnum.WHLB.getCode(), tXinyiIndustry, normConfig);
  345. }
  346. }
  347. //最新的一条日报数据
  348. List<TXinyiDaily> tXinyiDailies = this.xinyiDailyMapper.selectTXinyiDailyList(null);
  349. if(CollectionUtils.isEmpty(tXinyiDailies))
  350. return;//肯定不会出现这种情况 因为有很多历史数据了
  351. TXinyiDaily tXinyiDaily = tXinyiDailies.get(0);
  352. log.info("生化报警获取日报的最新的一条数据为{}", JSON.toJSONString(tXinyiDaily));
  353. BigDecimal jsBod5 = tXinyiDaily.getJsBod5();
  354. //污泥负荷(需要从日报获取数据) 计算 + 部分数据从日报获取
  355. //污泥负荷=[Ls]=24*([BOD_in]-[BOD_off])*[Q_in]/[MLSS]/([V_hao]+[V_que]+[V_yan])/2 kgBOD/(kgMLSS·d)
  356. //todo 后面再加 计算太复杂
  357. //碳氮比(需要从日报获取数据)
  358. //进水碳氮比=[b]=[BOD_in]/[TN_in]
  359. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  360. if(!Objects.isNull(jsBod5) && !Objects.isNull(jsTn)){
  361. BigDecimal divide = jsBod5.divide(jsTn, 4, RoundingMode.HALF_UP);
  362. BigDecimal jstdbnkzSxz = normConfig.getJstdbnkzSxz();
  363. BigDecimal cstdbSjz = normConfig.getCstdbSjz();
  364. if(!Objects.isNull(whlbSjz)){
  365. handleXinYiWarningsSH(cstdbSjz, divide, jstdbnkzSxz, BusinessEnum.WarningCategoryEnum.TDB.getCode(), tXinyiIndustry, normConfig);
  366. }
  367. }
  368. //碳磷比(需要从日报获取数据)
  369. //进水碳磷比=[c]=[BOD_in]/[TP_in]
  370. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  371. BigDecimal jstlbSjz = normConfig.getJstlbSjz();
  372. if(!Objects.isNull(jsBod5) && !Objects.isNull(jsTp)){
  373. BigDecimal divide = jsBod5.divide(jsTp, 4, RoundingMode.HALF_UP);
  374. BigDecimal jstlbNkz = normConfig.getJstlbNkz();
  375. if(!Objects.isNull(jstlbSjz)){
  376. handleXinYiWarningsSH(jstlbSjz, divide, jstlbNkz, BusinessEnum.WarningCategoryEnum.TLB.getCode(), tXinyiIndustry, normConfig);
  377. }
  378. }
  379. //BOD比COD(需要从日报获取数据)
  380. //进水BOD与COD比值数据=[d]=[BOD_in]/[COD_in]
  381. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  382. if(!Objects.isNull(jsBod5) && !Objects.isNull(jsCod)){
  383. BigDecimal jsbodycodbzSzj = normConfig.getJsbodycodbzSzj();
  384. String jsbodycodbzGkz = normConfig.getJsbodycodbzGkz();
  385. if(StringUtils.isNotBlank(jsbodycodbzGkz) && jsbodycodbzGkz.contains("-")){
  386. String[] split = jsbodycodbzGkz.split("-");
  387. BigDecimal gkz = new BigDecimal(split[1]);
  388. BigDecimal divide = jsBod5.divide(jsCod, 4, RoundingMode.HALF_UP);
  389. handleXinYiWarningsSH(gkz, divide, jsbodycodbzSzj, BusinessEnum.WarningCategoryEnum.BODCODB.getCode(), tXinyiIndustry, normConfig);
  390. }
  391. }
  392. //好氧区DO(一池)
  393. BigDecimal shcHyOneDo = tXinyiIndustry.getOneHymdDo();
  394. BigDecimal hycrjysjzSxz = normConfig.getHycrjysjzSxz();
  395. BigDecimal hycrjyNkz = normConfig.getHycrjyNkz();
  396. if(!Objects.isNull(shcHyOneDo) && !Objects.isNull(hycrjysjzSxz)){
  397. handleXinYiWarningsSH(hycrjysjzSxz, shcHyOneDo, hycrjyNkz, BusinessEnum.WarningCategoryEnum.HYQDO_ONE.getCode(), tXinyiIndustry, normConfig);
  398. }
  399. //好氧区DO(二池)
  400. BigDecimal shcHyTwoDo = tXinyiIndustry.getTwoHymdDo();
  401. if(!Objects.isNull(shcHyTwoDo) && !Objects.isNull(hycrjysjzSxz)){
  402. handleXinYiWarningsSH(hycrjysjzSxz, shcHyTwoDo, hycrjyNkz, BusinessEnum.WarningCategoryEnum.HYQDO_TWO.getCode(), tXinyiIndustry, normConfig);
  403. }
  404. //气水比(需要从日报获取数据)
  405. BigDecimal gfjgzts = normConfig.getGFJGZTS();
  406. BigDecimal gfjckll = normConfig.getGFJCKLL();
  407. BigDecimal shcqbSjz = normConfig.getShcqbSjz();
  408. if(!Objects.isNull(gfjgzts) && !Objects.isNull(gfjckll) && !Objects.isNull(shcqbSjz) && !Objects.isNull(jsSlq)){
  409. BigDecimal qsb = gfjgzts.multiply(gfjckll).divide(jsSlq, 4, RoundingMode.HALF_UP);
  410. BigDecimal shcqbNkz = normConfig.getShcqbNkz();
  411. handleXinYiWarningsSH(shcqbSjz, qsb, shcqbNkz, BusinessEnum.WarningCategoryEnum.WHLB.getCode(), tXinyiIndustry, normConfig);
  412. }
  413. }
  414. /**
  415. * 处理信义生化报警的逻辑 统一处理
  416. * @param bzz
  417. * @param currentVal
  418. * @param gkz
  419. * @param category
  420. * @param tXinyiIndustry
  421. * @param normConfig
  422. */
  423. private void handleXinYiWarningsSH(BigDecimal bzz, BigDecimal currentVal, BigDecimal gkz, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  424. BigDecimal multiply = bzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  425. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  426. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  427. tXinyiWarningRecord.setStatus(0);
  428. tXinyiWarningRecord.setType(1);
  429. tXinyiWarningRecord.setCategory(category);
  430. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  431. tXinyiWarningRecord.setWarningVal(currentVal);
  432. tXinyiWarningRecord.setDesignVal(bzz);
  433. tXinyiWarningRecord.setControlVal(gkz);
  434. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  435. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  436. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  437. if (Objects.isNull(currentVal)) {
  438. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  439. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  440. } else if (currentVal.compareTo(multiply) > 0) {//一级
  441. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  442. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  443. } else if (currentVal.compareTo(bzz) >= 0 && currentVal.compareTo(multiply) <= 0) {//二级
  444. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  445. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  446. } else if (!Objects.isNull(gkz) && currentVal.compareTo(gkz) > 0) {
  447. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  448. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  449. } else {
  450. tXinyiWarningRecord = null;//这种的无需处理
  451. }
  452. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  453. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(1).category(category).status(0).build());
  454. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  455. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  456. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  457. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  458. xinyiWarningRecord.setStatus(2);
  459. Date nowDate = DateUtils.getNowDate();
  460. xinyiWarningRecord.setOffTime(nowDate);
  461. xinyiWarningRecord.setUpdateTime(nowDate);
  462. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  463. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  464. }
  465. }
  466. }else{//有新的告警信息
  467. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  468. //保存到数据库中
  469. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  470. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  471. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  472. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  473. }else {
  474. //继续调用决策(普通问答)
  475. this.askBigModelForSHWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  476. }
  477. }else{
  478. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  479. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  480. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  481. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  482. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  483. }else {
  484. //继续调用决策(普通问答)
  485. this.askBigModelForSHWarning(xinyiWarningRecord, tXinyiIndustry, normConfig);
  486. }
  487. }
  488. }
  489. }
  490. }
  491. private void askBigModelForSHWarning(TXinyiWarningRecord xinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  492. log.info("进入了后台接口调⽤⼤模型获取问答结果处理");
  493. StringBuilder sb = new StringBuilder();
  494. String sessionId = IdUtils.simpleUUID();
  495. ChatReq chatReq = new ChatReq();
  496. // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型
  497. String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址
  498. int counts = 1;//默认是第一次
  499. //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录
  500. List<String> historyDates = new ArrayList<>();
  501. //构建问题(替换提示词中的占位符)
  502. String shWarningPrompt = SH_WARNING_PROMPT;
  503. shWarningPrompt =shWarningPrompt.replace("#{0}", xinyiWarningRecord.getReason());
  504. shWarningPrompt =shWarningPrompt.replace("#{1}", String.valueOf(xinyiWarningRecord.getDesignVal()));
  505. shWarningPrompt =shWarningPrompt.replace("#{2}", String.valueOf(xinyiWarningRecord.getControlVal()));
  506. shWarningPrompt =shWarningPrompt.replace("#{3}", String.valueOf(xinyiWarningRecord.getWarningVal()));
  507. historyDates.add(shWarningPrompt);
  508. // 获取输出流
  509. ManagedChannel channel = null;
  510. try {
  511. channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
  512. .usePlaintext()
  513. .build();
  514. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  515. 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) + "}";
  516. log.info("请求大模型的问答参数为{}", dataJson);
  517. PredictionsRequest request = PredictionsRequest.newBuilder()
  518. .setModelName("slibra_bot")
  519. .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理
  520. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  521. .buildPartial();
  522. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  523. //将结果记录到问答表
  524. while (predictions.hasNext()) {
  525. String responseStr = predictions.next().getPrediction().toStringUtf8();
  526. log.info("大模型问答返回的原始结果为{}", responseStr);
  527. responseStr = JSON.parseObject(responseStr).getString("message");
  528. if("complete".equals(responseStr)){
  529. log.info("结尾语句并且是非JSON,无需处理");
  530. }else{
  531. sb.append(responseStr);
  532. }
  533. }
  534. //将问答更新到数据库中
  535. chatReq.setSessionId(sessionId);
  536. chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
  537. chatReq.setModule(3);//0专家问答 1智能工单 2智能体助手 3告警 4简报
  538. String showVal = this.buildShowValue(xinyiWarningRecord, tXinyiIndustry, normConfig);
  539. chatReq.setShowVal(showVal);
  540. chatReq.setQuestion(shWarningPrompt);
  541. chatReq.setAnswer(sb.toString());
  542. chatReq.setWarningId(String.valueOf(xinyiWarningRecord.getId()));
  543. chatReq.setCounts(counts);//问答次数
  544. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  545. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  546. chatReq.setCreateTime(DateUtils.getNowDate());
  547. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  548. } catch (IOException e) {
  549. throw new RuntimeException(e);
  550. } finally {
  551. // 关闭输出流
  552. channel.shutdown();
  553. }
  554. }
  555. private void handleSZWarning(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  556. //出水相关
  557. //出水COD报警
  558. BigDecimal csCod = tXinyiIndustry.getCsCod();
  559. BigDecimal cscodBzz = normConfig.getCscodBzz();
  560. BigDecimal cscodGkz = normConfig.getCscodGkz();
  561. if(!Objects.isNull(cscodBzz)){
  562. handleXinYiWarningsCs(cscodBzz, csCod, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_COD.getCode(), tXinyiIndustry, normConfig);
  563. }
  564. //出水总磷超标报警
  565. BigDecimal csTp = tXinyiIndustry.getCsTp();
  566. BigDecimal cszlBzz = normConfig.getCszlBzz();
  567. BigDecimal cszlGkz = normConfig.getCszlGkz();
  568. if(!Objects.isNull(cszlBzz)){
  569. handleXinYiWarningsCs(cszlBzz, csTp, cszlGkz, BusinessEnum.WarningCategoryEnum.CS_ZL.getCode(), tXinyiIndustry, normConfig);
  570. }
  571. //出水总氮超标报警
  572. BigDecimal csTn = tXinyiIndustry.getCsTn();
  573. BigDecimal cszzBzz = normConfig.getCszzBzz();
  574. BigDecimal cszzGkz = normConfig.getCszzGkz();
  575. if(!Objects.isNull(cszzBzz)){
  576. handleXinYiWarningsCs(cszzBzz, csTn, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_ZD.getCode(), tXinyiIndustry, normConfig);
  577. }
  578. //出水氨氮超标报警
  579. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  580. BigDecimal csadBzz = normConfig.getCsadBzz();
  581. BigDecimal csadGkz = normConfig.getCsadGkz();
  582. if(!Objects.isNull(csadBzz)){
  583. handleXinYiWarningsCs(csadBzz, csNh3, csadGkz, BusinessEnum.WarningCategoryEnum.CS_AD.getCode(), tXinyiIndustry, normConfig);
  584. }
  585. //出水SS超标报警
  586. BigDecimal csSS = tXinyiIndustry.getCsSs();
  587. BigDecimal csSSBzz = normConfig.getCsssBzz();
  588. BigDecimal csssGkz = normConfig.getCsssGkz();
  589. if(!Objects.isNull(csSSBzz)){
  590. handleXinYiWarningsCs(csSSBzz, csSS, csssGkz, BusinessEnum.WarningCategoryEnum.CS_SS.getCode(), tXinyiIndustry, normConfig);
  591. }
  592. //进水相关报警
  593. //进水总磷超标报警
  594. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  595. BigDecimal jszlSjz = normConfig.getJszlSjz();
  596. if(!Objects.isNull(jszlSjz)){
  597. handleXinYiWarningRecordJS(jszlSjz, jsTp, BusinessEnum.WarningCategoryEnum.JS_ZL.getCode(), tXinyiIndustry, normConfig);
  598. }
  599. //进水COD超标报警
  600. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  601. BigDecimal jscodSjz = normConfig.getJscodSjz();
  602. if(!Objects.isNull(jscodSjz)){
  603. handleXinYiWarningRecordJS(jscodSjz, jsCod, BusinessEnum.WarningCategoryEnum.JS_COD.getCode(), tXinyiIndustry, normConfig);
  604. }
  605. //进水总氮超标报警
  606. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  607. BigDecimal jszdSjz = normConfig.getJszdSjz();
  608. if(!Objects.isNull(jszdSjz)){
  609. handleXinYiWarningRecordJS(jszdSjz, jsTn, BusinessEnum.WarningCategoryEnum.JS_ZD.getCode(), tXinyiIndustry, normConfig);
  610. }
  611. //进水氨氮超标报警
  612. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  613. BigDecimal jsadSjz = normConfig.getJsadSjz();
  614. if(!Objects.isNull(jsadSjz)){
  615. handleXinYiWarningRecordJS(jsadSjz, jsNh3, BusinessEnum.WarningCategoryEnum.JS_AD.getCode(), tXinyiIndustry, normConfig);
  616. }
  617. //进水SS超标报警
  618. BigDecimal jsSS = tXinyiIndustry.getJsSs();
  619. BigDecimal jsSSSjz = normConfig.getJsssSjz();
  620. if(!Objects.isNull(jsSSSjz)){
  621. handleXinYiWarningRecordJS(jsSSSjz, jsSS, BusinessEnum.WarningCategoryEnum.JS_SS.getCode(), tXinyiIndustry, normConfig);
  622. }
  623. }
  624. /**
  625. * 调用大模型获取决策结果 并同时记录对应信息到聊天记录表中
  626. *
  627. * @param tXinyiWarningRecord
  628. * @param tXinyiIndustry
  629. * @param normConfig
  630. */
  631. private void handleDecision(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  632. log.info("进入了调⽤大模型决策接口");
  633. ChatReq chatReq = new ChatReq();
  634. // StringBuilder sb = new StringBuilder();
  635. //大模型结果 放入一个结合中
  636. List<String> resultData = new ArrayList<>();
  637. //决策和问答不一样 没有历史的概念 所以sessionId都是新的 次数都是1
  638. String sessionId = IdUtils.simpleUUID();
  639. String feedback = chatReq.getFeedback();
  640. //决策请求的业务参数
  641. // List<HashMap<String, Object>> list = this.xinyiIndustryMapper.selectLast10RecordsForDecision();
  642. //2024年5月21日15:23:07 这里不能用关联查询处理,日报要获取最新的一条而不是今日的数据。
  643. List<DecisionReq> decisionReqs = this.xinyiIndustryMapper.selectLast10RecordsForDecisionOnlyIndustry();
  644. if(!CollectionUtils.isEmpty(decisionReqs)){
  645. for (DecisionReq decisionReq : decisionReqs) {
  646. //处理日报数据
  647. TXinyiDaily daily = this.xinyiDailyMapper.selectNewestData();
  648. if(!Objects.isNull(daily)){
  649. decisionReq.setT(daily.getJsSw());
  650. decisionReq.setSVI(daily.getWntjzsAll());
  651. decisionReq.setSV(daily.getWncjbAll());
  652. decisionReq.setMlvss(daily.getHfxwnndAll());
  653. decisionReq.setDoAna(daily.getYycRjyAll());
  654. decisionReq.setDoQue(daily.getQycRjyAll());
  655. //2024年5月26日11:59:02 干污泥量数据做了同步
  656. decisionReq.setGwnl(daily.getGWNL());
  657. BigDecimal jsBod5 = daily.getJsBod5();
  658. decisionReq.setBodIn(jsBod5);
  659. BigDecimal tpIn = decisionReq.getTpIn();
  660. BigDecimal tnIn = decisionReq.getTnIn();
  661. if(!Objects.isNull(jsBod5)){
  662. if(!Objects.isNull(tpIn) && tpIn.compareTo(new BigDecimal("0")) >0){
  663. decisionReq.setC(jsBod5.divide(tpIn, 4, RoundingMode.HALF_UP));
  664. }
  665. if(!Objects.isNull(tnIn) && tnIn.compareTo(new BigDecimal("0")) >0){
  666. decisionReq.setB(jsBod5.divide(tnIn, 4, RoundingMode.HALF_UP));
  667. }
  668. }
  669. }
  670. }
  671. }
  672. String rows = JSON.toJSONString(decisionReqs, JSONWriter.Feature.WriteNulls);
  673. // 获取输出流
  674. ManagedChannel channel = null;
  675. String dataJson = "";
  676. try {
  677. channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
  678. .usePlaintext()
  679. .build();
  680. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  681. dataJson = "{\"bot_id\":\"b00001\",\"exp_id\":\"721\",\"norm\":\"" + tXinyiWarningRecord.getCategory() + "\",\"feedback\":" + feedback + ",\"session_id\":" + "\"" + sessionId + "\"" + ",\"generate_args\":{\"max_new_tokens\":1024,\"max_length\":4096,\"num_beams\":1,\"do_sample\":true,\"top_p\":0.7,\"temperature\":0.95},\"extra\":{\"rows\":" + rows + "}}";
  682. log.info("请求大模型的决策的参数为{}", dataJson);
  683. PredictionsRequest request = PredictionsRequest.newBuilder()
  684. .setModelName("slibra_bot")
  685. .putInput("method", ByteString.copyFrom("decision_stream", "utf-8"))//推理
  686. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  687. .buildPartial();
  688. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  689. while (predictions.hasNext()) {
  690. String responseStr = predictions.next().getPrediction().toStringUtf8();
  691. log.info("决策流式返回的结果是{}", responseStr);
  692. //2024年5月25日16:37:16 按照大模型返回的类型解析数据
  693. String biz = JSON.parseObject(responseStr).getString("biz");
  694. if(BusinessEnum.BigModelBizEnum.OK.getCode().equals(biz)){
  695. log.info("结尾语句并且是非JSON,无需处理");
  696. //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端
  697. /*outputStream.write(responseStr.getBytes());
  698. outputStream.flush();*/
  699. }else if(BusinessEnum.BigModelBizEnum.DECISION_DEBUGGER.getCode().equals(biz)){
  700. log.info("中间过程,目前只打印日志,不记录数据,也不返回给前端,返回数据为{}", responseStr);
  701. //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端
  702. /*outputStream.write(responseStr.getBytes());
  703. outputStream.flush();*/
  704. }else{//其他 要么错误 要么alert 要么出的报告
  705. // sb.append(responseStr);
  706. resultData.add(responseStr);
  707. }
  708. }
  709. } catch (Exception e) {
  710. // throw new RuntimeException(e);
  711. log.error("定时任务处理告警调用决策异常,异常信息为{}", JSON.toJSONString(e));
  712. resultData.add("{\"biz\":\"ERROR\",\"message\":\"大模型分析数据异常,请稍后再试\"}");
  713. } finally {
  714. log.info("决策最终要保存的数据是{}", JSON.toJSONString(resultData));
  715. //保存聊天记录
  716. //将问答更新到数据库中
  717. chatReq.setSessionId(sessionId);
  718. chatReq.setType(1);//0问答 1决策
  719. chatReq.setModule(3);
  720. /*String userId = SecurityUtils.getUserId().toString();
  721. String username = SecurityUtils.getUsername();*/
  722. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  723. String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  724. chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
  725. chatReq.setQuestion(dataJson);
  726. chatReq.setAnswer(JSON.toJSONString(resultData));
  727. chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
  728. chatReq.setCounts(1);//问答次数
  729. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  730. chatReq.setCreateTime(DateUtils.getNowDate());
  731. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  732. // 关闭输出流
  733. if(!Objects.isNull(channel))
  734. channel.shutdown();
  735. }
  736. }
  737. private String buildShowValue(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  738. JSONObject result = new JSONObject();
  739. JSONObject basic = new JSONObject();
  740. Integer status = tXinyiWarningRecord.getStatus();
  741. Date warningTime = tXinyiWarningRecord.getTime();
  742. int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1;
  743. basic.put("title", tXinyiWarningRecord.getReason());
  744. basic.put("报警时间", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime));
  745. basic.put("报警值", tXinyiWarningRecord.getWarningVal());
  746. basic.put("标准值", tXinyiWarningRecord.getDesignVal());
  747. basic.put("管控值", tXinyiWarningRecord.getControlVal());
  748. basic.put("报警次数", Math.min(count, MAX_COUNT));
  749. if(tXinyiWarningRecord.getType() != 2)
  750. basic.put("状态", status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中");
  751. else
  752. basic.put("状态", status == 0 ? "预警中" : "已完成");
  753. //2024年5月27日14:04:22 额外返回2个字段 [管控值 和 告警级别] 返回的json没有数据是因为value没有值
  754. // basic.put("管控值", tXinyiWarningRecord.getControlVal());
  755. basic.put("告警级别", tXinyiWarningRecord.getLevel());
  756. result.put("basic", basic);
  757. JSONObject jsData = getJsonObject(tXinyiIndustry, normConfig);//进水数据
  758. result.put("jsData", jsData);
  759. JSONObject csData = getCsonObject(tXinyiIndustry, normConfig);//出水数据
  760. result.put("csData", csData);
  761. return JSON.toJSONString(result, JSONWriter.Feature.WriteNulls);
  762. }
  763. private static JSONObject getJsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  764. JSONObject jsData = new JSONObject();
  765. HashMap<Object, Object> temp1 = new HashMap<>();
  766. BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  767. temp1.put("value", jsSlq);
  768. temp1.put("exceed", jsSlq.compareTo(normConfig.getJsslSjz()) >0);
  769. jsData.put("流量", temp1);
  770. HashMap<Object, Object> temp2 = new HashMap<>();
  771. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  772. temp2.put("value", jsCod);
  773. temp2.put("exceed", jsCod.compareTo(normConfig.getJscodSjz()) > 0);
  774. jsData.put("COD", temp2);
  775. HashMap<Object, Object> temp3 = new HashMap<>();
  776. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  777. temp3.put("value", jsNh3);
  778. temp3.put("exceed", jsNh3.compareTo(normConfig.getJsadSjz()) > 0);
  779. jsData.put("NH3-N", temp3);
  780. HashMap<Object, Object> temp4 = new HashMap<>();
  781. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  782. temp4.put("value", jsTp);
  783. temp4.put("exceed", jsTp.compareTo(normConfig.getJszlSjz()) > 0);
  784. jsData.put("TP", temp4);
  785. HashMap<Object, Object> temp5 = new HashMap<>();
  786. BigDecimal jsSs = tXinyiIndustry.getJsSs();
  787. temp5.put("value", jsSs);
  788. temp5.put("exceed", jsSs.compareTo(normConfig.getJsssSjz()) > 0);
  789. jsData.put("SS", temp5);
  790. HashMap<Object, Object> temp6 = new HashMap<>();
  791. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  792. temp6.put("value", jsTn);
  793. temp6.put("exceed", jsTn.compareTo(normConfig.getJszdSjz()) > 0);
  794. jsData.put("TN", temp6);
  795. return jsData;
  796. }
  797. private static JSONObject getCsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  798. JSONObject csData = new JSONObject();
  799. HashMap<Object, Object> temp1 = new HashMap<>();
  800. BigDecimal csSlq = tXinyiIndustry.getCsSlqc();
  801. temp1.put("value", csSlq);
  802. temp1.put("exceed", false);//出水水量没有管控值
  803. csData.put("流量", temp1);
  804. HashMap<Object, Object> temp2 = new HashMap<>();
  805. BigDecimal csCod = tXinyiIndustry.getCsCod();
  806. temp2.put("value", csCod);
  807. temp2.put("exceed", csCod.compareTo(normConfig.getCscodGkz()) > 0);
  808. csData.put("COD", temp2);
  809. HashMap<Object, Object> temp3 = new HashMap<>();
  810. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  811. temp3.put("value", csNh3);
  812. temp3.put("exceed", csNh3.compareTo(normConfig.getCsadGkz()) > 0);
  813. csData.put("NH3-N", temp3);
  814. HashMap<Object, Object> temp4 = new HashMap<>();
  815. BigDecimal csTp = tXinyiIndustry.getCsTp();
  816. temp4.put("value", csTp);
  817. temp4.put("exceed", csTp.compareTo(normConfig.getCszlGkz()) > 0);
  818. csData.put("TP", temp4);
  819. HashMap<Object, Object> temp5 = new HashMap<>();
  820. BigDecimal csSs = tXinyiIndustry.getCsSs();
  821. temp5.put("value", csSs);
  822. temp5.put("exceed", csSs.compareTo(normConfig.getCsssGkz()) > 0);
  823. csData.put("SS", temp5);
  824. HashMap<Object, Object> temp6 = new HashMap<>();
  825. BigDecimal csTn = tXinyiIndustry.getCsTn();
  826. temp6.put("value", csTn);
  827. temp6.put("exceed", csTn.compareTo(normConfig.getCszzGkz()) > 0);
  828. csData.put("TN", temp6);
  829. return csData;
  830. }
  831. /**
  832. * 通过输入的值 生成对应类型的报警对象(出水)
  833. *
  834. * @param csBzz
  835. * @param currentVal
  836. * @param csGkz
  837. * @param category
  838. * @param tXinyiIndustry
  839. * @param normConfig
  840. * @return
  841. */
  842. private void handleXinYiWarningsCs(BigDecimal csBzz, BigDecimal currentVal, BigDecimal csGkz, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  843. BigDecimal multiply = csBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  844. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  845. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  846. tXinyiWarningRecord.setStatus(0);
  847. tXinyiWarningRecord.setType(0);
  848. tXinyiWarningRecord.setCategory(category);
  849. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  850. tXinyiWarningRecord.setWarningVal(currentVal);
  851. tXinyiWarningRecord.setDesignVal(csBzz);
  852. tXinyiWarningRecord.setControlVal(csGkz);
  853. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  854. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  855. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  856. if(Objects.isNull(currentVal)){
  857. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  858. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  859. }else if(currentVal.compareTo(multiply) > 0){//一级
  860. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  861. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  862. }else if(currentVal.compareTo(csBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  863. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  864. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  865. }else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  866. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  867. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  868. }else{
  869. tXinyiWarningRecord = null;//这种的无需处理
  870. }
  871. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  872. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).warningStatus(0).build());
  873. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  874. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  875. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  876. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  877. xinyiWarningRecord.setStatus(2);
  878. Date nowDate = DateUtils.getNowDate();
  879. xinyiWarningRecord.setOffTime(nowDate);
  880. xinyiWarningRecord.setUpdateTime(nowDate);
  881. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  882. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  883. }
  884. }
  885. }else{//有告警信息
  886. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  887. //保存到数据库中
  888. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  889. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  890. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  891. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  892. }else {
  893. //继续调用决策
  894. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  895. }
  896. }else{
  897. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  898. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  899. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  900. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  901. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  902. }else {
  903. //继续调用决策
  904. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig);
  905. }
  906. }
  907. }
  908. }
  909. }
  910. /**
  911. * 通过输入的值 生成对应类型的报警对象(进水)
  912. *
  913. * @param jsBzz
  914. * @param currentVal
  915. * @param category
  916. * @param tXinyiIndustry
  917. * @param normConfig
  918. * @return
  919. */
  920. private void handleXinYiWarningRecordJS(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  921. BigDecimal multiply = jsBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  922. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  923. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  924. tXinyiWarningRecord.setStatus(0);
  925. tXinyiWarningRecord.setType(0);
  926. tXinyiWarningRecord.setCategory(category);
  927. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  928. tXinyiWarningRecord.setWarningVal(currentVal);
  929. tXinyiWarningRecord.setDesignVal(jsBzz);
  930. // tXinyiWarningRecord.setControlVal(csGkz);
  931. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  932. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  933. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  934. if(Objects.isNull(currentVal)){
  935. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  936. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  937. }else if(currentVal.compareTo(multiply) > 0){//一级
  938. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  939. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  940. }else if(currentVal.compareTo(jsBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  941. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  942. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  943. }else{
  944. tXinyiWarningRecord = null;//这种的无需处理
  945. }
  946. /*else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  947. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  948. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  949. }*/
  950. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  951. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).status(0).build());
  952. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  953. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  954. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  955. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  956. xinyiWarningRecord.setStatus(2);
  957. Date nowDate = DateUtils.getNowDate();
  958. xinyiWarningRecord.setOffTime(nowDate);
  959. xinyiWarningRecord.setUpdateTime(nowDate);
  960. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  961. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  962. }
  963. }
  964. }else{//有告警信息
  965. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  966. //保存到数据库中
  967. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  968. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  969. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  970. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  971. }else {
  972. //继续调用决策
  973. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  974. }
  975. }else{
  976. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  977. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  978. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  979. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  980. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  981. }else {
  982. //继续调用决策
  983. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig);
  984. }
  985. }
  986. }
  987. }
  988. }
  989. private void addChatRecordByWarning(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  990. ChatReq chatReq = new ChatReq();
  991. //保存聊天记录
  992. //将问答更新到数据库中
  993. chatReq.setSessionId(IdUtils.simpleUUID());
  994. chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
  995. chatReq.setModule(3);
  996. /*String userId = SecurityUtils.getUserId().toString();
  997. String username = SecurityUtils.getUsername();*/
  998. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  999. String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1000. chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
  1001. chatReq.setQuestion(WARNING_DEFAULT_QUESTION);//本地问题
  1002. chatReq.setAnswer(tXinyiWarningRecord.getReason() + ",请检查设备是否正常运行");
  1003. chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
  1004. chatReq.setCounts(1);//问答次数
  1005. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  1006. chatReq.setCreateTime(DateUtils.getNowDate());
  1007. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  1008. }
  1009. /**
  1010. * 定时从sqlserver获取数据
  1011. */
  1012. public void sqlserverData(){
  1013. log.info("进入了定时同步SqlServer的任务");
  1014. //主库获取上次最新的同步日期
  1015. String lastTime = this.xinyiRobotMapper.selectLastTime();
  1016. log.info("上次同步的日期是{}", lastTime);
  1017. //从
  1018. DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
  1019. List<TXinyiRobot> tXinyiRobots = xinyiRobotMapper.selectTXinyiRobotListByTime(lastTime);
  1020. DynamicDataSourceContextHolder.clearDataSourceType();
  1021. // System.out.println(JSON.toJSONString(tXinyiRobots));
  1022. // System.out.println("-------------");
  1023. //主
  1024. if(!CollectionUtils.isEmpty(tXinyiRobots)){
  1025. for (TXinyiRobot tXinyiRobot : tXinyiRobots) {
  1026. String date = handleDate(tXinyiRobot.getVDate().replaceAll(" ", ""));//有空格
  1027. String time = handleDate(tXinyiRobot.getVTime().replaceAll(" ", ""));//有空格
  1028. tXinyiRobot.setVDate(date);
  1029. tXinyiRobot.setVTime(time);
  1030. tXinyiRobot.setVDateTime(date + " " + time);
  1031. //处理给前端展示的字段
  1032. tXinyiRobot.setTestDate(date);//日期
  1033. tXinyiRobot.setTestHour(date + " " + time.substring(0, 2));//小时
  1034. tXinyiRobot.setTestTime(date + " " + time.substring(0, 5));//分钟
  1035. tXinyiRobot.setCreatedTime(new Date());
  1036. //2024年5月29日10:33:32 额外处理几个新增的字段 多个池子数据合并一个
  1037. List<BigDecimal> extraList = new ArrayList<>();
  1038. extraList.add(tXinyiRobot.getNo3Hlj1Jqr());
  1039. extraList.add(tXinyiRobot.getNo3Hlj2Jqr());
  1040. tXinyiRobot.setHycxsyAll(JSON.toJSONString(extraList));
  1041. extraList.clear();
  1042. extraList.add(tXinyiRobot.getNh31Jqr());
  1043. extraList.add(tXinyiRobot.getNh32Jqr());
  1044. tXinyiRobot.setQyanAll(JSON.toJSONString(extraList));
  1045. extraList.clear();
  1046. extraList.add(tXinyiRobot.getNo3Qyc1Jqr());
  1047. extraList.add(tXinyiRobot.getNo3Qyc2Jqr());
  1048. tXinyiRobot.setQyckxsyAll(JSON.toJSONString(extraList));
  1049. extraList.clear();
  1050. extraList.add(tXinyiRobot.getTpHl1Jqr());
  1051. extraList.add(tXinyiRobot.getTpHl2Jqr());
  1052. tXinyiRobot.setHyzlsyAll(JSON.toJSONString(extraList));
  1053. this.xinyiRobotMapper.insertTXinyiRobot(tXinyiRobot);
  1054. }
  1055. }
  1056. }
  1057. /**
  1058. *
  1059. * 定时生成每日简报数据
  1060. *
  1061. */
  1062. public void generageShortReport(){
  1063. log.info("进入了定时生成每日简报数据");
  1064. List<TXinyiDaily> dailyTwoRecords = this.xinyiDailyMapper.selectNRecords(2);
  1065. //正常不会有这种问题 因为日报有很多条
  1066. if(CollectionUtils.isEmpty(dailyTwoRecords) || dailyTwoRecords.size() < 2){
  1067. log.error("进入了定时生成每日简报数据 获取最新的2条数据不足,终止");
  1068. return;
  1069. }
  1070. //暂时不考虑因为没有填写日报 导致生成重复数据的问题(后续需要的话再添加)
  1071. //处理数据 并 拼装
  1072. String queryData = buildShortReportQueryData(dailyTwoRecords);
  1073. log.info("定时生成简报,组装好的请求大模型的参数为:{}", queryData);
  1074. if(StringUtils.isBlank(queryData)){
  1075. log.error("无法拼装请求数据!!!!!!");
  1076. return;
  1077. }
  1078. String showVal = formateDateStr(dailyTwoRecords.get(0).getTestDate()) + JIAN_BAO_END;
  1079. //调用模型 并保存结果
  1080. this.askBigModel(queryData, showVal);
  1081. log.info("定时生成简报任务结束~~~~~~~~~~~~~~");
  1082. }
  1083. /**
  1084. *
  1085. * 2022/01/01 转成2022年01月01日 数据
  1086. * @param testDate
  1087. * @return
  1088. */
  1089. private String formateDateStr(String testDate) {
  1090. if(StringUtils.isBlank(testDate))
  1091. return "";
  1092. if(!testDate.contains("/"))
  1093. return testDate;
  1094. String[] split = testDate.split("/");
  1095. return split[0] + "年" + split[1] + "月" + split[2] + "日";
  1096. }
  1097. private void askBigModel(String question, String showVal) {
  1098. log.info("进入了后台接口调⽤⼤模型获取问答结果处理");
  1099. StringBuilder sb = new StringBuilder();
  1100. String sessionId = IdUtils.simpleUUID();
  1101. ChatReq chatReq = new ChatReq();
  1102. // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型
  1103. String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址
  1104. int counts = 1;//默认是第一次
  1105. //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录
  1106. List<String> historyDates = new ArrayList<>();
  1107. historyDates.add(question);
  1108. // 获取输出流
  1109. ManagedChannel channel = null;
  1110. try {
  1111. channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
  1112. .usePlaintext()
  1113. .build();
  1114. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  1115. 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) + "}";
  1116. log.info("请求大模型的问答参数为{}", dataJson);
  1117. PredictionsRequest request = PredictionsRequest.newBuilder()
  1118. .setModelName("slibra_bot")
  1119. .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理
  1120. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  1121. .buildPartial();
  1122. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  1123. //将结果记录到问答表
  1124. while (predictions.hasNext()) {
  1125. String responseStr = predictions.next().getPrediction().toStringUtf8();
  1126. log.info("大模型问答返回的原始结果为{}", responseStr);
  1127. responseStr = JSON.parseObject(responseStr).getString("message");
  1128. if("complete".equals(responseStr)){
  1129. System.out.println("结尾语句并且是非JSON,无需处理");
  1130. //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端
  1131. /*outputStream.write(responseStr.getBytes());
  1132. outputStream.flush();*/
  1133. }else{
  1134. sb.append(responseStr);
  1135. }
  1136. }
  1137. //将问答更新到数据库中
  1138. chatReq.setSessionId(sessionId);
  1139. chatReq.setType(2);//0问答 1决策 2本地 3仿真预测
  1140. chatReq.setModule(4);//0专家问答 1智能工单 2智能体助手 3告警 4简报
  1141. chatReq.setShowVal(showVal);
  1142. chatReq.setQuestion(question);
  1143. chatReq.setAnswer(sb.toString());
  1144. chatReq.setCounts(counts);//问答次数
  1145. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  1146. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  1147. chatReq.setCreateTime(DateUtils.getNowDate());
  1148. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  1149. } catch (IOException e) {
  1150. throw new RuntimeException(e);
  1151. } finally {
  1152. // 关闭输出流
  1153. channel.shutdown();
  1154. }
  1155. }
  1156. private String buildShortReportQueryData(List<TXinyiDaily> dailyTwoRecords) {
  1157. //查询配置信息
  1158. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  1159. if(CollectionUtils.isEmpty(tXinyiNormConfigs))
  1160. return null;
  1161. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  1162. //获取数据
  1163. TXinyiDaily yesterdayData = dailyTwoRecords.get(0);
  1164. TXinyiDaily beforeYesterdayData = dailyTwoRecords.get(1);
  1165. String originStr = JIAN_BAO_PROMPT;
  1166. String yesterdayStr = yesterdayData.getTestDate().substring(5).replace("/", "月") + "日";
  1167. String beforeYesterdayStr = beforeYesterdayData.getTestDate().substring(5).replace("/", "月") + "日";
  1168. originStr = originStr.replace("#{0}", yesterdayStr);
  1169. originStr = originStr.replace("#{1}", beforeYesterdayStr);
  1170. originStr = originStr.replace("#{2}", String.valueOf(yesterdayData.getJsCod()));
  1171. originStr = originStr.replace("#{3}", String.valueOf(yesterdayData.getJsTn()));
  1172. originStr = originStr.replace("#{4}", String.valueOf(yesterdayData.getJsTp()));
  1173. originStr = originStr.replace("#{5}", String.valueOf(yesterdayData.getJsNh3()));
  1174. originStr = originStr.replace("#{6}", String.valueOf(yesterdayData.getJsSs()));
  1175. originStr = originStr.replace("#{7}", String.valueOf(yesterdayData.getJSL()));
  1176. originStr = originStr.replace("#{8}", String.valueOf(yesterdayData.getCsCod()));
  1177. originStr = originStr.replace("#{9}", String.valueOf(yesterdayData.getCsTn()));
  1178. originStr = originStr.replace("#{10}", String.valueOf(yesterdayData.getCsTp()));
  1179. originStr = originStr.replace("#{11}", String.valueOf(yesterdayData.getCsNh3()));
  1180. originStr = originStr.replace("#{12}", String.valueOf(yesterdayData.getCsSs()));
  1181. originStr = originStr.replace("#{13}", String.valueOf(yesterdayData.getCSL()));
  1182. originStr = originStr.replace("#{14}", String.valueOf(beforeYesterdayData.getJsCod()));
  1183. originStr = originStr.replace("#{15}", String.valueOf(beforeYesterdayData.getJsTn()));
  1184. originStr = originStr.replace("#{16}", String.valueOf(beforeYesterdayData.getJsTp()));
  1185. originStr = originStr.replace("#{17}", String.valueOf(beforeYesterdayData.getJsNh3()));
  1186. originStr = originStr.replace("#{18}", String.valueOf(beforeYesterdayData.getJsSs()));
  1187. originStr = originStr.replace("#{19}", String.valueOf(beforeYesterdayData.getJSL()));
  1188. originStr = originStr.replace("#{20}", String.valueOf(beforeYesterdayData.getCsCod()));
  1189. originStr = originStr.replace("#{21}", String.valueOf(beforeYesterdayData.getCsTn()));
  1190. originStr = originStr.replace("#{22}", String.valueOf(beforeYesterdayData.getCsTp()));
  1191. originStr = originStr.replace("#{23}", String.valueOf(beforeYesterdayData.getCsNh3()));
  1192. originStr = originStr.replace("#{24}", String.valueOf(beforeYesterdayData.getCsSs()));
  1193. originStr = originStr.replace("#{25}", String.valueOf(beforeYesterdayData.getCSL()));
  1194. originStr = originStr.replace("#{26}", String.valueOf(normConfig.getJscodSjz()));
  1195. originStr = originStr.replace("#{27}", String.valueOf(normConfig.getJszdSjz()));
  1196. originStr = originStr.replace("#{28}", String.valueOf(normConfig.getJszlSjz()));
  1197. originStr = originStr.replace("#{29}", String.valueOf(normConfig.getJsadSjz()));
  1198. originStr = originStr.replace("#{30}", String.valueOf(normConfig.getJsssSjz()));
  1199. originStr = originStr.replace("#{31}", String.valueOf(normConfig.getCscodBzz()));
  1200. originStr = originStr.replace("#{32}", String.valueOf(normConfig.getCszzBzz()));
  1201. originStr = originStr.replace("#{33}", String.valueOf(normConfig.getCszlBzz()));
  1202. originStr = originStr.replace("#{34}", String.valueOf(normConfig.getCsadBzz()));
  1203. originStr = originStr.replace("#{35}", String.valueOf(normConfig.getCsssBzz()));
  1204. return originStr;
  1205. }
  1206. public static String handleDate(String str){
  1207. StringBuilder sb = new StringBuilder();
  1208. if(str.contains(" ")){//包含空格 就是年月日时分秒了
  1209. String[] split = str.split(" ");
  1210. addBeforeZero(sb, split[0], "/");
  1211. sb.append(" ");
  1212. addBeforeZero(sb, split[1], ":");
  1213. }else{
  1214. if(str.contains("/")){//年月日
  1215. addBeforeZero(sb, str, "/");
  1216. }else if(str.contains(":")){//时分秒
  1217. addBeforeZero(sb, str, ":");
  1218. }else {
  1219. sb.append(str);
  1220. }
  1221. }
  1222. return sb.toString();
  1223. }
  1224. public static StringBuilder addBeforeZero(StringBuilder sb, String str, String tag){
  1225. String[] split = str.split(tag);
  1226. int length = split.length;
  1227. for (int i = 0; i < length; i++) {
  1228. String value = split[i];
  1229. Integer intValue = Integer.parseInt(value);
  1230. if(intValue < 10 && value.length() == 1){////防止有正确的情况 额外再补充字符串
  1231. sb.append(0).append(value);
  1232. }else{
  1233. sb.append(value);
  1234. }
  1235. if(i < length-1){
  1236. sb.append(tag);
  1237. }
  1238. }
  1239. return sb;
  1240. }
  1241. public static void main(String[] args) {
  1242. /*LocalDateTime endTime = LocalDateTime.now();
  1243. System.out.println("endTime = " + endTime);
  1244. endTime = endTime.plusMinutes(60);
  1245. System.out.println("endTime = " + endTime);*/
  1246. /*String str = "2024/04/15 09:55";
  1247. System.out.println(str);
  1248. System.out.println(str.substring(0,10));
  1249. System.out.println(str.substring(0,13));*/
  1250. /*String str = "2024/04/18 08:00";
  1251. str = str + ":00";
  1252. System.out.println(str);
  1253. LocalDateTime startTime = LocalDateTime.parse(str.replaceAll("/", "-").replace(" ", "T"));
  1254. System.out.println(startTime.plusMinutes(1L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));*/
  1255. /*ArrayList<Integer> objects = new ArrayList<>();
  1256. objects.add(1);
  1257. objects.add(2);
  1258. objects.add(3);
  1259. System.out.println(objects);
  1260. objects.clear();
  1261. System.out.println(objects);
  1262. // test();
  1263. Date date = new Date();
  1264. System.out.println(DateUtils.differentHoursByMillisecond(date, date));
  1265. HashMap<Object, Object> map = new HashMap<>();
  1266. map.put("a", null);
  1267. map.put("b", "ab");
  1268. map.put("c", "");
  1269. map.put("d", '1');
  1270. System.out.println(JSON.toJSONString(map, JSONWriter.Feature.WriteNulls));
  1271. TXinyiIndustry tXinyiIndustry = new TXinyiIndustry();
  1272. System.out.println(JSON.toJSONString(tXinyiIndustry, JSONWriter.Feature.WriteNulls));*/
  1273. String s = "2022/01/01".substring(5).replace("/", "月") + "日";
  1274. System.out.println("s = " + s);
  1275. System.out.println(new BigDecimal("1").compareTo(null));//空指针 要判断
  1276. }
  1277. //测试工业库 没小时保存一条记录是否可行
  1278. public static void test() {
  1279. // 每个小时的时间格式
  1280. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  1281. LocalDateTime startTime = LocalDateTime.parse("2024-05-18T00:00:00");
  1282. LocalDateTime endTime = LocalDateTime.now();
  1283. // 循环按小时分割
  1284. LocalDateTime currentHour = startTime;
  1285. //最终获取的数据
  1286. Map<String, TXinyiIndustry> needMap = new LinkedHashMap<>();
  1287. while (currentHour.isBefore(endTime)) {
  1288. String begin = currentHour.format(formatter);
  1289. String end = currentHour.plusMinutes(5).format(formatter);
  1290. // 输出当前小时的起始时间和结束时间
  1291. System.out.println("起始时间:" + begin);
  1292. System.out.println("结束时间:" + end);
  1293. // 当前小时加一小时,作为下一个小时的起始时间
  1294. currentHour = currentHour.plusMinutes(5);
  1295. //每个小时查询一次数据
  1296. String url = "http://10.0.0.27:4568/api/v1/khquerydata";
  1297. HashMap<String, Object> req = new HashMap<>();
  1298. req.put("tagNames", queryTags);
  1299. req.put("startTime", begin);
  1300. req.put("endTime", end);
  1301. req.put("recordNumbers", 100000);
  1302. String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body();
  1303. // System.out.println("body = " + body);
  1304. List<HashMap<String, String>> list = new ArrayList<>();
  1305. //行转列数据处理
  1306. for (String queryTag : queryTags) {
  1307. JSONArray array = JSON.parseObject(body).getJSONArray(queryTag);
  1308. //特殊数据处理一
  1309. if(Objects.isNull(array) || array.isEmpty()){
  1310. System.out.println(queryTag + "查询到了空的数据,跳过本次循环");
  1311. continue;
  1312. }
  1313. int size = array.size();
  1314. //特殊数据处理二
  1315. if("0".equals(array.get(1) + "")){
  1316. System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0");
  1317. continue;
  1318. }
  1319. //结合至少62个数据才满足条件(有可能获取不到)
  1320. /*if(size < 62){
  1321. System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环");
  1322. continue;
  1323. }*/
  1324. //存放的数据集
  1325. //利用map去重
  1326. HashMap<String, String> map = new LinkedHashMap<>();
  1327. for (int i = 2; i < size; i++) {
  1328. // System.out.println(i + "" + array.get(i));
  1329. JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i)));
  1330. //处理为空或者为0的数据
  1331. Object timeStampValue = oneRecord.get(2);
  1332. if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + ""))
  1333. continue;
  1334. BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + "");
  1335. long timestamp = (long) timeStampValue;
  1336. String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS);
  1337. map.put(format, queryTag + "-" + value);
  1338. }
  1339. list.add(map);
  1340. }
  1341. Set<String> recordTimeSet = new HashSet<>();
  1342. Map<String, TXinyiIndustry> recordMap = new HashMap<>();
  1343. for (int i = 0; i < list.size(); i++) {
  1344. HashMap<String, String> map = list.get(i);
  1345. int finalJ = i;
  1346. map.forEach((k, v) ->{
  1347. TXinyiIndustry industry = null;
  1348. if(!recordTimeSet.contains(k)){//第一次
  1349. industry = new TXinyiIndustry();
  1350. recordTimeSet.add(k);
  1351. recordMap.put(k, industry);
  1352. }else{
  1353. industry = recordMap.get(k);
  1354. }
  1355. industry.setTestTime(k + ":00");
  1356. //2024年4月15日11:19:52 额外增加2个字段
  1357. industry.setTestDate(k.substring(0,10));
  1358. industry.setTestHour(k.substring(0,13));
  1359. //解析值
  1360. String[] split = v.split("-");
  1361. String type = split[0];
  1362. BigDecimal value = new BigDecimal(split[1]);
  1363. if ("信义污水厂JS_COD_Value".equals(type)) {
  1364. industry.setJsCod(value);
  1365. } else if ("信义污水厂JS_PH_Value".equals(type)) {
  1366. industry.setJsPh(value);
  1367. } else if ("信义污水厂JS_SS_Value".equals(type)) {
  1368. industry.setJsSs(value);
  1369. } else if ("信义污水厂JS_ZL_Value".equals(type)) {
  1370. industry.setJsTp(value);
  1371. } else if ("信义污水厂JS_ZA_Value".equals(type)) {
  1372. industry.setJsTn(value);
  1373. } else if ("信义污水厂JS_AD_Value".equals(type)) {
  1374. industry.setJsNh3(value);
  1375. } else if ("信义污水厂JS_T_Value".equals(type)) {
  1376. industry.setJsSwPh(value);
  1377. } else if ("信义污水厂进水泵房液位".equals(type)) {
  1378. industry.setJsBfyw(value);
  1379. } else if ("信义污水厂出水瞬时流量".equals(type)) {
  1380. industry.setCsSlqc(value);
  1381. } else if ("信义污水厂升级出水COD".equals(type)) {
  1382. industry.setCsCod(value);
  1383. } else if ("信义污水厂升级出水PH".equals(type)) {
  1384. industry.setCsPh(value);
  1385. } else if ("信义污水厂升级出水SS".equals(type)) {
  1386. industry.setCsSs(value);
  1387. } else if ("信义污水厂升级出水TN".equals(type)) {
  1388. industry.setCsTn(value);
  1389. } else if ("信义污水厂升级出水TP".equals(type)) {
  1390. industry.setCsTp(value);
  1391. } else if ("信义污水厂升级出水氨氮".equals(type)) {
  1392. industry.setCsNh3(value);
  1393. } else if ("信义污水厂AIT202_Value".equals(type)) {
  1394. industry.setOneHyzdDo(value);
  1395. } else if ("信义污水厂AIT203_Value".equals(type)) {
  1396. industry.setOneHymdDo(value);
  1397. } else if ("信义污水厂AIT207_Value".equals(type)) {
  1398. industry.setTwoHyzdDo(value);
  1399. } else if ("信义污水厂AIT206_Value".equals(type)) {
  1400. industry.setTwoHymdDo(value);
  1401. } else if ("信义污水厂AIT209_Value".equals(type)) {
  1402. industry.setOneMlss(value);
  1403. } else if ("信义污水厂AIT210_Value".equals(type)) {
  1404. industry.setTwoMlss(value);
  1405. } else if ("信义污水厂进水TDS".equals(type)) {
  1406. industry.setJsTds(value);
  1407. } else if ("信义污水厂FT101_Value".equals(type)) {
  1408. industry.setJsSlq(value);
  1409. } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) {
  1410. industry.setNHlbOneGp(value);
  1411. } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) {
  1412. industry.setNHlbTwoGp(value);
  1413. } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) {
  1414. industry.setNHlbThreeGp(value);
  1415. } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) {
  1416. industry.setNHlbFourGp(value);
  1417. } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) {
  1418. industry.setNhlBFiveGp(value);
  1419. } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) {
  1420. industry.setNHlbSixGp(value);
  1421. } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) {
  1422. industry.setWHlbOneGp(value);
  1423. } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) {
  1424. industry.setWHlbTwoGp(value);
  1425. } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) {
  1426. industry.setWHlbThreeGp(value);
  1427. } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) {
  1428. industry.setWHlbFourGp(value);
  1429. } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) {
  1430. industry.setWHlbFiveGp(value);
  1431. } else if ("信义污水厂GFJ1_R_Value".equals(type)) {
  1432. industry.setFjOne(value);
  1433. } else if ("信义污水厂GFJ2_R_Value".equals(type)) {
  1434. industry.setFjTwo(value);
  1435. } else if ("信义污水厂GFJ3_R_Value".equals(type)) {
  1436. industry.setFjThree(value);
  1437. } else if ("信义污水厂GFJ4_R_Value".equals(type)) {
  1438. industry.setFjFour(value);
  1439. } else if ("信义污水厂GFJ5_R_Value".equals(type)) {
  1440. industry.setFjFive(value);
  1441. } else if ("信义污水厂GFJ6_R_Value".equals(type)) {
  1442. industry.setFjSix(value);
  1443. } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) {
  1444. industry.setKqllOne(value);
  1445. } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) {
  1446. industry.setKqllTwo(value);
  1447. } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) {
  1448. industry.setKqllThree(value);
  1449. } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) {
  1450. industry.setKqllFour(value);
  1451. } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) {
  1452. industry.setKqllFive(value);
  1453. } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) {
  1454. industry.setKqllSix(value);
  1455. }else if ("信义污水厂实际碳源加药量".equals(type)) {
  1456. industry.setSJTYJLY(value);
  1457. }else if ("信义污水厂除磷加药瞬时流量".equals(type)) {
  1458. industry.setCLJYSSLL(value);
  1459. } else if ("信义污水厂_除磷P04预测值_".equals(type)) {
  1460. industry.setCLP04YCZ(value);
  1461. }
  1462. //只有最后一次才执行数据库添加
  1463. if(finalJ == list.size()-1){
  1464. needMap.put(industry.getTestHour(), industry);
  1465. }
  1466. });
  1467. }
  1468. }
  1469. //保存数据 触发告警 决策 问答记录等等
  1470. needMap.forEach((k, industry) ->{
  1471. System.out.println(JSON.toJSONString(industry));
  1472. });
  1473. }
  1474. }