AsyncTask.java 95 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592
  1. package com.slibra.quartz.task;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONObject;
  4. import com.alibaba.fastjson2.JSONWriter;
  5. import com.google.protobuf.ByteString;
  6. import com.slibra.business.domain.*;
  7. import com.slibra.business.mapper.*;
  8. import com.slibra.business.req.ChatReq;
  9. import com.slibra.business.req.ChatRequest;
  10. import com.slibra.business.req.DecisionReq;
  11. import com.slibra.business.req.PolicyReq;
  12. import com.slibra.business.res.ShowValueCSBasic;
  13. import com.slibra.business.res.ShowValueJSBasic;
  14. import com.slibra.common.constant.MyConstants;
  15. import com.slibra.common.enums.BusinessEnum;
  16. import com.slibra.common.utils.DateUtils;
  17. import com.slibra.common.utils.LocalDateTimeUtil;
  18. import com.slibra.common.utils.StringUtils;
  19. import com.slibra.common.utils.uuid.IdUtils;
  20. import inference.InferenceAPIsServiceGrpc;
  21. import inference.PredictionResponse;
  22. import inference.PredictionsRequest;
  23. import io.grpc.ManagedChannel;
  24. import io.grpc.ManagedChannelBuilder;
  25. import lombok.extern.slf4j.Slf4j;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.scheduling.annotation.Async;
  28. import org.springframework.stereotype.Component;
  29. import org.springframework.util.CollectionUtils;
  30. import java.io.IOException;
  31. import java.math.BigDecimal;
  32. import java.math.RoundingMode;
  33. import java.util.*;
  34. import static com.slibra.common.constant.MyConstants.*;
  35. @Component
  36. @Slf4j
  37. public class AsyncTask {
  38. @Autowired
  39. private TXinyiIndustryMapper xinyiIndustryMapper;
  40. @Autowired
  41. private TXinyiNormConfigMapper xinyiNormConfigMapper;
  42. @Autowired
  43. private TXinyiWarningRecordMapper xinyiWarningRecordMapper;
  44. @Autowired
  45. private TXinyiChatRecordMapper xinyiChatRecordMapper;
  46. @Autowired
  47. private TXinyiDailyMapper xinyiDailyMapper;
  48. @Autowired
  49. private TXinyiCalculateMapper xinyiCalculateMapper;
  50. @Autowired
  51. private TXinyiRobotMapper xinyiRobotMapper;
  52. @Autowired
  53. private TXinyiForecastComparisonMapper xinyiForecastComparisonMapper;
  54. /**
  55. *
  56. * 异步处理告警任务
  57. * @param tXinyiIndustry
  58. */
  59. @Async("customizeExecutor")
  60. public void handleWarning(TXinyiIndustry tXinyiIndustry){
  61. //2024年6月18日10:45:20 额外计算一下预测的准确度
  62. try {
  63. this.updateForecastComparisonByIndustry(tXinyiIndustry);
  64. } catch (Exception e) {
  65. log.error("-------------------------------更新预测准确度的时候异常,异常信息为{}", e.getMessage());
  66. }
  67. log.info("进入了定时任务保存工业库数据并触发报警操作");
  68. //获取配置表
  69. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  70. if(CollectionUtils.isEmpty(tXinyiNormConfigs))
  71. throw new RuntimeException("未查询到配置信息");
  72. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  73. //2024年6月7日15:26:44 把一些额外的计算的值,同时记录下来(xinyiCalculate对象在生化报警可能用的到)
  74. TXinyiCalculate xinyiCalculate = this.addCalculateByIndustry(tXinyiIndustry, normConfig);
  75. this.xinyiCalculateMapper.insertTXinyiCalculate(xinyiCalculate);
  76. //水质报警
  77. this.handleSZWarning(tXinyiIndustry, normConfig);
  78. //2024年5月28日14:14:26 下面是新增的 生化报警处理
  79. this.handleSHWarning(tXinyiIndustry, normConfig, xinyiCalculate);
  80. }
  81. /**
  82. * 额外计算一下预测的准确度
  83. * @param tXinyiIndustry
  84. */
  85. private void updateForecastComparisonByIndustry(TXinyiIndustry tXinyiIndustry) {
  86. BigDecimal csCod = tXinyiIndustry.getCsCod();
  87. BigDecimal csSs = tXinyiIndustry.getCsSs();
  88. BigDecimal csTn = tXinyiIndustry.getCsTn();
  89. BigDecimal csTp = tXinyiIndustry.getCsTp();
  90. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  91. String testHour = tXinyiIndustry.getTestHour();
  92. //时间段1
  93. List<TXinyiForecastComparison> tXinyiForecastComparisons1 = this.xinyiForecastComparisonMapper.selectTXinyiForecastComparisonList(TXinyiForecastComparison.builder().forecastTimeOne(testHour).build());
  94. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons1)){
  95. for (TXinyiForecastComparison tXinyiForecastComparison : tXinyiForecastComparisons1) {
  96. BigDecimal hsForecastOne = tXinyiForecastComparison.getHsForecastOne();
  97. BigDecimal yyForecastOne = tXinyiForecastComparison.getYyForecastOne();
  98. if("cod".equals(tXinyiForecastComparison.getCategory())){
  99. tXinyiForecastComparison.setRealOne(csCod);
  100. if(!Objects.isNull(csCod) && csCod.compareTo(BigDecimal.ZERO) > 0){
  101. if(!Objects.isNull(hsForecastOne))
  102. tXinyiForecastComparison.setHsErrorRateOne((csCod.subtract(hsForecastOne)).divide(csCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  103. if(!Objects.isNull(yyForecastOne))
  104. tXinyiForecastComparison.setYyErrorRateOne((csCod.subtract(yyForecastOne)).divide(csCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  105. }
  106. }
  107. if("ss".equals(tXinyiForecastComparison.getCategory())){
  108. tXinyiForecastComparison.setRealOne(csSs);
  109. if(!Objects.isNull(csSs) && csSs.compareTo(BigDecimal.ZERO) > 0){
  110. if(!Objects.isNull(hsForecastOne))
  111. tXinyiForecastComparison.setHsErrorRateOne((csSs.subtract(hsForecastOne)).divide(csSs, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  112. if(!Objects.isNull(yyForecastOne))
  113. tXinyiForecastComparison.setYyErrorRateOne((csSs.subtract(yyForecastOne)).divide(csSs, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  114. }
  115. }
  116. //2024年6月21日16:28:56 tn总氮的预测用xsy1和xsy2计算 并从化验库获取
  117. /*if("tn".equals(tXinyiForecastComparison.getCategory())){
  118. tXinyiForecastComparison.setRealOne(csTn);
  119. if(!Objects.isNull(csTn) && csTn.compareTo(BigDecimal.ZERO) > 0){
  120. if(!Objects.isNull(hsForecastOne))
  121. tXinyiForecastComparison.setHsErrorRateOne((csTn.subtract(hsForecastOne)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  122. if(!Objects.isNull(yyForecastOne))
  123. tXinyiForecastComparison.setYyErrorRateOne((csTn.subtract(yyForecastOne)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  124. }
  125. }*/
  126. //2024年6月20日11:16:55 出水总磷的真实值从化验室获取
  127. /*if("tp".equals(tXinyiForecastComparison.getCategory())){
  128. tXinyiForecastComparison.setRealOne(csTp);
  129. if(!Objects.isNull(csTp) && csTp.compareTo(BigDecimal.ZERO) > 0){
  130. tXinyiForecastComparison.setHsErrorRateOne((csTp.subtract(hsForecastOne)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  131. tXinyiForecastComparison.setYyErrorRateOne((csTp.subtract(yyForecastOne)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  132. }
  133. }*/
  134. if("nh3".equals(tXinyiForecastComparison.getCategory())){
  135. tXinyiForecastComparison.setRealOne(csNh3);
  136. if(!Objects.isNull(csNh3) && csNh3.compareTo(BigDecimal.ZERO) > 0){
  137. if(!Objects.isNull(hsForecastOne))
  138. tXinyiForecastComparison.setHsErrorRateOne((csNh3.subtract(hsForecastOne)).divide(csNh3, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  139. if(!Objects.isNull(yyForecastOne))
  140. tXinyiForecastComparison.setYyErrorRateOne((csNh3.subtract(yyForecastOne)).divide(csNh3, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  141. }
  142. }
  143. this.xinyiForecastComparisonMapper.updateTXinyiForecastComparison(tXinyiForecastComparison);
  144. }
  145. }
  146. //时间段2
  147. List<TXinyiForecastComparison> tXinyiForecastComparisons2 = this.xinyiForecastComparisonMapper.selectTXinyiForecastComparisonList(TXinyiForecastComparison.builder().forecastTimeTwo(testHour).build());
  148. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons2)){
  149. for (TXinyiForecastComparison tXinyiForecastComparison : tXinyiForecastComparisons2) {
  150. BigDecimal hsForecastTwo = tXinyiForecastComparison.getHsForecastTwo();
  151. BigDecimal yyForecastTwo = tXinyiForecastComparison.getYyForecastTwo();
  152. if("cod".equals(tXinyiForecastComparison.getCategory())){
  153. tXinyiForecastComparison.setRealTwo(csCod);
  154. if(!Objects.isNull(csCod) && csCod.compareTo(BigDecimal.ZERO) > 0){
  155. if(!Objects.isNull(hsForecastTwo))
  156. tXinyiForecastComparison.setHsErrorRateTwo((csCod.subtract(hsForecastTwo)).divide(csCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  157. if(!Objects.isNull(yyForecastTwo))
  158. tXinyiForecastComparison.setYyErrorRateTwo((csCod.subtract(yyForecastTwo)).divide(csCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  159. }
  160. }
  161. if("ss".equals(tXinyiForecastComparison.getCategory())){
  162. tXinyiForecastComparison.setRealTwo(csSs);
  163. if(!Objects.isNull(csSs) && csSs.compareTo(BigDecimal.ZERO) > 0){
  164. if(!Objects.isNull(hsForecastTwo))
  165. tXinyiForecastComparison.setHsErrorRateTwo((csSs.subtract(hsForecastTwo)).divide(csSs, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  166. if(!Objects.isNull(yyForecastTwo))
  167. tXinyiForecastComparison.setYyErrorRateTwo((csSs.subtract(yyForecastTwo)).divide(csSs, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  168. }
  169. }
  170. /*if("tn".equals(tXinyiForecastComparison.getCategory())){
  171. tXinyiForecastComparison.setRealTwo(csTn);
  172. if(!Objects.isNull(csTn) && csTn.compareTo(BigDecimal.ZERO) > 0){
  173. if(!Objects.isNull(hsForecastTwo))
  174. tXinyiForecastComparison.setHsErrorRateTwo((csTn.subtract(hsForecastTwo)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  175. if(!Objects.isNull(yyForecastTwo))
  176. tXinyiForecastComparison.setYyErrorRateTwo((csTn.subtract(yyForecastTwo)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  177. }
  178. }*/
  179. //2024年6月20日11:16:55 出水总磷的真实值从化验室获取
  180. /*if("tp".equals(tXinyiForecastComparison.getCategory())){
  181. tXinyiForecastComparison.setRealTwo(csTp);
  182. if(!Objects.isNull(csTp) && csTp.compareTo(BigDecimal.ZERO) > 0){
  183. tXinyiForecastComparison.setHsErrorRateTwo((csTp.subtract(hsForecastTwo)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  184. tXinyiForecastComparison.setYyErrorRateTwo((csTp.subtract(yyForecastTwo)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  185. }
  186. }*/
  187. if("nh3".equals(tXinyiForecastComparison.getCategory())){
  188. tXinyiForecastComparison.setRealTwo(csNh3);
  189. if(!Objects.isNull(csNh3) && csNh3.compareTo(BigDecimal.ZERO) > 0){
  190. if(!Objects.isNull(hsForecastTwo))
  191. tXinyiForecastComparison.setHsErrorRateTwo((csNh3.subtract(hsForecastTwo)).divide(csNh3, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  192. if(!Objects.isNull(yyForecastTwo))
  193. tXinyiForecastComparison.setYyErrorRateTwo((csNh3.subtract(yyForecastTwo)).divide(csNh3, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  194. }
  195. }
  196. this.xinyiForecastComparisonMapper.updateTXinyiForecastComparison(tXinyiForecastComparison);
  197. }
  198. }
  199. //时间段3
  200. List<TXinyiForecastComparison> tXinyiForecastComparisons3 = this.xinyiForecastComparisonMapper.selectTXinyiForecastComparisonList(TXinyiForecastComparison.builder().forecastTimeThree(testHour).build());
  201. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons3)){
  202. for (TXinyiForecastComparison tXinyiForecastComparison : tXinyiForecastComparisons3) {
  203. BigDecimal hsForecastThree = tXinyiForecastComparison.getHsForecastThree();
  204. BigDecimal yyForecastThree = tXinyiForecastComparison.getYyForecastThree();
  205. if("cod".equals(tXinyiForecastComparison.getCategory())){
  206. tXinyiForecastComparison.setRealThree(csCod);
  207. if(!Objects.isNull(csCod) && csCod.compareTo(BigDecimal.ZERO) > 0){
  208. if(!Objects.isNull(hsForecastThree))
  209. tXinyiForecastComparison.setHsErrorRateThree((csCod.subtract(hsForecastThree)).divide(csCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  210. if(!Objects.isNull(yyForecastThree))
  211. tXinyiForecastComparison.setYyErrorRateThree((csCod.subtract(yyForecastThree)).divide(csCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  212. }
  213. }
  214. if("ss".equals(tXinyiForecastComparison.getCategory())){
  215. tXinyiForecastComparison.setRealThree(csSs);
  216. if(!Objects.isNull(csSs) && csSs.compareTo(BigDecimal.ZERO) > 0){
  217. if(!Objects.isNull(hsForecastThree))
  218. tXinyiForecastComparison.setHsErrorRateThree((csSs.subtract(hsForecastThree)).divide(csSs, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  219. if(!Objects.isNull(yyForecastThree))
  220. tXinyiForecastComparison.setYyErrorRateThree((csSs.subtract(yyForecastThree)).divide(csSs, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  221. }
  222. }
  223. /*if("tn".equals(tXinyiForecastComparison.getCategory())){
  224. tXinyiForecastComparison.setRealThree(csTn);
  225. if(!Objects.isNull(csTn) && csTn.compareTo(BigDecimal.ZERO) > 0){
  226. if(!Objects.isNull(hsForecastThree))
  227. tXinyiForecastComparison.setHsErrorRateThree((csTn.subtract(hsForecastThree)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  228. if(!Objects.isNull(yyForecastThree))
  229. tXinyiForecastComparison.setYyErrorRateThree((csTn.subtract(yyForecastThree)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  230. }
  231. }*/
  232. //2024年6月20日11:16:55 出水总磷的真实值从化验室获取
  233. /*if("tp".equals(tXinyiForecastComparison.getCategory())){
  234. tXinyiForecastComparison.setRealThree(csTp);
  235. if(!Objects.isNull(csTp) && csTp.compareTo(BigDecimal.ZERO) > 0){
  236. tXinyiForecastComparison.setHsErrorRateThree((csTp.subtract(hsForecastThree)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  237. tXinyiForecastComparison.setYyErrorRateThree((csTp.subtract(yyForecastThree)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  238. }
  239. }*/
  240. if("nh3".equals(tXinyiForecastComparison.getCategory())){
  241. tXinyiForecastComparison.setRealThree(csNh3);
  242. if(!Objects.isNull(csNh3) && csNh3.compareTo(BigDecimal.ZERO) > 0){
  243. if(!Objects.isNull(hsForecastThree))
  244. tXinyiForecastComparison.setHsErrorRateThree((csNh3.subtract(hsForecastThree)).divide(csNh3, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  245. if(!Objects.isNull(yyForecastThree))
  246. tXinyiForecastComparison.setYyErrorRateThree((csNh3.subtract(yyForecastThree)).divide(csNh3, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  247. }
  248. }
  249. this.xinyiForecastComparisonMapper.updateTXinyiForecastComparison(tXinyiForecastComparison);
  250. }
  251. }
  252. }
  253. /**
  254. * 额外计算一下预测的准确度
  255. * @param tXinyiRobot
  256. */
  257. public void updateForecastComparisonByRobot(TXinyiRobot tXinyiRobot) {
  258. BigDecimal no3Hlj1Jqr = tXinyiRobot.getNo3Hlj1Jqr();
  259. BigDecimal no3Hlj2Jqr = tXinyiRobot.getNo3Hlj2Jqr();
  260. String testHour = tXinyiRobot.getTestHour();
  261. BigDecimal tpRccJqr = tXinyiRobot.getTpRccJqr();
  262. BigDecimal csTp = null;
  263. BigDecimal csTn = null;
  264. if(!Objects.isNull(tpRccJqr)){
  265. csTp = tpRccJqr.divide(ROBOT_HY_DIVIDE, NUMBER_SCALE_4, RoundingMode.HALF_UP);
  266. //2024年6月20日13:44:26 先不计算,结果会更准确
  267. //2024年6月21日14:23:14 就是要 除以0.8
  268. // csTp = tpRccJqr;
  269. }
  270. if(!Objects.isNull(no3Hlj1Jqr) && !Objects.isNull(no3Hlj2Jqr))
  271. csTn = (no3Hlj1Jqr.add(no3Hlj2Jqr)).divide(new BigDecimal(2), NUMBER_SCALE_4, RoundingMode.HALF_UP).divide(ROBOT_HY_DIVIDE, NUMBER_SCALE_4, RoundingMode.HALF_UP);
  272. //时间段1
  273. List<TXinyiForecastComparison> tXinyiForecastComparisons1 = this.xinyiForecastComparisonMapper.selectTXinyiForecastComparisonList(TXinyiForecastComparison.builder().forecastTimeOne(testHour).build());
  274. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons1)){
  275. for (TXinyiForecastComparison tXinyiForecastComparison : tXinyiForecastComparisons1) {
  276. BigDecimal hsForecastOne = tXinyiForecastComparison.getHsForecastOne();
  277. BigDecimal yyForecastOne = tXinyiForecastComparison.getYyForecastOne();
  278. /*if("xsy1".equals(tXinyiForecastComparison.getCategory())){
  279. tXinyiForecastComparison.setRealOne(no3Hlj1Jqr);
  280. if(!Objects.isNull(no3Hlj1Jqr) && no3Hlj1Jqr.compareTo(BigDecimal.ZERO) > 0){
  281. if(!Objects.isNull(hsForecastOne))
  282. tXinyiForecastComparison.setHsErrorRateOne((no3Hlj1Jqr.subtract(hsForecastOne)).divide(no3Hlj1Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  283. if(!Objects.isNull(yyForecastOne))
  284. tXinyiForecastComparison.setYyErrorRateOne((no3Hlj1Jqr.subtract(yyForecastOne)).divide(no3Hlj1Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  285. }
  286. }
  287. if("xsy2".equals(tXinyiForecastComparison.getCategory())){
  288. tXinyiForecastComparison.setRealOne(no3Hlj2Jqr);
  289. if(!Objects.isNull(no3Hlj2Jqr) && no3Hlj2Jqr.compareTo(BigDecimal.ZERO) > 0){
  290. if(!Objects.isNull(hsForecastOne))
  291. tXinyiForecastComparison.setHsErrorRateOne((no3Hlj2Jqr.subtract(hsForecastOne)).divide(no3Hlj2Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  292. if(!Objects.isNull(yyForecastOne))
  293. tXinyiForecastComparison.setYyErrorRateOne((no3Hlj2Jqr.subtract(yyForecastOne)).divide(no3Hlj2Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  294. }
  295. }*/
  296. //2024年6月21日17:04:01 总磷的真实值也从化验室获取
  297. if("tn".equals(tXinyiForecastComparison.getCategory())){
  298. tXinyiForecastComparison.setRealOne(csTn);
  299. if(!Objects.isNull(csTn) && csTn.compareTo(BigDecimal.ZERO) > 0){
  300. if(!Objects.isNull(hsForecastOne))
  301. tXinyiForecastComparison.setHsErrorRateOne((csTn.subtract(hsForecastOne)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  302. if(!Objects.isNull(yyForecastOne))
  303. tXinyiForecastComparison.setYyErrorRateOne((csTn.subtract(yyForecastOne)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  304. }
  305. }
  306. //2024年6月20日11:14:42 总磷的真实值也从化验室获取
  307. if("tp".equals(tXinyiForecastComparison.getCategory())){
  308. tXinyiForecastComparison.setRealOne(csTp);
  309. if(!Objects.isNull(csTp) && csTp.compareTo(BigDecimal.ZERO) > 0){
  310. if(!Objects.isNull(hsForecastOne))
  311. tXinyiForecastComparison.setHsErrorRateOne((csTp.subtract(hsForecastOne)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  312. if(!Objects.isNull(yyForecastOne))
  313. tXinyiForecastComparison.setYyErrorRateOne((csTp.subtract(yyForecastOne)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  314. }
  315. }
  316. this.xinyiForecastComparisonMapper.updateTXinyiForecastComparison(tXinyiForecastComparison);
  317. }
  318. }
  319. //时间段2
  320. List<TXinyiForecastComparison> tXinyiForecastComparisons2 = this.xinyiForecastComparisonMapper.selectTXinyiForecastComparisonList(TXinyiForecastComparison.builder().forecastTimeTwo(testHour).build());
  321. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons2)){
  322. for (TXinyiForecastComparison tXinyiForecastComparison : tXinyiForecastComparisons2) {
  323. BigDecimal hsForecastTwo = tXinyiForecastComparison.getHsForecastTwo();
  324. BigDecimal yyForecastTwo = tXinyiForecastComparison.getYyForecastTwo();
  325. /*if("xsy1".equals(tXinyiForecastComparison.getCategory())){
  326. tXinyiForecastComparison.setRealTwo(no3Hlj1Jqr);
  327. if(!Objects.isNull(no3Hlj1Jqr) && no3Hlj1Jqr.compareTo(BigDecimal.ZERO) > 0){
  328. if(!Objects.isNull(hsForecastTwo))
  329. tXinyiForecastComparison.setHsErrorRateTwo((no3Hlj1Jqr.subtract(hsForecastTwo)).divide(no3Hlj1Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  330. if(!Objects.isNull(yyForecastTwo))
  331. tXinyiForecastComparison.setYyErrorRateTwo((no3Hlj1Jqr.subtract(yyForecastTwo)).divide(no3Hlj1Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  332. }
  333. }
  334. if("xsy2".equals(tXinyiForecastComparison.getCategory())){
  335. tXinyiForecastComparison.setRealTwo(no3Hlj2Jqr);
  336. if(!Objects.isNull(no3Hlj2Jqr) && no3Hlj2Jqr.compareTo(BigDecimal.ZERO) > 0){
  337. if(!Objects.isNull(hsForecastTwo))
  338. tXinyiForecastComparison.setHsErrorRateTwo((no3Hlj2Jqr.subtract(hsForecastTwo)).divide(no3Hlj2Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  339. if(!Objects.isNull(yyForecastTwo))
  340. tXinyiForecastComparison.setYyErrorRateTwo((no3Hlj2Jqr.subtract(yyForecastTwo)).divide(no3Hlj2Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  341. }
  342. }*/
  343. //2024年6月21日17:04:01 总磷的真实值也从化验室获取
  344. if("tn".equals(tXinyiForecastComparison.getCategory())){
  345. tXinyiForecastComparison.setRealTwo(csTn);
  346. if(!Objects.isNull(csTn) && csTn.compareTo(BigDecimal.ZERO) > 0){
  347. if(!Objects.isNull(hsForecastTwo))
  348. tXinyiForecastComparison.setHsErrorRateTwo((csTn.subtract(hsForecastTwo)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  349. if(!Objects.isNull(yyForecastTwo))
  350. tXinyiForecastComparison.setYyErrorRateTwo((csTn.subtract(yyForecastTwo)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  351. }
  352. }
  353. //2024年6月20日11:14:42 总磷的真实值也从化验室获取
  354. if("tp".equals(tXinyiForecastComparison.getCategory())){
  355. tXinyiForecastComparison.setRealTwo(csTp);
  356. if(!Objects.isNull(csTp) && csTp.compareTo(BigDecimal.ZERO) > 0){
  357. if(!Objects.isNull(hsForecastTwo))
  358. tXinyiForecastComparison.setHsErrorRateTwo((csTp.subtract(hsForecastTwo)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  359. if(!Objects.isNull(yyForecastTwo))
  360. tXinyiForecastComparison.setYyErrorRateTwo((csTp.subtract(yyForecastTwo)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  361. }
  362. }
  363. this.xinyiForecastComparisonMapper.updateTXinyiForecastComparison(tXinyiForecastComparison);
  364. }
  365. }
  366. //时间段3
  367. List<TXinyiForecastComparison> tXinyiForecastComparisons3 = this.xinyiForecastComparisonMapper.selectTXinyiForecastComparisonList(TXinyiForecastComparison.builder().forecastTimeThree(testHour).build());
  368. if(!CollectionUtils.isEmpty(tXinyiForecastComparisons3)){
  369. for (TXinyiForecastComparison tXinyiForecastComparison : tXinyiForecastComparisons3) {
  370. BigDecimal hsForecastThree = tXinyiForecastComparison.getHsForecastThree();
  371. BigDecimal yyForecastThree = tXinyiForecastComparison.getYyForecastThree();
  372. /*if("xsy1".equals(tXinyiForecastComparison.getCategory())){
  373. tXinyiForecastComparison.setRealThree(no3Hlj1Jqr);
  374. if(!Objects.isNull(no3Hlj1Jqr) && no3Hlj1Jqr.compareTo(BigDecimal.ZERO) > 0){
  375. if(!Objects.isNull(hsForecastThree))
  376. tXinyiForecastComparison.setHsErrorRateThree((no3Hlj1Jqr.subtract(hsForecastThree)).divide(no3Hlj1Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  377. if(!Objects.isNull(yyForecastThree))
  378. tXinyiForecastComparison.setYyErrorRateThree((no3Hlj1Jqr.subtract(yyForecastThree)).divide(no3Hlj1Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  379. }
  380. }
  381. if("xsy2".equals(tXinyiForecastComparison.getCategory())){
  382. tXinyiForecastComparison.setRealThree(no3Hlj2Jqr);
  383. if(!Objects.isNull(no3Hlj2Jqr) && no3Hlj2Jqr.compareTo(BigDecimal.ZERO) > 0){
  384. if(!Objects.isNull(hsForecastThree))
  385. tXinyiForecastComparison.setHsErrorRateThree((no3Hlj2Jqr.subtract(hsForecastThree)).divide(no3Hlj2Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  386. if(!Objects.isNull(yyForecastThree))
  387. tXinyiForecastComparison.setYyErrorRateThree((no3Hlj2Jqr.subtract(yyForecastThree)).divide(no3Hlj2Jqr, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  388. }
  389. }*/
  390. //2024年6月21日17:04:01 总磷的真实值也从化验室获取
  391. if("tn".equals(tXinyiForecastComparison.getCategory())){
  392. tXinyiForecastComparison.setRealThree(csTn);
  393. if(!Objects.isNull(csTn) && csTn.compareTo(BigDecimal.ZERO) > 0){
  394. if(!Objects.isNull(hsForecastThree))
  395. tXinyiForecastComparison.setHsErrorRateThree((csTn.subtract(hsForecastThree)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  396. if(!Objects.isNull(yyForecastThree))
  397. tXinyiForecastComparison.setYyErrorRateThree((csTn.subtract(yyForecastThree)).divide(csTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  398. }
  399. }
  400. //2024年6月20日11:14:42 总磷的真实值也从化验室获取
  401. if("tp".equals(tXinyiForecastComparison.getCategory())){
  402. tXinyiForecastComparison.setRealThree(csTp);
  403. if(!Objects.isNull(csTp) && csTp.compareTo(BigDecimal.ZERO) > 0){
  404. if(!Objects.isNull(hsForecastThree))
  405. tXinyiForecastComparison.setHsErrorRateThree((csTp.subtract(hsForecastThree)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  406. if(!Objects.isNull(yyForecastThree))
  407. tXinyiForecastComparison.setYyErrorRateThree((csTp.subtract(yyForecastThree)).divide(csTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  408. }
  409. }
  410. this.xinyiForecastComparisonMapper.updateTXinyiForecastComparison(tXinyiForecastComparison);
  411. }
  412. }
  413. }
  414. private TXinyiCalculate addCalculateByIndustry(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  415. //获取的一些配置信息
  416. BigDecimal nhlbqdsl = normConfig.getNHLBQDSL();
  417. BigDecimal nhlbdsjll = normConfig.getNHLBDSJLL();
  418. BigDecimal nhlbgzxl = normConfig.getNHLBGZXL();
  419. BigDecimal whlbqdsl = normConfig.getWHLBQDSL();
  420. BigDecimal whlbdsjll = normConfig.getWHLBDSJLL();
  421. BigDecimal whlbgzxl = normConfig.getWHLBGZXL();
  422. BigDecimal gfjgzts = normConfig.getGFJGZTS();
  423. BigDecimal gfjckll = normConfig.getGFJCKLL();
  424. BigDecimal fcxbsjll = normConfig.getFCXBSJLL();
  425. BigDecimal fclbsl = normConfig.getFCLBSL();
  426. BigDecimal fcxbgzxl = normConfig.getFCXBGZXL();
  427. //结算结果
  428. TXinyiCalculate tXinyiCalculate = new TXinyiCalculate();
  429. //时间相关
  430. tXinyiCalculate.setTestDate(tXinyiIndustry.getTestDate());
  431. tXinyiCalculate.setTestHour(tXinyiIndustry.getTestHour());
  432. tXinyiCalculate.setTestTime(tXinyiIndustry.getTestTime());
  433. //获取最新的一条日报信息
  434. TXinyiDaily tXinyiDaily = this.xinyiDailyMapper.selectNewestData();
  435. if(Objects.isNull(tXinyiDaily)){
  436. //理论不会出现
  437. log.error("没有日报数据");
  438. return null;
  439. }
  440. BigDecimal jsBod5 = tXinyiDaily.getJsBod5();
  441. BigDecimal csBod5 = tXinyiDaily.getCsBod5();
  442. BigDecimal whlR = tXinyiDaily.getWhlR();
  443. BigDecimal oneMlvss = tXinyiDaily.getShcHyOneMlvss();
  444. BigDecimal twoMlvss = tXinyiDaily.getShcHyTwoMlvss();
  445. BigDecimal avgMlvss = null;
  446. if(!Objects.isNull(oneMlvss) && !Objects.isNull(twoMlvss))
  447. avgMlvss = ((oneMlvss.add(twoMlvss)).divide(new BigDecimal(2),4, RoundingMode.HALF_UP));
  448. BigDecimal oneMlss = tXinyiDaily.getShcHyOneMlss();
  449. BigDecimal twoMlss = tXinyiDaily.getShcHyTwoMlss();
  450. BigDecimal avgMlss = null;
  451. if(!Objects.isNull(oneMlss) && !Objects.isNull(twoMlss))
  452. avgMlss = ((oneMlss.add(twoMlss)).divide(new BigDecimal(NUMBER_2),NUMBER_SCALE_4, RoundingMode.HALF_UP));
  453. //工业库的指标
  454. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  455. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  456. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  457. BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  458. //计算
  459. if(!Objects.isNull(jsBod5)){
  460. if(!Objects.isNull(jsTn) && jsTn.compareTo(BigDecimal.ZERO) > 0)
  461. tXinyiCalculate.setJsTdb(jsBod5.divide(jsTn, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  462. if(!Objects.isNull(jsTp) && jsTp.compareTo(BigDecimal.ZERO) > 0)
  463. tXinyiCalculate.setJsTlb(jsBod5.divide(jsTp, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  464. if(!Objects.isNull(jsCod) && jsCod.compareTo(BigDecimal.ZERO) > 0)
  465. tXinyiCalculate.setJsBodBCod(jsBod5.divide(jsCod, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  466. if(!Objects.isNull(csBod5) && !Objects.isNull(avgMlss) && avgMlss.compareTo(BigDecimal.ZERO) > 0 && !Objects.isNull(jsSlq) && jsSlq.compareTo(BigDecimal.ZERO) > 0)
  467. tXinyiCalculate.setFM(new BigDecimal(ONE_DAY_HOURS).multiply((jsBod5.subtract(csBod5))).multiply(jsSlq).divide(avgMlss, NUMBER_SCALE_4, RoundingMode.HALF_UP).divide(new BigDecimal(F_M_LAST), NUMBER_SCALE_4, RoundingMode.HALF_UP));
  468. }
  469. if(!Objects.isNull(avgMlss) && avgMlss.compareTo(BigDecimal.ZERO) > 0 && !Objects.isNull(avgMlvss) && avgMlvss.compareTo(BigDecimal.ZERO) > 0)
  470. tXinyiCalculate.setHFXWNNDZB(avgMlvss.divide(avgMlss, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  471. if(!Objects.isNull(jsSlq) && jsSlq.compareTo(BigDecimal.ZERO) > 0){
  472. tXinyiCalculate.setYyqHrt(new BigDecimal(YYQ_TLSJ_FIRST).divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  473. tXinyiCalculate.setQyqHrt(new BigDecimal(QYQ_TLSJ_FIRST).divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  474. tXinyiCalculate.setHyqHrt(new BigDecimal(HYQ_TLSJ_FIRST).divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  475. // tXinyiCalculate.setGSLS(jsSlq.divide(new BigDecimal(NUMBER_3600), NUMBER_SCALE_4, RoundingMode.HALF_UP).multiply(new BigDecimal(NUMBER_4)).divide((new BigDecimal(Math.PI).multiply(new BigDecimal(NUMBER_0_0_0_3)).multiply(new BigDecimal(NUMBER_0_0_0_3)).multiply(new BigDecimal(NUMBER_4)).multiply(new BigDecimal(NUMBER_4)).multiply(new BigDecimal(NUMBER_97119))) , NUMBER_SCALE_4, RoundingMode.HALF_UP));
  476. tXinyiCalculate.setGSLS(jsSlq.divide(GSLS_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  477. tXinyiCalculate.setGslsOne(jsSlq.divide(new BigDecimal(NUMBER_3600), NUMBER_SCALE_4, RoundingMode.HALF_UP).multiply(new BigDecimal(Math.sqrt(Math.sin(Math.toRadians(DOUBLE_75))))).divide(GSLSONE_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  478. tXinyiCalculate.setGslsTwo(jsSlq.divide(new BigDecimal(NUMBER_3600), NUMBER_SCALE_4, RoundingMode.HALF_UP).multiply(new BigDecimal(Math.sqrt(Math.sin(Math.toRadians(DOUBLE_75))))).divide(GSLSTWO_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  479. tXinyiCalculate.setXgsGsls(jsSlq.divide(new BigDecimal(NUMBER_3600), NUMBER_SCALE_4, RoundingMode.HALF_UP).multiply(new BigDecimal(NUMBER_4)).divide((GSLS_XGS_LAST) , NUMBER_SCALE_4, RoundingMode.HALF_UP));
  480. tXinyiCalculate.setXlcscBmfh(jsSlq.divide(XLCSCBMFH_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  481. tXinyiCalculate.setXlcscHrt(XLCSCHRT_LAST.divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  482. tXinyiCalculate.setCccdcBmfh(jsSlq.divide(CCCDCBMFH_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  483. tXinyiCalculate.setCccdcHrt(CCCDCHRT_LAST.divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  484. tXinyiCalculate.setEccBmfh(jsSlq.divide(ECCBMFH_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  485. tXinyiCalculate.setEccHrt(ECCHRT_LAST.divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  486. //2024年7月1日17:16:16 计算逻辑调整
  487. tXinyiCalculate.setEccGtfh((new BigDecimal(1).add(whlR.divide(BigDecimal_100, NUMBER_SCALE_4, RoundingMode.HALF_UP))).multiply(jsSlq).multiply(new BigDecimal(NUMBER_24)).multiply(avgMlss).divide(ECCGTFH_LAST, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  488. tXinyiCalculate.setClsnJcsj(CLSNJCSJ_LAST.divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  489. tXinyiCalculate.setXgcdcQsqSsls(jsSlq.multiply(XGCDCQSQSSLS_LAST));
  490. //2024年6月29日15:18:01 增加几个新的计算指标
  491. if(!Objects.isNull(nhlbqdsl) && !Objects.isNull(nhlbdsjll) && !Objects.isNull(nhlbgzxl))
  492. tXinyiCalculate.setNHLB(nhlbqdsl.multiply(nhlbdsjll).multiply(nhlbgzxl).multiply(BigDecimal_100).divide(jsSlq, 4, RoundingMode.HALF_UP));
  493. if(!Objects.isNull(whlbqdsl) && !Objects.isNull(whlbdsjll) && !Objects.isNull(whlbgzxl))
  494. tXinyiCalculate.setWHLB(whlbqdsl.multiply(whlbdsjll).multiply(whlbgzxl).multiply(BigDecimal_100).divide(jsSlq, 4, RoundingMode.HALF_UP));
  495. if(!Objects.isNull(gfjgzts) && !Objects.isNull(gfjckll))
  496. tXinyiCalculate.setQSB(gfjgzts.multiply(gfjckll).divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  497. if(!Objects.isNull(fcxbsjll) && !Objects.isNull(fclbsl) && !Objects.isNull(fcxbgzxl)){
  498. BigDecimal fcxsl = fcxbsjll.multiply(fclbsl).multiply(fcxbgzxl);
  499. tXinyiCalculate.setFCXSL(fcxsl);
  500. //2024年7月3日10:54:28 额外再增加一个字段
  501. tXinyiCalculate.setFCXSLBL(fcxsl.divide(jsSlq, NUMBER_SCALE_4, RoundingMode.HALF_UP).multiply(BigDecimal_100));
  502. }
  503. }
  504. return tXinyiCalculate;
  505. }
  506. private void handleSHWarning(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, TXinyiCalculate xinyiCalculate) {
  507. //判断对应指标是否报警 然后调研大模型获取决策信息
  508. // BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  509. //内回流比报警
  510. // BigDecimal nhlbSjz = normConfig.getNhlbSjz();//400
  511. // BigDecimal nhlbnkSxz = normConfig.getNhlbnkSxz();//360
  512. BigDecimal nhlbnkXxz = normConfig.getNhlbnkXxz();//270
  513. // BigDecimal nhlbqdsl = normConfig.getNHLBQDSL();
  514. // BigDecimal nhlbdsjll = normConfig.getNHLBDSJLL();
  515. // BigDecimal nhlbgzxl = normConfig.getNHLBGZXL();
  516. BigDecimal nhlb = xinyiCalculate.getNHLB();
  517. if(!Objects.isNull(nhlb) && !Objects.isNull(nhlbnkXxz)){
  518. // BigDecimal divide = nhlbqdsl.multiply(nhlbdsjll).multiply(nhlbgzxl).divide(jsSlq, 4, RoundingMode.HALF_UP);
  519. handleXinYiWarningsSH(nhlbnkXxz, nhlb, BusinessEnum.WarningCategoryEnum.NHLB.getCode(), tXinyiIndustry, normConfig, true);
  520. }
  521. //外回流比报警
  522. // BigDecimal whlbqdsl = normConfig.getWHLBQDSL();
  523. // BigDecimal whlbdsjll = normConfig.getWHLBDSJLL();
  524. // BigDecimal whlbgzxl = normConfig.getWHLBGZXL();
  525. BigDecimal whlbnkXxz = normConfig.getWhlbnkXxz();//75
  526. // BigDecimal whlbSjz = normConfig.getWhlbSjz();
  527. BigDecimal whlb = xinyiCalculate.getWHLB();
  528. if(!Objects.isNull(whlb) && !Objects.isNull(whlbnkXxz)){
  529. handleXinYiWarningsSH(whlbnkXxz, whlb, BusinessEnum.WarningCategoryEnum.WHLB.getCode(), tXinyiIndustry, normConfig, true);
  530. }
  531. //最新的一条日报数据
  532. /*List<TXinyiDaily> tXinyiDailies = this.xinyiDailyMapper.selectTXinyiDailyList(null);
  533. if(CollectionUtils.isEmpty(tXinyiDailies))
  534. return;//肯定不会出现这种情况 因为有很多历史数据了
  535. TXinyiDaily tXinyiDaily = tXinyiDailies.get(0);*/
  536. TXinyiDaily tXinyiDaily = this.xinyiDailyMapper.selectNewestData();
  537. if(Objects.isNull(tXinyiDaily))
  538. return;//肯定不会出现这种情况 因为有很多历史数据了 新水厂可能会有这个问题
  539. log.info("生化报警获取日报的最新的一条数据为{}", JSON.toJSONString(tXinyiDaily));
  540. //污泥浓度报警
  541. BigDecimal sjscgkz = null;
  542. //判断是否是夏季
  543. if(LocalDateTimeUtil.isSummer())
  544. sjscgkz = normConfig.getXjwnndXxz();
  545. else
  546. sjscgkz = normConfig.getDjwnndXxz();
  547. //#1
  548. BigDecimal oneMlss = tXinyiIndustry.getOneMlss();
  549. if(!Objects.isNull(oneMlss) && !Objects.isNull(sjscgkz)){
  550. handleXinYiWarningsSH(sjscgkz, oneMlss, BusinessEnum.WarningCategoryEnum.WNND_MLSS_1.getCode(), tXinyiIndustry, normConfig, true);
  551. }
  552. //#1
  553. BigDecimal twoMlss = tXinyiIndustry.getTwoMlss();
  554. if(!Objects.isNull(twoMlss) && !Objects.isNull(sjscgkz)){
  555. handleXinYiWarningsSH(sjscgkz, twoMlss, BusinessEnum.WarningCategoryEnum.WNND_MLSS_2.getCode(), tXinyiIndustry, normConfig, true);
  556. }
  557. //污泥负荷(需要从日报获取数据) 计算 + 部分数据从日报获取
  558. //污泥负荷=[Ls]=24*([BOD_in]-[BOD_off])*[Q_in]/[MLSS]/([V_hao]+[V_que]+[V_yan])/2 kgBOD/(kgMLSS·d)
  559. //2024年6月27日17:18:33 直接从计算结果拿到
  560. BigDecimal fm = xinyiCalculate.getFM();
  561. //2024年6月28日17:17:03 已经配置了新的
  562. BigDecimal wnfhnkXxz = normConfig.getWnfhnkXxz();
  563. if(!Objects.isNull(fm) && !Objects.isNull(wnfhnkXxz)){
  564. handleXinYiWarningsSH(wnfhnkXxz, fm, BusinessEnum.WarningCategoryEnum.WNFH.getCode(), tXinyiIndustry, normConfig, true);
  565. }
  566. //万吨水产泥率(todo 没有计算规则,只能从日报获取)
  567. //挥发性污泥浓度占比(MLVSS/MLSS)
  568. //特殊:小于
  569. BigDecimal hfxwnndzb = xinyiCalculate.getHFXWNNDZB();
  570. BigDecimal hfxwnndzbSjz = normConfig.getHfxwnndzbSjz();
  571. if(!Objects.isNull(hfxwnndzb) && !Objects.isNull(hfxwnndzbSjz)){
  572. handleXinYiWarningsSH(hfxwnndzbSjz, hfxwnndzb, BusinessEnum.WarningCategoryEnum.HFXWNNDZB.getCode(), tXinyiIndustry, normConfig, false);
  573. }
  574. //进水碳氮比
  575. BigDecimal jsTdb = xinyiCalculate.getJsTdb();
  576. BigDecimal jstdbnkzXxz = normConfig.getJstdbnkzXxz();
  577. if(!Objects.isNull(jsTdb) && !Objects.isNull(jstdbnkzXxz)){
  578. handleXinYiWarningsSH(jstdbnkzXxz, jsTdb, BusinessEnum.WarningCategoryEnum.TDB.getCode(), tXinyiIndustry, normConfig, true);
  579. }
  580. //进水碳磷比
  581. BigDecimal jsTlb = xinyiCalculate.getJsTlb();
  582. BigDecimal jstlbNkz = normConfig.getJstlbNkz();
  583. if(!Objects.isNull(jsTlb) && !Objects.isNull(jstlbNkz)){
  584. handleXinYiWarningsSH(jstlbNkz, jsTlb, BusinessEnum.WarningCategoryEnum.TLB.getCode(), tXinyiIndustry, normConfig, true);
  585. }
  586. //进水BOD与COD比值(生化性)
  587. BigDecimal jsBodBCod = xinyiCalculate.getJsBodBCod();
  588. String jsbodycodbzGkz = normConfig.getJsbodycodbzGkz();
  589. if(!StringUtils.isBlank(jsbodycodbzGkz) && jsbodycodbzGkz.contains("-")){
  590. String[] split = jsbodycodbzGkz.split("-");
  591. sjscgkz = new BigDecimal(split[0]);
  592. if(!Objects.isNull(jsBodBCod)){
  593. handleXinYiWarningsSH(sjscgkz, jsBodBCod, BusinessEnum.WarningCategoryEnum.TLB.getCode(), tXinyiIndustry, normConfig, true);
  594. }
  595. }
  596. //好氧区DO(一池) 2024年5月31日14:04:37 加数据,让他一直报警
  597. BigDecimal shcHyOneDo = tXinyiIndustry.getOneHymdDo();
  598. // BigDecimal shcHyOneDo = new BigDecimal("5");
  599. // BigDecimal hycrjysjzSxz = normConfig.getHycrjysjzSxz();
  600. BigDecimal hycrjyNkz = normConfig.getHycrjyNkz();
  601. if(!Objects.isNull(shcHyOneDo) && !Objects.isNull(hycrjyNkz)){
  602. handleXinYiWarningsSH(hycrjyNkz, shcHyOneDo, BusinessEnum.WarningCategoryEnum.HYQDO_ONE.getCode(), tXinyiIndustry, normConfig, true);
  603. }
  604. //好氧区DO(二池) 2024年5月31日14:09:36 溶解氧从日报获取 工业的不准
  605. //2024年6月27日17:00:31 都先从工业库获取,日报没有必要再报警了
  606. BigDecimal shcHyTwoDo = tXinyiIndustry.getTwoHymdDo();
  607. if(!Objects.isNull(shcHyTwoDo) && !Objects.isNull(hycrjyNkz)){
  608. handleXinYiWarningsSH(hycrjyNkz, shcHyTwoDo, BusinessEnum.WarningCategoryEnum.HYQDO_TWO.getCode(), tXinyiIndustry, normConfig, true);
  609. }
  610. //气水比
  611. BigDecimal qsb = xinyiCalculate.getQSB();
  612. BigDecimal shcqbNkz = normConfig.getShcqbNkz();
  613. if(!Objects.isNull(qsb) && !Objects.isNull(shcqbNkz))
  614. handleXinYiWarningsSH(shcqbNkz, qsb, BusinessEnum.WarningCategoryEnum.QSB.getCode(), tXinyiIndustry, normConfig, true);
  615. //二沉池表面负荷
  616. BigDecimal eccBmfh = xinyiCalculate.getEccBmfh();
  617. BigDecimal eccbmfhznkzXxz = normConfig.getEccbmfhznkzXxz();
  618. if(!Objects.isNull(eccBmfh) && !Objects.isNull(eccbmfhznkzXxz)){
  619. handleXinYiWarningsSH(eccbmfhznkzXxz, eccBmfh, BusinessEnum.WarningCategoryEnum.ECC_BMFH.getCode(), tXinyiIndustry, normConfig, true);
  620. }
  621. //二沉池固体负荷
  622. BigDecimal eccGtfh = xinyiCalculate.getEccGtfh();
  623. BigDecimal eccgtfhnkxxz = normConfig.getECCGTFHNKXXZ();
  624. if(!Objects.isNull(eccGtfh) && !Objects.isNull(eccgtfhnkxxz)){
  625. handleXinYiWarningsSH(eccgtfhnkxxz, eccGtfh, BusinessEnum.WarningCategoryEnum.ECC_GTFH.getCode(), tXinyiIndustry, normConfig, true);
  626. }
  627. //反冲洗水量
  628. //2024年7月3日10:59:32 这里用反冲洗水量比例做计算
  629. BigDecimal fcxslBl = xinyiCalculate.getFCXSLBL();
  630. BigDecimal fcxslblsjzXxz = normConfig.getFcxslblsjzXxz();
  631. if(!Objects.isNull(fcxslBl) && !Objects.isNull(fcxslblsjzXxz))
  632. handleXinYiWarningsSH(fcxslblsjzXxz, fcxslBl, BusinessEnum.WarningCategoryEnum.FCXSL.getCode(), tXinyiIndustry, normConfig, true);
  633. }
  634. /**
  635. * 处理信义生化报警的逻辑 统一处理
  636. * @param sjscgkz :实际生产管控值
  637. * @param currentVal
  638. * @param category
  639. * @param tXinyiIndustry
  640. * @param normConfig
  641. * @param normal 是否常规判断:默认都是超过;只有这个挥发性污泥浓度占比(VSS/SS)是小于才报警
  642. * 2024年6月27日15:39:15 调整:生化报警只取实际生产管控指标
  643. *
  644. */
  645. private void handleXinYiWarningsSH(BigDecimal sjscgkz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, Boolean normal) {
  646. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  647. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  648. tXinyiWarningRecord.setStatus(0);
  649. tXinyiWarningRecord.setType(1);
  650. tXinyiWarningRecord.setCategory(category);
  651. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  652. tXinyiWarningRecord.setWarningVal(currentVal);
  653. tXinyiWarningRecord.setDesignVal(sjscgkz);
  654. tXinyiWarningRecord.setControlVal(sjscgkz);
  655. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  656. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  657. tXinyiWarningRecord.setRemark("1");
  658. //2024年6月27日17:36:25 有一个判断是反正的
  659. if(normal){
  660. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  661. if (Objects.isNull(currentVal) || currentVal.compareTo(BigDecimal.ZERO) == 0) {
  662. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  663. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  664. } else if (currentVal.compareTo(sjscgkz) > 0) {//一级
  665. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  666. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  667. } /*else if (currentVal.compareTo(bzz) >= 0 && currentVal.compareTo(multiply) <= 0) {//二级
  668. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  669. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  670. } else if (!Objects.isNull(gkz) && currentVal.compareTo(gkz) > 0) {
  671. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  672. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  673. }*/ else {
  674. tXinyiWarningRecord = null;//这种的无需处理
  675. }
  676. }else{
  677. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  678. if (Objects.isNull(currentVal) || currentVal.compareTo(BigDecimal.ZERO) == 0) {
  679. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  680. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  681. } else if (currentVal.compareTo(sjscgkz) < 0) {//一级
  682. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  683. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  684. } /*else if (currentVal.compareTo(bzz) >= 0 && currentVal.compareTo(multiply) <= 0) {//二级
  685. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  686. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  687. } else if (!Objects.isNull(gkz) && currentVal.compareTo(gkz) > 0) {
  688. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  689. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  690. }*/ else {
  691. tXinyiWarningRecord = null;//这种的无需处理
  692. }
  693. }
  694. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  695. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(1).category(category).status(0).build());
  696. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  697. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  698. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  699. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  700. xinyiWarningRecord.setStatus(2);
  701. Date nowDate = DateUtils.getNowDate();
  702. xinyiWarningRecord.setOffTime(nowDate);
  703. xinyiWarningRecord.setUpdateTime(nowDate);
  704. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  705. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  706. }
  707. }
  708. }else{//有新的告警信息
  709. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  710. //保存到数据库中
  711. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  712. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  713. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  714. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  715. }else {
  716. //继续调用决策(普通问答)
  717. this.askBigModelForSHWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  718. }
  719. }else{
  720. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  721. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  722. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  723. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  724. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  725. }else {
  726. //继续调用决策(普通问答)
  727. this.askBigModelForSHWarning(xinyiWarningRecord, tXinyiIndustry, normConfig);
  728. }
  729. }
  730. }
  731. }
  732. }
  733. private void handleSZWarning(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  734. //出水相关
  735. //出水COD报警
  736. BigDecimal csCod = tXinyiIndustry.getCsCod();
  737. BigDecimal cscodBzz = normConfig.getCscodBzz();
  738. BigDecimal cscodGkz = normConfig.getCscodGkz();
  739. if(!Objects.isNull(cscodBzz)){
  740. handleXinYiWarningsCs(cscodBzz, csCod, cscodGkz, BusinessEnum.WarningCategoryEnum.CS_COD.getCode(), tXinyiIndustry, normConfig);
  741. }
  742. //出水总磷超标报警
  743. BigDecimal csTp = tXinyiIndustry.getCsTp();
  744. BigDecimal cszlBzz = normConfig.getCszlBzz();
  745. BigDecimal cszlGkz = normConfig.getCszlGkz();
  746. if(!Objects.isNull(cszlBzz)){
  747. handleXinYiWarningsCs(cszlBzz, csTp, cszlGkz, BusinessEnum.WarningCategoryEnum.CS_ZL.getCode(), tXinyiIndustry, normConfig);
  748. }
  749. //出水总氮超标报警
  750. BigDecimal csTn = tXinyiIndustry.getCsTn();
  751. BigDecimal cszzBzz = normConfig.getCszzBzz();
  752. BigDecimal cszzGkz = normConfig.getCszzGkz();
  753. if(!Objects.isNull(cszzBzz)){
  754. handleXinYiWarningsCs(cszzBzz, csTn, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_ZD.getCode(), tXinyiIndustry, normConfig);
  755. }
  756. //出水氨氮超标报警
  757. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  758. BigDecimal csadBzz = normConfig.getCsadBzz();
  759. BigDecimal csadGkz = normConfig.getCsadGkz();
  760. if(!Objects.isNull(csadBzz)){
  761. handleXinYiWarningsCs(csadBzz, csNh3, csadGkz, BusinessEnum.WarningCategoryEnum.CS_AD.getCode(), tXinyiIndustry, normConfig);
  762. }
  763. //出水SS超标报警
  764. BigDecimal csSS = tXinyiIndustry.getCsSs();
  765. BigDecimal csSSBzz = normConfig.getCsssBzz();
  766. BigDecimal csssGkz = normConfig.getCsssGkz();
  767. if(!Objects.isNull(csSSBzz)){
  768. handleXinYiWarningsCs(csSSBzz, csSS, csssGkz, BusinessEnum.WarningCategoryEnum.CS_SS.getCode(), tXinyiIndustry, normConfig);
  769. }
  770. //进水相关报警
  771. //进水总磷超标报警
  772. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  773. BigDecimal jszlSjz = normConfig.getJszlSjz();
  774. if(!Objects.isNull(jszlSjz)){
  775. handleXinYiWarningRecordJS(jszlSjz, jsTp, BusinessEnum.WarningCategoryEnum.JS_ZL.getCode(), tXinyiIndustry, normConfig);
  776. }
  777. //进水COD超标报警
  778. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  779. BigDecimal jscodSjz = normConfig.getJscodSjz();
  780. if(!Objects.isNull(jscodSjz)){
  781. handleXinYiWarningRecordJS(jscodSjz, jsCod, BusinessEnum.WarningCategoryEnum.JS_COD.getCode(), tXinyiIndustry, normConfig);
  782. }
  783. //进水总氮超标报警
  784. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  785. BigDecimal jszdSjz = normConfig.getJszdSjz();
  786. if(!Objects.isNull(jszdSjz)){
  787. handleXinYiWarningRecordJS(jszdSjz, jsTn, BusinessEnum.WarningCategoryEnum.JS_ZD.getCode(), tXinyiIndustry, normConfig);
  788. }
  789. //进水氨氮超标报警
  790. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  791. BigDecimal jsadSjz = normConfig.getJsadSjz();
  792. if(!Objects.isNull(jsadSjz)){
  793. handleXinYiWarningRecordJS(jsadSjz, jsNh3, BusinessEnum.WarningCategoryEnum.JS_AD.getCode(), tXinyiIndustry, normConfig);
  794. }
  795. //进水SS超标报警
  796. BigDecimal jsSS = tXinyiIndustry.getJsSs();
  797. BigDecimal jsSSSjz = normConfig.getJsssSjz();
  798. if(!Objects.isNull(jsSSSjz)){
  799. handleXinYiWarningRecordJS(jsSSSjz, jsSS, BusinessEnum.WarningCategoryEnum.JS_SS.getCode(), tXinyiIndustry, normConfig);
  800. }
  801. }
  802. private void askBigModelForSHWarning(TXinyiWarningRecord xinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  803. log.info("进入了后台接口调⽤⼤模型获取问答结果处理");
  804. StringBuilder sb = new StringBuilder();
  805. String sessionId = IdUtils.simpleUUID();
  806. ChatReq chatReq = new ChatReq();
  807. // String ipAddr = IpUtils.getIpAddr();//获取用户的ip地址 传给大模型
  808. String ipAddr = "";//获取用户的ip地址 传给大模型 定时任务获取不到ip地址
  809. int counts = 1;//默认是第一次
  810. //这种问答 没有历史问答的概念 直接把问题扔进去就行 无需查询历史记录
  811. List<String> historyDates = new ArrayList<>();
  812. //构建问题(替换提示词中的占位符)
  813. String shWarningPrompt = SH_WARNING_PROMPT;
  814. shWarningPrompt =shWarningPrompt.replace("#{0}", xinyiWarningRecord.getReason());
  815. shWarningPrompt =shWarningPrompt.replace("#{1}", String.valueOf(xinyiWarningRecord.getDesignVal()));
  816. shWarningPrompt =shWarningPrompt.replace("#{2}", String.valueOf(xinyiWarningRecord.getControlVal()));
  817. shWarningPrompt =shWarningPrompt.replace("#{3}", String.valueOf(xinyiWarningRecord.getWarningVal()));
  818. historyDates.add(shWarningPrompt);
  819. // 获取输出流
  820. ManagedChannel channel = null;
  821. try {
  822. channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
  823. .usePlaintext()
  824. .build();
  825. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  826. // 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) + "}";
  827. //2024年6月27日13:29:18 优化,不再使用拼接JSON字符串
  828. String dataJson = buildBigModelReqForChat(sessionId, historyDates, ipAddr, false);
  829. log.info("请求大模型的问答参数为{}", dataJson);
  830. PredictionsRequest request = PredictionsRequest.newBuilder()
  831. .setModelName("slibra_bot")
  832. .putInput("method", ByteString.copyFrom("infer_stream", "utf-8"))//推理
  833. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  834. .buildPartial();
  835. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  836. //将结果记录到问答表
  837. while (predictions.hasNext()) {
  838. String responseStr = predictions.next().getPrediction().toStringUtf8();
  839. log.info("大模型问答返回的原始结果为{}", responseStr);
  840. responseStr = JSON.parseObject(responseStr).getString("message");
  841. if("complete".equals(responseStr)){
  842. log.info("结尾语句并且是非JSON,无需处理");
  843. }else{
  844. sb.append(responseStr);
  845. }
  846. }
  847. //将问答更新到数据库中
  848. chatReq.setSessionId(sessionId);
  849. chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
  850. chatReq.setModule(3);//0专家问答 1智能工单 2智能体助手 3告警 4简报
  851. String showVal = this.buildShowValue(xinyiWarningRecord, tXinyiIndustry, normConfig);
  852. chatReq.setShowVal(showVal);
  853. chatReq.setQuestion(shWarningPrompt);
  854. chatReq.setAnswer(sb.toString());
  855. chatReq.setWarningId(String.valueOf(xinyiWarningRecord.getId()));
  856. chatReq.setCounts(counts);//问答次数
  857. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  858. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  859. chatReq.setCreateTime(DateUtils.getNowDate());
  860. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  861. } catch (IOException e) {
  862. throw new RuntimeException(e);
  863. } finally {
  864. // 关闭输出流
  865. channel.shutdown();
  866. }
  867. }
  868. private static String buildBigModelReqForChat(String sessionId, List<String> historyDates, String ipAddr, Boolean strengthen) {
  869. ChatRequest chatRequest = new ChatRequest();
  870. chatRequest.setSessionId(sessionId);
  871. chatRequest.setHistoryDia(historyDates);
  872. Map<String, Object> extra = new HashMap<>();
  873. extra.put("ip_address", ipAddr);
  874. chatRequest.setExtra(extra);
  875. chatRequest.setStrengthen(strengthen);
  876. //2024年7月3日16:21:28 明确该常见不用调工具
  877. chatRequest.setTools(String.valueOf(false));
  878. return JSON.toJSONString(chatRequest);
  879. }
  880. /**
  881. * 调用大模型获取决策结果 并同时记录对应信息到聊天记录表中
  882. *
  883. * @param tXinyiWarningRecord
  884. * @param tXinyiIndustry
  885. * @param normConfig
  886. * @param isSpecial 机器人化验库,需要把总磷和总氮的值特殊处理一下
  887. */
  888. private void handleDecision(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig, boolean isSpecial) {
  889. log.info("进入了调⽤大模型决策接口");
  890. ChatReq chatReq = new ChatReq();
  891. // StringBuilder sb = new StringBuilder();
  892. //大模型结果 放入一个结合中
  893. List<String> resultData = new ArrayList<>();
  894. //决策和问答不一样 没有历史的概念 所以sessionId都是新的 次数都是1
  895. String sessionId = IdUtils.simpleUUID();
  896. // String feedback = chatReq.getFeedback();
  897. //决策请求的业务参数
  898. // List<HashMap<String, Object>> list = this.xinyiIndustryMapper.selectLast10RecordsForDecision();
  899. //2024年5月21日15:23:07 这里不能用关联查询处理,日报要获取最新的一条而不是今日的数据。
  900. List<DecisionReq> decisionReqs = this.xinyiIndustryMapper.selectLast10RecordsForDecisionOnlyIndustry();
  901. if(!CollectionUtils.isEmpty(decisionReqs)){
  902. //处理日报数据
  903. TXinyiDaily daily = this.xinyiDailyMapper.selectNewestData();
  904. for (DecisionReq decisionReq : decisionReqs) {
  905. if(!Objects.isNull(daily)){
  906. decisionReq.setT(daily.getJsSw());
  907. decisionReq.setSVI(daily.getWntjzsAll());
  908. decisionReq.setSV(daily.getWncjbAll());
  909. decisionReq.setMlvss(daily.getHfxwnndAll());
  910. //2024年7月2日17:20:12 mlss和DO_O也要从日报获取
  911. decisionReq.setMlss(daily.getHycWnndAll());
  912. decisionReq.setDoO(daily.getHycRjyAll());
  913. decisionReq.setDoAna(daily.getYycRjyAll());
  914. decisionReq.setDoQue(daily.getQycRjyAll());
  915. //2024年5月26日11:59:02 干污泥量数据做了同步
  916. decisionReq.setGwnl(daily.getGWNL());
  917. BigDecimal jsBod5 = daily.getJsBod5();
  918. decisionReq.setBodIn(jsBod5);
  919. BigDecimal tpIn = decisionReq.getTpIn();
  920. BigDecimal tnIn = decisionReq.getTnIn();
  921. if(!Objects.isNull(jsBod5)){
  922. if(!Objects.isNull(tpIn) && tpIn.compareTo(new BigDecimal("0")) >0){
  923. decisionReq.setC(jsBod5.divide(tpIn, 4, RoundingMode.HALF_UP));
  924. }
  925. if(!Objects.isNull(tnIn) && tnIn.compareTo(new BigDecimal("0")) >0){
  926. decisionReq.setB(jsBod5.divide(tnIn, 4, RoundingMode.HALF_UP));
  927. }
  928. }
  929. //2024年6月1日08:37:09 内回流加上
  930. decisionReq.setR(daily.getNhlR());
  931. decisionReq.setRR(daily.getWhlR());
  932. }
  933. //如果是机器人化验室的报警,需要把总磷和总氮,获取化验室对应的数据且计算
  934. if(isSpecial){
  935. List<TXinyiRobot> xinyiRobots = this.xinyiRobotMapper.selectTXinyiRobotList(TXinyiRobot.builder().testHour(tXinyiIndustry.getTestHour()).build());
  936. if(CollectionUtils.isEmpty(xinyiRobots)){
  937. log.error("{}获取化验室数据失败", tXinyiIndustry.getTestHour());
  938. }else{
  939. TXinyiRobot tXinyiRobot = xinyiRobots.get(0);
  940. //总氮
  941. BigDecimal no3Hlj1Jqr = tXinyiRobot.getNo3Hlj1Jqr();
  942. BigDecimal no3Hlj2Jqr = tXinyiRobot.getNo3Hlj2Jqr();
  943. if(!Objects.isNull(no3Hlj1Jqr) && !Objects.isNull(no3Hlj2Jqr)){
  944. decisionReq.setTnOff((no3Hlj1Jqr.add(no3Hlj2Jqr)).divide((new BigDecimal("2").multiply(ROBOT_HY_DIVIDE)), NUMBER_SCALE_4, RoundingMode.HALF_UP));
  945. }
  946. //总磷
  947. BigDecimal tpRccJqr = tXinyiRobot.getTpRccJqr();
  948. if(!Objects.isNull(tpRccJqr)){
  949. decisionReq.setTpOff(tpRccJqr.divide(ROBOT_HY_DIVIDE, NUMBER_SCALE_4, RoundingMode.HALF_UP));
  950. }
  951. }
  952. }
  953. }
  954. }
  955. // String rows = JSON.toJSONString(decisionReqs, JSONWriter.Feature.WriteNulls);
  956. // 获取输出流
  957. ManagedChannel channel = null;
  958. String dataJson = "";
  959. try {
  960. channel = ManagedChannelBuilder.forAddress("10.0.0.24", 17070)
  961. .usePlaintext()
  962. .build();
  963. InferenceAPIsServiceGrpc.InferenceAPIsServiceBlockingStub stub = InferenceAPIsServiceGrpc.newBlockingStub(channel);
  964. // dataJson = "{\"bot_id\":\"b00001\",\"exp_id\":\"721\",\"norm\":\"" + tXinyiWarningRecord.getCategory() + "\",\"feedback\":" + feedback + ",\"session_id\":" + "\"" + sessionId + "\"" + ",\"generate_args\":{\"max_new_tokens\":1024,\"max_length\":4096,\"num_beams\":1,\"do_sample\":true,\"top_p\":0.7,\"temperature\":0.95},\"extra\":{\"rows\":" + rows + "}}";
  965. //2024年6月24日17:59:17 优化,不再拼接JSON字符串
  966. PolicyReq policyReq = new PolicyReq();
  967. policyReq.setNorm(tXinyiWarningRecord.getCategory());
  968. HashMap<String, Object> hashMap = new HashMap<>();
  969. policyReq.setFeedback(hashMap);//不能传null
  970. policyReq.setSimulate(hashMap);//不能传null
  971. policyReq.setSessionId(sessionId);
  972. HashMap<String, Object> map = new HashMap<>();
  973. map.put("rows", decisionReqs);
  974. //2024年6月25日14:16:05 增加报警是管控值报警还是标准值报警
  975. if(WARNING_LEVEL_ONE.equals(tXinyiWarningRecord.getLevel()) || WARNING_LEVEL_TWO.equals(tXinyiWarningRecord.getLevel()))
  976. map.put("source", "bzz");
  977. else
  978. map.put("source", "gkz");
  979. policyReq.setExtra(map);
  980. dataJson = JSON.toJSONString(policyReq, JSONWriter.Feature.WriteNulls);
  981. log.info("请求大模型的决策的参数为{}", dataJson);
  982. PredictionsRequest request = PredictionsRequest.newBuilder()
  983. .setModelName("slibra_bot")
  984. .putInput("method", ByteString.copyFrom("decision_stream", "utf-8"))//推理
  985. .putInput("data", ByteString.copyFrom(dataJson, "utf-8"))
  986. .buildPartial();
  987. Iterator<PredictionResponse> predictions = stub.streamPredictions(request);
  988. while (predictions.hasNext()) {
  989. String responseStr = predictions.next().getPrediction().toStringUtf8();
  990. log.info("决策流式返回的结果是{}", responseStr);
  991. //2024年5月25日16:37:16 按照大模型返回的类型解析数据
  992. String biz = JSON.parseObject(responseStr).getString("biz");
  993. if(BusinessEnum.BigModelBizEnum.OK.getCode().equals(biz)){
  994. log.info("结尾语句并且是非JSON,无需处理");
  995. //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端
  996. /*outputStream.write(responseStr.getBytes());
  997. outputStream.flush();*/
  998. }else if(BusinessEnum.BigModelBizEnum.DECISION_DEBUGGER.getCode().equals(biz)){
  999. log.info("中间过程,目前只打印日志,不记录数据,也不返回给前端,返回数据为{}", responseStr);
  1000. //结束语句也流式输出,但是并不记录下来 2024年5月24日11:15:23 也不返回前端
  1001. /*outputStream.write(responseStr.getBytes());
  1002. outputStream.flush();*/
  1003. }else{//其他 要么错误 要么alert 要么出的报告
  1004. // sb.append(responseStr);
  1005. resultData.add(responseStr);
  1006. }
  1007. }
  1008. } catch (Exception e) {
  1009. // throw new RuntimeException(e);
  1010. log.error("定时任务处理告警调用决策异常,异常信息为{}", JSON.toJSONString(e));
  1011. resultData.add("{\"biz\":\"ERROR\",\"message\":\"大模型分析数据异常,请稍后再试\"}");
  1012. } finally {
  1013. log.info("决策最终要保存的数据是{}", JSON.toJSONString(resultData));
  1014. //保存聊天记录
  1015. //将问答更新到数据库中
  1016. chatReq.setSessionId(sessionId);
  1017. chatReq.setType(1);//0问答 1决策
  1018. chatReq.setModule(3);
  1019. /*String userId = SecurityUtils.getUserId().toString();
  1020. String username = SecurityUtils.getUsername();*/
  1021. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  1022. String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1023. chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
  1024. chatReq.setQuestion(dataJson);
  1025. chatReq.setAnswer(JSON.toJSONString(resultData));
  1026. chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
  1027. chatReq.setCounts(1);//问答次数
  1028. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  1029. chatReq.setCreateTime(DateUtils.getNowDate());
  1030. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  1031. // 关闭输出流
  1032. if(!Objects.isNull(channel))
  1033. channel.shutdown();
  1034. }
  1035. }
  1036. private String buildShowValue(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1037. JSONObject result = new JSONObject();
  1038. // JSONObject basic = new JSONObject();
  1039. Integer status = tXinyiWarningRecord.getStatus();
  1040. Date warningTime = tXinyiWarningRecord.getTime();
  1041. String remark = tXinyiWarningRecord.getRemark();
  1042. int count = DateUtils.differentHoursByMillisecond(warningTime, DateUtils.getNowDate()) + 1;
  1043. /*basic.put("title", tXinyiWarningRecord.getReason());
  1044. basic.put("报警时间", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime));
  1045. basic.put("报警值", tXinyiWarningRecord.getWarningVal());
  1046. basic.put("标准值", tXinyiWarningRecord.getDesignVal());
  1047. basic.put("管控值", tXinyiWarningRecord.getControlVal());
  1048. basic.put("报警次数", Math.min(count, MAX_COUNT));
  1049. if(tXinyiWarningRecord.getType() != 2)
  1050. basic.put("状态", status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中");
  1051. else
  1052. basic.put("状态", status == 0 ? "预警中" : "已完成");
  1053. //2024年5月27日14:04:22 额外返回2个字段 [管控值 和 告警级别] 返回的json没有数据是因为value没有值
  1054. // basic.put("管控值", tXinyiWarningRecord.getControlVal());
  1055. basic.put("告警级别", tXinyiWarningRecord.getLevel());*/
  1056. //2024年6月25日16:00:18 进出水展示的不一样
  1057. if(tXinyiWarningRecord.getCategory().contains("出水")){//出水的展示
  1058. ShowValueCSBasic showValueCSBasic = new ShowValueCSBasic();
  1059. if("0".equals(remark)){//水质报警
  1060. showValueCSBasic.setH("在线仪表");
  1061. showValueCSBasic.setF(tXinyiWarningRecord.getLevel());
  1062. }else if("1".equals(remark)){//生化报警
  1063. showValueCSBasic.setH("在线仪表");
  1064. }else if("2".equals(remark)){//预测报警
  1065. showValueCSBasic.setH("预测");
  1066. // showValueCSBasic.setF(tXinyiWarningRecord.getLevel());
  1067. }else {//机器人化验室报警(特殊的水质报警)
  1068. showValueCSBasic.setH("化验室");
  1069. showValueCSBasic.setF(tXinyiWarningRecord.getLevel());
  1070. }
  1071. //通用的
  1072. // showValueBasic.setA(tXinyiWarningRecord.getReason());
  1073. showValueCSBasic.setB(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime));
  1074. showValueCSBasic.setC(tXinyiWarningRecord.getWarningVal());
  1075. showValueCSBasic.setD(tXinyiWarningRecord.getControlVal());
  1076. showValueCSBasic.setE(tXinyiWarningRecord.getDesignVal());
  1077. showValueCSBasic.setG(Math.min(count, MAX_COUNT));
  1078. if(tXinyiWarningRecord.getType() != 2)
  1079. showValueCSBasic.setI(status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中");
  1080. else
  1081. showValueCSBasic.setI(status == 0 ? "预警中" : "已完成");
  1082. result.put("basic", showValueCSBasic);
  1083. }else{//进水的展示
  1084. ShowValueJSBasic showValueJSBasic = new ShowValueJSBasic();
  1085. if("0".equals(remark)){//水质报警
  1086. showValueJSBasic.setH("在线仪表");
  1087. showValueJSBasic.setF(tXinyiWarningRecord.getLevel());
  1088. }else if("1".equals(remark)){//生化报警
  1089. showValueJSBasic.setH("在线仪表");
  1090. }else if("2".equals(remark)){//预测报警
  1091. showValueJSBasic.setH("预测");
  1092. // showValueCSBasic.setF(tXinyiWarningRecord.getLevel());
  1093. }else {//机器人化验室报警(特殊的 水质报警)
  1094. showValueJSBasic.setH("化验室");
  1095. showValueJSBasic.setF(tXinyiWarningRecord.getLevel());
  1096. }
  1097. //通用的
  1098. // showValueBasic.setA(tXinyiWarningRecord.getReason());
  1099. showValueJSBasic.setB(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM ,warningTime));
  1100. showValueJSBasic.setC(tXinyiWarningRecord.getWarningVal());
  1101. showValueJSBasic.setE(tXinyiWarningRecord.getDesignVal());
  1102. showValueJSBasic.setG(Math.min(count, MAX_COUNT));
  1103. if(tXinyiWarningRecord.getType() != 2)
  1104. showValueJSBasic.setI(status == 0 ? "报警中" : status == 1 ? "用户关闭" : status == 2 ? "系统关闭" : "应急处理中");
  1105. else
  1106. showValueJSBasic.setI(status == 0 ? "预警中" : "已完成");
  1107. result.put("basic", showValueJSBasic);
  1108. }
  1109. JSONObject jsData = getJsonObject(tXinyiIndustry, normConfig);//进水数据
  1110. result.put("jsData", jsData);
  1111. JSONObject csData = getCsonObject(tXinyiIndustry, normConfig);//出水数据
  1112. result.put("csData", csData);
  1113. // return JSON.toJSONString(result, JSONWriter.Feature.WriteNulls);
  1114. return JSON.toJSONString(result);
  1115. }
  1116. private static JSONObject getJsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1117. JSONObject jsData = new JSONObject();
  1118. HashMap<Object, Object> temp1 = new HashMap<>();
  1119. BigDecimal jsSlq = tXinyiIndustry.getJsSlq();
  1120. temp1.put("value", jsSlq);
  1121. temp1.put("exceed", jsSlq.compareTo(normConfig.getJsslSjz()) >0);
  1122. jsData.put("流量", temp1);
  1123. HashMap<Object, Object> temp2 = new HashMap<>();
  1124. BigDecimal jsCod = tXinyiIndustry.getJsCod();
  1125. temp2.put("value", jsCod);
  1126. temp2.put("exceed", jsCod.compareTo(normConfig.getJscodSjz()) > 0);
  1127. jsData.put("COD", temp2);
  1128. HashMap<Object, Object> temp3 = new HashMap<>();
  1129. BigDecimal jsNh3 = tXinyiIndustry.getJsNh3();
  1130. temp3.put("value", jsNh3);
  1131. temp3.put("exceed", jsNh3.compareTo(normConfig.getJsadSjz()) > 0);
  1132. jsData.put("NH3-N", temp3);
  1133. HashMap<Object, Object> temp4 = new HashMap<>();
  1134. BigDecimal jsTp = tXinyiIndustry.getJsTp();
  1135. temp4.put("value", jsTp);
  1136. temp4.put("exceed", jsTp.compareTo(normConfig.getJszlSjz()) > 0);
  1137. jsData.put("TP", temp4);
  1138. HashMap<Object, Object> temp5 = new HashMap<>();
  1139. BigDecimal jsSs = tXinyiIndustry.getJsSs();
  1140. temp5.put("value", jsSs);
  1141. temp5.put("exceed", jsSs.compareTo(normConfig.getJsssSjz()) > 0);
  1142. jsData.put("SS", temp5);
  1143. HashMap<Object, Object> temp6 = new HashMap<>();
  1144. BigDecimal jsTn = tXinyiIndustry.getJsTn();
  1145. temp6.put("value", jsTn);
  1146. temp6.put("exceed", jsTn.compareTo(normConfig.getJszdSjz()) > 0);
  1147. jsData.put("TN", temp6);
  1148. return jsData;
  1149. }
  1150. private static JSONObject getCsonObject(TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1151. JSONObject csData = new JSONObject();
  1152. HashMap<Object, Object> temp1 = new HashMap<>();
  1153. BigDecimal csSlq = tXinyiIndustry.getCsSlqc();
  1154. temp1.put("value", csSlq);
  1155. temp1.put("exceed", false);//出水水量没有管控值
  1156. csData.put("流量", temp1);
  1157. HashMap<Object, Object> temp2 = new HashMap<>();
  1158. BigDecimal csCod = tXinyiIndustry.getCsCod();
  1159. temp2.put("value", csCod);
  1160. temp2.put("exceed", csCod.compareTo(normConfig.getCscodGkz()) > 0);
  1161. csData.put("COD", temp2);
  1162. HashMap<Object, Object> temp3 = new HashMap<>();
  1163. BigDecimal csNh3 = tXinyiIndustry.getCsNh3();
  1164. temp3.put("value", csNh3);
  1165. temp3.put("exceed", csNh3.compareTo(normConfig.getCsadGkz()) > 0);
  1166. csData.put("NH3-N", temp3);
  1167. HashMap<Object, Object> temp4 = new HashMap<>();
  1168. BigDecimal csTp = tXinyiIndustry.getCsTp();
  1169. temp4.put("value", csTp);
  1170. temp4.put("exceed", csTp.compareTo(normConfig.getCszlGkz()) > 0);
  1171. csData.put("TP", temp4);
  1172. HashMap<Object, Object> temp5 = new HashMap<>();
  1173. BigDecimal csSs = tXinyiIndustry.getCsSs();
  1174. temp5.put("value", csSs);
  1175. temp5.put("exceed", csSs.compareTo(normConfig.getCsssGkz()) > 0);
  1176. csData.put("SS", temp5);
  1177. HashMap<Object, Object> temp6 = new HashMap<>();
  1178. BigDecimal csTn = tXinyiIndustry.getCsTn();
  1179. temp6.put("value", csTn);
  1180. temp6.put("exceed", csTn.compareTo(normConfig.getCszzGkz()) > 0);
  1181. csData.put("TN", temp6);
  1182. return csData;
  1183. }
  1184. /**
  1185. * 通过输入的值 生成对应类型的报警对象(出水)
  1186. *
  1187. * @param csBzz
  1188. * @param currentVal
  1189. * @param csGkz
  1190. * @param category
  1191. * @param tXinyiIndustry
  1192. * @param normConfig
  1193. * @return
  1194. */
  1195. private void handleXinYiWarningsCs(BigDecimal csBzz, BigDecimal currentVal, BigDecimal csGkz, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1196. BigDecimal multiply = csBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  1197. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  1198. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  1199. tXinyiWarningRecord.setStatus(0);
  1200. tXinyiWarningRecord.setType(0);
  1201. tXinyiWarningRecord.setCategory(category);
  1202. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  1203. tXinyiWarningRecord.setWarningVal(currentVal);
  1204. tXinyiWarningRecord.setDesignVal(csBzz);
  1205. tXinyiWarningRecord.setControlVal(csGkz);
  1206. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  1207. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  1208. tXinyiWarningRecord.setRemark("0");
  1209. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  1210. if(Objects.isNull(currentVal) || currentVal.compareTo(BigDecimal.ZERO) == 0){
  1211. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  1212. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  1213. }else if(currentVal.compareTo(multiply) > 0){//一级
  1214. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  1215. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  1216. }else if(currentVal.compareTo(csBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  1217. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  1218. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  1219. }else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  1220. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  1221. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  1222. }else{
  1223. tXinyiWarningRecord = null;//这种的无需处理
  1224. }
  1225. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  1226. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).warningStatus(0).build());
  1227. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  1228. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  1229. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  1230. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  1231. xinyiWarningRecord.setStatus(2);
  1232. Date nowDate = DateUtils.getNowDate();
  1233. xinyiWarningRecord.setOffTime(nowDate);
  1234. xinyiWarningRecord.setUpdateTime(nowDate);
  1235. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  1236. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  1237. }
  1238. }
  1239. }else{//有告警信息
  1240. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  1241. //保存到数据库中
  1242. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  1243. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1244. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1245. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1246. }else {
  1247. //继续调用决策
  1248. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig, false);
  1249. }
  1250. }else{
  1251. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  1252. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  1253. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1254. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1255. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1256. }else {
  1257. //继续调用决策
  1258. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig, false);
  1259. }
  1260. }
  1261. }
  1262. }
  1263. }
  1264. /**
  1265. * 通过输入的值 生成对应类型的报警对象(进水)
  1266. *
  1267. * @param jsBzz
  1268. * @param currentVal
  1269. * @param category
  1270. * @param tXinyiIndustry
  1271. * @param normConfig
  1272. * @return
  1273. */
  1274. private void handleXinYiWarningRecordJS(BigDecimal jsBzz, BigDecimal currentVal, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1275. BigDecimal multiply = jsBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  1276. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  1277. /*String category = BusinessEnum.WarningCategoryEnum.CS_AD.getCode();*/
  1278. tXinyiWarningRecord.setStatus(0);
  1279. tXinyiWarningRecord.setType(0);
  1280. tXinyiWarningRecord.setCategory(category);
  1281. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  1282. tXinyiWarningRecord.setWarningVal(currentVal);
  1283. tXinyiWarningRecord.setDesignVal(jsBzz);
  1284. // tXinyiWarningRecord.setControlVal(csGkz);
  1285. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  1286. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  1287. tXinyiWarningRecord.setRemark("0");
  1288. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  1289. if(Objects.isNull(currentVal) || currentVal.compareTo(BigDecimal.ZERO) == 0){
  1290. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  1291. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  1292. }else if(currentVal.compareTo(multiply) > 0){//一级
  1293. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  1294. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  1295. }else if(currentVal.compareTo(jsBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  1296. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  1297. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  1298. }else{
  1299. tXinyiWarningRecord = null;//这种的无需处理
  1300. }
  1301. /*else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  1302. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  1303. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  1304. }*/
  1305. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  1306. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).status(0).build());
  1307. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  1308. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  1309. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  1310. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  1311. xinyiWarningRecord.setStatus(2);
  1312. Date nowDate = DateUtils.getNowDate();
  1313. xinyiWarningRecord.setOffTime(nowDate);
  1314. xinyiWarningRecord.setUpdateTime(nowDate);
  1315. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  1316. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  1317. }
  1318. }
  1319. }else{//有告警信息
  1320. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  1321. //保存到数据库中
  1322. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  1323. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1324. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1325. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1326. }else {
  1327. //继续调用决策
  1328. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig, false);
  1329. }
  1330. }else{
  1331. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  1332. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  1333. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1334. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1335. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1336. }else {
  1337. //继续调用决策
  1338. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig, false);
  1339. }
  1340. }
  1341. }
  1342. }
  1343. }
  1344. private void addChatRecordByWarning(TXinyiWarningRecord tXinyiWarningRecord, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1345. ChatReq chatReq = new ChatReq();
  1346. //保存聊天记录
  1347. //将问答更新到数据库中
  1348. chatReq.setSessionId(IdUtils.simpleUUID());
  1349. chatReq.setType(1);//0问答 1决策 2本地 3仿真预测
  1350. chatReq.setModule(3);
  1351. /*String userId = SecurityUtils.getUserId().toString();
  1352. String username = SecurityUtils.getUsername();*/
  1353. chatReq.setUserId(WARNING_DEFAULT_CREATE);
  1354. String showVal = this.buildShowValue(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1355. chatReq.setShowVal(showVal);//前端展示的数据和提问的数据不一致
  1356. chatReq.setQuestion(WARNING_DEFAULT_QUESTION);//本地问题
  1357. chatReq.setAnswer(tXinyiWarningRecord.getReason() + ",请检查设备是否正常运行");
  1358. chatReq.setWarningId(String.valueOf(tXinyiWarningRecord.getId()));
  1359. chatReq.setCounts(1);//问答次数
  1360. chatReq.setCreateBy(WARNING_DEFAULT_CREATE);
  1361. chatReq.setCreateTime(DateUtils.getNowDate());
  1362. this.xinyiChatRecordMapper.insertTXinyiChatRecord(chatReq);
  1363. }
  1364. public static void main(String[] args) {
  1365. System.out.println(CCCDCHRT_LAST);
  1366. System.out.println(GSLS_LAST);
  1367. System.out.println(BigDecimal.valueOf(1).subtract(null));
  1368. }
  1369. /**
  1370. * 处理机器人化验数据报警
  1371. * @param uniqueList
  1372. */
  1373. public void handleRobotWarning(List<TXinyiRobot> uniqueList) {
  1374. log.info("进入了定时任务判断机器人化验库是否超标及后续逻辑");
  1375. //查询配置
  1376. List<TXinyiNormConfig> tXinyiNormConfigs = this.xinyiNormConfigMapper.selectTXinyiNormConfigList(null);
  1377. if(CollectionUtils.isEmpty(tXinyiNormConfigs))
  1378. throw new RuntimeException("未查询到配置信息");
  1379. TXinyiNormConfig normConfig = tXinyiNormConfigs.get(0);
  1380. //查询最新的一条工业库的数据(showvalue展示使用)
  1381. List<TXinyiIndustry> tXinyiIndustries = this.xinyiIndustryMapper.selectNIndustry(1);
  1382. TXinyiIndustry tXinyiIndustry = CollectionUtils.isEmpty(tXinyiIndustries) ? new TXinyiIndustry() : tXinyiIndustries.get(0);
  1383. //处理数据
  1384. for (TXinyiRobot tXinyiRobot : uniqueList) {
  1385. //处理总氮和总磷报警
  1386. //总氮
  1387. BigDecimal no3Hlj1Jqr = tXinyiRobot.getNo3Hlj1Jqr();
  1388. BigDecimal no3Hlj2Jqr = tXinyiRobot.getNo3Hlj2Jqr();
  1389. if(!Objects.isNull(no3Hlj1Jqr) && !Objects.isNull(no3Hlj2Jqr)){
  1390. BigDecimal csTn = (no3Hlj1Jqr.add(no3Hlj2Jqr)).divide((new BigDecimal("2").multiply(ROBOT_HY_DIVIDE)), NUMBER_SCALE_4, RoundingMode.HALF_UP);
  1391. BigDecimal cszzBzz = normConfig.getCszzBzz();
  1392. BigDecimal cszzGkz = normConfig.getCszzGkz();
  1393. if(!Objects.isNull(cszzBzz)){
  1394. handleXinYiWarningsRobot(cszzBzz, csTn, cszzGkz, BusinessEnum.WarningCategoryEnum.CS_ZD.getCode(), tXinyiIndustry, normConfig);
  1395. }
  1396. }
  1397. //总磷
  1398. BigDecimal tpRccJqr = tXinyiRobot.getTpRccJqr();
  1399. if(!Objects.isNull(tpRccJqr)){
  1400. BigDecimal csTp = tpRccJqr.divide(ROBOT_HY_DIVIDE, NUMBER_SCALE_4, RoundingMode.HALF_UP);
  1401. BigDecimal cszlBzz = normConfig.getCszlBzz();
  1402. BigDecimal cszlGkz = normConfig.getCszlGkz();
  1403. if(!Objects.isNull(cszlBzz)){
  1404. handleXinYiWarningsRobot(cszlBzz, csTp, cszlGkz, BusinessEnum.WarningCategoryEnum.CS_ZL.getCode(), tXinyiIndustry, normConfig);
  1405. }
  1406. }
  1407. }
  1408. }
  1409. /**
  1410. * 通过输入的值 生成对应类型的报警对象(出水)
  1411. *
  1412. * @param csBzz
  1413. * @param currentVal
  1414. * @param csGkz
  1415. * @param category
  1416. * @param tXinyiIndustry
  1417. * @param normConfig
  1418. * @return
  1419. */
  1420. private void handleXinYiWarningsRobot(BigDecimal csBzz, BigDecimal currentVal, BigDecimal csGkz, String category, TXinyiIndustry tXinyiIndustry, TXinyiNormConfig normConfig) {
  1421. BigDecimal multiply = csBzz.multiply(new BigDecimal(MyConstants.SCALE_VALUE));
  1422. TXinyiWarningRecord tXinyiWarningRecord = new TXinyiWarningRecord();
  1423. tXinyiWarningRecord.setStatus(0);
  1424. tXinyiWarningRecord.setType(0);
  1425. tXinyiWarningRecord.setCategory(category);
  1426. tXinyiWarningRecord.setTime(DateUtils.getNowDate());
  1427. tXinyiWarningRecord.setWarningVal(currentVal);
  1428. tXinyiWarningRecord.setDesignVal(csBzz);
  1429. tXinyiWarningRecord.setControlVal(csGkz);
  1430. tXinyiWarningRecord.setCreateBy(WARNING_DEFAULT_CREATE);
  1431. tXinyiWarningRecord.setCreateTime(DateUtils.getNowDate());
  1432. tXinyiWarningRecord.setRemark("3");//化验室
  1433. //2024年5月25日17:52:33 如果工业库获取不到数据,也触发报警,但是不调用决策接口
  1434. if(Objects.isNull(currentVal)){
  1435. tXinyiWarningRecord.setReason(category + EXCEPTION_WARNING);
  1436. tXinyiWarningRecord.setLevel(WARNING_LEVEL_NO_DATE);
  1437. }else if(currentVal.compareTo(multiply) > 0){//一级
  1438. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  1439. tXinyiWarningRecord.setLevel(WARNING_LEVEL_ONE);
  1440. }else if(currentVal.compareTo(csBzz) >= 0 && currentVal.compareTo(multiply) <= 0){//二级
  1441. tXinyiWarningRecord.setReason(category + CHAOBIAO_WARNING);
  1442. tXinyiWarningRecord.setLevel(WARNING_LEVEL_TWO);
  1443. }else if(!Objects.isNull(csGkz) && currentVal.compareTo(csGkz) > 0){
  1444. tXinyiWarningRecord.setReason(category + CHAOGUANKONG_WARNING);
  1445. tXinyiWarningRecord.setLevel(WARNING_LEVEL_THREE);
  1446. }else{
  1447. tXinyiWarningRecord = null;//这种的无需处理
  1448. }
  1449. //当前状态正常 需要查询历史有无正在报警的数据,如果有,将报警状态改完2(系统自动关闭)
  1450. List<TXinyiWarningRecord> tXinyiWarningRecords = this.xinyiWarningRecordMapper.selectTXinyiWarningRecordList(TXinyiWarningRecord.builder().delFlag(0).type(0).category(category).warningStatus(0).build());
  1451. if(Objects.isNull(tXinyiWarningRecord)){//数据正常,无告警信息
  1452. if(!CollectionUtils.isEmpty(tXinyiWarningRecords)){
  1453. log.info( "{}:现在恢复正常,历史报警数据为{}", category,JSON.toJSONString(tXinyiWarningRecords));
  1454. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {
  1455. xinyiWarningRecord.setStatus(2);
  1456. Date nowDate = DateUtils.getNowDate();
  1457. xinyiWarningRecord.setOffTime(nowDate);
  1458. xinyiWarningRecord.setUpdateTime(nowDate);
  1459. xinyiWarningRecord.setUpdateBy(WARNING_DEFAULT_CREATE);
  1460. this.xinyiWarningRecordMapper.updateTXinyiWarningRecord(xinyiWarningRecord);
  1461. }
  1462. }
  1463. }else{//有告警信息
  1464. if(CollectionUtils.isEmpty(tXinyiWarningRecords)){//之前没有告警记录
  1465. //保存到数据库中
  1466. this.xinyiWarningRecordMapper.insertTXinyiWarningRecord(tXinyiWarningRecord);
  1467. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1468. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1469. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1470. }else {
  1471. //继续调用决策
  1472. this.handleDecision(tXinyiWarningRecord, tXinyiIndustry, normConfig, true);
  1473. }
  1474. }else{
  1475. log.info("{}:之前已经有过告警记录了,且还是继续报警,无需重复添加报警,但是决策仍然要调用", category);
  1476. for (TXinyiWarningRecord xinyiWarningRecord : tXinyiWarningRecords) {//理论上只有一个的
  1477. if(WARNING_LEVEL_NO_DATE.equals(tXinyiWarningRecord.getLevel())){
  1478. //只保存一个普通的问答记录 不需要调用决策信息,但是实时数据还是要记录的
  1479. this.addChatRecordByWarning(tXinyiWarningRecord, tXinyiIndustry, normConfig);
  1480. }else {
  1481. //继续调用决策
  1482. this.handleDecision(xinyiWarningRecord, tXinyiIndustry, normConfig, true);
  1483. }
  1484. }
  1485. }
  1486. }
  1487. }
  1488. }