RyTask.java 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  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.SecurityUtils;
  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. //出水COD报警
  316. BigDecimal csCod = tXinyiIndustry.getCsCod();
  317. BigDecimal cscodBzz = normConfig.getCscodBzz();
  318. BigDecimal cscodGkz = normConfig.getCscodGkz();
  319. if(!Objects.isNull(csCod) && !Objects.isNull(cscodBzz)){
  320. handleXinYiWarningsCs(cscodBzz, csCod, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_COD.getCode(), tXinyiIndustry, normConfig);
  321. }
  322. //出水总磷超标报警
  323. BigDecimal csTp = tXinyiIndustry.getCsTp();
  324. BigDecimal cszlBzz = normConfig.getCszlBzz();
  325. BigDecimal cszlGkz = normConfig.getCszlGkz();
  326. if(!Objects.isNull(csTp) && !Objects.isNull(cszlBzz)){
  327. handleXinYiWarningsCs(cszlBzz, csTp, cszlGkz, BusinessEnum.WarningCategoryEnum.CS_ZL.getCode(), tXinyiIndustry, normConfig);
  328. }
  329. //出水总氮超标报警
  330. BigDecimal csTn = tXinyiIndustry.getCsTn();
  331. BigDecimal cszzBzz = normConfig.getCszzBzz();
  332. BigDecimal cszzGkz = normConfig.getCszzGkz();
  333. if(!Objects.isNull(csTn) && !Objects.isNull(cszzBzz)){
  334. handleXinYiWarningsCs(cszzBzz, csTn, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_ZD.getCode(), tXinyiIndustry, normConfig);
  335. }
  336. //出水氨氮超标报警
  337. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  338. BigDecimal csadBzz = normConfig.getCsadBzz();
  339. BigDecimal csadGkz = normConfig.getCsadGkz();
  340. if(!Objects.isNull(csNh3) && !Objects.isNull(csadBzz)){
  341. handleXinYiWarningsCs(csadBzz, csNh3, csadGkz, BusinessEnum.WarningCategoryEnum.CS_AD.getCode(), tXinyiIndustry, normConfig);
  342. }
  343. //出水SS超标报警
  344. BigDecimal csSS = tXinyiIndustry.getCsSs();
  345. BigDecimal csSSBzz = normConfig.getCsssBzz();
  346. BigDecimal csssGkz = normConfig.getCsssGkz();
  347. if(!Objects.isNull(csSS) && !Objects.isNull(csSSBzz)){
  348. handleXinYiWarningsCs(csSSBzz, csSS, csssGkz, BusinessEnum.WarningCategoryEnum.CS_SS.getCode(), tXinyiIndustry, normConfig);
  349. }
  350. //进水相关报警
  351. //进水总磷超标报警
  352. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  353. BigDecimal jszlSjz = normConfig.getJszlSjz();
  354. if(!Objects.isNull(jsTp) && !Objects.isNull(jszlSjz)){
  355. handleXinYiWarningRecordJS(jszlSjz, jsTp, BusinessEnum.WarningCategoryEnum.JS_ZL.getCode(), tXinyiIndustry, normConfig);
  356. }
  357. //进水COD超标报警
  358. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  359. BigDecimal jscodSjz = normConfig.getJscodSjz();
  360. if(!Objects.isNull(jsCod) && !Objects.isNull(jscodSjz)){
  361. handleXinYiWarningRecordJS(jscodSjz, jsCod, BusinessEnum.WarningCategoryEnum.JS_COD.getCode(), tXinyiIndustry, normConfig);
  362. }
  363. //进水总氮超标报警
  364. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  365. BigDecimal jszdSjz = normConfig.getJszdSjz();
  366. if(!Objects.isNull(jsTn) && !Objects.isNull(jszdSjz)){
  367. handleXinYiWarningRecordJS(jszdSjz, jsTn, BusinessEnum.WarningCategoryEnum.JS_ZD.getCode(), tXinyiIndustry, normConfig);
  368. }
  369. //进水氨氮超标报警
  370. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  371. BigDecimal jsadSjz = normConfig.getJsadSjz();
  372. if(!Objects.isNull(jsNh3) && !Objects.isNull(jsadSjz)){
  373. handleXinYiWarningRecordJS(jsadSjz, jsNh3, BusinessEnum.WarningCategoryEnum.JS_AD.getCode(), tXinyiIndustry, normConfig);
  374. }
  375. //进水SS超标报警
  376. BigDecimal jsSS = tXinyiIndustry.getJsSs();
  377. BigDecimal jsSSSjz = normConfig.getJsssSjz();
  378. if(!Objects.isNull(jsSS) && !Objects.isNull(jsSSSjz)){
  379. handleXinYiWarningRecordJS(jsSSSjz, jsSS, BusinessEnum.WarningCategoryEnum.JS_SS.getCode(), tXinyiIndustry, normConfig);
  380. }
  381. }
  382. /**
  383. * 调用大模型获取决策结果 并同时记录对应信息到聊天记录表中
  384. *
  385. * @param tXinyiWarningRecord
  386. * @param tXinyiIndustry
  387. * @param normConfig
  388. */
  389. private void handleDecision(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  390. log.info("进入了调⽤大模型决策接口");
  391. ChatReq chatReq = new ChatReq();
  392. // StringBuilder sb = new StringBuilder();
  393. //大模型结果 放入一个结合中
  394. List<String> resultData = new ArrayList<>();
  395. //决策和问答不一样 没有历史的概念 所以sessionId都是新的 次数都是1
  396. String sessionId = IdUtils.simpleUUID();
  397. String feedback = chatReq.getFeedback();
  398. //决策请求的业务参数
  399. // List<HashMap<String, Object>> list = this.xinyiIndustryMapper.selectLast10RecordsForDecision();
  400. //2024年5月21日15:23:07 这里不能用关联查询处理,日报要获取最新的一条而不是今日的数据。
  401. List<DecisionReq> decisionReqs = this.xinyiIndustryMapper.selectLast10RecordsForDecisionOnlyIndustry();
  402. if(!CollectionUtils.isEmpty(decisionReqs)){
  403. for (DecisionReq decisionReq : decisionReqs) {
  404. //处理日报数据
  405. TXinyiDaily daily = this.xinyiDailyMapper.selectNewestData();
  406. if(!Objects.isNull(daily)){
  407. decisionReq.setT(daily.getJsSw());
  408. decisionReq.setSVI(daily.getWntjzsAll());
  409. decisionReq.setSV(daily.getWncjbAll());
  410. decisionReq.setMlvss(daily.getHfxwnndAll());
  411. decisionReq.setDoAna(daily.getYycRjyAll());
  412. decisionReq.setDoQue(daily.getQycRjyAll());
  413. BigDecimal jsBod5 = daily.getJsBod5();
  414. decisionReq.setBodIn(jsBod5);
  415. BigDecimal tpIn = decisionReq.getTpIn();
  416. BigDecimal tnIn = decisionReq.getTnIn();
  417. if(!Objects.isNull(jsBod5)){
  418. if(!Objects.isNull(tpIn) && tpIn.compareTo(new BigDecimal("0")) >0){
  419. decisionReq.setC(jsBod5.divide(tpIn, 4, RoundingMode.HALF_UP));
  420. }
  421. if(!Objects.isNull(tnIn) && tnIn.compareTo(new BigDecimal("0")) >0){
  422. decisionReq.setB(jsBod5.divide(tnIn, 4, RoundingMode.HALF_UP));
  423. }
  424. }
  425. }
  426. }
  427. }
  428. String rows = JSON.toJSONString(decisionReqs, JSONWriter.Feature.WriteNulls);
  429. // 获取输出流
  430. ManagedChannel channel = null;
  431. String dataJson = "";
  432. try {
  433. channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
  434. .usePlaintext()
  435. .build();
  436. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  437. 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 + "}}";
  438. log.info("请求大模型的决策的参数为{}", dataJson);
  439. PredictionsRequest request = PredictionsRequest.newBuilder()
  440. .setModelName("slibra_bot")
  441. .putInput("method", ByteString.copyFrom("decision_stream", "utf-8"))//推理
  442. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  443. .buildPartial();
  444. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  445. while (predictions.hasNext()) {
  446. String responseStr = predictions.next().getPrediction().toStringUtf8();
  447. log.info("决策流式返回的结果是{}", responseStr);
  448. responseStr = JSON.parseObject(responseStr).getString("message");
  449. if("complete".equals(responseStr)){
  450. System.out.println("结尾语句并且是非JSON,无需处理");
  451. }else{
  452. // sb.append(responseStr);
  453. resultData.add(responseStr);
  454. }
  455. // todo 类型判断处理
  456. }
  457. } catch (Exception e) {
  458. // throw new RuntimeException(e);
  459. log.error("处理大模型推理异常,异常信息为{}", JSON.toJSONString(e));
  460. } finally {
  461. System.out.println(JSON.toJSONString(resultData));
  462. //保存聊天记录
  463. //将问答更新到数据库中
  464. chatReq.setSessionId(sessionId);
  465. chatReq.setType(0);//0问答 1决策
  466. chatReq.setModule(3);
  467. /*String userId = SecurityUtils.getUserId().toString();
  468. String username = SecurityUtils.getUsername();*/
  469. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  470. String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  471. chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
  472. chatReq.setQuestion(dataJson);
  473. chatReq.setAnswer(JSON.toJSONString(resultData));
  474. chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
  475. chatReq.setCounts(1);//问答次数
  476. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  477. chatReq.setCreateTime(DateUtils.getNowDate());
  478. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  479. // 关闭输出流
  480. if(!Objects.isNull(channel))
  481. channel.shutdown();
  482. }
  483. }
  484. private String buildShowValue(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  485. JSONObject result = new JSONObject();
  486. JSONObject basic = new JSONObject();
  487. Integer status = tXinyiWarningRecord.getStatus();
  488. Date warningTime = tXinyiWarningRecord.getTime();
  489. int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1;
  490. basic.put(tXinyiWarningRecord.getReason(), tXinyiWarningRecord.getReason());
  491. basic.put("报警时间", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime));
  492. basic.put("报警值", tXinyiWarningRecord.getWarningVal());
  493. basic.put("标准值", tXinyiWarningRecord.getDesignVal());
  494. basic.put("管控值", tXinyiWarningRecord.getControlVal());
  495. basic.put("报警次数", Math.min(count, maxCount));
  496. if(tXinyiWarningRecord.getType() != 2)
  497. basic.put("状态", status == 0 ? "告警中" : status == 1 ? "用户关闭" : status == 2 ? "系统自动关闭" : "用户转为应急处理中");
  498. else
  499. basic.put("状态", status == 0 ? "预警中" : "已完成");
  500. result.put("basic", basic);
  501. JSONObject jsData = getJsonObject(tXinyiIndustry, normConfig);//进水数据
  502. result.put("jsData", jsData);
  503. JSONObject csData = getCsonObject(tXinyiIndustry, normConfig);//出水数据
  504. result.put("csData", csData);
  505. return JSON.toJSONString(result);
  506. }
  507. private static JSONObject getJsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  508. JSONObject jsData = new JSONObject();
  509. HashMap<Object, Object> temp1 = new HashMap<>();
  510. BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  511. temp1.put("value", jsSlq);
  512. temp1.put("exceed", jsSlq.compareTo(normConfig.getJsslSjz()) >0);
  513. jsData.put("流量", temp1);
  514. HashMap<Object, Object> temp2 = new HashMap<>();
  515. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  516. temp2.put("value", jsCod);
  517. temp2.put("exceed", jsCod.compareTo(normConfig.getJscodSjz()) > 0);
  518. jsData.put("COD", temp2);
  519. HashMap<Object, Object> temp3 = new HashMap<>();
  520. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  521. temp3.put("value", jsNh3);
  522. temp3.put("exceed", jsNh3.compareTo(normConfig.getJsadSjz()) > 0);
  523. jsData.put("NH3-N", temp3);
  524. HashMap<Object, Object> temp4 = new HashMap<>();
  525. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  526. temp4.put("value", jsTp);
  527. temp4.put("exceed", jsTp.compareTo(normConfig.getJszlSjz()) > 0);
  528. jsData.put("TP", temp4);
  529. HashMap<Object, Object> temp5 = new HashMap<>();
  530. BigDecimal jsSs = tXinyiIndustry.getJsSs();
  531. temp5.put("value", jsSs);
  532. temp5.put("exceed", jsSs.compareTo(normConfig.getJsssSjz()) > 0);
  533. jsData.put("SS", temp5);
  534. HashMap<Object, Object> temp6 = new HashMap<>();
  535. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  536. temp6.put("value", jsTn);
  537. temp6.put("exceed", jsTn.compareTo(normConfig.getJszdSjz()) > 0);
  538. jsData.put("TN", temp6);
  539. return jsData;
  540. }
  541. private static JSONObject getCsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  542. JSONObject csData = new JSONObject();
  543. HashMap<Object, Object> temp1 = new HashMap<>();
  544. BigDecimal csSlq = tXinyiIndustry.getCsSlqc();
  545. temp1.put("value", csSlq);
  546. temp1.put("exceed", false);//出水水量没有管控值
  547. csData.put("流量", temp1);
  548. HashMap<Object, Object> temp2 = new HashMap<>();
  549. BigDecimal csCod = tXinyiIndustry.getCsCod();
  550. temp2.put("value", csCod);
  551. temp2.put("exceed", csCod.compareTo(normConfig.getCscodGkz()) > 0);
  552. csData.put("COD", temp2);
  553. HashMap<Object, Object> temp3 = new HashMap<>();
  554. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  555. temp3.put("value", csNh3);
  556. temp3.put("exceed", csNh3.compareTo(normConfig.getCsadGkz()) > 0);
  557. csData.put("NH3-N", temp3);
  558. HashMap<Object, Object> temp4 = new HashMap<>();
  559. BigDecimal csTp = tXinyiIndustry.getCsTp();
  560. temp4.put("value", csTp);
  561. temp4.put("exceed", csTp.compareTo(normConfig.getCszlGkz()) > 0);
  562. csData.put("TP", temp4);
  563. HashMap<Object, Object> temp5 = new HashMap<>();
  564. BigDecimal csSs = tXinyiIndustry.getCsSs();
  565. temp5.put("value", csSs);
  566. temp5.put("exceed", csSs.compareTo(normConfig.getCsssGkz()) > 0);
  567. csData.put("SS", temp5);
  568. HashMap<Object, Object> temp6 = new HashMap<>();
  569. BigDecimal csTn = tXinyiIndustry.getCsTn();
  570. temp6.put("value", csTn);
  571. temp6.put("exceed", csTn.compareTo(normConfig.getCszzGkz()) > 0);
  572. csData.put("TN", temp6);
  573. return csData;
  574. }
  575. /**
  576. * 通过输入的值 生成对应类型的报警对象(出水)
  577. *
  578. * @param csBzz
  579. * @param currentVal
  580. * @param csGkz
  581. * @param category
  582. * @param tXinyiIndustry
  583. * @param normConfig
  584. * @return
  585. */
  586. private void handleXinYiWarningsCs(BigDecimal csBzz, BigDecimal currentVal, BigDecimal csGkz, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  587. BigDecimal multiply = csBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  588. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  589. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  590. tXinyiWarningRecord.setStatus(0);
  591. tXinyiWarningRecord.setType(0);
  592. tXinyiWarningRecord.setCategory(category);
  593. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  594. tXinyiWarningRecord.setWarningVal(currentVal);
  595. tXinyiWarningRecord.setDesignVal(csBzz);
  596. tXinyiWarningRecord.setControlVal(csGkz);
  597. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  598. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  599. if(currentVal.compareTo(multiply) > 0){//一级
  600. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  601. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  602. }else if(currentVal.compareTo(csBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  603. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  604. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  605. }else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  606. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  607. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  608. }else{
  609. tXinyiWarningRecord = null;//这种的无需处理
  610. }
  611. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  612. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).status(0).build());
  613. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  614. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  615. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  616. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  617. xinyiWarningRecord.setStatus(2);
  618. Date nowDate = DateUtils.getNowDate();
  619. xinyiWarningRecord.setOffTime(nowDate);
  620. xinyiWarningRecord.setUpdateTime(nowDate);
  621. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  622. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  623. }
  624. }
  625. }else{//有告警信息
  626. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  627. //保存到数据库中
  628. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  629. //继续调用决策
  630. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  631. }else{
  632. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  633. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  634. //继续调用决策
  635. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig);
  636. }
  637. }
  638. }
  639. }
  640. /**
  641. * 通过输入的值 生成对应类型的报警对象(进水)
  642. *
  643. * @param jsBzz
  644. * @param currentVal
  645. * @param category
  646. * @param tXinyiIndustry
  647. * @param normConfig
  648. * @return
  649. */
  650. private void handleXinYiWarningRecordJS(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  651. BigDecimal multiply = jsBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  652. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  653. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  654. tXinyiWarningRecord.setStatus(0);
  655. tXinyiWarningRecord.setType(0);
  656. tXinyiWarningRecord.setCategory(category);
  657. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  658. tXinyiWarningRecord.setWarningVal(currentVal);
  659. tXinyiWarningRecord.setDesignVal(jsBzz);
  660. // tXinyiWarningRecord.setControlVal(csGkz);
  661. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  662. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  663. if(currentVal.compareTo(multiply) > 0){//一级
  664. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  665. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  666. }else if(currentVal.compareTo(jsBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  667. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  668. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  669. }else{
  670. tXinyiWarningRecord = null;//这种的无需处理
  671. }
  672. /*else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  673. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  674. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  675. }*/
  676. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  677. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).status(0).build());
  678. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  679. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  680. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  681. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  682. xinyiWarningRecord.setStatus(2);
  683. Date nowDate = DateUtils.getNowDate();
  684. xinyiWarningRecord.setOffTime(nowDate);
  685. xinyiWarningRecord.setUpdateTime(nowDate);
  686. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  687. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  688. }
  689. }
  690. }else{//有告警信息
  691. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  692. //保存到数据库中
  693. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  694. //继续调用决策
  695. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  696. }else{
  697. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  698. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  699. //继续调用决策
  700. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig);
  701. }
  702. }
  703. }
  704. }
  705. /**
  706. * 定时从sqlserver获取数据
  707. */
  708. public void sqlserverData(){
  709. log.info("进入了定时同步SqlServer的任务");
  710. //主库获取上次最新的同步日期
  711. String lastTime = this.xinyiRobotMapper.selectLastTime();
  712. log.info("上次同步的日期是{}", lastTime);
  713. //从
  714. DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
  715. List<TXinyiRobot> tXinyiRobots = xinyiRobotMapper.selectTXinyiRobotListByTime(lastTime);
  716. DynamicDataSourceContextHolder.clearDataSourceType();
  717. // System.out.println(JSON.toJSONString(tXinyiRobots));
  718. // System.out.println("-------------");
  719. //主
  720. if(!CollectionUtils.isEmpty(tXinyiRobots)){
  721. for (TXinyiRobot tXinyiRobot : tXinyiRobots) {
  722. String date = handleDate(tXinyiRobot.getVDate().replaceAll(" ", ""));//有空格
  723. String time = handleDate(tXinyiRobot.getVTime().replaceAll(" ", ""));//有空格
  724. tXinyiRobot.setVDate(date);
  725. tXinyiRobot.setVTime(time);
  726. tXinyiRobot.setVDateTime(date + " " + time);
  727. //处理给前端展示的字段
  728. tXinyiRobot.setTestDate(date);//日期
  729. tXinyiRobot.setTestHour(date + " " + time.substring(0, 2));//小时
  730. tXinyiRobot.setTestTime(date + " " + time.substring(0, 5));//分钟
  731. tXinyiRobot.setCreatedTime(new Date());
  732. this.xinyiRobotMapper.insertTXinyiRobot(tXinyiRobot);
  733. }
  734. }
  735. }
  736. public static String handleDate(String str){
  737. StringBuilder sb = new StringBuilder();
  738. if(str.contains(" ")){//包含空格 就是年月日时分秒了
  739. String[] split = str.split(" ");
  740. addBeforeZero(sb, split[0], "/");
  741. sb.append(" ");
  742. addBeforeZero(sb, split[1], ":");
  743. }else{
  744. if(str.contains("/")){//年月日
  745. addBeforeZero(sb, str, "/");
  746. }else if(str.contains(":")){//时分秒
  747. addBeforeZero(sb, str, ":");
  748. }else {
  749. sb.append(str);
  750. }
  751. }
  752. return sb.toString();
  753. }
  754. public static StringBuilder addBeforeZero(StringBuilder sb, String str, String tag){
  755. String[] split = str.split(tag);
  756. int length = split.length;
  757. for (int i = 0; i < length; i++) {
  758. String value = split[i];
  759. Integer intValue = Integer.parseInt(value);
  760. if(intValue < 10 && value.length() == 1){////防止有正确的情况 额外再补充字符串
  761. sb.append(0).append(value);
  762. }else{
  763. sb.append(value);
  764. }
  765. if(i < length-1){
  766. sb.append(tag);
  767. }
  768. }
  769. return sb;
  770. }
  771. public static void main(String[] args) {
  772. /*LocalDateTime endTime = LocalDateTime.now();
  773. System.out.println("endTime = " + endTime);
  774. endTime = endTime.plusMinutes(60);
  775. System.out.println("endTime = " + endTime);*/
  776. /*String str = "2024/04/15 09:55";
  777. System.out.println(str);
  778. System.out.println(str.substring(0,10));
  779. System.out.println(str.substring(0,13));*/
  780. /*String str = "2024/04/18 08:00";
  781. str = str + ":00";
  782. System.out.println(str);
  783. LocalDateTime startTime = LocalDateTime.parse(str.replaceAll("/", "-").replace(" ", "T"));
  784. System.out.println(startTime.plusMinutes(1L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));*/
  785. ArrayList<Integer> objects = new ArrayList<>();
  786. objects.add(1);
  787. objects.add(2);
  788. objects.add(3);
  789. System.out.println(objects);
  790. objects.clear();
  791. System.out.println(objects);
  792. // test();
  793. Date date = new Date();
  794. System.out.println(DateUtils.differentHoursByMillisecond(date, date));
  795. HashMap<Object, Object> map = new HashMap<>();
  796. map.put("a", null);
  797. map.put("b", "ab");
  798. map.put("c", "");
  799. map.put("d", '1');
  800. System.out.println(JSON.toJSONString(map, JSONWriter.Feature.WriteNulls));
  801. TXinyiIndustry tXinyiIndustry = new TXinyiIndustry();
  802. System.out.println(JSON.toJSONString(tXinyiIndustry, JSONWriter.Feature.WriteNulls));
  803. }
  804. //测试工业库 没小时保存一条记录是否可行
  805. public static void test() {
  806. // 每个小时的时间格式
  807. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  808. LocalDateTime startTime = LocalDateTime.parse("2024-05-18T00:00:00");
  809. LocalDateTime endTime = LocalDateTime.now();
  810. // 循环按小时分割
  811. LocalDateTime currentHour = startTime;
  812. //最终获取的数据
  813. Map<String, TXinyiIndustry> needMap = new LinkedHashMap<>();
  814. while (currentHour.isBefore(endTime)) {
  815. String begin = currentHour.format(formatter);
  816. String end = currentHour.plusMinutes(5).format(formatter);
  817. // 输出当前小时的起始时间和结束时间
  818. System.out.println("起始时间:" + begin);
  819. System.out.println("结束时间:" + end);
  820. // 当前小时加一小时,作为下一个小时的起始时间
  821. currentHour = currentHour.plusMinutes(5);
  822. //每个小时查询一次数据
  823. String url = "http://10.0.0.27:4568/api/v1/khquerydata";
  824. HashMap<String, Object> req = new HashMap<>();
  825. req.put("tagNames", queryTags);
  826. req.put("startTime", begin);
  827. req.put("endTime", end);
  828. req.put("recordNumbers", 100000);
  829. String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body();
  830. // System.out.println("body = " + body);
  831. List<HashMap<String, String>> list = new ArrayList<>();
  832. //行转列数据处理
  833. for (String queryTag : queryTags) {
  834. JSONArray array = JSON.parseObject(body).getJSONArray(queryTag);
  835. //特殊数据处理一
  836. if(Objects.isNull(array) || array.isEmpty()){
  837. System.out.println(queryTag + "查询到了空的数据,跳过本次循环");
  838. continue;
  839. }
  840. int size = array.size();
  841. //特殊数据处理二
  842. if("0".equals(array.get(1) + "")){
  843. System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0");
  844. continue;
  845. }
  846. //结合至少62个数据才满足条件(有可能获取不到)
  847. /*if(size < 62){
  848. System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环");
  849. continue;
  850. }*/
  851. //存放的数据集
  852. //利用map去重
  853. HashMap<String, String> map = new LinkedHashMap<>();
  854. for (int i = 2; i < size; i++) {
  855. // System.out.println(i + "" + array.get(i));
  856. JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i)));
  857. //处理为空或者为0的数据
  858. Object timeStampValue = oneRecord.get(2);
  859. if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + ""))
  860. continue;
  861. BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + "");
  862. long timestamp = (long) timeStampValue;
  863. String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS);
  864. map.put(format, queryTag + "-" + value);
  865. }
  866. list.add(map);
  867. }
  868. Set<String> recordTimeSet = new HashSet<>();
  869. Map<String, TXinyiIndustry> recordMap = new HashMap<>();
  870. for (int i = 0; i < list.size(); i++) {
  871. HashMap<String, String> map = list.get(i);
  872. int finalJ = i;
  873. map.forEach((k, v) ->{
  874. TXinyiIndustry industry = null;
  875. if(!recordTimeSet.contains(k)){//第一次
  876. industry = new TXinyiIndustry();
  877. recordTimeSet.add(k);
  878. recordMap.put(k, industry);
  879. }else{
  880. industry = recordMap.get(k);
  881. }
  882. industry.setTestTime(k + ":00");
  883. //2024年4月15日11:19:52 额外增加2个字段
  884. industry.setTestDate(k.substring(0,10));
  885. industry.setTestHour(k.substring(0,13));
  886. //解析值
  887. String[] split = v.split("-");
  888. String type = split[0];
  889. BigDecimal value = new BigDecimal(split[1]);
  890. if ("信义污水厂JS_COD_Value".equals(type)) {
  891. industry.setJsCod(value);
  892. } else if ("信义污水厂JS_PH_Value".equals(type)) {
  893. industry.setJsPh(value);
  894. } else if ("信义污水厂JS_SS_Value".equals(type)) {
  895. industry.setJsSs(value);
  896. } else if ("信义污水厂JS_ZL_Value".equals(type)) {
  897. industry.setJsTp(value);
  898. } else if ("信义污水厂JS_ZA_Value".equals(type)) {
  899. industry.setJsTn(value);
  900. } else if ("信义污水厂JS_AD_Value".equals(type)) {
  901. industry.setJsNh3(value);
  902. } else if ("信义污水厂JS_T_Value".equals(type)) {
  903. industry.setJsSwPh(value);
  904. } else if ("信义污水厂进水泵房液位".equals(type)) {
  905. industry.setJsBfyw(value);
  906. } else if ("信义污水厂出水瞬时流量".equals(type)) {
  907. industry.setCsSlqc(value);
  908. } else if ("信义污水厂升级出水COD".equals(type)) {
  909. industry.setCsCod(value);
  910. } else if ("信义污水厂升级出水PH".equals(type)) {
  911. industry.setCsPh(value);
  912. } else if ("信义污水厂升级出水SS".equals(type)) {
  913. industry.setCsSs(value);
  914. } else if ("信义污水厂升级出水TN".equals(type)) {
  915. industry.setCsTn(value);
  916. } else if ("信义污水厂升级出水TP".equals(type)) {
  917. industry.setCsTp(value);
  918. } else if ("信义污水厂升级出水氨氮".equals(type)) {
  919. industry.setCsNh3(value);
  920. } else if ("信义污水厂AIT202_Value".equals(type)) {
  921. industry.setOneHyzdDo(value);
  922. } else if ("信义污水厂AIT203_Value".equals(type)) {
  923. industry.setOneHymdDo(value);
  924. } else if ("信义污水厂AIT207_Value".equals(type)) {
  925. industry.setTwoHyzdDo(value);
  926. } else if ("信义污水厂AIT206_Value".equals(type)) {
  927. industry.setTwoHymdDo(value);
  928. } else if ("信义污水厂AIT209_Value".equals(type)) {
  929. industry.setOneMlss(value);
  930. } else if ("信义污水厂AIT210_Value".equals(type)) {
  931. industry.setTwoMlss(value);
  932. } else if ("信义污水厂进水TDS".equals(type)) {
  933. industry.setJsTds(value);
  934. } else if ("信义污水厂FT101_Value".equals(type)) {
  935. industry.setJsSlq(value);
  936. } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) {
  937. industry.setNHlbOneGp(value);
  938. } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) {
  939. industry.setNHlbTwoGp(value);
  940. } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) {
  941. industry.setNHlbThreeGp(value);
  942. } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) {
  943. industry.setNHlbFourGp(value);
  944. } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) {
  945. industry.setNhlBFiveGp(value);
  946. } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) {
  947. industry.setNHlbSixGp(value);
  948. } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) {
  949. industry.setWHlbOneGp(value);
  950. } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) {
  951. industry.setWHlbTwoGp(value);
  952. } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) {
  953. industry.setWHlbThreeGp(value);
  954. } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) {
  955. industry.setWHlbFourGp(value);
  956. } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) {
  957. industry.setWHlbFiveGp(value);
  958. } else if ("信义污水厂GFJ1_R_Value".equals(type)) {
  959. industry.setFjOne(value);
  960. } else if ("信义污水厂GFJ2_R_Value".equals(type)) {
  961. industry.setFjTwo(value);
  962. } else if ("信义污水厂GFJ3_R_Value".equals(type)) {
  963. industry.setFjThree(value);
  964. } else if ("信义污水厂GFJ4_R_Value".equals(type)) {
  965. industry.setFjFour(value);
  966. } else if ("信义污水厂GFJ5_R_Value".equals(type)) {
  967. industry.setFjFive(value);
  968. } else if ("信义污水厂GFJ6_R_Value".equals(type)) {
  969. industry.setFjSix(value);
  970. } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) {
  971. industry.setKqllOne(value);
  972. } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) {
  973. industry.setKqllTwo(value);
  974. } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) {
  975. industry.setKqllThree(value);
  976. } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) {
  977. industry.setKqllFour(value);
  978. } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) {
  979. industry.setKqllFive(value);
  980. } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) {
  981. industry.setKqllSix(value);
  982. }else if ("信义污水厂实际碳源加药量".equals(type)) {
  983. industry.setSJTYJLY(value);
  984. }else if ("信义污水厂除磷加药瞬时流量".equals(type)) {
  985. industry.setCLJYSSLL(value);
  986. } else if ("信义污水厂_除磷P04预测值_".equals(type)) {
  987. industry.setCLP04YCZ(value);
  988. }
  989. //只有最后一次才执行数据库添加
  990. if(finalJ == list.size()-1){
  991. needMap.put(industry.getTestHour(), industry);
  992. }
  993. });
  994. }
  995. }
  996. //保存数据 触发告警 决策 问答记录等等
  997. needMap.forEach((k, industry) ->{
  998. System.out.println(JSON.toJSONString(industry));
  999. });
  1000. }
  1001. }