RyTask.java 140 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464
  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.res.SmartAdd;
  19. import com.slibra.business.service.IFrontService;
  20. import com.slibra.business.service.ITXinyiForecastComparisonService;
  21. import com.slibra.common.DecimalUtils;
  22. import com.slibra.common.config.BigModelConfig;
  23. import com.slibra.common.constant.MyConstants;
  24. import com.slibra.common.core.domain.TXinyiDaily;
  25. import com.slibra.common.enums.BusinessEnum;
  26. import com.slibra.common.enums.DataSourceType;
  27. import com.slibra.common.utils.DateUtils;
  28. import com.slibra.common.utils.LocalDateTimeUtil;
  29. import com.slibra.common.utils.uuid.IdUtils;
  30. import com.slibra.framework.datasource.DynamicDataSourceContextHolder;
  31. import com.slibra.quartz.business.JsCsFormatData;
  32. import inference.InferenceAPIsServiceGrpc;
  33. import inference.PredictionResponse;
  34. import inference.PredictionsRequest;
  35. import io.grpc.ManagedChannel;
  36. import io.grpc.ManagedChannelBuilder;
  37. import lombok.extern.slf4j.Slf4j;
  38. import org.springframework.beans.factory.annotation.Autowired;
  39. import org.springframework.beans.factory.annotation.Value;
  40. import org.springframework.stereotype.Component;
  41. import com.slibra.common.utils.StringUtils;
  42. import org.springframework.util.CollectionUtils;
  43. import java.io.IOException;
  44. import java.math.BigDecimal;
  45. import java.math.RoundingMode;
  46. import java.text.ParseException;
  47. import java.time.LocalDateTime;
  48. import java.time.format.DateTimeFormatter;
  49. import java.util.*;
  50. import java.util.concurrent.TimeUnit;
  51. import java.util.stream.Collectors;
  52. import static com.slibra.common.constant.MyConstants.*;
  53. import static com.slibra.common.enums.BusinessEnum.BigModelWarningTypeRemarkEnum.TWO_YC_WARNING;
  54. import static com.slibra.common.enums.BusinessEnum.WarningCategoryEnum.CS_TP_YC;
  55. /**
  56. * 定时任务调度测试
  57. *
  58. *
  59. */
  60. @Component("ryTask")
  61. @Slf4j
  62. public class RyTask
  63. {
  64. public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
  65. {
  66. System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
  67. }
  68. public void ryParams(String params)
  69. {
  70. System.out.println("执行有参方法:" + params);
  71. }
  72. public void ryNoParams()
  73. {
  74. System.out.println("执行无参方法");
  75. }
  76. //----------------------------------------------下面是新增的方法----------------------------------------------
  77. @Autowired
  78. private TXinyiIndustryMapper xinyiIndustryMapper;
  79. @Autowired
  80. private TXinyiRobotMapper xinyiRobotMapper;
  81. @Autowired
  82. private TXinyiNormConfigMapper xinyiNormConfigMapper;
  83. @Autowired
  84. private TXinyiWarningRecordMapper xinyiWarningRecordMapper;
  85. @Autowired
  86. private TXinyiChatRecordMapper xinyiChatRecordMapper;
  87. @Autowired
  88. private TXinyiDailyMapper xinyiDailyMapper;
  89. @Autowired
  90. private AsyncTask asyncTask;
  91. @Autowired
  92. private ITXinyiForecastComparisonService xinyiForecastComparisonService;
  93. @Autowired
  94. private BigModelConfig bigModelConfig;
  95. @Autowired
  96. private TXinyiBigTableDayMapper xinyiBigTableDayMapper;
  97. @Autowired
  98. private TXinyiBigTableMonthMapper xinyiBigTableMonthMapper;
  99. @Autowired
  100. private TXinyiBigTableHourMapper xinyiBigTableHourMapper;
  101. @Autowired
  102. private JsCsFormatData jsCsFormatData;
  103. @Autowired
  104. private TXinyiMedicineParamMapper xinyiMedicineParamMapper;
  105. @Autowired
  106. private TXinyiMedicineConfMapper xinyiMedicineConfMapper;
  107. @Autowired
  108. private IFrontService frontService;
  109. /** 使用的是哪个环境 */
  110. @Value("${spring.profiles.active}")
  111. private String environment;
  112. // public final static StopWatch watch = new StopWatch("task");
  113. 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预测值_"};
  114. /**
  115. *
  116. * 2024年6月21日14:52:05 调整逻辑:
  117. * 出水总氮 的预测:使用 (xsy1 + xsy2) /2 /0.8 做为出水总氮的结果
  118. *
  119. */
  120. // public static final String[] predictorArr = {"出水COD", "出水SS", "出水总磷", "出水氨氮"};
  121. public static final String[] predictorArr = {"cs_cod", "cs_ss", "cs_tp", "cs_andan", "xsy1", "xsy2", "qyxsy1", "qyxsy2", "缺氧出水氨氮1", "缺氧出水氨氮2"};
  122. public static final String[] predictorArrSpecial = {"xsy1", "xsy2"};
  123. /**
  124. * 定时从工业库获取数据
  125. *
  126. * 2024年4月17日17:44:15 调整逻辑:考虑到因断电等情况导致服务断电,所以不再同步最近一小时,而是同步从上次成功的最后一条数据开始。
  127. */
  128. public void getIndustryData(){
  129. log.info("进入了定时同步工业库数据的任务");
  130. //耗时工具
  131. // watch.start("parseJob");
  132. // 给定时间段的起始时间和结束时间
  133. LocalDateTime endTime = LocalDateTime.now();
  134. // LocalDateTime startTime = endTime.plusMinutes(-60);
  135. //获取上次最后一条同步的数据的日期到 分钟维度
  136. String lastDateHour = this.xinyiIndustryMapper.getLastMinute();
  137. log.info("获取上次同步工业库的最后一条记录的时间是{}", lastDateHour);
  138. lastDateHour = lastDateHour + ":00";
  139. //开始时间
  140. LocalDateTime startTime = LocalDateTime.parse(lastDateHour.replaceAll("/", "-").replace(" ", "T"));
  141. startTime = startTime.plusMinutes(60L);//加一分钟 从上次最后一条记录的下一分钟开始
  142. /*LocalDateTime startTime = LocalDateTime.parse("2024-02-26T00:00:00");
  143. LocalDateTime endTime = LocalDateTime.parse("2024-02-27T00:00:00");*/
  144. // 每个小时的时间格式
  145. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  146. // 循环按小时分割
  147. LocalDateTime currentHour = startTime;
  148. //最终获取的数据
  149. Map<String, TXinyiIndustry> needMap = new LinkedHashMap<>();
  150. while (currentHour.isBefore(endTime)) {
  151. String begin = currentHour.format(formatter);
  152. String end = currentHour.plusMinutes(5).format(formatter);
  153. // 输出当前小时的起始时间和结束时间
  154. System.out.println("起始时间:" + begin);
  155. System.out.println("结束时间:" + end);
  156. // 当前小时加一小时,作为下一个小时的起始时间
  157. currentHour = currentHour.plusMinutes(5);
  158. //每个小时查询一次数据
  159. String url = "http://10.0.0.27:4568/api/v1/khquerydata";
  160. HashMap<String, Object> req = new HashMap<>();
  161. req.put("tagNames", queryTags);
  162. req.put("startTime", begin);
  163. req.put("endTime", end);
  164. req.put("recordNumbers", 100000);
  165. String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body();
  166. // System.out.println("body = " + body);
  167. List<HashMap<String, String>> list = new ArrayList<>();
  168. //行转列数据处理
  169. for (String queryTag : queryTags) {
  170. JSONArray array = JSON.parseObject(body).getJSONArray(queryTag);
  171. //特殊数据处理一
  172. if(Objects.isNull(array) || array.isEmpty()){
  173. System.out.println(queryTag + "查询到了空的数据,跳过本次循环");
  174. continue;
  175. }
  176. int size = array.size();
  177. //特殊数据处理二
  178. if("0".equals(array.get(1) + "")){
  179. System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0");
  180. continue;
  181. }
  182. //结合至少62个数据才满足条件(有可能获取不到)
  183. /*if(size < 62){
  184. System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环");
  185. continue;
  186. }*/
  187. //存放的数据集
  188. //利用map去重
  189. HashMap<String, String> map = new LinkedHashMap<>();
  190. for (int i = 2; i < size; i++) {
  191. // System.out.println(i + "" + array.get(i));
  192. JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i)));
  193. //处理为空或者为0的数据
  194. Object timeStampValue = oneRecord.get(2);
  195. if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + ""))
  196. continue;
  197. BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + "");
  198. long timestamp = (long) timeStampValue;
  199. String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS);
  200. map.put(format, queryTag + "-" + value);
  201. }
  202. list.add(map);
  203. }
  204. Set<String> recordTimeSet = new HashSet<>();
  205. Map<String, TXinyiIndustry> recordMap = new HashMap<>();
  206. for (int i = 0; i < list.size(); i++) {
  207. HashMap<String, String> map = list.get(i);
  208. int finalJ = i;
  209. map.forEach((k, v) ->{
  210. TXinyiIndustry industry = null;
  211. if(!recordTimeSet.contains(k)){//第一次
  212. industry = new TXinyiIndustry();
  213. recordTimeSet.add(k);
  214. recordMap.put(k, industry);
  215. }else{
  216. industry = recordMap.get(k);
  217. }
  218. industry.setTestTime(k + ":00");
  219. //2024年4月15日11:19:52 额外增加2个字段
  220. industry.setTestDate(k.substring(0,10));
  221. industry.setTestHour(k.substring(0,13));
  222. //解析值
  223. String[] split = v.split("-");
  224. String type = split[0];
  225. BigDecimal value = new BigDecimal(split[1]);
  226. if ("信义污水厂JS_COD_Value".equals(type)) {
  227. industry.setJsCod(value);
  228. } else if ("信义污水厂JS_PH_Value".equals(type)) {
  229. industry.setJsPh(value);
  230. } else if ("信义污水厂JS_SS_Value".equals(type)) {
  231. // log.info("************----------真实的进水SS的值为{}\n时间为{}", value, k);
  232. industry.setJsSs(value);
  233. } else if ("信义污水厂JS_ZL_Value".equals(type)) {
  234. industry.setJsTp(value);
  235. } else if ("信义污水厂JS_ZA_Value".equals(type)) {
  236. industry.setJsTn(value);
  237. } else if ("信义污水厂JS_AD_Value".equals(type)) {
  238. industry.setJsNh3(value);
  239. } else if ("信义污水厂JS_T_Value".equals(type)) {
  240. industry.setJsSwPh(value);
  241. } else if ("信义污水厂进水泵房液位".equals(type)) {
  242. industry.setJsBfyw(value);
  243. } else if ("信义污水厂出水瞬时流量".equals(type)) {
  244. industry.setCsSlqc(value);
  245. } else if ("信义污水厂升级出水COD".equals(type)) {
  246. industry.setCsCod(value);
  247. } else if ("信义污水厂升级出水PH".equals(type)) {
  248. industry.setCsPh(value);
  249. } else if ("信义污水厂升级出水SS".equals(type)) {
  250. industry.setCsSs(value);
  251. } else if ("信义污水厂升级出水TN".equals(type)) {
  252. // log.info("************----------真实的出水总氮的值为{}\n时间为{}", value, k);
  253. // industry.setCsTn(new BigDecimal(17));
  254. industry.setCsTn(value);
  255. } else if ("信义污水厂升级出水TP".equals(type)) {
  256. industry.setCsTp(value);
  257. } else if ("信义污水厂升级出水氨氮".equals(type)) {
  258. industry.setCsNh3(value);
  259. } else if ("信义污水厂AIT202_Value".equals(type)) {
  260. industry.setOneHyzdDo(value);
  261. } else if ("信义污水厂AIT203_Value".equals(type)) {
  262. industry.setOneHymdDo(value);
  263. } else if ("信义污水厂AIT207_Value".equals(type)) {
  264. industry.setTwoHyzdDo(value);
  265. } else if ("信义污水厂AIT206_Value".equals(type)) {
  266. industry.setTwoHymdDo(value);
  267. } else if ("信义污水厂AIT209_Value".equals(type)) {
  268. industry.setOneMlss(value);
  269. } else if ("信义污水厂AIT210_Value".equals(type)) {
  270. industry.setTwoMlss(value);
  271. } else if ("信义污水厂进水TDS".equals(type)) {
  272. industry.setJsTds(value);
  273. } else if ("信义污水厂FT101_Value".equals(type)) {
  274. industry.setJsSlq(value);
  275. } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) {
  276. industry.setNHlbOneGp(value);
  277. } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) {
  278. industry.setNHlbTwoGp(value);
  279. } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) {
  280. industry.setNHlbThreeGp(value);
  281. } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) {
  282. industry.setNHlbFourGp(value);
  283. } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) {
  284. industry.setNhlBFiveGp(value);
  285. } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) {
  286. industry.setNHlbSixGp(value);
  287. } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) {
  288. industry.setWHlbOneGp(value);
  289. } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) {
  290. industry.setWHlbTwoGp(value);
  291. } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) {
  292. industry.setWHlbThreeGp(value);
  293. } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) {
  294. industry.setWHlbFourGp(value);
  295. } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) {
  296. industry.setWHlbFiveGp(value);
  297. } else if ("信义污水厂GFJ1_R_Value".equals(type)) {
  298. industry.setFjOne(value);
  299. } else if ("信义污水厂GFJ2_R_Value".equals(type)) {
  300. industry.setFjTwo(value);
  301. } else if ("信义污水厂GFJ3_R_Value".equals(type)) {
  302. industry.setFjThree(value);
  303. } else if ("信义污水厂GFJ4_R_Value".equals(type)) {
  304. industry.setFjFour(value);
  305. } else if ("信义污水厂GFJ5_R_Value".equals(type)) {
  306. industry.setFjFive(value);
  307. } else if ("信义污水厂GFJ6_R_Value".equals(type)) {
  308. industry.setFjSix(value);
  309. } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) {
  310. industry.setKqllOne(value);
  311. } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) {
  312. industry.setKqllTwo(value);
  313. } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) {
  314. industry.setKqllThree(value);
  315. } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) {
  316. industry.setKqllFour(value);
  317. } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) {
  318. industry.setKqllFive(value);
  319. } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) {
  320. industry.setKqllSix(value);
  321. }else if ("信义污水厂实际碳源加药量".equals(type)) {
  322. industry.setSJTYJLY(value);
  323. }else if ("信义污水厂除磷加药瞬时流量".equals(type)) {
  324. industry.setCLJYSSLL(value);
  325. } else if ("信义污水厂_除磷P04预测值_".equals(type)) {
  326. industry.setCLP04YCZ(value);
  327. }
  328. //只有最后一次才执行数据库添加
  329. if(finalJ == list.size()-1){
  330. needMap.put(industry.getTestHour(), industry);
  331. }
  332. });
  333. }
  334. }
  335. //保存数据 触发告警 决策 问答记录等等
  336. needMap.forEach((k, industry) ->{
  337. //2024年4月22日15:45:24 额外保存两个字段 数组
  338. List<BigDecimal> extraList = new ArrayList<>();
  339. extraList.add(industry.getOneHymdDo());
  340. extraList.add(industry.getTwoHymdDo());
  341. industry.setHycRjyAll(JSON.toJSONString(extraList));
  342. extraList.clear();
  343. extraList.add(industry.getOneHyzdDo());
  344. extraList.add(industry.getTwoHyzdDo());
  345. industry.setHycRjyZdAll(JSON.toJSONString(extraList));
  346. extraList.clear();
  347. extraList.add(industry.getOneMlss());
  348. extraList.add(industry.getTwoMlss());
  349. industry.setHycWnndAll(JSON.toJSONString(extraList));
  350. //插入数据库
  351. xinyiIndustryMapper.insertTXinyiIndustry(industry);
  352. //判断是否触发告警、接触告警、保存决策等等
  353. // this.handleWarning(industry);
  354. //2024年5月30日18:29:20 改为异步处理
  355. asyncTask.handleWarning(industry);
  356. });
  357. //执行完成 测试执行时间
  358. //计时结束
  359. // watch.stop();
  360. // System.out.println(watch.getLastTaskName() + " 执行耗时:" + watch.getLastTaskTimeMillis() + " ms");
  361. }
  362. private String buildShowValueDeviceErr(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  363. JSONObject result = new JSONObject();
  364. JSONObject basic = new JSONObject();
  365. Integer status = tXinyiWarningRecord.getStatus();
  366. Date warningTime = tXinyiWarningRecord.getTime();
  367. int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1;
  368. basic.put("title", tXinyiWarningRecord.getReason());
  369. basic.put("报警时间", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime));
  370. basic.put("报警值", DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getWarningVal(), INT_2));
  371. basic.put("标准值", DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getDesignVal(), INT_2));
  372. basic.put("管控值", DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getControlVal(), INT_2));
  373. basic.put("报警次数", Math.min(count, MAX_COUNT));
  374. if(tXinyiWarningRecord.getType() != 2)
  375. basic.put("状态", status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中");
  376. else
  377. basic.put("状态", status == 0 ? "预警中" : "已完成");
  378. //2024年5月27日14:04:22 额外返回2个字段 [管控值 和 告警级别] 返回的json没有数据是因为value没有值
  379. // basic.put("管控值", tXinyiWarningRecord.getControlVal());
  380. basic.put("告警级别", tXinyiWarningRecord.getLevel());
  381. result.put("basic", basic);
  382. JSONObject jsData = jsCsFormatData.getJsonObject(tXinyiIndustry, normConfig);//进水数据
  383. result.put("jsData", jsData);
  384. JSONObject csData = jsCsFormatData.getCsonObject(tXinyiIndustry, normConfig);//出水数据
  385. result.put("csData", csData);
  386. return JSON.toJSONString(result, JSONWriter.Feature.WriteNulls);
  387. }
  388. /**
  389. * 带图形的构建展示数据
  390. *
  391. * @param tXinyiWarningRecord
  392. * @param tXinyiIndustry
  393. * @param normConfig
  394. * @param date
  395. * @param yjHour
  396. * @param nowDate
  397. * @return
  398. */
  399. private String buildShowValueWithCharts(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, List<ChartBasic> chartsDataList, String date, String yjHour, Date nowDate) {
  400. JSONObject result = new JSONObject();
  401. // JSONObject basic = new JSONObject();
  402. Integer status = tXinyiWarningRecord.getStatus();
  403. /*Date warningTime = tXinyiWarningRecord.getTime();
  404. String remark = tXinyiWarningRecord.getRemark();
  405. int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1;*/
  406. ShowValueChartBasic showValueChartBasic = new ShowValueChartBasic();
  407. /*if("0".equals(remark)){//水质报警
  408. showValueChartBasic.setH(ZAIXIANYIBIAO);
  409. }else if("1".equals(remark)){//生化报警
  410. showValueChartBasic.setH(ZAIXIANYIBIAO);
  411. }else if("2".equals(remark)){//预测报错
  412. showValueChartBasic.setH(YVCE);
  413. }else {//机器人化验室报警
  414. showValueChartBasic.setH(LIANXUJIANCE);
  415. }*/
  416. //通用的
  417. // showValueBasic.setA(tXinyiWarningRecord.getReason());
  418. //2024年6月23日17:01:30 预警时间改成当前时间
  419. showValueChartBasic.setB(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM, nowDate));
  420. showValueChartBasic.setC(date + " " + yjHour);//预计超标时间
  421. showValueChartBasic.setD(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getWarningVal(), INT_2));//改成现在值 不是报警时候的值(在发现存在告警记录的时候更新)
  422. showValueChartBasic.setE(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getForecastVal(), INT_2));//改成预测值 不是报警时候的值(在发现存在告警记录的时候更新)
  423. showValueChartBasic.setF(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getControlVal(), INT_2));
  424. showValueChartBasic.setG(DecimalUtils.getAbsAndScale(tXinyiWarningRecord.getDesignVal(), INT_2));
  425. // showValueChartBasic.setH(Math.min(count, MAX_COUNT));
  426. //2024年7月20日17:28:17 增加数据来源展示
  427. String category = tXinyiWarningRecord.getCategory();
  428. if(BusinessEnum.WarningCategoryEnum.CS_COD_YC.getCode().equals(category)
  429. || BusinessEnum.WarningCategoryEnum.CS_SS_YC.getCode().equals(category)
  430. || BusinessEnum.WarningCategoryEnum.CS_AD_YC.getCode().equals(category))
  431. showValueChartBasic.setH(ZAIXIANYIBIAO);
  432. else
  433. showValueChartBasic.setH(LIANXUJIANCE);
  434. if(tXinyiWarningRecord.getType() != 2)
  435. showValueChartBasic.setI(status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中");
  436. else
  437. showValueChartBasic.setI(status == 0 ? "预警中" : "已完成");
  438. result.put("basic", showValueChartBasic);
  439. JSONObject jsData = jsCsFormatData.getJsonObject(tXinyiIndustry, normConfig);//进水数据
  440. result.put("jsData", jsData);
  441. JSONObject csData = jsCsFormatData.getCsonObject(tXinyiIndustry, normConfig);//出水数据
  442. result.put("csData", csData);
  443. // JSONObject chartsData = getChartsCsonObject(tXinyiIndustry, normConfig);//图表数据 因为展示不同,所以要传过来或者判断
  444. result.put("chartsData", chartsDataList);
  445. result.put("chartsTitle", tXinyiWarningRecord.getCategory() + "数据趋势图");
  446. return JSON.toJSONString(result, JSONWriter.Feature.WriteNulls);
  447. }
  448. private static JSONObject getJsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  449. JSONObject jsData = new JSONObject();
  450. HashMap<Object, Object> temp1 = new HashMap<>();
  451. BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  452. temp1.put("value", DecimalUtils.getAbsAndScale(jsSlq, INT_2));
  453. temp1.put("exceed", jsSlq.compareTo(normConfig.getJsslSjz()) >0);
  454. jsData.put("流量", temp1);
  455. HashMap<Object, Object> temp2 = new HashMap<>();
  456. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  457. temp2.put("value", DecimalUtils.getAbsAndScale(jsCod, INT_2));
  458. temp2.put("exceed", jsCod.compareTo(normConfig.getJscodSjz()) > 0);
  459. jsData.put("COD", temp2);
  460. HashMap<Object, Object> temp3 = new HashMap<>();
  461. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  462. temp3.put("value", DecimalUtils.getAbsAndScale(jsNh3, INT_2));
  463. temp3.put("exceed", jsNh3.compareTo(normConfig.getJsadSjz()) > 0);
  464. jsData.put("NH3-N", temp3);
  465. HashMap<Object, Object> temp4 = new HashMap<>();
  466. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  467. temp4.put("value", DecimalUtils.getAbsAndScale(jsTp, INT_2));
  468. temp4.put("exceed", jsTp.compareTo(normConfig.getJszlSjz()) > 0);
  469. jsData.put("TP", temp4);
  470. HashMap<Object, Object> temp5 = new HashMap<>();
  471. BigDecimal jsSs = tXinyiIndustry.getJsSs();
  472. temp5.put("value", DecimalUtils.getAbsAndScale(jsSs, INT_2));
  473. temp5.put("exceed", jsSs.compareTo(normConfig.getJsssSjz()) > 0);
  474. jsData.put("SS", temp5);
  475. HashMap<Object, Object> temp6 = new HashMap<>();
  476. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  477. temp6.put("value", DecimalUtils.getAbsAndScale(jsTn, INT_2));
  478. temp6.put("exceed", jsTn.compareTo(normConfig.getJszdSjz()) > 0);
  479. jsData.put("TN", temp6);
  480. return jsData;
  481. }
  482. private static JSONObject getCsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  483. JSONObject csData = new JSONObject();
  484. HashMap<Object, Object> temp1 = new HashMap<>();
  485. BigDecimal csSlq = tXinyiIndustry.getCsSlqc();
  486. temp1.put("value", DecimalUtils.getAbsAndScale(csSlq, INT_2));
  487. temp1.put("exceed", false);//出水水量没有管控值
  488. csData.put("流量", temp1);
  489. HashMap<Object, Object> temp2 = new HashMap<>();
  490. BigDecimal csCod = tXinyiIndustry.getCsCod();
  491. temp2.put("value", DecimalUtils.getAbsAndScale(csCod, INT_2));
  492. temp2.put("exceed", csCod.compareTo(normConfig.getCscodGkz()) > 0);
  493. csData.put("COD", temp2);
  494. HashMap<Object, Object> temp3 = new HashMap<>();
  495. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  496. temp3.put("value", DecimalUtils.getAbsAndScale(csNh3, INT_2));
  497. temp3.put("exceed", csNh3.compareTo(normConfig.getCsadGkz()) > 0);
  498. csData.put("NH3-N", temp3);
  499. HashMap<Object, Object> temp4 = new HashMap<>();
  500. BigDecimal csTp = tXinyiIndustry.getCsTp();
  501. temp4.put("value", DecimalUtils.getAbsAndScale(csTp, INT_2));
  502. temp4.put("exceed", csTp.compareTo(normConfig.getCszlGkz()) > 0);
  503. csData.put("TP", temp4);
  504. HashMap<Object, Object> temp5 = new HashMap<>();
  505. BigDecimal csSs = tXinyiIndustry.getCsSs();
  506. temp5.put("value", DecimalUtils.getAbsAndScale(csSs, INT_2));
  507. temp5.put("exceed", csSs.compareTo(normConfig.getCsssGkz()) > 0);
  508. csData.put("SS", temp5);
  509. HashMap<Object, Object> temp6 = new HashMap<>();
  510. BigDecimal csTn = tXinyiIndustry.getCsTn();
  511. temp6.put("value", DecimalUtils.getAbsAndScale(csTn, INT_2));
  512. temp6.put("exceed", csTn.compareTo(normConfig.getCszzGkz()) > 0);
  513. csData.put("TN", temp6);
  514. return csData;
  515. }
  516. private void addChatRecordByDeviceErr(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  517. ChatReq chatReq = new ChatReq();
  518. //保存聊天记录
  519. //将问答更新到数据库中
  520. chatReq.setSessionId(IdUtils.simpleUUID());
  521. chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
  522. chatReq.setModule(3);
  523. /*String userId = SecurityUtils.getUserId().toString();
  524. String username = SecurityUtils.getUsername();*/
  525. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  526. String showVal = this.buildShowValueDeviceErr(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  527. chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
  528. chatReq.setQuestion(WARNING_DEFAULT_QUESTION);//本地问题
  529. chatReq.setAnswer(tXinyiWarningRecord.getReason() + ",请检查设备是否正常运行");
  530. chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
  531. chatReq.setCounts(1);//问答次数
  532. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  533. chatReq.setCreateTime(DateUtils.getNowDate());
  534. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  535. }
  536. /**
  537. * 定时从sqlserver获取数据
  538. */
  539. public void sqlserverData(){
  540. log.info("进入了定时同步SqlServer的任务");
  541. //主库获取上次最新的同步日期
  542. String lastTime = this.xinyiRobotMapper.selectLastTime();
  543. log.info("上次同步的日期是{}", lastTime);
  544. //从
  545. DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
  546. List<TXinyiRobot> tXinyiRobots = xinyiRobotMapper.selectTXinyiRobotListByTime(lastTime);
  547. DynamicDataSourceContextHolder.clearDataSourceType();
  548. // System.out.println(JSON.toJSONString(tXinyiRobots));
  549. // System.out.println("-------------");
  550. //主
  551. List<TXinyiRobot> needHandleList = new ArrayList<>();
  552. if(!CollectionUtils.isEmpty(tXinyiRobots)){
  553. for (TXinyiRobot tXinyiRobot : tXinyiRobots) {
  554. String date = handleDate(tXinyiRobot.getVDate().replaceAll(" ", ""));//有空格
  555. String time = handleDate(tXinyiRobot.getVTime().replaceAll(" ", ""));//有空格
  556. tXinyiRobot.setVDate(date);
  557. tXinyiRobot.setVTime(time);
  558. tXinyiRobot.setVDateTime(date + " " + time);
  559. //处理给前端展示的字段
  560. tXinyiRobot.setTestDate(date);//日期
  561. tXinyiRobot.setTestHour(date + " " + time.substring(0, 2));//小时
  562. tXinyiRobot.setTestTime(date + " " + time.substring(0, 5));//分钟
  563. tXinyiRobot.setCreatedTime(new Date());
  564. //2024年5月29日10:33:32 额外处理几个新增的字段 多个池子数据合并一个
  565. List<BigDecimal> extraList = new ArrayList<>();
  566. extraList.add(tXinyiRobot.getNo3Hlj1Jqr());
  567. extraList.add(tXinyiRobot.getNo3Hlj2Jqr());
  568. tXinyiRobot.setHycxsyAll(JSON.toJSONString(extraList));
  569. extraList.clear();
  570. extraList.add(tXinyiRobot.getNh31Jqr());
  571. extraList.add(tXinyiRobot.getNh32Jqr());
  572. tXinyiRobot.setQyanAll(JSON.toJSONString(extraList));
  573. extraList.clear();
  574. extraList.add(tXinyiRobot.getNo3Qyc1Jqr());
  575. extraList.add(tXinyiRobot.getNo3Qyc2Jqr());
  576. tXinyiRobot.setQyckxsyAll(JSON.toJSONString(extraList));
  577. extraList.clear();
  578. extraList.add(tXinyiRobot.getTpHl1Jqr());
  579. extraList.add(tXinyiRobot.getTpHl2Jqr());
  580. tXinyiRobot.setHyzlsyAll(JSON.toJSONString(extraList));
  581. //按照小时填充集合 然后处理报警相关逻辑
  582. //2024年6月17日13:32:59 因为机器人化验室数据基本几个小时的都一致 改成一小时取一次
  583. needHandleList.add(tXinyiRobot);
  584. // this.xinyiRobotMapper.insertTXinyiRobot(tXinyiRobot);
  585. }
  586. }
  587. if(!CollectionUtils.isEmpty(needHandleList)){
  588. List<TXinyiRobot> uniqueList = needHandleList.stream()
  589. .collect(Collectors.collectingAndThen(
  590. Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TXinyiRobot::getTestHour))),
  591. ArrayList::new
  592. ));
  593. if(!CollectionUtils.isEmpty(uniqueList)){
  594. for (TXinyiRobot tXinyiRobot : uniqueList) {
  595. //判断是否添加过了(小时)
  596. String testHour = tXinyiRobot.getTestHour();
  597. List<TXinyiRobot> tXinyiRobotList = this.xinyiRobotMapper.selectTXinyiRobotList(TXinyiRobot.builder().testHour(testHour).build());
  598. if(CollectionUtils.isEmpty(tXinyiRobotList)){
  599. this.xinyiRobotMapper.insertTXinyiRobot(tXinyiRobot);
  600. //2024年6月18日10:45:20 额外计算一下预测的准确度
  601. asyncTask.updateForecastComparisonByRobot(tXinyiRobot);
  602. //2024年7月6日10:32:36 大宽表的数据处理
  603. asyncTask.updateBigTableHourByRobot(tXinyiRobot);
  604. }
  605. else
  606. log.info("{}已经吧保存过了,无需重复保存***&&&···", testHour);
  607. }
  608. //2024年08月09日14:26:29 为了节省费用,测试环境关闭报警并增加手动触发报警操作
  609. if(PROD_ENVIRONMENT.equalsIgnoreCase(environment)){
  610. asyncTask.handleRobotWarning(uniqueList);
  611. }
  612. }
  613. }
  614. }
  615. /**
  616. *
  617. * 定时生成每日简报数据
  618. *
  619. */
  620. public void generateShortReport(){
  621. log.info("进入了定时生成每日简报数据");
  622. List<TXinyiDaily> dailyTwoRecords = this.xinyiDailyMapper.selectNRecords(DAILY_REPORT_COUNT_RECORD);
  623. //正常不会有这种问题 因为日报有很多条
  624. if(CollectionUtils.isEmpty(dailyTwoRecords) || dailyTwoRecords.size() < DAILY_REPORT_COUNT_RECORD){
  625. log.error("进入了定时生成每日简报数据 获取最新的{}条数据不足,终止", DAILY_REPORT_COUNT_RECORD);
  626. return;
  627. }
  628. //暂时不考虑因为没有填写日报 导致生成重复数据的问题(后续需要的话再添加)
  629. //处理数据 并 拼装
  630. String queryData = buildShortReportQueryDataNew(dailyTwoRecords);
  631. // log.info("定时生成简报,组装好的请求大模型的参数为:{}", queryData);
  632. if(StringUtils.isBlank(queryData)){
  633. log.error("无法拼装请求数据!!!!!!");
  634. return;
  635. }
  636. String showVal = formateDateStr(dailyTwoRecords.get(0).getTestDate()) + JIAN_BAO_END;
  637. //调用模型 并保存结果
  638. this.askBigModel(queryData, showVal);
  639. log.info("定时生成简报任务结束~~~~~~~~~~~~~~");
  640. }
  641. /**
  642. *
  643. * 每小时发一一次预测
  644. *
  645. */
  646. public void predictor(){
  647. //获取最新的6条工业科数据
  648. List<TXinyiIndustry> tXinyiIndustries6 = this.xinyiIndustryMapper.selectNIndustry(INT_6);
  649. List<TXinyiRobot> tXinyiRobots6 = this.xinyiRobotMapper.selectNRobot(INT_6);
  650. //2024年7月18日10:31:18 加个校验,只有从来没有数据的水厂才会进入下面的判断
  651. if(CollectionUtils.isEmpty(tXinyiIndustries6) || tXinyiIndustries6.size() < INT_6
  652. || CollectionUtils.isEmpty(tXinyiRobots6) || tXinyiRobots6.size() <INT_6){
  653. log.error("预测的时候,获取最新的6条工业数据或者化验数据不满足,任务终止,工业数据为{}\n化验数据为{}", JSON.toJSONString(tXinyiIndustries6), JSON.toJSONString(tXinyiRobots6));
  654. return;
  655. }
  656. //先处理xsy1 和 xsy2 合并成一个数据
  657. // this.predictorSpecial(tXinyiIndustries6, tXinyiRobots6);
  658. //2024年7月11日16:55:27 xsy1 和 xsy2 又不合并了。。。 再次分开处理
  659. for (int i = 0; i < predictorArr.length; i++) {
  660. String result = getPredictor(predictorArr[i]);
  661. if(StringUtils.isBlank(result) || "error".equals(result)){
  662. log.info("预测数据返回结果不符合解析条件,返回结果为{}", result);
  663. continue;
  664. }
  665. JSONObject jsonObject = null;
  666. try {
  667. jsonObject = JSON.parseObject(result);
  668. } catch (Exception e) {
  669. log.error("[转JSON的时候]预测数据返回结果不符合解析条件,返回结果为{}", result);
  670. continue;
  671. }
  672. log.info("^^^^^^^^^^^^^预测接口转弯JSON对象后,原内容是{}", JSON.toJSONString(jsonObject));
  673. //2024年7月8日15:25:51 加个校验 因为各种奇葩返回。。 比如返回的结果是 "null"
  674. if(Objects.isNull(jsonObject)){
  675. log.error("[转JSON的时候]预测数据返回结果是null,不处里");
  676. continue;
  677. }
  678. String task = jsonObject.getString("task");
  679. String hour = jsonObject.getString("hour");
  680. String pred = jsonObject.getString("pred");
  681. String date = jsonObject.getString("date");
  682. if(StringUtils.isNotBlank(pred) && pred.contains(",")){
  683. String[] split = pred.split(",");
  684. if(split.length != 3){
  685. log.error("预测数据返回结果为{},长度不是3,无法正常解析", result);
  686. //因为部分预测还不支持 所以不需要
  687. // handleXinYiWarningsYC(cscodBzz, split, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_COD_YC.getCode(), hour, normConfig);
  688. continue;
  689. }
  690. if(PROD_ENVIRONMENT.equalsIgnoreCase(environment)){
  691. //解析数据 处理报警 调研prompt 保存等
  692. this.handlePredictorWarning(split, hour, task, tXinyiIndustries6, tXinyiRobots6, date);
  693. }
  694. }else {
  695. log.error("预测数据返回结果为{},无法正常解析", result);
  696. }
  697. }
  698. }
  699. /**
  700. *
  701. * 每天定时计算天维度的数据
  702. *
  703. */
  704. public void bigModelDayHandle(){
  705. log.info("进入了定时处理 按天维度的大表数据 处理");
  706. //获取昨日的统计数据
  707. TXinyiBigTableDay xinyiBigTableDay = this.xinyiBigTableDayMapper.selectAvgByDay(LocalDateTimeUtil.getCurrentDate().plusDays(-1).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS)));
  708. //保存到插入对象
  709. //插入到数据库
  710. if(!Objects.isNull(xinyiBigTableDay)){
  711. ArrayList<BigDecimal> gyHycRjyAll = new ArrayList<>();
  712. ArrayList<BigDecimal> gyHycRjyZdAll = new ArrayList<>();
  713. ArrayList<BigDecimal> gyHycWnndAll = new ArrayList<>();
  714. ArrayList<BigDecimal> rbHycRjyAll = new ArrayList<>();
  715. ArrayList<BigDecimal> rbHycWnndAll = new ArrayList<>();
  716. ArrayList<BigDecimal> rbYycRjyAll = new ArrayList<>();
  717. ArrayList<BigDecimal> rbQycRjyAll = new ArrayList<>();
  718. ArrayList<BigDecimal> rbWncjbAll = new ArrayList<>();
  719. ArrayList<BigDecimal> rbWntjzsAll = new ArrayList<>();
  720. ArrayList<BigDecimal> rbHfxwnndAll = new ArrayList<>();
  721. ArrayList<BigDecimal> hyHycxsyAll = new ArrayList<>();
  722. ArrayList<BigDecimal> hyQyanAll = new ArrayList<>();
  723. ArrayList<BigDecimal> hyQyckxsyAll = new ArrayList<>();
  724. ArrayList<BigDecimal> hyHyzlsyAll = new ArrayList<>();
  725. gyHycRjyAll.add(xinyiBigTableDay.getGyOneHymdDo());
  726. gyHycRjyAll.add(xinyiBigTableDay.getGyTwoHymdDo());
  727. gyHycRjyZdAll.add(xinyiBigTableDay.getGyOneHyzdDo());
  728. gyHycRjyZdAll.add(xinyiBigTableDay.getGyTwoHyzdDo());
  729. gyHycWnndAll.add(xinyiBigTableDay.getGyOneMlss());
  730. gyHycWnndAll.add(xinyiBigTableDay.getGyTwoMlss());
  731. rbHycRjyAll.add(xinyiBigTableDay.getGyOneHymdDo());
  732. rbHycRjyAll.add(xinyiBigTableDay.getGyTwoHymdDo());
  733. rbHycWnndAll.add(xinyiBigTableDay.getRbShcHyOneMlss());
  734. rbHycWnndAll.add(xinyiBigTableDay.getRbShcHyTwoMlss());
  735. rbYycRjyAll.add(xinyiBigTableDay.getRbShcYyOneDo());
  736. rbYycRjyAll.add(xinyiBigTableDay.getRbShcYyTwoDo());
  737. rbQycRjyAll.add(xinyiBigTableDay.getRbShcQyOneDo());
  738. rbQycRjyAll.add(xinyiBigTableDay.getRbShcQyTwoDo());
  739. rbWncjbAll.add(xinyiBigTableDay.getRbShcHyOneSv());
  740. rbWncjbAll.add(xinyiBigTableDay.getRbShcHyTwoSv());
  741. rbWntjzsAll.add(xinyiBigTableDay.getRbShcHyOneSvi());
  742. rbWntjzsAll.add(xinyiBigTableDay.getRbShcHyTwoSvi());
  743. rbHfxwnndAll.add(xinyiBigTableDay.getRbShcHyOneMlvss());
  744. rbHfxwnndAll.add(xinyiBigTableDay.getRbShcHyTwoMlvss());
  745. hyHycxsyAll.add(xinyiBigTableDay.getHyNo3Hlj1Jqr());
  746. hyHycxsyAll.add(xinyiBigTableDay.getHyNo3Hlj2Jqr());
  747. hyQyanAll.add(xinyiBigTableDay.getHyNh31Jqr());
  748. hyQyanAll.add(xinyiBigTableDay.getHyNh32Jqr());
  749. hyQyckxsyAll.add(xinyiBigTableDay.getHyNo3Qyc1Jqr());
  750. hyQyckxsyAll.add(xinyiBigTableDay.getHyNo3Qyc2Jqr());
  751. hyHyzlsyAll.add(xinyiBigTableDay.getHyTpHl1Jqr());
  752. hyHyzlsyAll.add(xinyiBigTableDay.getHyTpHl2Jqr());
  753. xinyiBigTableDay.setGyHycRjyAll(formatList(gyHycRjyAll));
  754. xinyiBigTableDay.setGyHycRjyZdAll(formatList(gyHycRjyZdAll));
  755. xinyiBigTableDay.setGyHycWnndAll(formatList(gyHycWnndAll));
  756. xinyiBigTableDay.setRbHycRjyAll(formatList(rbHycRjyAll));
  757. xinyiBigTableDay.setRbHycWnndAll(formatList(rbHycWnndAll));
  758. xinyiBigTableDay.setRbYycRjyAll(formatList(rbYycRjyAll));
  759. xinyiBigTableDay.setRbQycRjyAll(formatList(rbQycRjyAll));
  760. xinyiBigTableDay.setRbWncjbAll(formatList(rbWncjbAll));
  761. xinyiBigTableDay.setRbWntjzsAll(formatList(rbWntjzsAll));
  762. xinyiBigTableDay.setRbHfxwnndAll(formatList(rbHfxwnndAll));
  763. xinyiBigTableDay.setHyHycxsyAll(formatList(hyHycxsyAll));
  764. xinyiBigTableDay.setHyQyanAll(formatList(hyQyanAll));
  765. xinyiBigTableDay.setHyQyckxsyAll(formatList(hyQyckxsyAll));
  766. xinyiBigTableDay.setHyHyzlsyAll(formatList(hyHyzlsyAll));
  767. this.xinyiBigTableDayMapper.insertTXinyiBigTableDay(xinyiBigTableDay);
  768. }
  769. }
  770. public void calculateAndAddMedicine(){
  771. log.info("进入了 定时计算投药 定时任务处理++++++");
  772. BigDecimal val = this.calculateMedicine();
  773. log.info("计算的结果是{}", val);
  774. boolean canAdd = false;
  775. TXinyiMedicineConf tXinyiMedicineConf = xinyiMedicineConfMapper.selectTXinyiMedicineConfById(LONG_1);
  776. if(!Objects.isNull(tXinyiMedicineConf) && !Objects.isNull(tXinyiMedicineConf.getAddStatus()) && 1 == tXinyiMedicineConf.getAddStatus()){
  777. canAdd = true;
  778. }
  779. if(!Objects.isNull(val) && canAdd){
  780. //todo 调用组态接口,实施碳源投加
  781. log.info("开始调用组态接口,实施碳源投加^^^^^^");
  782. log.info("调用组态接口,实施碳源投加结束******");
  783. }
  784. log.info(" 定时计算投药 定时任务处理 结束------");
  785. }
  786. private BigDecimal calculateMedicine() {
  787. //获取最新的配置信息
  788. TXinyiMedicineParam latestRecord = this.xinyiMedicineParamMapper.getLatestRecord();
  789. if(!Objects.isNull(latestRecord)){
  790. return this.calculateMedicineByLastRecord(latestRecord);
  791. }
  792. return null;
  793. }
  794. private BigDecimal calculateMedicineByLastRecord(TXinyiMedicineParam param) {
  795. if (Objects.isNull(param)) {
  796. return null;
  797. }
  798. //计算用到的值
  799. Integer hycXsyType = param.getHycXsyType();
  800. BigDecimal hycXsyOne = param.getHycXsyOne();
  801. BigDecimal hycXsyTwo = param.getHycXsyTwo();
  802. BigDecimal htfksd = param.getHtfksd();
  803. Integer qycAdType = param.getQycAdType();
  804. BigDecimal qycAdOne = param.getQycAdOne();
  805. BigDecimal qycAdTwo = param.getQycAdTwo();
  806. Integer qycYxyType = param.getQycYxyType();
  807. BigDecimal qycYxyOne = param.getQycYxyOne();
  808. BigDecimal qycYxyTwo = param.getQycYxyTwo();
  809. BigDecimal xzxs = param.getXzxs();
  810. BigDecimal jzxs = param.getJzxs();
  811. Integer jsLlType = param.getJsLlType();
  812. BigDecimal jsLlOne = param.getJsLlOne();//两个池子的值是一样的
  813. BigDecimal slfpxs = param.getSlfpxs();
  814. BigDecimal kzxs = param.getKzxs();
  815. Integer jsCodType = param.getJsCodType();
  816. BigDecimal jsCodOne = param.getJsCodOne();
  817. BigDecimal jsCodTwo = param.getJsCodTwo();
  818. BigDecimal zhxs = param.getZhxs();
  819. BigDecimal tydl = param.getTydl();
  820. BigDecimal medicineAmount = param.getMedicineAmount();//手动需要
  821. Integer type = param.getType();//0自动 1一号池 2二号池 3人工投放
  822. BigDecimal yymd = param.getYymd();
  823. //计算
  824. if(!Objects.isNull(type)) {
  825. if(3 == type){
  826. return medicineAmount;
  827. }
  828. //计算1号池的值
  829. BigDecimal oneResult = this.getResultByDiff(hycXsyType, hycXsyOne, htfksd, qycAdType, qycAdOne, qycYxyType, qycYxyOne, xzxs, jzxs, jsLlType, jsLlOne, slfpxs, kzxs, jsCodType, jsCodOne, zhxs, tydl, "one", yymd);
  830. //计算二号池的值
  831. BigDecimal twoResult = this.getResultByDiff(hycXsyType, hycXsyTwo, htfksd, qycAdType, qycAdTwo, qycYxyType, qycYxyTwo, xzxs, jzxs, jsLlType, jsLlOne, slfpxs, kzxs, jsCodType, jsCodTwo, zhxs, tydl, "two", yymd);
  832. //判断,返回值
  833. if(0 == type)
  834. return oneResult.compareTo(twoResult) > 0 ? oneResult : twoResult;
  835. else if(1 == type) {
  836. return oneResult;
  837. }else if(2 == type)
  838. return twoResult;
  839. else {
  840. return null;//错误的配置
  841. }
  842. }
  843. return null;
  844. }
  845. private BigDecimal getResultByDiff(Integer hycXsyType, BigDecimal hycXsyVal, BigDecimal htfksd, Integer qycAdType, BigDecimal qycAdVal, Integer qycYxyType,
  846. BigDecimal qycYxyVal, BigDecimal xzxs, BigDecimal jzxs, Integer jsLlType, BigDecimal jsLlVal, BigDecimal slfpxs, BigDecimal kzxs, Integer jsCodType,
  847. BigDecimal jsCodVal, BigDecimal zhxs, BigDecimal tydl, String whichCZ, BigDecimal yymd) {
  848. //2024年09月14日10:26:11 不同池子,根据不同类型,获取最新的数据,计算碳源投加量
  849. //获取最新的实时数据
  850. SmartAdd smartAdd = this.frontService.smartAddDataInfo();
  851. if(!Objects.isNull(smartAdd)){
  852. if("one".equals(whichCZ)){//一池
  853. if(!Objects.isNull(hycXsyType)){
  854. if(1 == hycXsyType){//化验
  855. hycXsyVal = smartAdd.getHyXsyHYOne();
  856. }else if(2 == hycXsyType){//预测
  857. hycXsyVal = smartAdd.getHyXsyYCOne();
  858. }
  859. }
  860. if(!Objects.isNull(qycAdType) && 1 == qycAdType){//化验
  861. qycAdVal = smartAdd.getQyAdHYOne();
  862. }
  863. if(!Objects.isNull(qycYxyType) && 1 == qycYxyType){//化验
  864. qycYxyVal = smartAdd.getQyXsyHYOne();
  865. }
  866. if(!Objects.isNull(jsCodType)){
  867. if(1 == jsCodType){//仪表
  868. jsCodVal = smartAdd.getJsCodYB();
  869. }else if(2 == jsCodType){//化验
  870. jsCodVal = smartAdd.getJsCodHY();
  871. }
  872. }
  873. if(!Objects.isNull(jsLlType) && 1 == jsLlType){//仪表
  874. jsLlVal = smartAdd.getJslYB();
  875. }
  876. }else {//二池
  877. if(!Objects.isNull(hycXsyType)){
  878. if(1 == hycXsyType){//化验
  879. hycXsyVal = smartAdd.getHyXsyHYTwo();
  880. }else if(2 == hycXsyType){//预测
  881. hycXsyVal = smartAdd.getHyXsyYCTwo();
  882. }
  883. }
  884. if(!Objects.isNull(qycAdType) && 1 == qycAdType){//化验
  885. qycAdVal = smartAdd.getQyAdHYTwo();
  886. }
  887. if(!Objects.isNull(qycYxyType) && 1 == qycYxyType){//化验
  888. qycYxyVal = smartAdd.getQyXsyHYTwo();
  889. }
  890. if(!Objects.isNull(jsCodType)){
  891. if(1 == jsCodType){//仪表
  892. jsCodVal = smartAdd.getJsCodYB();
  893. }else if(2 == jsCodType){//化验
  894. jsCodVal = smartAdd.getJsCodHY();
  895. }
  896. }
  897. if(!Objects.isNull(jsLlType) && 1 == jsLlType){//仪表
  898. jsLlVal = smartAdd.getJslYB();
  899. }
  900. }
  901. }
  902. //兜底处理
  903. if(Objects.isNull(hycXsyVal))
  904. hycXsyVal = BigDecimal.ZERO;
  905. if(Objects.isNull(htfksd))
  906. htfksd = BigDecimal.ZERO;
  907. if(Objects.isNull(qycAdVal))
  908. qycAdVal = BigDecimal.ZERO;
  909. if(Objects.isNull(qycYxyVal))
  910. qycYxyVal = BigDecimal.ZERO;
  911. if(Objects.isNull(xzxs))
  912. xzxs = BigDecimal.ZERO;
  913. if(Objects.isNull(jzxs))
  914. jzxs = BigDecimal.ZERO;
  915. if(Objects.isNull(jsLlVal))
  916. jsLlVal = BigDecimal.ZERO;
  917. if(Objects.isNull(slfpxs))
  918. slfpxs = BigDecimal.ZERO;
  919. if(Objects.isNull(kzxs))
  920. kzxs = BigDecimal.ZERO;
  921. if(Objects.isNull(jsCodVal))
  922. jsCodVal = BigDecimal.ZERO;
  923. if(Objects.isNull(zhxs))
  924. zhxs = BigDecimal.ZERO;
  925. if(Objects.isNull(tydl))
  926. tydl = BigDecimal.ZERO;
  927. if(Objects.isNull(yymd) || yymd.compareTo(BigDecimal.ZERO) <= 0)
  928. return null;//除数不能为0
  929. //1)计算挟走量
  930. BigDecimal xzl = (((BigDecimal_2.multiply(hycXsyVal).subtract(htfksd)).add(((qycAdVal.add(qycYxyVal)).multiply(xzxs).subtract(htfksd)))).multiply((jzxs.subtract(BigDecimal_1)))).multiply((jsLlVal.multiply(slfpxs))).divide(BigDecimal_1000, NUMBER_SCALE_4, RoundingMode.HALF_UP);
  931. //2)计算碳源投加总量
  932. BigDecimal total = (xzl.multiply(kzxs).subtract((jsLlVal.multiply(slfpxs).multiply(jsCodVal).multiply(zhxs).divide(BigDecimal_1000, NUMBER_SCALE_4, RoundingMode.HALF_UP)))).divide(tydl, NUMBER_SCALE_4, RoundingMode.HALF_UP);
  933. //2024年09月14日15:33:37 计算出来的结果太大,是几千,把第三步公式也加上
  934. //计算加药流量
  935. return DecimalUtils.getNLengthHalfUp(total.divide(yymd, NUMBER_SCALE_10, RoundingMode.HALF_UP).divide(BigDecimal_1000, NUMBER_SCALE_10, RoundingMode.HALF_UP), INT_3);
  936. }
  937. public String formatList(List<BigDecimal> list) {
  938. if (CollectionUtils.isEmpty(list)) {
  939. return null;
  940. }
  941. boolean isNullList = list.stream().allMatch(x -> x == null);
  942. return isNullList ? null : list.toString();
  943. }
  944. /**
  945. *
  946. * 每个月第一天定时计算月度维度的数据
  947. *
  948. */
  949. public void bigModelMonthHandle(){
  950. log.info("进入了 每个月第一天定时计算月度维度的数据 处理");
  951. //获取上个月的第一天和最后一天(定时任务是某个月第一天开始执行的 所以减7天,肯定是上个月的数据)
  952. LocalDateTime lastMonthDateTime = LocalDateTime.now().plusDays(-7);
  953. String begin = LocalDateTimeUtil.getMonthFirst(lastMonthDateTime).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS));
  954. String end = LocalDateTimeUtil.getMonthLast(lastMonthDateTime).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS));
  955. //获取昨日的统计数据
  956. TXinyiBigTableMonth xinyiBigTableMonth = this.xinyiBigTableMonthMapper.selectAvgByMonth(begin, end);
  957. //保存到插入对象
  958. //插入到数据库
  959. if(!Objects.isNull(xinyiBigTableMonth)){
  960. //先把日期处理一下 处理成只要月份的
  961. xinyiBigTableMonth.setTestDate(xinyiBigTableMonth.getTestDate().substring(0, 7));
  962. ArrayList<BigDecimal> gyHycRjyAll = new ArrayList<>();
  963. ArrayList<BigDecimal> gyHycRjyZdAll = new ArrayList<>();
  964. ArrayList<BigDecimal> gyHycWnndAll = new ArrayList<>();
  965. ArrayList<BigDecimal> rbHycRjyAll = new ArrayList<>();
  966. ArrayList<BigDecimal> rbHycWnndAll = new ArrayList<>();
  967. ArrayList<BigDecimal> rbYycRjyAll = new ArrayList<>();
  968. ArrayList<BigDecimal> rbQycRjyAll = new ArrayList<>();
  969. ArrayList<BigDecimal> rbWncjbAll = new ArrayList<>();
  970. ArrayList<BigDecimal> rbWntjzsAll = new ArrayList<>();
  971. ArrayList<BigDecimal> rbHfxwnndAll = new ArrayList<>();
  972. ArrayList<BigDecimal> hyHycxsyAll = new ArrayList<>();
  973. ArrayList<BigDecimal> hyQyanAll = new ArrayList<>();
  974. ArrayList<BigDecimal> hyQyckxsyAll = new ArrayList<>();
  975. ArrayList<BigDecimal> hyHyzlsyAll = new ArrayList<>();
  976. gyHycRjyAll.add(xinyiBigTableMonth.getGyOneHymdDo());
  977. gyHycRjyAll.add(xinyiBigTableMonth.getGyTwoHymdDo());
  978. gyHycRjyZdAll.add(xinyiBigTableMonth.getGyOneHyzdDo());
  979. gyHycRjyZdAll.add(xinyiBigTableMonth.getGyTwoHyzdDo());
  980. gyHycWnndAll.add(xinyiBigTableMonth.getGyOneMlss());
  981. gyHycWnndAll.add(xinyiBigTableMonth.getGyTwoMlss());
  982. rbHycRjyAll.add(xinyiBigTableMonth.getGyOneHymdDo());
  983. rbHycRjyAll.add(xinyiBigTableMonth.getGyTwoHymdDo());
  984. rbHycWnndAll.add(xinyiBigTableMonth.getRbShcHyOneMlss());
  985. rbHycWnndAll.add(xinyiBigTableMonth.getRbShcHyTwoMlss());
  986. rbYycRjyAll.add(xinyiBigTableMonth.getRbShcYyOneDo());
  987. rbYycRjyAll.add(xinyiBigTableMonth.getRbShcYyTwoDo());
  988. rbQycRjyAll.add(xinyiBigTableMonth.getRbShcQyOneDo());
  989. rbQycRjyAll.add(xinyiBigTableMonth.getRbShcQyTwoDo());
  990. rbWncjbAll.add(xinyiBigTableMonth.getRbShcHyOneSv());
  991. rbWncjbAll.add(xinyiBigTableMonth.getRbShcHyTwoSv());
  992. rbWntjzsAll.add(xinyiBigTableMonth.getRbShcHyOneSvi());
  993. rbWntjzsAll.add(xinyiBigTableMonth.getRbShcHyTwoSvi());
  994. rbHfxwnndAll.add(xinyiBigTableMonth.getRbShcHyOneMlvss());
  995. rbHfxwnndAll.add(xinyiBigTableMonth.getRbShcHyTwoMlvss());
  996. hyHycxsyAll.add(xinyiBigTableMonth.getHyNo3Hlj1Jqr());
  997. hyHycxsyAll.add(xinyiBigTableMonth.getHyNo3Hlj2Jqr());
  998. hyQyanAll.add(xinyiBigTableMonth.getHyNh31Jqr());
  999. hyQyanAll.add(xinyiBigTableMonth.getHyNh32Jqr());
  1000. hyQyckxsyAll.add(xinyiBigTableMonth.getHyNo3Qyc1Jqr());
  1001. hyQyckxsyAll.add(xinyiBigTableMonth.getHyNo3Qyc2Jqr());
  1002. hyHyzlsyAll.add(xinyiBigTableMonth.getHyTpHl1Jqr());
  1003. hyHyzlsyAll.add(xinyiBigTableMonth.getHyTpHl2Jqr());
  1004. xinyiBigTableMonth.setGyHycRjyAll(formatList(gyHycRjyAll));
  1005. xinyiBigTableMonth.setGyHycRjyZdAll(formatList(gyHycRjyZdAll));
  1006. xinyiBigTableMonth.setGyHycWnndAll(formatList(gyHycWnndAll));
  1007. xinyiBigTableMonth.setRbHycRjyAll(formatList(rbHycRjyAll));
  1008. xinyiBigTableMonth.setRbHycWnndAll(formatList(rbHycWnndAll));
  1009. xinyiBigTableMonth.setRbYycRjyAll(formatList(rbYycRjyAll));
  1010. xinyiBigTableMonth.setRbQycRjyAll(formatList(rbQycRjyAll));
  1011. xinyiBigTableMonth.setRbWncjbAll(formatList(rbWncjbAll));
  1012. xinyiBigTableMonth.setRbWntjzsAll(formatList(rbWntjzsAll));
  1013. xinyiBigTableMonth.setRbHfxwnndAll(formatList(rbHfxwnndAll));
  1014. xinyiBigTableMonth.setHyHycxsyAll(formatList(hyHycxsyAll));
  1015. xinyiBigTableMonth.setHyQyanAll(formatList(hyQyanAll));
  1016. xinyiBigTableMonth.setHyQyckxsyAll(formatList(hyQyckxsyAll));
  1017. xinyiBigTableMonth.setHyHyzlsyAll(formatList(hyHyzlsyAll));
  1018. this.xinyiBigTableMonthMapper.insertTXinyiBigTableMonth(xinyiBigTableMonth);
  1019. }
  1020. }
  1021. private void predictorSpecial(List<TXinyiIndustry> tXinyiIndustries6, List<TXinyiRobot> tXinyiRobots6) {
  1022. //数据1
  1023. String result1 = getPredictor(predictorArrSpecial[0]);
  1024. if(StringUtils.isBlank(result1) || "error".equals(result1)){
  1025. log.info("预测数据返回结果不符合解析条件,返回结果为{}", result1);
  1026. return;
  1027. }
  1028. JSONObject jsonObject1 = null;
  1029. try {
  1030. jsonObject1 = JSON.parseObject(result1);
  1031. } catch (Exception e) {
  1032. log.error("[转JSON的时候]预测数据返回结果不符合解析条件,返回结果为{}", result1);
  1033. return;
  1034. }
  1035. String hour1 = jsonObject1.getString("hour");
  1036. String pred1 = jsonObject1.getString("pred");
  1037. String date1 = jsonObject1.getString("date");
  1038. //数据2
  1039. String result2 = getPredictor(predictorArrSpecial[1]);
  1040. if(StringUtils.isBlank(result2) || "error".equals(result2)){
  1041. log.info("预测数据返回结果不符合解析条件,返回结果为{}", result2);
  1042. return;
  1043. }
  1044. JSONObject jsonObject2 = null;
  1045. try {
  1046. jsonObject2 = JSON.parseObject(result2);
  1047. } catch (Exception e) {
  1048. log.error("[转JSON的时候]预测数据返回结果不符合解析条件,返回结果为{}", result2);
  1049. return;
  1050. }
  1051. String pred2 = jsonObject2.getString("pred");
  1052. if(StringUtils.isNotBlank(pred1) && pred1.contains(",") && StringUtils.isNotBlank(pred2) && pred2.contains(",")){
  1053. String[] split1 = pred1.split(",");
  1054. String[] split2 = pred2.split(",");
  1055. if(split1.length != 3 || split2.length != 3){
  1056. return;
  1057. }
  1058. //构建两个的平均值
  1059. String[] splitNew = new String[3];
  1060. for (int i = 0; i < split1.length; i++) {
  1061. splitNew[i] = String.valueOf((Double.parseDouble(split1[i]) + Double.parseDouble(split2[i]))/2/0.8);
  1062. }
  1063. // log.info("取完平均值再组装的数组为{}", Arrays.toString(splitNew));
  1064. //解析数据 处理报警 调研prompt 保存等
  1065. this.handlePredictorWarningSpecialTn(splitNew, hour1, "tn", tXinyiIndustries6, tXinyiRobots6, date1);
  1066. }else {
  1067. log.error("预测数据返回结果为{}和{},无法正常解析", result1, result2);
  1068. }
  1069. }
  1070. private void handlePredictorWarningSpecialTn(String[] split, String hour, String task, List<TXinyiIndustry> tXinyiIndustries6, List<TXinyiRobot> tXinyiRobots6, String date) {
  1071. String[] hours = hour.split(",");
  1072. //2024年6月23日18:28:55 因为存在跨天问题 所以日期也是逗号拼接的
  1073. String[] dates = date.split(",");
  1074. //2024年6月18日13:41:10 统一格式,否则查询不到结果
  1075. //2024年6月18日10:36:49 增加预测记录,预测准确度计算等
  1076. TXinyiForecastComparison tXinyiForecastComparison = new TXinyiForecastComparison();
  1077. tXinyiForecastComparison.setCategory(task);
  1078. tXinyiForecastComparison.setForecastTimeOne(dates[0].replaceAll("-", "/") + " " + hours[0]);
  1079. tXinyiForecastComparison.setForecastTimeTwo(dates[1].replaceAll("-", "/") + " " + hours[1]);
  1080. tXinyiForecastComparison.setForecastTimeThree(dates[2].replaceAll("-", "/") + " " + hours[2]);
  1081. tXinyiForecastComparison.setHsForecastOne(new BigDecimal(split[0]));
  1082. tXinyiForecastComparison.setHsForecastTwo(new BigDecimal(split[1]));
  1083. tXinyiForecastComparison.setHsForecastThree(new BigDecimal(split[2]));
  1084. //2024年6月20日14:28:31 增加字段,方便查询
  1085. tXinyiForecastComparison.setRemark(DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYYMMDDHH_TS));
  1086. //防止工业库挂掉以后持续预测同一数据
  1087. //2024年6月20日14:59:23 因为预测bug 判断是否生成过了否则不生成
  1088. String remark = tXinyiForecastComparison.getRemark();
  1089. String category = tXinyiForecastComparison.getCategory();
  1090. TXinyiForecastComparison tXinyiForecastComparisonReq = new TXinyiForecastComparison();
  1091. tXinyiForecastComparisonReq.setRemark(remark);
  1092. tXinyiForecastComparisonReq.setCategory(category);
  1093. List<TXinyiForecastComparison> tXinyiForecastComparisons = this.xinyiForecastComparisonService.selectTXinyiForecastComparisonList(tXinyiForecastComparisonReq);
  1094. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons)){
  1095. log.error("预测已经进行过了,无需重复运行~~~~~~~~~~~@@@@@@@,时间为{}\n类型为{}", remark, category);
  1096. return;
  1097. }
  1098. //获取配置表
  1099. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  1100. if(CollectionUtils.isEmpty(tXinyiNormConfigs)) {
  1101. log.error( "未查询到配置信息");
  1102. return;
  1103. }
  1104. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  1105. //获取最新的工业库的数据
  1106. TXinyiIndustry tXinyiIndustry = this.xinyiIndustryMapper.selectTXinyiIndustryNewest();
  1107. List<ChartBasic> chartsDataList = new ArrayList<>(9);
  1108. //同时调用跃渊的预测接口 保存记录值
  1109. try {
  1110. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=3&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1111. if(!StringUtils.isBlank(result)){
  1112. JSONArray array = JSON.parseArray(result);
  1113. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1114. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1115. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1116. }
  1117. } catch (Exception e) {
  1118. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1119. }
  1120. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1121. BigDecimal cscodBzz = normConfig.getCscodBzz();
  1122. BigDecimal cscodGkz = normConfig.getCscodGkz();
  1123. //处理展示数据
  1124. for (int i = 0; i < tXinyiIndustries6.size(); i++) {
  1125. TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i);
  1126. ChartBasic chartBasic = new ChartBasic();
  1127. chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11));
  1128. //todo 2024年6月25日10:09:24 目前就存放工业库的,后续看是否调整取化验室的
  1129. chartBasic.setVal(tXinyiIndustryTemp.getCsTn());
  1130. chartsDataList.add(chartBasic);
  1131. }
  1132. for (int i = 0; i < split.length; i++) {
  1133. String val = split[i];
  1134. ChartBasic chartBasic = new ChartBasic();
  1135. chartBasic.setTime(hours[i]);
  1136. chartBasic.setVal(new BigDecimal(val));
  1137. chartsDataList.add(chartBasic);
  1138. }
  1139. handleXinYiWarningsYC(cscodBzz, split, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_TN_YC.getCode(), hour, normConfig,tXinyiIndustry.getCsTn(), tXinyiIndustry, chartsDataList, date);
  1140. //插入到数据库
  1141. //2024年6月21日14:18:55 如果红杉预测和跃渊预测都有数据再保存
  1142. //2024年7月8日15:15:46 逻辑调整:只要红杉的数据不为空就保存
  1143. if(Objects.isNull(tXinyiForecastComparison.getHsForecastOne()) || Objects.isNull(tXinyiForecastComparison.getHsForecastTwo()) ||Objects.isNull(tXinyiForecastComparison.getHsForecastThree())){
  1144. // || Objects.isNull(tXinyiForecastComparison.getYyForecastOne()) || Objects.isNull(tXinyiForecastComparison.getYyForecastTwo()) || Objects.isNull(tXinyiForecastComparison.getYyForecastThree())){
  1145. log.error("保存预测对比数据时,有存在不满足条件的数据,不再保存数据,数据为{}", JSON.toJSONString(tXinyiForecastComparison));
  1146. }else
  1147. this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1148. }
  1149. private void handlePredictorWarning(String[] split, String hour, String task, List<TXinyiIndustry> tXinyiIndustries6, List<TXinyiRobot> tXinyiRobots6, String date) {
  1150. String[] hours = hour.split(",");
  1151. //2024年6月23日18:28:55 因为存在跨天问题 所以日期也是逗号拼接的
  1152. String[] dates = date.split(",");
  1153. //2024年6月18日13:41:10 统一格式,否则查询不到结果
  1154. //2024年6月18日10:36:49 增加预测记录,预测准确度计算等
  1155. TXinyiForecastComparison tXinyiForecastComparison = new TXinyiForecastComparison();
  1156. //2024年7月11日17:04:11 TP改为zlsy
  1157. tXinyiForecastComparison.setCategory(BusinessEnum.BigModelForecastEnum.TP.getCode().equalsIgnoreCase(task) ? BusinessEnum.BigModelForecastEnum.ZLSY.getCode() : task);
  1158. tXinyiForecastComparison.setForecastTimeOne(dates[0].replaceAll("-", "/") + " " + hours[0]);
  1159. tXinyiForecastComparison.setForecastTimeTwo(dates[1].replaceAll("-", "/") + " " + hours[1]);
  1160. tXinyiForecastComparison.setForecastTimeThree(dates[2].replaceAll("-", "/") + " " + hours[2]);
  1161. tXinyiForecastComparison.setHsForecastOne(new BigDecimal(split[0]));
  1162. tXinyiForecastComparison.setHsForecastTwo(new BigDecimal(split[1]));
  1163. tXinyiForecastComparison.setHsForecastThree(new BigDecimal(split[2]));
  1164. //2024年6月20日14:28:31 增加字段,方便查询
  1165. tXinyiForecastComparison.setRemark(DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYYMMDDHH_TS));
  1166. //防止工业库挂掉以后持续预测同一数据
  1167. //2024年6月20日14:59:23 因为预测bug(以工业库为准,假如工业库挂了,获取的全是挂了时间段后的三小时) 判断是否生成过了否则不生成
  1168. TXinyiForecastComparison tXinyiForecastComparisonReq = new TXinyiForecastComparison();
  1169. //2024年08月20日16:24:56 因为remark存放的是当前时间,也就是每个小时的,所以都是不一样的,修复此bug
  1170. // tXinyiForecastComparisonReq.setRemark(tXinyiForecastComparison.getRemark());
  1171. tXinyiForecastComparisonReq.setCategory(tXinyiForecastComparison.getCategory());
  1172. //2024年7月18日15:04:37 如果工业库挂掉以后,不管什么时刻,调用预测返回的未来三小时时间都是一样的,再增加一个查询条件
  1173. tXinyiForecastComparisonReq.setForecastTimeOne(tXinyiForecastComparison.getForecastTimeOne());//一个时刻就可以了 没必要再比较第二和第三时刻了。
  1174. List<TXinyiForecastComparison> tXinyiForecastComparisons = this.xinyiForecastComparisonService.selectTXinyiForecastComparisonList(tXinyiForecastComparisonReq);
  1175. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons)){
  1176. log.error("预测已经进行过了,无需重复运行~~~~~~~~~~~@@@@@@@,要保存的预测数据为{}", JSON.toJSONString(tXinyiForecastComparison));
  1177. return;
  1178. }
  1179. //获取配置表
  1180. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  1181. if(CollectionUtils.isEmpty(tXinyiNormConfigs)) {
  1182. log.error( "未查询到配置信息");
  1183. return;
  1184. }
  1185. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  1186. //获取最新的工业库的数据
  1187. // TXinyiIndustry tXinyiIndustry = this.xinyiIndustryMapper.selectTXinyiIndustryNewest();
  1188. //2024年7月18日10:29:44 因为获取了最新的六条数据,所以无需再查询最新的数据了
  1189. TXinyiIndustry tXinyiIndustry = tXinyiIndustries6.get(0);
  1190. TXinyiRobot tXinyiRobot = tXinyiRobots6.get(0);
  1191. List<ChartBasic> chartsDataList = new ArrayList<>(9);
  1192. if(BusinessEnum.BigModelForecastEnum.COD.getCode().equals(task)){
  1193. //同时调用跃渊的预测接口 保存记录值
  1194. try {
  1195. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=2&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1196. if(!StringUtils.isBlank(result)){
  1197. JSONArray array = JSON.parseArray(result);
  1198. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1199. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1200. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1201. }
  1202. } catch (Exception e) {
  1203. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1204. }
  1205. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1206. BigDecimal cscodBzz = normConfig.getCscodBzz();
  1207. BigDecimal cscodGkz = normConfig.getCscodGkz();
  1208. //处理展示数据
  1209. for (int i = 0; i < tXinyiIndustries6.size(); i++) {
  1210. TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i);
  1211. ChartBasic chartBasic = new ChartBasic();
  1212. chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11));
  1213. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsCod(), INT_2));
  1214. chartsDataList.add(chartBasic);
  1215. }
  1216. for (int i = 0; i < split.length; i++) {
  1217. String val = split[i];
  1218. ChartBasic chartBasic = new ChartBasic();
  1219. chartBasic.setTime(hours[i]);
  1220. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1221. chartsDataList.add(chartBasic);
  1222. }
  1223. handleXinYiWarningsYC(cscodBzz, split, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_COD_YC.getCode(), hour, normConfig, tXinyiIndustry.getCsCod(), tXinyiIndustry, chartsDataList, date);
  1224. }else if(BusinessEnum.BigModelForecastEnum.SS.getCode().equals(task)){
  1225. //同时调用跃渊的预测接口 保存记录值
  1226. try {
  1227. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=5&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1228. if(!StringUtils.isBlank(result)){
  1229. JSONArray array = JSON.parseArray(result);
  1230. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1231. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1232. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1233. }
  1234. } catch (Exception e) {
  1235. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1236. }
  1237. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1238. BigDecimal csSSBzz = normConfig.getCsssBzz();
  1239. BigDecimal csssGkz = normConfig.getCsssGkz();
  1240. //处理展示数据
  1241. for (int i = 0; i < tXinyiIndustries6.size(); i++) {
  1242. TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i);
  1243. ChartBasic chartBasic = new ChartBasic();
  1244. chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11));
  1245. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsSs(), INT_2));
  1246. chartsDataList.add(chartBasic);
  1247. }
  1248. for (int i = 0; i < split.length; i++) {
  1249. String val = split[i];
  1250. ChartBasic chartBasic = new ChartBasic();
  1251. chartBasic.setTime(hours[i]);
  1252. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1253. chartsDataList.add(chartBasic);
  1254. }
  1255. handleXinYiWarningsYC(csSSBzz, split, csssGkz, BusinessEnum.WarningCategoryEnum.CS_SS_YC.getCode(), hour, normConfig, tXinyiIndustry.getCsSs(), tXinyiIndustry, chartsDataList, date);
  1256. }/*else if(BusinessEnum.BigModelForecastEnum.TN.getCode().equals(task)){
  1257. //同时调用跃渊的预测接口 保存记录值
  1258. try {
  1259. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=3&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10);
  1260. if(!StringUtils.isBlank(result)){
  1261. JSONArray array = JSON.parseArray(result);
  1262. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1263. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1264. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1265. }
  1266. } catch (Exception e) {
  1267. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1268. }
  1269. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1270. BigDecimal cszzBzz = normConfig.getCszzBzz();
  1271. BigDecimal cszzGkz = normConfig.getCszzGkz();
  1272. //处理展示数据
  1273. for (int i = 0; i < tXinyiIndustries6.size(); i++) {
  1274. TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i);
  1275. ChartBasic chartBasic = new ChartBasic();
  1276. chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11));
  1277. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsTn(), INT_2));
  1278. chartsDataList.add(chartBasic);
  1279. }
  1280. for (int i = 0; i < split.length; i++) {
  1281. String val = split[i];
  1282. ChartBasic chartBasic = new ChartBasic();
  1283. chartBasic.setTime(hours[i]);
  1284. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1285. chartsDataList.add(chartBasic);
  1286. }
  1287. handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_TN_YC.getCode(), hour, normConfig,tXinyiIndustry.getCsCod(), tXinyiIndustry, chartsDataList, date);
  1288. }*/else if(BusinessEnum.BigModelForecastEnum.TP.getCode().equals(task)){
  1289. //同时调用跃渊的预测接口 保存记录值
  1290. try {
  1291. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=1&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1292. if(!StringUtils.isBlank(result)){
  1293. JSONArray array = JSON.parseArray(result);
  1294. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1295. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1296. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1297. }
  1298. } catch (Exception e) {
  1299. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1300. }
  1301. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1302. BigDecimal cszlBzz = normConfig.getCszlBzz();
  1303. BigDecimal cszlGkz = normConfig.getCszlGkz();
  1304. //处理展示数据
  1305. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1306. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1307. ChartBasic chartBasic = new ChartBasic();
  1308. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1309. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getTpRccJqr(), INT_2));
  1310. chartsDataList.add(chartBasic);
  1311. }
  1312. for (int i = 0; i < split.length; i++) {
  1313. String val = split[i];
  1314. ChartBasic chartBasic = new ChartBasic();
  1315. chartBasic.setTime(hours[i]);
  1316. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1317. chartsDataList.add(chartBasic);
  1318. }
  1319. handleXinYiWarningsYC(cszlBzz, split, cszlGkz, CS_TP_YC.getCode(), hour, normConfig, tXinyiRobot.getTpRccJqr(), tXinyiIndustry, chartsDataList, date);
  1320. }else if(BusinessEnum.BigModelForecastEnum.NH3.getCode().equals(task)){
  1321. //同时调用跃渊的预测接口 保存记录值
  1322. try {
  1323. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=4&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1324. if(!StringUtils.isBlank(result)){
  1325. JSONArray array = JSON.parseArray(result);
  1326. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1327. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1328. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1329. }
  1330. } catch (Exception e) {
  1331. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1332. }
  1333. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1334. BigDecimal csadBzz = normConfig.getCsadBzz();
  1335. BigDecimal csadGkz = normConfig.getCsadGkz();
  1336. //处理展示数据
  1337. for (int i = 0; i < tXinyiIndustries6.size(); i++) {
  1338. TXinyiIndustry tXinyiIndustryTemp = tXinyiIndustries6.get(5 - i);
  1339. ChartBasic chartBasic = new ChartBasic();
  1340. chartBasic.setTime(tXinyiIndustryTemp.getTestHour().substring(11));
  1341. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiIndustryTemp.getCsNh3(), INT_2));
  1342. chartsDataList.add(chartBasic);
  1343. }
  1344. for (int i = 0; i < split.length; i++) {
  1345. String val = split[i];
  1346. ChartBasic chartBasic = new ChartBasic();
  1347. chartBasic.setTime(hours[i]);
  1348. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1349. chartsDataList.add(chartBasic);
  1350. }
  1351. handleXinYiWarningsYC(csadBzz, split, csadGkz, BusinessEnum.WarningCategoryEnum.CS_AD_YC.getCode(), hour, normConfig, tXinyiIndustry.getCsNh3(), tXinyiIndustry, chartsDataList, date);
  1352. }else if(BusinessEnum.BigModelForecastEnum.XSY1.getCode().equals(task)){
  1353. //2024年6月21日14:57:02 红杉的出水总氮预测改成 不用工业库的,用化验科的两个xsy 相关指标
  1354. //同时调用跃渊的预测接口 保存记录值
  1355. try {
  1356. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=6&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1357. if(!StringUtils.isBlank(result)){
  1358. JSONArray array = JSON.parseArray(result);
  1359. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1360. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1361. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1362. }
  1363. } catch (Exception e) {
  1364. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1365. }
  1366. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1367. /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK);
  1368. BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/
  1369. //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警
  1370. BigDecimal cszzBzz = normConfig.getCszzBzz();
  1371. BigDecimal cszzGkz = normConfig.getCszzGkz();
  1372. //处理展示数据
  1373. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1374. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1375. ChartBasic chartBasic = new ChartBasic();
  1376. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1377. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Hlj1Jqr(), INT_2));
  1378. chartsDataList.add(chartBasic);
  1379. }
  1380. for (int i = 0; i < split.length; i++) {
  1381. String val = split[i];
  1382. ChartBasic chartBasic = new ChartBasic();
  1383. chartBasic.setTime(hours[i]);
  1384. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1385. chartsDataList.add(chartBasic);
  1386. }
  1387. handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_XSY_1_YC.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj1Jqr(), tXinyiIndustry, chartsDataList, date);
  1388. }else if(BusinessEnum.BigModelForecastEnum.XSY2.getCode().equals(task)){
  1389. //同时调用跃渊的预测接口 保存记录值
  1390. try {
  1391. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1392. if(!StringUtils.isBlank(result)){
  1393. JSONArray array = JSON.parseArray(result);
  1394. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1395. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1396. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1397. }
  1398. } catch (Exception e) {
  1399. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1400. }
  1401. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1402. /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK);
  1403. BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/
  1404. //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警
  1405. BigDecimal cszzBzz = normConfig.getCszzBzz();
  1406. BigDecimal cszzGkz = normConfig.getCszzGkz();
  1407. //处理展示数据
  1408. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1409. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1410. ChartBasic chartBasic = new ChartBasic();
  1411. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1412. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Hlj2Jqr(), INT_2));
  1413. chartsDataList.add(chartBasic);
  1414. }
  1415. for (int i = 0; i < split.length; i++) {
  1416. String val = split[i];
  1417. ChartBasic chartBasic = new ChartBasic();
  1418. chartBasic.setTime(hours[i]);
  1419. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1420. chartsDataList.add(chartBasic);
  1421. }
  1422. handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_XSY_2_YC.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date);
  1423. }else if(BusinessEnum.BigModelForecastEnum.QYXSY1.getCode().equals(task)){
  1424. //同时调用跃渊的预测接口 保存记录值
  1425. /*try {
  1426. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1427. if(!StringUtils.isBlank(result)){
  1428. JSONArray array = JSON.parseArray(result);
  1429. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1430. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1431. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1432. }
  1433. } catch (Exception e) {
  1434. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1435. }*/
  1436. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1437. /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK);
  1438. BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/
  1439. //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警
  1440. BigDecimal cszzBzz = normConfig.getCszzBzz();
  1441. BigDecimal cszzGkz = normConfig.getCszzGkz();
  1442. //处理展示数据
  1443. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1444. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1445. ChartBasic chartBasic = new ChartBasic();
  1446. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1447. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Qyc1Jqr(), INT_2));
  1448. chartsDataList.add(chartBasic);
  1449. }
  1450. for (int i = 0; i < split.length; i++) {
  1451. String val = split[i];
  1452. ChartBasic chartBasic = new ChartBasic();
  1453. chartBasic.setTime(hours[i]);
  1454. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1455. chartsDataList.add(chartBasic);
  1456. }
  1457. handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.QYCXSY_1.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date);
  1458. }else if(BusinessEnum.BigModelForecastEnum.QYXSY2.getCode().equals(task)){
  1459. //同时调用跃渊的预测接口 保存记录值
  1460. /*try {
  1461. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1462. if(!StringUtils.isBlank(result)){
  1463. JSONArray array = JSON.parseArray(result);
  1464. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1465. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1466. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1467. }
  1468. } catch (Exception e) {
  1469. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1470. }*/
  1471. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1472. /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK);
  1473. BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/
  1474. //2024年7月11日17:19:47 1#好氧硝酸盐、2#好氧硝酸盐使用总氮标准值和管控值来预警
  1475. BigDecimal cszzBzz = normConfig.getCszzBzz();
  1476. BigDecimal cszzGkz = normConfig.getCszzGkz();
  1477. //处理展示数据
  1478. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1479. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1480. ChartBasic chartBasic = new ChartBasic();
  1481. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1482. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNo3Qyc2Jqr(), INT_2));
  1483. chartsDataList.add(chartBasic);
  1484. }
  1485. for (int i = 0; i < split.length; i++) {
  1486. String val = split[i];
  1487. ChartBasic chartBasic = new ChartBasic();
  1488. chartBasic.setTime(hours[i]);
  1489. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1490. chartsDataList.add(chartBasic);
  1491. }
  1492. handleXinYiWarningsYC(cszzBzz, split, cszzGkz, BusinessEnum.WarningCategoryEnum.QYCXSY_2.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date);
  1493. }else if(BusinessEnum.BigModelForecastEnum.QYNH31.getCode().equals(task)){
  1494. //同时调用跃渊的预测接口 保存记录值
  1495. /*try {
  1496. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1497. if(!StringUtils.isBlank(result)){
  1498. JSONArray array = JSON.parseArray(result);
  1499. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1500. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1501. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1502. }
  1503. } catch (Exception e) {
  1504. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1505. }*/
  1506. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1507. /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK);
  1508. BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/
  1509. //2024年09月08日11:21:25 采用出水氨氮的标准值和管控值
  1510. BigDecimal csadBzz = normConfig.getCsadBzz();
  1511. BigDecimal csadGkz = normConfig.getCsadGkz();
  1512. //处理展示数据
  1513. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1514. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1515. ChartBasic chartBasic = new ChartBasic();
  1516. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1517. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNh31Jqr(), INT_2));
  1518. chartsDataList.add(chartBasic);
  1519. }
  1520. for (int i = 0; i < split.length; i++) {
  1521. String val = split[i];
  1522. ChartBasic chartBasic = new ChartBasic();
  1523. chartBasic.setTime(hours[i]);
  1524. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1525. chartsDataList.add(chartBasic);
  1526. }
  1527. handleXinYiWarningsYC(csadBzz, split, csadGkz, BusinessEnum.WarningCategoryEnum.QYAD_1.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date);
  1528. }else if(BusinessEnum.BigModelForecastEnum.QYNH32.getCode().equals(task)){
  1529. //同时调用跃渊的预测接口 保存记录值
  1530. /*try {
  1531. String result = HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=7&time=" + DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH), INT_10000);
  1532. if(!StringUtils.isBlank(result)){
  1533. JSONArray array = JSON.parseArray(result);
  1534. tXinyiForecastComparison.setYyForecastOne(array.getBigDecimal(6));
  1535. tXinyiForecastComparison.setYyForecastTwo(array.getBigDecimal(7));
  1536. tXinyiForecastComparison.setYyForecastThree(array.getBigDecimal(8));
  1537. }
  1538. } catch (Exception e) {
  1539. log.error("调用跃渊的预测接口出现异常,异常信息为{}", e.getMessage());
  1540. }*/
  1541. // this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1542. /*BigDecimal cscodBzz = new BigDecimal(XIAOSUANYAN_BZK);
  1543. BigDecimal cscodGkz = new BigDecimal(XIAOSUANYAN_GKZ);*/
  1544. //2024年09月08日11:21:25 采用出水氨氮的标准值和管控值
  1545. BigDecimal csadBzz = normConfig.getCsadBzz();
  1546. BigDecimal csadGkz = normConfig.getCsadGkz();
  1547. //处理展示数据
  1548. for (int i = 0; i < tXinyiRobots6.size(); i++) {
  1549. TXinyiRobot tXinyiRobotTemp = tXinyiRobots6.get(5 - i);
  1550. ChartBasic chartBasic = new ChartBasic();
  1551. chartBasic.setTime(tXinyiRobotTemp.getTestHour().substring(11));
  1552. chartBasic.setVal(DecimalUtils.getAbsAndScale(tXinyiRobotTemp.getNh32Jqr(), INT_2));
  1553. chartsDataList.add(chartBasic);
  1554. }
  1555. for (int i = 0; i < split.length; i++) {
  1556. String val = split[i];
  1557. ChartBasic chartBasic = new ChartBasic();
  1558. chartBasic.setTime(hours[i]);
  1559. chartBasic.setVal(DecimalUtils.getAbsAndScale(new BigDecimal(val), INT_2));
  1560. chartsDataList.add(chartBasic);
  1561. }
  1562. handleXinYiWarningsYC(csadBzz, split, csadGkz, BusinessEnum.WarningCategoryEnum.QYAD_2.getCode(), hour, normConfig, tXinyiRobot.getNo3Hlj2Jqr(), tXinyiIndustry, chartsDataList, date);
  1563. }else {
  1564. log.error("暂未支持的类型{}", task);
  1565. }
  1566. //插入到数据库
  1567. //2024年6月21日14:18:55 如果红杉预测和跃渊预测都有数据再保存
  1568. //2024年7月8日15:15:46 逻辑调整:只要红杉的数据不为空就保存
  1569. if(Objects.isNull(tXinyiForecastComparison.getHsForecastOne()) || Objects.isNull(tXinyiForecastComparison.getHsForecastTwo()) ||Objects.isNull(tXinyiForecastComparison.getHsForecastThree())){
  1570. // || Objects.isNull(tXinyiForecastComparison.getYyForecastOne()) || Objects.isNull(tXinyiForecastComparison.getYyForecastTwo()) || Objects.isNull(tXinyiForecastComparison.getYyForecastThree())){
  1571. log.error("保存预测对比数据时,有存在不满足条件的数据,不再保存数据,数据为{}", JSON.toJSONString(tXinyiForecastComparison));
  1572. }else
  1573. this.xinyiForecastComparisonService.insertTXinyiForecastComparison(tXinyiForecastComparison);
  1574. }
  1575. public void handleXinYiWarningsYC(BigDecimal csBzz, String[] split, BigDecimal csGkz, String category, String hour, TXinyiNormConfig normConfig, BigDecimal currentVal, TXinyiIndustry tXinyiIndustry, List<ChartBasic> chartsDataList, String date) {
  1576. BigDecimal multiply = csBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  1577. TXinyiWarningRecord tXinyiWarningRecord = null;
  1578. String yjHour = null;
  1579. for (int i = 0, splitLength = split.length; i < splitLength; i++) {
  1580. String forecast = split[i];
  1581. /*BigDecimal forecastVal = new BigDecimal("10000");*/
  1582. BigDecimal forecastVal = new BigDecimal(forecast);
  1583. tXinyiWarningRecord = new TXinyiWarningRecord();
  1584. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  1585. tXinyiWarningRecord.setStatus(0);
  1586. tXinyiWarningRecord.setType(2);
  1587. tXinyiWarningRecord.setCategory(category);
  1588. tXinyiWarningRecord.setWarningVal(currentVal);//当前值
  1589. tXinyiWarningRecord.setForecastVal(forecastVal);
  1590. tXinyiWarningRecord.setDesignVal(csBzz);
  1591. tXinyiWarningRecord.setControlVal(csGkz);
  1592. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  1593. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  1594. tXinyiWarningRecord.setRemark(TWO_YC_WARNING.getCode());
  1595. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  1596. if (Objects.isNull(forecastVal)) {
  1597. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING_YC);
  1598. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  1599. } else if (forecastVal.compareTo(multiply) > 0) {//一级
  1600. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING_YC);
  1601. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  1602. } else if (forecastVal.compareTo(csBzz) >= 0 && forecastVal.compareTo(multiply) <= 0) {//二级
  1603. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING_YC);
  1604. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  1605. } else if (!Objects.isNull(csGkz) && forecastVal.compareTo(csGkz) > 0) {
  1606. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING_YC);
  1607. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  1608. } else {
  1609. tXinyiWarningRecord = null;//这种的无需处理
  1610. }
  1611. if (!Objects.isNull(tXinyiWarningRecord)) {
  1612. log.info("预测报警中出现了超标的情况,循环可以退出了");
  1613. yjHour = hour.split(",")[i];
  1614. date = date.split(",")[i];//2024年6月23日18:34:49 日期也是多个了
  1615. //预计超标时间 不是当前值,是预测超标的时间。
  1616. try {
  1617. tXinyiWarningRecord.setTime(DateUtils.parseDate(date + " " + yjHour, DateUtils.YYYY_MM_DD_HH));
  1618. } catch (ParseException e) {
  1619. log.error("处理语句的预计超标时间是,异常,异常信息为{}", e.getMessage());
  1620. }
  1621. break;
  1622. }
  1623. }
  1624. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  1625. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(2).category(category).warningStatus(0).build());
  1626. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  1627. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  1628. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  1629. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  1630. xinyiWarningRecord.setStatus(2);
  1631. Date nowDate = DateUtils.getNowDate();
  1632. xinyiWarningRecord.setOffTime(nowDate);
  1633. xinyiWarningRecord.setUpdateTime(nowDate);
  1634. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  1635. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  1636. }
  1637. }
  1638. }else{//有告警信息
  1639. //2024年6月27日10:45:49 列表的预警时间和showval里的预警时间保持一致(用同一个,否则可能有一分钟左右的误差)
  1640. Date nowDate = DateUtils.getNowDate();
  1641. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  1642. //2024年7月15日11:06:16 因为只有一个告警记录,但是如果一直报警,现在报警时间取的是更新时间,兼容第一次报警处理
  1643. tXinyiWarningRecord.setUpdateTime(nowDate);
  1644. //保存到数据库中
  1645. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  1646. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1647. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1648. this.addChatRecordByDeviceErr(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1649. }else {
  1650. //继续调用大模型prompt
  1651. try {
  1652. this.askBigModelForYC(tXinyiWarningRecord, tXinyiIndustry, normConfig, chartsDataList, date, yjHour, nowDate);
  1653. } catch (Exception e) {
  1654. log.error("预测完成调用大模型获取解决方案时异常,异常信息为{}", JSON.toJSONString(e));
  1655. }
  1656. }
  1657. }else{
  1658. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  1659. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  1660. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1661. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1662. this.addChatRecordByDeviceErr(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1663. }else {
  1664. //2024年6月25日11:32:13 预测的相对特殊:因为前端不展示次数,所以这里把 超标时间+现在值+预测值更新一下
  1665. xinyiWarningRecord.setForecastVal(tXinyiWarningRecord.getForecastVal());
  1666. xinyiWarningRecord.setWarningVal(currentVal);
  1667. xinyiWarningRecord.setTime(tXinyiWarningRecord.getTime());
  1668. xinyiWarningRecord.setUpdateTime(nowDate);
  1669. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  1670. //2024年7月15日11:07:33 报警的级别也要重新计算并更新
  1671. xinyiWarningRecord.setLevel(tXinyiWarningRecord.getLevel());
  1672. //2024年7月31日09:20:47 报警的原因(超标还是超管控也需要更新)
  1673. xinyiWarningRecord.setReason(tXinyiWarningRecord.getReason());
  1674. //更新数据库
  1675. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  1676. //继续调用决策
  1677. try {
  1678. this.askBigModelForYC(xinyiWarningRecord, tXinyiIndustry, normConfig, chartsDataList, date, yjHour, nowDate);
  1679. } catch (Exception e) {
  1680. log.error("预测完成调用大模型获取解决方案时异常,异常信息为{}", JSON.toJSONString(e));
  1681. }
  1682. }
  1683. }
  1684. }
  1685. }
  1686. }
  1687. private void askBigModelForYC(TXinyiWarningRecord xinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, List<ChartBasic> chartsDataList, String date, String yjHour, Date nowDate) {
  1688. log.info("预测进入了后台接口调⽤⼤模型获取问答结果处理(预测)");
  1689. StringBuilder sb = new StringBuilder();
  1690. String sessionId = IdUtils.simpleUUID();
  1691. ChatReq chatReq = new ChatReq();
  1692. // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型
  1693. String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址
  1694. int counts = 1;//默认是第一次
  1695. //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录
  1696. List<String> historyDates = new ArrayList<>();
  1697. //构建问题(替换提示词中的占位符)
  1698. /*String shWarningPrompt = YC_WARNING_PROMPT;
  1699. shWarningPrompt =shWarningPrompt.replace("#{0}", xinyiWarningRecord.getReason());
  1700. shWarningPrompt =shWarningPrompt.replace("#{1}", String.valueOf(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getDesignVal(), INT_2)));
  1701. shWarningPrompt =shWarningPrompt.replace("#{2}", String.valueOf(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getWarningVal(), INT_2)));
  1702. shWarningPrompt =shWarningPrompt.replace("#{3}", String.valueOf(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getForecastVal(), INT_2)));*/
  1703. StringBuilder prompt = new StringBuilder(YC_WARNING_PROMPT_1);
  1704. if(CS_TP_YC.getCode().equalsIgnoreCase(xinyiWarningRecord.getCategory())){
  1705. log.info("进入了需要特殊处理的预警:二沉池正磷酸盐");
  1706. prompt.append(xinyiWarningRecord.getReason());
  1707. prompt.append(YC_WARNING_PROMPT_2).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getDesignVal(), INT_2));
  1708. prompt.append(YC_WARNING_PROMPT_3).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getWarningVal(), INT_2));
  1709. prompt.append(YC_WARNING_PROMPT_4).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getForecastVal(), INT_2));
  1710. prompt.append(YC_WARNING_PROMPT_6);
  1711. //查询最近7天的二沉池正磷酸盐数据
  1712. List<HashMap<String, Object>> list = this.xinyiRobotMapper.selectAvg7Datas();
  1713. if(!CollectionUtils.isEmpty(list)){
  1714. for (int i = 0; i < list.size(); i++) {
  1715. HashMap<String, Object> map = list.get(i);
  1716. prompt.append(map.get("DATE")).append(":").append(DecimalUtils.getAbsAndScale(new BigDecimal(map.get("VAL").toString()), INT_2)).append(YC_WARNING_PROMPT_UNIT_MG_L);
  1717. if(i < list.size() -1)//不是最后一条
  1718. prompt.append(",");
  1719. }
  1720. }
  1721. prompt.append(YC_WARNING_PROMPT_7);
  1722. //查询最近7天的进水总磷数据
  1723. List<TXinyiDaily> tXinyiDailies = this.xinyiDailyMapper.selectNRecords(7);
  1724. if(!CollectionUtils.isEmpty(tXinyiDailies)){
  1725. for (int i = 0; i < tXinyiDailies.size(); i++) {
  1726. TXinyiDaily tXinyiDaily = tXinyiDailies.get(i);
  1727. prompt.append(tXinyiDaily.getTestDate()).append(":").append(DecimalUtils.getAbsAndScale(tXinyiDaily.getJsTp(), INT_2)).append(YC_WARNING_PROMPT_UNIT_MG_L);
  1728. if(i < tXinyiDailies.size() -1)//不是最后一条
  1729. prompt.append(",");
  1730. }
  1731. }
  1732. prompt.append(YC_WARNING_PROMPT_8);
  1733. }else{//
  1734. prompt.append(xinyiWarningRecord.getReason());
  1735. prompt.append(YC_WARNING_PROMPT_2).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getDesignVal(), INT_2));
  1736. prompt.append(YC_WARNING_PROMPT_3).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getWarningVal(), INT_2));
  1737. prompt.append(YC_WARNING_PROMPT_4).append(DecimalUtils.getAbsAndScale(xinyiWarningRecord.getForecastVal(), INT_2));
  1738. prompt.append(YC_WARNING_PROMPT_5);
  1739. }
  1740. historyDates.add(prompt.toString());
  1741. // 获取输出流
  1742. ManagedChannel channel = null;
  1743. try {
  1744. channel = ManagedChannelBuilder.forAddress(bigModelConfig.getIp(), bigModelConfig.getPort())
  1745. .usePlaintext()
  1746. .build();
  1747. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  1748. // 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) + "}";
  1749. //2024年6月27日10:51:47 优化:不再手动拼接JSON字符串
  1750. String dataJson = buildBigModelReqForChat(sessionId, historyDates);
  1751. // log.info("请求大模型的问答参数为{}", dataJson);
  1752. PredictionsRequest request = PredictionsRequest.newBuilder()
  1753. .setModelName("slibra_bot")
  1754. .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理
  1755. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  1756. .buildPartial();
  1757. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  1758. //将结果记录到问答表
  1759. while (predictions.hasNext()) {
  1760. String responseStr = predictions.next().getPrediction().toStringUtf8();
  1761. // log.info("大模型问答返回的原始结果为{}", responseStr);
  1762. responseStr = JSON.parseObject(responseStr).getString("message");
  1763. if("complete".equals(responseStr)){
  1764. log.info("结尾语句并且是非JSON,无需处理");
  1765. }else{
  1766. sb.append(responseStr);
  1767. }
  1768. }
  1769. //将问答更新到数据库中
  1770. chatReq.setSessionId(sessionId);
  1771. chatReq.setType(1);//0问答 1决策 2本地 3仿真预测 预测报警这里也算是决策 仿真预测是在调用仿真那里使用的
  1772. chatReq.setModule(3);//0专家问答 1智能工单 2智能体助手 3告警 4简报
  1773. String showVal = this.buildShowValueWithCharts(xinyiWarningRecord, tXinyiIndustry, normConfig, chartsDataList, date, yjHour, nowDate);
  1774. chatReq.setShowVal(showVal);
  1775. chatReq.setQuestion(prompt.toString());
  1776. chatReq.setAnswer(sb.toString());
  1777. chatReq.setWarningId(String.valueOf(xinyiWarningRecord.getId()));
  1778. chatReq.setCounts(counts);//问答次数
  1779. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  1780. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  1781. chatReq.setCreateTime(DateUtils.getNowDate());
  1782. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  1783. } catch (IOException e) {
  1784. throw new RuntimeException(e);
  1785. } finally {
  1786. // 关闭输出流
  1787. channel.shutdown();
  1788. }
  1789. }
  1790. private String buildBigModelReqForChat(String sessionId, List<String> historyDates) {
  1791. ChatRequest chatRequest = new ChatRequest();
  1792. chatRequest.setSessionId(sessionId);
  1793. chatRequest.setHistoryDia(historyDates);
  1794. //2024年7月5日13:24:10 temperature做区分
  1795. GenerateArgs generateArgs = new GenerateArgs();
  1796. generateArgs.setTemperature(bigModelConfig.getTemperature());
  1797. chatRequest.setGenerateArgs(generateArgs);
  1798. Map<String, Object> extra = new HashMap<>();
  1799. // extra.put("ip_address", IpUtils.getIpAddr());
  1800. extra.put("ip_address", null);
  1801. chatRequest.setExtra(extra);
  1802. chatRequest.setStrengthen(true);
  1803. return JSON.toJSONString(chatRequest);
  1804. }
  1805. public String getPredictor(String type){
  1806. // 获取输出流
  1807. ManagedChannel channel = null;
  1808. try {
  1809. channel = ManagedChannelBuilder.forAddress(bigModelConfig.getIp(), bigModelConfig.getPort())
  1810. .usePlaintext()
  1811. .build();
  1812. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  1813. // String dataJson = "{\"bot_id\":\"b00001\",\"exp_id\":\"721\",\"norm\":\"" + type + "\",\"session_id\":\" " + IdUtils.simpleUUID() + " \",\"extra\":{}}";
  1814. //2024年6月27日13:23:25 优化:改成非拼接JSON字符串
  1815. String dataJson = buildBigModelReqForPredictor(type);
  1816. // log.info("请求大模型的预测的参数为{}", dataJson);
  1817. PredictionsRequest request = PredictionsRequest.newBuilder()
  1818. .setModelName("slibra_bot")
  1819. .putInput("method", ByteString.copyFrom("predictor", "utf-8"))//推理
  1820. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  1821. .buildPartial();
  1822. /*Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  1823. //将结果记录到问答表
  1824. String responseStr = predictions.next().getPrediction().toStringUtf8();
  1825. log.info("大模型的预测的返回结果为{}", responseStr);*/
  1826. //2024年6月21日11:46:36 改成非流式输出
  1827. PredictionResponse predictions = stub.predictions(request);
  1828. String responseStr = predictions.getPrediction().toStringUtf8();
  1829. log.info("调用TFT预测大模型返回的原始结果为{}", responseStr);
  1830. // return JSON.parseObject(responseStr).getString("pred");
  1831. return responseStr;
  1832. } catch (IOException e) {
  1833. throw new RuntimeException(e);
  1834. } finally {
  1835. assert channel != null;
  1836. channel.shutdown();
  1837. }
  1838. }
  1839. private static String buildBigModelReqForPredictor(String type) {
  1840. PredictorRequest predictorRequest = new PredictorRequest();
  1841. predictorRequest.setNorm(type);
  1842. predictorRequest.setSessionId(IdUtils.simpleUUID());
  1843. return JSON.toJSONString(predictorRequest);
  1844. }
  1845. /**
  1846. *
  1847. * 2022/01/01 转成2022年01月01日 数据
  1848. * @param testDate
  1849. * @return
  1850. */
  1851. private String formateDateStr(String testDate) {
  1852. if(StringUtils.isBlank(testDate))
  1853. return "";
  1854. if(!testDate.contains("/"))
  1855. return testDate;
  1856. String[] split = testDate.split("/");
  1857. return split[0] + "年" + split[1] + "月" + split[2] + "日";
  1858. }
  1859. private void askBigModel(String question, String showVal) {
  1860. log.info("进入了后台接口调⽤⼤模型获取问答结果处理");
  1861. StringBuilder sb = new StringBuilder();
  1862. String sessionId = IdUtils.simpleUUID();
  1863. ChatReq chatReq = new ChatReq();
  1864. // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型
  1865. String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址
  1866. int counts = 1;//默认是第一次
  1867. //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录
  1868. List<String> historyDates = new ArrayList<>();
  1869. historyDates.add(question);
  1870. // 获取输出流
  1871. ManagedChannel channel = null;
  1872. try {
  1873. channel = ManagedChannelBuilder.forAddress(bigModelConfig.getIp(), bigModelConfig.getPort())
  1874. .usePlaintext()
  1875. .build();
  1876. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  1877. // 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) + "}";
  1878. //2024年6月27日10:51:47 优化:不再手动拼接JSON字符串
  1879. String dataJson = buildBigModelReqForChat(sessionId, historyDates);
  1880. // log.info("请求大模型的问答参数为{}", dataJson);
  1881. PredictionsRequest request = PredictionsRequest.newBuilder()
  1882. .setModelName("slibra_bot")
  1883. .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理
  1884. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  1885. .buildPartial();
  1886. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  1887. //将结果记录到问答表
  1888. while (predictions.hasNext()) {
  1889. String responseStr = predictions.next().getPrediction().toStringUtf8();
  1890. // log.info("大模型问答返回的原始结果为{}", responseStr);
  1891. responseStr = JSON.parseObject(responseStr).getString("message");
  1892. if("complete".equals(responseStr)){
  1893. System.out.println("结尾语句并且是非JSON,无需处理");
  1894. //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端
  1895. /*outputStream.write(responseStr.getBytes());
  1896. outputStream.flush();*/
  1897. }else{
  1898. sb.append(responseStr);
  1899. }
  1900. }
  1901. //将问答更新到数据库中
  1902. chatReq.setSessionId(sessionId);
  1903. chatReq.setType(2);//0问答 1决策 2本地 3仿真预测
  1904. chatReq.setModule(4);//0专家问答 1智能工单 2智能体助手 3告警 4简报
  1905. chatReq.setShowVal(showVal);
  1906. chatReq.setQuestion(question);
  1907. chatReq.setAnswer(sb.toString());
  1908. chatReq.setCounts(counts);//问答次数
  1909. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  1910. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  1911. chatReq.setCreateTime(DateUtils.getNowDate());
  1912. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  1913. } catch (IOException e) {
  1914. throw new RuntimeException(e);
  1915. } finally {
  1916. // 关闭输出流
  1917. channel.shutdown();
  1918. }
  1919. }
  1920. /**
  1921. * @param dailyTwoRecords
  1922. * @return
  1923. */
  1924. @Deprecated
  1925. private String buildShortReportQueryData(List<TXinyiDaily> dailyTwoRecords) {
  1926. //查询配置信息
  1927. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  1928. if(CollectionUtils.isEmpty(tXinyiNormConfigs))
  1929. return null;
  1930. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  1931. //获取数据
  1932. TXinyiDaily yesterdayData = dailyTwoRecords.get(0);
  1933. TXinyiDaily beforeYesterdayData = dailyTwoRecords.get(1);
  1934. String originStr = JIAN_BAO_PROMPT;
  1935. String yesterdayStr = yesterdayData.getTestDate().substring(5).replace("/", "月") + "日";
  1936. String beforeYesterdayStr = beforeYesterdayData.getTestDate().substring(5).replace("/", "月") + "日";
  1937. originStr = originStr.replace("#{0}", yesterdayStr);
  1938. originStr = originStr.replace("#{1}", beforeYesterdayStr);
  1939. originStr = originStr.replace("#{2}", String.valueOf(yesterdayData.getJsCod()));
  1940. originStr = originStr.replace("#{3}", String.valueOf(yesterdayData.getJsTn()));
  1941. originStr = originStr.replace("#{4}", String.valueOf(yesterdayData.getJsTp()));
  1942. originStr = originStr.replace("#{5}", String.valueOf(yesterdayData.getJsNh3()));
  1943. originStr = originStr.replace("#{6}", String.valueOf(yesterdayData.getJsSs()));
  1944. originStr = originStr.replace("#{7}", String.valueOf(yesterdayData.getJSL()));
  1945. originStr = originStr.replace("#{8}", String.valueOf(yesterdayData.getCsCod()));
  1946. originStr = originStr.replace("#{9}", String.valueOf(yesterdayData.getCsTn()));
  1947. originStr = originStr.replace("#{10}", String.valueOf(yesterdayData.getCsTp()));
  1948. originStr = originStr.replace("#{11}", String.valueOf(yesterdayData.getCsNh3()));
  1949. originStr = originStr.replace("#{12}", String.valueOf(yesterdayData.getCsSs()));
  1950. originStr = originStr.replace("#{13}", String.valueOf(yesterdayData.getCSL()));
  1951. originStr = originStr.replace("#{14}", String.valueOf(beforeYesterdayData.getJsCod()));
  1952. originStr = originStr.replace("#{15}", String.valueOf(beforeYesterdayData.getJsTn()));
  1953. originStr = originStr.replace("#{16}", String.valueOf(beforeYesterdayData.getJsTp()));
  1954. originStr = originStr.replace("#{17}", String.valueOf(beforeYesterdayData.getJsNh3()));
  1955. originStr = originStr.replace("#{18}", String.valueOf(beforeYesterdayData.getJsSs()));
  1956. originStr = originStr.replace("#{19}", String.valueOf(beforeYesterdayData.getJSL()));
  1957. originStr = originStr.replace("#{20}", String.valueOf(beforeYesterdayData.getCsCod()));
  1958. originStr = originStr.replace("#{21}", String.valueOf(beforeYesterdayData.getCsTn()));
  1959. originStr = originStr.replace("#{22}", String.valueOf(beforeYesterdayData.getCsTp()));
  1960. originStr = originStr.replace("#{23}", String.valueOf(beforeYesterdayData.getCsNh3()));
  1961. originStr = originStr.replace("#{24}", String.valueOf(beforeYesterdayData.getCsSs()));
  1962. originStr = originStr.replace("#{25}", String.valueOf(beforeYesterdayData.getCSL()));
  1963. originStr = originStr.replace("#{26}", String.valueOf(normConfig.getJscodSjz()));
  1964. originStr = originStr.replace("#{27}", String.valueOf(normConfig.getJszdSjz()));
  1965. originStr = originStr.replace("#{28}", String.valueOf(normConfig.getJszlSjz()));
  1966. originStr = originStr.replace("#{29}", String.valueOf(normConfig.getJsadSjz()));
  1967. originStr = originStr.replace("#{30}", String.valueOf(normConfig.getJsssSjz()));
  1968. originStr = originStr.replace("#{31}", String.valueOf(normConfig.getCscodBzz()));
  1969. originStr = originStr.replace("#{32}", String.valueOf(normConfig.getCszzBzz()));
  1970. originStr = originStr.replace("#{33}", String.valueOf(normConfig.getCszlBzz()));
  1971. originStr = originStr.replace("#{34}", String.valueOf(normConfig.getCsadBzz()));
  1972. originStr = originStr.replace("#{35}", String.valueOf(normConfig.getCsssBzz()));
  1973. return originStr;
  1974. }
  1975. //2024年6月23日19:58:21 简报生成的prompt调整。
  1976. private String buildShortReportQueryDataNew(List<TXinyiDaily> dailyTwoRecords) {
  1977. //查询配置信息
  1978. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  1979. if(CollectionUtils.isEmpty(tXinyiNormConfigs))
  1980. return null;
  1981. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  1982. //获取数据
  1983. TXinyiDaily yesterdayData = dailyTwoRecords.get(0);
  1984. // String originStr = SHORT_REPORT_BEGIN.replace("#{0}", yesterdayData.getTestDate());
  1985. StringBuilder sb = new StringBuilder(SHORT_REPORT_BEGIN_1);
  1986. sb.append(yesterdayData.getTestDate());
  1987. sb.append(SHORT_REPORT_BEGIN_2);
  1988. for (TXinyiDaily dailyTwoRecord : dailyTwoRecords) {
  1989. sb.append(formateDateStr(dailyTwoRecord.getTestDate())).append("进出水质数据:\n");
  1990. sb.append("进水:\n");
  1991. sb.append("进水COD").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsCod(), 2)).append("mg/L、");
  1992. sb.append("进水总氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsTn(), 2)).append("mg/L、");
  1993. sb.append("进水总磷").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsTp(), 2)).append("mg/L、");
  1994. sb.append("进水氨氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsNh3(), 2)).append("mg/L、");
  1995. sb.append("进水SS").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJsSs(), 2)).append("mg/L、");
  1996. sb.append("进水水量").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getJSL(), 2)).append("m³/d").append(";\n");
  1997. sb.append("出水:\n");
  1998. sb.append("出水COD").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsCod(), 2)).append("mg/L、");
  1999. sb.append("出水总氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsTn(), 2)).append("mg/L、");
  2000. sb.append("出水总磷").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsTp(), 2)).append("mg/L、");
  2001. sb.append("出水氨氮").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsNh3(), 2)).append("mg/L、");
  2002. sb.append("出水SS").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCsSs(), 2)).append("mg/L、");
  2003. sb.append("出水水量").append(DecimalUtils.getAbsAndScale(dailyTwoRecord.getCSL(), 2)).append("m³/d").append("。\n");
  2004. }
  2005. sb.append(SHORT_REPORT_END);
  2006. sb.append("进水COD:").append(DecimalUtils.getAbsAndScale(normConfig.getJscodSjz(), 2)).append("mg/L、");
  2007. sb.append("进水总氮:").append(DecimalUtils.getAbsAndScale(normConfig.getJszdSjz(), 2)).append("mg/L、");
  2008. sb.append("进水总磷:").append(DecimalUtils.getAbsAndScale(normConfig.getJszlSjz(), 2)).append("mg/L、");
  2009. sb.append("进水氨氮:").append(DecimalUtils.getAbsAndScale(normConfig.getJsadSjz(), 2)).append("mg/L、");
  2010. sb.append("进水SS:").append(DecimalUtils.getAbsAndScale(normConfig.getJsssSjz(), 2)).append("mg/L、");
  2011. sb.append("出水COD:").append(DecimalUtils.getAbsAndScale(normConfig.getCscodBzz(), 2)).append("mg/L、");
  2012. sb.append("出水总氮:").append(DecimalUtils.getAbsAndScale(normConfig.getCszzBzz(), 2)).append("mg/L、");
  2013. sb.append("出水总磷:").append(DecimalUtils.getAbsAndScale(normConfig.getCszlBzz(), 2)).append("mg/L、");
  2014. sb.append("出水氨氮:").append(DecimalUtils.getAbsAndScale(normConfig.getCsadBzz(), 2)).append("mg/L、");
  2015. sb.append("出水SS:").append(DecimalUtils.getAbsAndScale(normConfig.getCsssBzz(), 2)).append("mg/L").append("。");
  2016. return sb.toString();
  2017. }
  2018. public static String handleDate(String str){
  2019. StringBuilder sb = new StringBuilder();
  2020. if(str.contains(" ")){//包含空格 就是年月日时分秒了
  2021. String[] split = str.split(" ");
  2022. addBeforeZero(sb, split[0], "/");
  2023. sb.append(" ");
  2024. addBeforeZero(sb, split[1], ":");
  2025. }else{
  2026. if(str.contains("/")){//年月日
  2027. addBeforeZero(sb, str, "/");
  2028. }else if(str.contains(":")){//时分秒
  2029. addBeforeZero(sb, str, ":");
  2030. }else {
  2031. sb.append(str);
  2032. }
  2033. }
  2034. return sb.toString();
  2035. }
  2036. public static StringBuilder addBeforeZero(StringBuilder sb, String str, String tag){
  2037. String[] split = str.split(tag);
  2038. int length = split.length;
  2039. for (int i = 0; i < length; i++) {
  2040. String value = split[i];
  2041. Integer intValue = Integer.parseInt(value);
  2042. if(intValue < 10 && value.length() == 1){////防止有正确的情况 额外再补充字符串
  2043. sb.append(0).append(value);
  2044. }else{
  2045. sb.append(value);
  2046. }
  2047. if(i < length-1){
  2048. sb.append(tag);
  2049. }
  2050. }
  2051. return sb;
  2052. }
  2053. public static void main(String[] args) throws ParseException, InterruptedException {
  2054. /*LocalDateTime endTime = LocalDateTime.now();
  2055. System.out.println("endTime = " + endTime);
  2056. endTime = endTime.plusMinutes(60);
  2057. System.out.println("endTime = " + endTime);*/
  2058. /*String str = "2024/04/15 09:55";
  2059. System.out.println(str);
  2060. System.out.println(str.substring(0,10));
  2061. System.out.println(str.substring(0,13));*/
  2062. /*String str = "2024/04/18 08:00";
  2063. str = str + ":00";
  2064. System.out.println(str);
  2065. LocalDateTime startTime = LocalDateTime.parse(str.replaceAll("/", "-").replace(" ", "T"));
  2066. System.out.println(startTime.plusMinutes(1L).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));*/
  2067. /*ArrayList<Integer> objects = new ArrayList<>();
  2068. objects.add(1);
  2069. objects.add(2);
  2070. objects.add(3);
  2071. System.out.println(objects);
  2072. objects.clear();
  2073. System.out.println(objects);
  2074. // test();
  2075. Date date = new Date();
  2076. System.out.println(DateUtils.differentHoursByMillisecond(date, date));
  2077. HashMap<Object, Object> map = new HashMap<>();
  2078. map.put("a", null);
  2079. map.put("b", "ab");
  2080. map.put("c", "");
  2081. map.put("d", '1');
  2082. System.out.println(JSON.toJSONString(map, JSONWriter.Feature.WriteNulls));
  2083. TXinyiIndustry tXinyiIndustry = new TXinyiIndustry();
  2084. System.out.println(JSON.toJSONString(tXinyiIndustry, JSONWriter.Feature.WriteNulls));*/
  2085. /*String s = "2022/01/01".substring(5).replace("/", "月") + "日";
  2086. System.out.println("s = " + s);
  2087. // System.out.println(new BigDecimal("1").compareTo(null));//空指针 要判断
  2088. System.out.println("2022/01/01 10".substring(11));
  2089. String date = DateUtil.format(DateUtils.getNowDate(), DateUtils.YYYY_MM_DD_HH);
  2090. System.out.println("date = " + date);
  2091. System.out.println(HttpUtil.get("http://10.0.3.52:10003/system/forecast?type=2&time=" + date, 10));*/
  2092. System.out.println("2024-06-18 14".replaceAll("-", "/"));
  2093. String[] splitNew = new String[3];
  2094. splitNew[0] = "0";
  2095. splitNew[1] = "1";
  2096. splitNew[2] = "2";
  2097. System.out.println(Arrays.toString(splitNew));
  2098. System.out.println(DateUtils.parseDate("2024-06-25 10", DateUtils.YYYY_MM_DD_HH));
  2099. String yesterdayStr = LocalDateTimeUtil.getCurrentDate().plusDays(-1).format(DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD_TS));//昨天
  2100. System.out.println(yesterdayStr);
  2101. TimeUnit.MILLISECONDS.sleep(INT_10000);
  2102. System.out.println("2024/07/07 12".substring(0, 7));
  2103. System.out.println(BigDecimal_0_1.multiply(null));
  2104. }
  2105. //测试工业库 没小时保存一条记录是否可行
  2106. public static void test() {
  2107. // 每个小时的时间格式
  2108. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  2109. LocalDateTime startTime = LocalDateTime.parse("2024-05-18T00:00:00");
  2110. LocalDateTime endTime = LocalDateTime.now();
  2111. // 循环按小时分割
  2112. LocalDateTime currentHour = startTime;
  2113. //最终获取的数据
  2114. Map<String, TXinyiIndustry> needMap = new LinkedHashMap<>();
  2115. while (currentHour.isBefore(endTime)) {
  2116. String begin = currentHour.format(formatter);
  2117. String end = currentHour.plusMinutes(5).format(formatter);
  2118. // 输出当前小时的起始时间和结束时间
  2119. System.out.println("起始时间:" + begin);
  2120. System.out.println("结束时间:" + end);
  2121. // 当前小时加一小时,作为下一个小时的起始时间
  2122. currentHour = currentHour.plusMinutes(5);
  2123. //每个小时查询一次数据
  2124. String url = "http://10.0.0.27:4568/api/v1/khquerydata";
  2125. HashMap<String, Object> req = new HashMap<>();
  2126. req.put("tagNames", queryTags);
  2127. req.put("startTime", begin);
  2128. req.put("endTime", end);
  2129. req.put("recordNumbers", 100000);
  2130. String body = HttpRequest.post(url).header("Authorization", "c2E6c2E=").header("clientName", "hongshan").body(JSON.toJSONString(req)).execute().body();
  2131. // System.out.println("body = " + body);
  2132. List<HashMap<String, String>> list = new ArrayList<>();
  2133. //行转列数据处理
  2134. for (String queryTag : queryTags) {
  2135. JSONArray array = JSON.parseObject(body).getJSONArray(queryTag);
  2136. //特殊数据处理一
  2137. if(Objects.isNull(array) || array.isEmpty()){
  2138. System.out.println(queryTag + "查询到了空的数据,跳过本次循环");
  2139. continue;
  2140. }
  2141. int size = array.size();
  2142. //特殊数据处理二
  2143. if("0".equals(array.get(1) + "")){
  2144. System.out.println(queryTag + "查询到了数据,但是数据集合只有一条,且都是0");
  2145. continue;
  2146. }
  2147. //结合至少62个数据才满足条件(有可能获取不到)
  2148. /*if(size < 62){
  2149. System.out.println(queryTag + "查询到了不符合条件的数据,跳过本次循环");
  2150. continue;
  2151. }*/
  2152. //存放的数据集
  2153. //利用map去重
  2154. HashMap<String, String> map = new LinkedHashMap<>();
  2155. for (int i = 2; i < size; i++) {
  2156. // System.out.println(i + "" + array.get(i));
  2157. JSONArray oneRecord = JSON.parseArray(JSON.toJSONString(array.get(i)));
  2158. //处理为空或者为0的数据
  2159. Object timeStampValue = oneRecord.get(2);
  2160. if(Objects.isNull(timeStampValue) || "0".equals(timeStampValue + ""))
  2161. continue;
  2162. BigDecimal value = Objects.isNull(oneRecord.get(0)) ? null : new BigDecimal(oneRecord.get(0) + "");
  2163. long timestamp = (long) timeStampValue;
  2164. String format = DateUtil.format(new Date(timestamp), DateUtils.YYYYMMDDHH_TS);
  2165. map.put(format, queryTag + "-" + value);
  2166. }
  2167. list.add(map);
  2168. }
  2169. Set<String> recordTimeSet = new HashSet<>();
  2170. Map<String, TXinyiIndustry> recordMap = new HashMap<>();
  2171. for (int i = 0; i < list.size(); i++) {
  2172. HashMap<String, String> map = list.get(i);
  2173. int finalJ = i;
  2174. map.forEach((k, v) ->{
  2175. TXinyiIndustry industry = null;
  2176. if(!recordTimeSet.contains(k)){//第一次
  2177. industry = new TXinyiIndustry();
  2178. recordTimeSet.add(k);
  2179. recordMap.put(k, industry);
  2180. }else{
  2181. industry = recordMap.get(k);
  2182. }
  2183. industry.setTestTime(k + ":00");
  2184. //2024年4月15日11:19:52 额外增加2个字段
  2185. industry.setTestDate(k.substring(0,10));
  2186. industry.setTestHour(k.substring(0,13));
  2187. //解析值
  2188. String[] split = v.split("-");
  2189. String type = split[0];
  2190. BigDecimal value = new BigDecimal(split[1]);
  2191. if ("信义污水厂JS_COD_Value".equals(type)) {
  2192. industry.setJsCod(value);
  2193. } else if ("信义污水厂JS_PH_Value".equals(type)) {
  2194. industry.setJsPh(value);
  2195. } else if ("信义污水厂JS_SS_Value".equals(type)) {
  2196. industry.setJsSs(value);
  2197. } else if ("信义污水厂JS_ZL_Value".equals(type)) {
  2198. industry.setJsTp(value);
  2199. } else if ("信义污水厂JS_ZA_Value".equals(type)) {
  2200. industry.setJsTn(value);
  2201. } else if ("信义污水厂JS_AD_Value".equals(type)) {
  2202. industry.setJsNh3(value);
  2203. } else if ("信义污水厂JS_T_Value".equals(type)) {
  2204. industry.setJsSwPh(value);
  2205. } else if ("信义污水厂进水泵房液位".equals(type)) {
  2206. industry.setJsBfyw(value);
  2207. } else if ("信义污水厂出水瞬时流量".equals(type)) {
  2208. industry.setCsSlqc(value);
  2209. } else if ("信义污水厂升级出水COD".equals(type)) {
  2210. industry.setCsCod(value);
  2211. } else if ("信义污水厂升级出水PH".equals(type)) {
  2212. industry.setCsPh(value);
  2213. } else if ("信义污水厂升级出水SS".equals(type)) {
  2214. industry.setCsSs(value);
  2215. } else if ("信义污水厂升级出水TN".equals(type)) {
  2216. industry.setCsTn(value);
  2217. } else if ("信义污水厂升级出水TP".equals(type)) {
  2218. industry.setCsTp(value);
  2219. } else if ("信义污水厂升级出水氨氮".equals(type)) {
  2220. industry.setCsNh3(value);
  2221. } else if ("信义污水厂AIT202_Value".equals(type)) {
  2222. industry.setOneHyzdDo(value);
  2223. } else if ("信义污水厂AIT203_Value".equals(type)) {
  2224. industry.setOneHymdDo(value);
  2225. } else if ("信义污水厂AIT207_Value".equals(type)) {
  2226. industry.setTwoHyzdDo(value);
  2227. } else if ("信义污水厂AIT206_Value".equals(type)) {
  2228. industry.setTwoHymdDo(value);
  2229. } else if ("信义污水厂AIT209_Value".equals(type)) {
  2230. industry.setOneMlss(value);
  2231. } else if ("信义污水厂AIT210_Value".equals(type)) {
  2232. industry.setTwoMlss(value);
  2233. } else if ("信义污水厂进水TDS".equals(type)) {
  2234. industry.setJsTds(value);
  2235. } else if ("信义污水厂FT101_Value".equals(type)) {
  2236. industry.setJsSlq(value);
  2237. } else if ("信义污水厂SWCHHYHLB1_R_Value".equals(type)) {
  2238. industry.setNHlbOneGp(value);
  2239. } else if ("信义污水厂SWCHHYHLB2_R_Value".equals(type)) {
  2240. industry.setNHlbTwoGp(value);
  2241. } else if ("信义污水厂SWCHHYHLB3_R_Value".equals(type)) {
  2242. industry.setNHlbThreeGp(value);
  2243. } else if ("信义污水厂SWCHHYHLB4_R_Value".equals(type)) {
  2244. industry.setNHlbFourGp(value);
  2245. } else if ("信义污水厂SWCHHYHLB5_R_Value".equals(type)) {
  2246. industry.setNhlBFiveGp(value);
  2247. } else if ("信义污水厂SWCHHYHLB6_R_Value".equals(type)) {
  2248. industry.setNHlbSixGp(value);
  2249. } else if ("信义污水厂SWCWNHLB1_R_Value".equals(type)) {
  2250. industry.setWHlbOneGp(value);
  2251. } else if ("信义污水厂SWCWNHLB2_R_Value".equals(type)) {
  2252. industry.setWHlbTwoGp(value);
  2253. } else if ("信义污水厂SWCWNHLB3_R_Value".equals(type)) {
  2254. industry.setWHlbThreeGp(value);
  2255. } else if ("信义污水厂SWCWNHLB4_R_Value".equals(type)) {
  2256. industry.setWHlbFourGp(value);
  2257. } else if ("信义污水厂SWCWNHLB5_R_Value".equals(type)) {
  2258. industry.setWHlbFiveGp(value);
  2259. } else if ("信义污水厂GFJ1_R_Value".equals(type)) {
  2260. industry.setFjOne(value);
  2261. } else if ("信义污水厂GFJ2_R_Value".equals(type)) {
  2262. industry.setFjTwo(value);
  2263. } else if ("信义污水厂GFJ3_R_Value".equals(type)) {
  2264. industry.setFjThree(value);
  2265. } else if ("信义污水厂GFJ4_R_Value".equals(type)) {
  2266. industry.setFjFour(value);
  2267. } else if ("信义污水厂GFJ5_R_Value".equals(type)) {
  2268. industry.setFjFive(value);
  2269. } else if ("信义污水厂GFJ6_R_Value".equals(type)) {
  2270. industry.setFjSix(value);
  2271. } else if ("信义污水厂GFJ1_KQLL_Value".equals(type)) {
  2272. industry.setKqllOne(value);
  2273. } else if ("信义污水厂GFJ2_KQLL_Value".equals(type)) {
  2274. industry.setKqllTwo(value);
  2275. } else if ("信义污水厂GFJ3_KQLL_Value".equals(type)) {
  2276. industry.setKqllThree(value);
  2277. } else if ("信义污水厂GFJ4_KQLL_Value".equals(type)) {
  2278. industry.setKqllFour(value);
  2279. } else if ("信义污水厂GFJ5_KQLL_Value".equals(type)) {
  2280. industry.setKqllFive(value);
  2281. } else if ("信义污水厂GFJ6_KQLL_Value".equals(type)) {
  2282. industry.setKqllSix(value);
  2283. }else if ("信义污水厂实际碳源加药量".equals(type)) {
  2284. industry.setSJTYJLY(value);
  2285. }else if ("信义污水厂除磷加药瞬时流量".equals(type)) {
  2286. industry.setCLJYSSLL(value);
  2287. } else if ("信义污水厂_除磷P04预测值_".equals(type)) {
  2288. industry.setCLP04YCZ(value);
  2289. }
  2290. //只有最后一次才执行数据库添加
  2291. if(finalJ == list.size()-1){
  2292. needMap.put(industry.getTestHour(), industry);
  2293. }
  2294. });
  2295. }
  2296. }
  2297. //保存数据 触发告警 决策 问答记录等等
  2298. needMap.forEach((k, industry) ->{
  2299. System.out.println(JSON.toJSONString(industry));
  2300. });
  2301. }
  2302. }