RyTask.java 100 KB

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