RyTask.java 105 KB

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