KprAimWaterCollecationBizFun.java 134 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202
  1. package com.shkpr.service.aimodelpower.bizmgr;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.global.base.log.LogLevelFlag;
  5. import com.global.base.log.LogPrintMgr;
  6. import com.global.base.tools.FastJsonUtil;
  7. import com.shkpr.service.aimodelpower.commtools.ProbabilityAlgorithm;
  8. import com.shkpr.service.aimodelpower.commtools.TimeTool;
  9. import com.shkpr.service.aimodelpower.constants.LogFlagBusiType;
  10. import com.shkpr.service.aimodelpower.dbdao.DBMgrProxy;
  11. import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.WaterZILAISHUIDao;
  12. import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.service.intef.WaterCollecationService;
  13. import com.shkpr.service.aimodelpower.dbdao.shizilaishuiDataSource.service.intef.WaterTapWaterService;
  14. import com.shkpr.service.aimodelpower.dto.ResponseCode;
  15. import com.shkpr.service.aimodelpower.dto.ResponseRes;
  16. import com.shkpr.service.aimodelpower.dto.TraceRunnable;
  17. import com.shkpr.service.aimodelpower.dto.zilaishuiModel.InPumpModel;
  18. import com.shkpr.service.aimodelpower.globalmgr.ThreadTaskMgr;
  19. import com.shkpr.service.aimodelpower.globalmgr.TraceLogMgr;
  20. import com.shkpr.service.aimodelpower.jsonbean.zilaishui.*;
  21. import com.shkpr.service.aimodelpower.services.ServiceMgrProxy;
  22. import org.apache.commons.collections.MapUtils;
  23. import org.springframework.util.CollectionUtils;
  24. import org.springframework.util.ObjectUtils;
  25. import org.springframework.util.StringUtils;
  26. import java.io.*;
  27. import java.time.LocalDateTime;
  28. import java.time.LocalTime;
  29. import java.time.YearMonth;
  30. import java.time.format.DateTimeFormatter;
  31. import java.time.temporal.TemporalAdjusters;
  32. import java.util.*;
  33. import java.util.concurrent.CountDownLatch;
  34. import java.util.concurrent.ExecutorService;
  35. import java.util.concurrent.Executors;
  36. import java.util.concurrent.ThreadLocalRandom;
  37. import java.util.stream.Collectors;
  38. /**
  39. * @ClassName KprAimWaterCollecationBizFun
  40. * @Description: TODO
  41. * @Author LX
  42. * @Date 2024/5/27
  43. * @Version V1.0
  44. **/
  45. public class KprAimWaterCollecationBizFun {
  46. private static final String MSG_SUCCESS = "success.";
  47. private static final String MSG_FAILED = "failed.";
  48. private static final String mStrClassName = "KprAimTapWaterBizFun";
  49. private static final String EMPTY_NULL = "NULL";
  50. static JSONObject pumpObj = JSONObject.parseObject("{\n" +
  51. " \"UZD299F12944DC10957HJ\": {\n" +
  52. " \"outRoom\": {\n" +
  53. " \"pumps\": [\n" +
  54. " {\n" +
  55. " \"label\": \"1\",\n" +
  56. " \"status\": 1,\n" +
  57. " \"forecastStatus\": 0\n" +
  58. " },\n" +
  59. " {\n" +
  60. " \"label\": \"2\",\n" +
  61. " \"status\": 1,\n" +
  62. " \"forecastStatus\": 1\n" +
  63. " },\n" +
  64. " {\n" +
  65. " \"label\": \"3\",\n" +
  66. " \"status\": 1,\n" +
  67. " \"forecastStatus\": 0\n" +
  68. " },\n" +
  69. " {\n" +
  70. " \"label\": \"4\",\n" +
  71. " \"status\": 1,\n" +
  72. " \"forecastStatus\": 1\n" +
  73. " },\n" +
  74. " {\n" +
  75. " \"label\": \"5\",\n" +
  76. " \"status\": 1,\n" +
  77. " \"forecastStatus\": 0\n" +
  78. " },\n" +
  79. " {\n" +
  80. " \"label\": \"6\",\n" +
  81. " \"status\": 1,\n" +
  82. " \"forecastStatus\": 1\n" +
  83. " },\n" +
  84. " {\n" +
  85. " \"label\": \"7\",\n" +
  86. " \"status\": 1,\n" +
  87. " \"forecastStatus\": 0\n" +
  88. " }\n" +
  89. " ]\n" +
  90. " }\n" +
  91. " },\n" +
  92. " \"UZD299F12DF5241082772\": {\n" +
  93. " \"outRoom\": {\n" +
  94. " \"pumps\": [\n" +
  95. " {\n" +
  96. " \"label\": \"1\",\n" +
  97. " \"status\": 1,\n" +
  98. " \"forecastStatus\": 1\n" +
  99. " },\n" +
  100. " {\n" +
  101. " \"label\": \"2\",\n" +
  102. " \"status\": 1,\n" +
  103. " \"forecastStatus\": 0\n" +
  104. " },\n" +
  105. " {\n" +
  106. " \"label\": \"3\",\n" +
  107. " \"status\": 1,\n" +
  108. " \"forecastStatus\": 0\n" +
  109. " },\n" +
  110. " {\n" +
  111. " \"label\": \"4\",\n" +
  112. " \"status\": 1,\n" +
  113. " \"forecastStatus\": 1\n" +
  114. " },\n" +
  115. " {\n" +
  116. " \"label\": \"5\",\n" +
  117. " \"status\": 1,\n" +
  118. " \"forecastStatus\": 0\n" +
  119. " },\n" +
  120. " {\n" +
  121. " \"label\": \"6\",\n" +
  122. " \"status\": 1,\n" +
  123. " \"forecastStatus\": 1\n" +
  124. " },\n" +
  125. " {\n" +
  126. " \"label\": \"7\",\n" +
  127. " \"status\": 1,\n" +
  128. " \"forecastStatus\": 0\n" +
  129. " },\n" +
  130. " {\n" +
  131. " \"label\": \"8\",\n" +
  132. " \"status\": 1,\n" +
  133. " \"forecastStatus\": 0\n" +
  134. " },\n" +
  135. " {\n" +
  136. " \"label\": \"9\",\n" +
  137. " \"status\": 1,\n" +
  138. " \"forecastStatus\": 1\n" +
  139. " },\n" +
  140. " {\n" +
  141. " \"label\": \"10\",\n" +
  142. " \"status\": 1,\n" +
  143. " \"forecastStatus\": 0\n" +
  144. " }\n" +
  145. " ]\n" +
  146. " }\n" +
  147. " },\n" +
  148. " \"UZD299F1301D04107668V\": {\n" +
  149. " \"outRoom\": {\n" +
  150. " \"pumps\": [\n" +
  151. " {\n" +
  152. " \"label\": \"1\",\n" +
  153. " \"status\": 1,\n" +
  154. " \"forecastStatus\": 0\n" +
  155. " },\n" +
  156. " {\n" +
  157. " \"label\": \"2\",\n" +
  158. " \"status\": 1,\n" +
  159. " \"forecastStatus\": 1\n" +
  160. " },\n" +
  161. " {\n" +
  162. " \"label\": \"3\",\n" +
  163. " \"status\": 1,\n" +
  164. " \"forecastStatus\": 1\n" +
  165. " },\n" +
  166. " {\n" +
  167. " \"label\": \"4\",\n" +
  168. " \"status\": 1,\n" +
  169. " \"forecastStatus\": 1\n" +
  170. " },\n" +
  171. " {\n" +
  172. " \"label\": \"5\",\n" +
  173. " \"status\": 1,\n" +
  174. " \"forecastStatus\": 1\n" +
  175. " },\n" +
  176. " {\n" +
  177. " \"label\": \"6\",\n" +
  178. " \"status\": 1,\n" +
  179. " \"forecastStatus\": 0\n" +
  180. " },\n" +
  181. " {\n" +
  182. " \"label\": \"7\",\n" +
  183. " \"status\": 1,\n" +
  184. " \"forecastStatus\": 0\n" +
  185. " },\n" +
  186. " {\n" +
  187. " \"label\": \"8\",\n" +
  188. " \"status\": 1,\n" +
  189. " \"forecastStatus\": 0\n" +
  190. " }\n" +
  191. " ]\n" +
  192. " }\n" +
  193. " },\n" +
  194. " \"UZD299F133DE5C1066A5L\": {\n" +
  195. " \"outRoom\": {\n" +
  196. " \"pumps\": [\n" +
  197. " {\n" +
  198. " \"label\": \"1\",\n" +
  199. " \"status\": 1,\n" +
  200. " \"forecastStatus\": 0\n" +
  201. " },\n" +
  202. " {\n" +
  203. " \"label\": \"2\",\n" +
  204. " \"status\": 1,\n" +
  205. " \"forecastStatus\": 1\n" +
  206. " },\n" +
  207. " {\n" +
  208. " \"label\": \"3\",\n" +
  209. " \"status\": 1,\n" +
  210. " \"forecastStatus\": 1\n" +
  211. " },\n" +
  212. " {\n" +
  213. " \"label\": \"4\",\n" +
  214. " \"status\": 1,\n" +
  215. " \"forecastStatus\": 1\n" +
  216. " },\n" +
  217. " {\n" +
  218. " \"label\": \"5\",\n" +
  219. " \"status\": 1,\n" +
  220. " \"forecastStatus\": 1\n" +
  221. " },\n" +
  222. " {\n" +
  223. " \"label\": \"6\",\n" +
  224. " \"status\": 1,\n" +
  225. " \"forecastStatus\": 0\n" +
  226. " }\n" +
  227. " ]\n" +
  228. " }\n" +
  229. " },\n" +
  230. " \"UZD299F1389E6010476AV\": {\n" +
  231. " \"outRoom\": {\n" +
  232. " \"pumps\": [\n" +
  233. " {\n" +
  234. " \"label\": \"1\",\n" +
  235. " \"status\": 1,\n" +
  236. " \"forecastStatus\": 0\n" +
  237. " },\n" +
  238. " {\n" +
  239. " \"label\": \"2\",\n" +
  240. " \"status\": 1,\n" +
  241. " \"forecastStatus\": 0\n" +
  242. " },\n" +
  243. " {\n" +
  244. " \"label\": \"3\",\n" +
  245. " \"status\": 1,\n" +
  246. " \"forecastStatus\": 1\n" +
  247. " },\n" +
  248. " {\n" +
  249. " \"label\": \"4\",\n" +
  250. " \"status\": 1,\n" +
  251. " \"forecastStatus\": 1\n" +
  252. " },\n" +
  253. " {\n" +
  254. " \"label\": \"5\",\n" +
  255. " \"status\": 1,\n" +
  256. " \"forecastStatus\": 1\n" +
  257. " },\n" +
  258. " {\n" +
  259. " \"label\": \"6\",\n" +
  260. " \"status\": 1,\n" +
  261. " \"forecastStatus\": 0\n" +
  262. " },\n" +
  263. " {\n" +
  264. " \"label\": \"7\",\n" +
  265. " \"status\": 1,\n" +
  266. " \"forecastStatus\": 1\n" +
  267. " }\n" +
  268. " ]\n" +
  269. " }\n" +
  270. " },\n" +
  271. " \"UZD299F139CB2410181HP\": {\n" +
  272. " \"outRoom\": {\n" +
  273. " \"pumps\": [\n" +
  274. " {\n" +
  275. " \"label\": \"1\",\n" +
  276. " \"status\": 1\n" +
  277. " },\n" +
  278. " {\n" +
  279. " \"label\": \"2\",\n" +
  280. " \"status\": 1\n" +
  281. " },\n" +
  282. " {\n" +
  283. " \"label\": \"3\"\n" +
  284. " },\n" +
  285. " {\n" +
  286. " \"label\": \"4\"\n" +
  287. " },\n" +
  288. " {\n" +
  289. " \"label\": \"5\"\n" +
  290. " },\n" +
  291. " {\n" +
  292. " \"label\": \"6\"\n" +
  293. " }\n" +
  294. " ]\n" +
  295. " }\n" +
  296. " }\n" +
  297. "}");
  298. public static WaterCollecationService getWaterTapWaterApi(){
  299. return DBMgrProxy.getInstance().applyWaterCollecationService();
  300. }
  301. public static WaterTapWaterService getWaterTapApi(){
  302. return DBMgrProxy.getInstance().applyWaterTapWaterService();
  303. }
  304. static DateTimeFormatter formater = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  305. static DateTimeFormatter formater2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  306. public static String databaseName = "";
  307. //TODO 获取数据库名
  308. public static void initDatabaseName(){
  309. Properties prop = new Properties();
  310. InputStream input = null;
  311. try {
  312. input = new FileInputStream("./sql.properties");
  313. // 加载properties文件
  314. prop.load(input);
  315. // 根据属性名获取属性值
  316. String databaseName = prop.getProperty("spring,database.name");
  317. KprAimWaterCollecationBizFun.databaseName = databaseName;
  318. } catch (IOException ex) {
  319. ex.printStackTrace();
  320. } finally {
  321. if (input != null) {
  322. try {
  323. input.close();
  324. } catch (IOException e) {
  325. e.printStackTrace();
  326. }
  327. }
  328. }
  329. }
  330. /**
  331. * 通过 orgId 查找对应的 orgName
  332. *
  333. * @param workZoneIds Map 集合
  334. * @param orgId 指定的 orgId
  335. * @return Optional<String> 对应的 orgName
  336. */
  337. public static Optional<String> findOrgNameByOrgId(Map<String, String> workZoneIds, String orgId) {
  338. return workZoneIds.entrySet()
  339. .stream()
  340. .filter(entry -> orgId.equals(entry.getValue())) // 过滤出值等于 orgId 的条目
  341. .map(Map.Entry::getKey) // 提取键(orgName)
  342. .findFirst(); // 返回第一个匹配的 orgName
  343. }
  344. private static double parseDouble(Object value) {
  345. return value == null ? 0.0 : Double.parseDouble(value.toString());
  346. }
  347. //TODO 查询日取水量预测接口
  348. /**
  349. * 1.传入水厂Id及起止日期(日期格式为YYYY-MM-DD),返回日期内,每天的预测取水量数据和实际取水量数据
  350. * 2.同时返回指定截止日期之后,未来4天的预测水量数据和实际水量(如没有,则返回为空数据)
  351. */
  352. public static ResponseRes selectTbWaterList(JPTbMWater jpTbMWater,Integer level,Map<String, Map<String, List<String>>> result
  353. ,Map<String,String> workZonIds){
  354. ResponseRes responseRes = new ResponseRes();
  355. List<Map<String,Object>> list =new ArrayList<>();
  356. Map<String, Object> map = new HashMap<>();
  357. map.put("ID", null);
  358. map.put("Date", null);
  359. map.put("Max_temperature", null);
  360. map.put("Min_temperature", null);
  361. map.put("Weather", null);
  362. map.put("Month", null);
  363. map.put("Week", null);
  364. map.put("Holiday", null);
  365. map.put("LastActualWaterWithdrawals", null);
  366. map.put("LastActualWaterSupply", null);
  367. map.put("ActualWaterWithdrawals", null);
  368. map.put("ActualWaterSupply", null);
  369. map.put("ForecastWaterWithdrawals", null);
  370. map.put("ForecastActualWaterSupply", null);
  371. map.put("isAbnormal", null);
  372. map.put("isForecast", null);
  373. map.put("LastModifyTime", null);
  374. list.add(map);
  375. responseRes.setResdata(list);
  376. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  377. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  378. try {
  379. if ("water_volume_prediction".equals(databaseName)){
  380. //TODO 自来水分了二级泵房,要做查询数据处理,点击水厂查询条件时,查询其下的泵房数据 再相加,
  381. //TODO 点击泵房则就查泵房的数据 ,无需做处理
  382. List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
  383. List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
  384. if (level==1){
  385. //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
  386. //TODO 查询二级,及其二级带的三级
  387. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMWater.getOrgId());
  388. if(zoneNameOpt.isPresent()){
  389. String zoneName = zoneNameOpt.get().toString();
  390. Map<String, List<String>> childMap = result.get(zoneName);//二级
  391. Collection<List<String>> child2Map = childMap.values();//三级
  392. // 添加二级组织机构名称(childMap 的 keySet)
  393. childList.addAll(childMap.keySet());
  394. // 添加三级组织机构名称(child2Map 的所有 List<String>)
  395. for (List<String> child2List : child2Map) {
  396. childList.addAll(child2List);
  397. }
  398. }
  399. }else if(level==2){
  400. //TODO 如果是二级,就查询其自身,看看其下还有没有集合,有的话就查其下的所有集合,没有的话就查其自身
  401. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMWater.getOrgId());
  402. if(zoneNameOpt.isPresent()) {
  403. String zoneName = zoneNameOpt.get().toString();
  404. List<String> childMap = new ArrayList<>();//三级
  405. // 遍历第一级 Map
  406. for (Map.Entry<String, Map<String, List<String>>> entry : result.entrySet()) {
  407. Map<String, List<String>> nestedMap = entry.getValue();
  408. // 检查第二级键
  409. if (nestedMap.containsKey(zoneName)) {
  410. childMap = nestedMap.get(zoneName);
  411. }
  412. }
  413. if(childMap.size()>0) {
  414. // 添三级组织机构名称(childMap 的 keySet)
  415. childList.addAll(childMap);
  416. }else{
  417. childList.add(zoneName);
  418. }
  419. }
  420. }else if(level==3){
  421. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  422. , "5555");
  423. //TODO 如果是三级,就查询其自身
  424. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMWater.getOrgId());
  425. if(zoneNameOpt.isPresent()) {
  426. String zoneName = zoneNameOpt.get().toString();
  427. childList.add(zoneName);
  428. }
  429. }
  430. //TODO 开始查询
  431. // 结果集合,存储 childList 对应的组织机构 ID
  432. // 遍历 childList,从 workZonIds 中获取对应的 ID
  433. for (String orgName : childList) {
  434. String orgId = workZonIds.get(orgName);
  435. if (orgId != null) { // 避免空值
  436. childIdList.add(orgId);
  437. }
  438. }
  439. List<Map<String,Object>> newResList = new ArrayList<>();
  440. int index = 0;
  441. for (String orgId:childIdList){
  442. jpTbMWater.setOrgId(orgId);
  443. jpTbMWater.checkValid();
  444. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMWater(jpTbMWater.getIsPage(),
  445. jpTbMWater.getLimit(), jpTbMWater.getOffset(), jpTbMWater.getForDateStr() + " ORDER BY \"Date\" ASC ");
  446. if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
  447. //TODO 说明要查询的分区不止一个,则把原来有的数据与新查的数据相加,因为按Date排了序所以一致
  448. for (int i=0;i<newResList.size();i++){
  449. newResList.get(i).put("LastActualWaterWithdrawals",
  450. parseDouble(newResList.get(i).get("LastActualWaterWithdrawals")) +
  451. parseDouble(resList.get(i).get("LastActualWaterWithdrawals")));
  452. newResList.get(i).put("LastActualWaterSupply",
  453. parseDouble(newResList.get(i).get("LastActualWaterSupply")) +
  454. parseDouble(resList.get(i).get("LastActualWaterSupply")));
  455. newResList.get(i).put("ActualWaterWithdrawals",
  456. parseDouble(newResList.get(i).get("ActualWaterWithdrawals")) +
  457. parseDouble(resList.get(i).get("ActualWaterWithdrawals")));
  458. newResList.get(i).put("ActualWaterSupply",
  459. parseDouble(newResList.get(i).get("ActualWaterSupply")) +
  460. parseDouble(resList.get(i).get("ActualWaterSupply")));
  461. newResList.get(i).put("ForecastWaterWithdrawals",
  462. parseDouble(newResList.get(i).get("ForecastWaterWithdrawals")) +
  463. parseDouble(resList.get(i).get("ForecastWaterWithdrawals")));
  464. newResList.get(i).put("ForecastActualWaterSupply",
  465. parseDouble(newResList.get(i).get("ForecastActualWaterSupply")) +
  466. parseDouble(resList.get(i).get("ForecastActualWaterSupply")));
  467. }
  468. }else {
  469. newResList.addAll(resList);
  470. }
  471. index++;
  472. }
  473. if (!CollectionUtils.isEmpty(newResList)) {
  474. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  475. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  476. responseRes.setResdata(newResList);
  477. }
  478. }else {
  479. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMWater(jpTbMWater.getIsPage(),
  480. jpTbMWater.getLimit(), jpTbMWater.getOffset(), jpTbMWater.getForDateStr());
  481. if (!CollectionUtils.isEmpty(resList)) {
  482. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  483. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  484. responseRes.setResdata(resList);
  485. }
  486. }
  487. return responseRes;
  488. }catch(Exception ex){
  489. responseRes.setResdata(null);
  490. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  491. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  492. return responseRes;
  493. }
  494. }
  495. //TODO 获取15分钟实际水量数据
  496. public static ResponseRes selectRealMinutesWaterList(JPRealHourWater jpTbMHourWater,Integer level,Map<String, Map<String, List<String>>> result
  497. ,Map<String,String> workZonIds){
  498. ResponseRes responseRes = new ResponseRes();
  499. List<Map<String, Object>> list = new ArrayList<>();
  500. Map<String, Object> map = new HashMap<>();
  501. // map.put("id", null);
  502. map.put("org_name", null);
  503. map.put("time", null);
  504. map.put("value", null);
  505. // map.put("value_tag", null);
  506. // map.put("collcation_tag_array", null);
  507. list.add(map);
  508. responseRes.setResdata(list);
  509. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  510. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  511. try {
  512. List<Map<String, Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false, 0, 0, " AND org_name not like '%水厂'");
  513. if ("water_volume_prediction_jiangjin2".equals(databaseName)) {
  514. orgConfig = getWaterTapWaterApi().getOrgConfig(false, 0, 0, "");
  515. }
  516. if(!CollectionUtils.isEmpty(orgConfig)){
  517. //TODO 根据分区编号找到对应的名称
  518. if(level==null||level!=1) {
  519. Optional<Map<String, Object>> mapOrg = orgConfig.stream()
  520. .filter(maps -> jpTbMHourWater.getOrgId().equals(maps.get("org_id")))
  521. .findFirst();
  522. if (mapOrg.isPresent()) {
  523. Map<String, Object> currentOrg = mapOrg.get();
  524. List<Map<String, Object>> recordAllRes = getWaterTapApi()
  525. .getWaterCollectionRecordAllListAllNew(" WHERE 1=1 " +
  526. " AND org_name = '" + currentOrg.get("org_name").toString() + "'" +
  527. jpTbMHourWater.getForDateStr());
  528. recordAllRes.stream()
  529. .forEach(item -> {
  530. item.remove("id");
  531. item.remove("value_tag");
  532. item.remove("collcation_tag_array");
  533. });
  534. if (jpTbMHourWater.getDayData()) {
  535. responseRes.setResdata(aggregateByDay(recordAllRes));
  536. } else {
  537. responseRes.setResdata(recordAllRes);
  538. }
  539. }
  540. }else if(level!=null&&level ==1){
  541. //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
  542. //TODO 查询二级,及其二级带的三级
  543. List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
  544. List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
  545. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  546. if(zoneNameOpt.isPresent()){
  547. String zoneName = zoneNameOpt.get().toString();
  548. Map<String, List<String>> childMap = result.get(zoneName);//二级
  549. Collection<List<String>> child2Map = childMap.values();//三级
  550. // 添加二级组织机构名称(childMap 的 keySet)
  551. childList.addAll(childMap.keySet());
  552. // 添加三级组织机构名称(child2Map 的所有 List<String>)
  553. for (List<String> child2List : child2Map) {
  554. childList.addAll(child2List);
  555. }
  556. }
  557. // 结果集合,存储 childList 对应的组织机构 ID
  558. // 遍历 childList,从 workZonIds 中获取对应的 ID
  559. for (String orgName : childList) {
  560. String orgId = workZonIds.get(orgName);
  561. if (orgId != null) { // 避免空值
  562. childIdList.add(orgId);
  563. }
  564. }
  565. List<Map<String,Object>> newResList = new ArrayList<>();
  566. int index = 0;
  567. for (String orgName:childList){
  568. List<Map<String,Object>> resList = getWaterTapApi()
  569. .getWaterCollectionRecordAllListAllNew(" WHERE 1=1 " +
  570. " AND org_name = '"+orgName+"'" +
  571. jpTbMHourWater.getForDateStr() + " ORDER BY time ASC ");
  572. if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
  573. //TODO 说明要查询的分区不止一个,则&把原来有的数据与新查的数据相加,因为按Date排了序所以一致
  574. for (int i=0;i<newResList.size();i++){
  575. newResList.get(i).put("value",
  576. String.valueOf(parseDouble(newResList.get(i).get("value")) +
  577. parseDouble(resList.get(i).get("value"))));
  578. newResList.get(i).put("org_name",orgName);
  579. newResList.get(i).put("time",resList.get(i).get("time"));
  580. }
  581. }else {
  582. newResList.addAll(resList);
  583. }
  584. index++;
  585. }
  586. newResList.stream()
  587. .forEach(item -> {
  588. item.remove("id");
  589. item.remove("value_tag");
  590. item.remove("collcation_tag_array");
  591. });
  592. if(jpTbMHourWater.getDayData()){
  593. responseRes.setResdata(aggregateByDay(newResList));
  594. }else{
  595. responseRes.setResdata(newResList);
  596. }
  597. }
  598. }
  599. return responseRes;
  600. }catch(Exception ex){
  601. responseRes.setResdata(null);
  602. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  603. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  604. return responseRes;
  605. }
  606. }
  607. //TODO 获取小时实际水量数据
  608. public static ResponseRes selectRealHourWaterList(JPRealHourWater jpTbMHourWater,Integer level,Map<String, Map<String, List<String>>> result
  609. ,Map<String,String> workZonIds){
  610. ResponseRes responseRes = new ResponseRes();
  611. List<Map<String, Object>> list = new ArrayList<>();
  612. Map<String, Object> map = new HashMap<>();
  613. // map.put("id", null);
  614. map.put("org_name", null);
  615. map.put("time", null);
  616. map.put("value", null);
  617. // map.put("value_tag", null);
  618. // map.put("collcation_tag_array", null);
  619. list.add(map);
  620. responseRes.setResdata(list);
  621. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  622. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  623. try {
  624. List<Map<String, Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false, 0, 0, " AND org_name not like '%水厂'");
  625. if ("water_volume_prediction_jiangjin2".equals(databaseName)) {
  626. orgConfig = getWaterTapWaterApi().getOrgConfig(false, 0, 0, "");
  627. }
  628. if(!CollectionUtils.isEmpty(orgConfig)){
  629. //TODO 根据分区编号找到对应的名称
  630. if(level==null||level!=1) {
  631. Optional<Map<String, Object>> mapOrg = orgConfig.stream()
  632. .filter(maps -> jpTbMHourWater.getOrgId().equals(maps.get("org_id")))
  633. .findFirst();
  634. if (mapOrg.isPresent()) {
  635. Map<String, Object> currentOrg = mapOrg.get();
  636. List<Map<String, Object>> recordAllRes = getWaterTapApi()
  637. .getWaterCollectionRecordAllListAll(" WHERE 1=1 " +
  638. " AND org_name = '" + currentOrg.get("org_name").toString() + "'" +
  639. jpTbMHourWater.getForDateStr());
  640. recordAllRes.stream()
  641. .forEach(item -> {
  642. item.remove("id");
  643. item.remove("value_tag");
  644. item.remove("collcation_tag_array");
  645. });
  646. if (jpTbMHourWater.getDayData()) {
  647. responseRes.setResdata(aggregateByDay(recordAllRes));
  648. } else {
  649. responseRes.setResdata(recordAllRes);
  650. }
  651. }
  652. }else if(level!=null&&level ==1){
  653. //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
  654. //TODO 查询二级,及其二级带的三级
  655. List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
  656. List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
  657. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  658. if(zoneNameOpt.isPresent()){
  659. String zoneName = zoneNameOpt.get().toString();
  660. Map<String, List<String>> childMap = result.get(zoneName);//二级
  661. Collection<List<String>> child2Map = childMap.values();//三级
  662. // 添加二级组织机构名称(childMap 的 keySet)
  663. childList.addAll(childMap.keySet());
  664. // 添加三级组织机构名称(child2Map 的所有 List<String>)
  665. for (List<String> child2List : child2Map) {
  666. childList.addAll(child2List);
  667. }
  668. }
  669. // 结果集合,存储 childList 对应的组织机构 ID
  670. // 遍历 childList,从 workZonIds 中获取对应的 ID
  671. for (String orgName : childList) {
  672. String orgId = workZonIds.get(orgName);
  673. if (orgId != null) { // 避免空值
  674. childIdList.add(orgId);
  675. }
  676. }
  677. List<Map<String,Object>> newResList = new ArrayList<>();
  678. int index = 0;
  679. for (String orgName:childList){
  680. List<Map<String,Object>> resList = getWaterTapApi()
  681. .getWaterCollectionRecordAllListAll(" WHERE 1=1 " +
  682. " AND org_name = '"+orgName+"'" +
  683. jpTbMHourWater.getForDateStr() + " ORDER BY time ASC ");
  684. if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
  685. //TODO 说明要查询的分区不止一个,则&把原来有的数据与新查的数据相加,因为按Date排了序所以一致
  686. for (int i=0;i<newResList.size();i++){
  687. newResList.get(i).put("value",
  688. String.valueOf(parseDouble(newResList.get(i).get("value")) +
  689. parseDouble(resList.get(i).get("value"))));
  690. newResList.get(i).put("org_name",orgName);
  691. newResList.get(i).put("time",resList.get(i).get("time"));
  692. }
  693. }else {
  694. newResList.addAll(resList);
  695. }
  696. index++;
  697. }
  698. newResList.stream()
  699. .forEach(item -> {
  700. item.remove("id");
  701. item.remove("value_tag");
  702. item.remove("collcation_tag_array");
  703. });
  704. if(jpTbMHourWater.getDayData()){
  705. responseRes.setResdata(aggregateByDay(newResList));
  706. }else{
  707. responseRes.setResdata(newResList);
  708. }
  709. }
  710. }
  711. return responseRes;
  712. }catch(Exception ex){
  713. responseRes.setResdata(null);
  714. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  715. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  716. return responseRes;
  717. }
  718. }
  719. public static List<Map<String, Object>> aggregateByDay(List<Map<String, Object>> hourlyData) {
  720. // 定义日期格式
  721. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  722. DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
  723. // 按日期分组
  724. Map<String, List<Map<String, Object>>> groupedByDate = hourlyData.stream()
  725. .collect(Collectors.groupingBy(
  726. record -> {
  727. String timeStr = (String) record.get("time");
  728. LocalDateTime dateTime = LocalDateTime.parse(timeStr, formatter);
  729. return dateTime.format(dateFormatter);
  730. }
  731. ));
  732. // 创建结果列表
  733. List<Map<String, Object>> dailyData = new ArrayList<>();
  734. // 对每天的数据进行聚合
  735. groupedByDate.forEach((date, records) -> {
  736. Map<String, Object> dailyRecord = new HashMap<>();
  737. // 保留第一个记录的id和org_name
  738. dailyRecord.put("org_name", records.get(0).get("org_name"));
  739. dailyRecord.put("time", date);
  740. // 计算当天的总值(示例为求和)
  741. double sum = records.stream()
  742. .mapToDouble(record -> Double.parseDouble((String) record.get("value")))
  743. .sum();
  744. // 计算当天平均值
  745. double average = sum / records.size();
  746. // dailyRecord.put("total_value", String.valueOf(sum));
  747. // dailyRecord.put("average_value", String.valueOf(average));
  748. // dailyRecord.put("record_count", records.size());
  749. dailyRecord.put("value", String.valueOf(sum));
  750. dailyData.add(dailyRecord);
  751. });
  752. return dailyData;
  753. }
  754. //TODO 15分钟水量预测接口
  755. /**
  756. * 传入水厂id及日期,返回指定日期内的小时取水量预测数据和实际小时取水量数据
  757. */
  758. public static ResponseRes selectTbMinutesWaterList(JPTbMMinutesWater jpTbMHourWater,Integer level,Map<String, Map<String, List<String>>> result
  759. ,Map<String,String> workZonIds){
  760. ResponseRes responseRes = new ResponseRes();
  761. List<Map<String, Object>> list = new ArrayList<>();
  762. Map<String, Object> map = new HashMap<>();
  763. map.put("ID", null);
  764. map.put("Date", null);
  765. map.put("Hour", null);
  766. map.put("HourForecastWaterWithdrawals", null);
  767. map.put("HourForecastActualWaterSupply", null);
  768. map.put("WaterWithdrawalsEnergy", null);
  769. map.put("WaterSupplyEnergy", null);
  770. map.put("RealWaterWithdrawalsEnergy", null);
  771. map.put("RealWaterSupplyEnergy", null);
  772. map.put("LastModifyTime", null);
  773. map.put("HourActualWaterWithdrawals", null);
  774. map.put("HourActualWaterSupply ", null);
  775. list.add(map);
  776. responseRes.setResdata(list);
  777. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  778. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  779. try {
  780. if ("water_volume_prediction".equals(databaseName)){
  781. //TODO 自来水分了二级泵房,要做查询数据处理,点击水厂查询条件时,查询其下的泵房数据 再相加,
  782. //TODO 点击泵房则就查泵房的数据 ,无需做处理
  783. List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
  784. List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
  785. if (level==1){
  786. //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
  787. //TODO 查询二级,及其二级带的三级
  788. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  789. if(zoneNameOpt.isPresent()){
  790. String zoneName = zoneNameOpt.get().toString();
  791. Map<String, List<String>> childMap = result.get(zoneName);//二级
  792. Collection<List<String>> child2Map = childMap.values();//三级
  793. // 添加二级组织机构名称(childMap 的 keySet)
  794. childList.addAll(childMap.keySet());
  795. // 添加三级组织机构名称(child2Map 的所有 List<String>)
  796. for (List<String> child2List : child2Map) {
  797. childList.addAll(child2List);
  798. }
  799. }
  800. }else if(level==2){
  801. //TODO 如果是二级,就查询其自身,看看其下还有没有集合,有的话就查其下的所有集合,没有的话就查其自身
  802. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  803. if(zoneNameOpt.isPresent()) {
  804. String zoneName = zoneNameOpt.get().toString();
  805. List<String> childMap = new ArrayList<>();//三级
  806. // 遍历第一级 Map
  807. for (Map.Entry<String, Map<String, List<String>>> entry : result.entrySet()) {
  808. Map<String, List<String>> nestedMap = entry.getValue();
  809. // 检查第二级键
  810. if (nestedMap.containsKey(zoneName)) {
  811. childMap = nestedMap.get(zoneName);
  812. }
  813. }
  814. if(childMap.size()>0) {
  815. // 添三级组织机构名称(childMap 的 keySet)
  816. childList.addAll(childMap);
  817. }else{
  818. childList.add(zoneName);
  819. }
  820. }
  821. }else if(level==3){
  822. //TODO 如果是三级,就查询其自身
  823. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  824. if(zoneNameOpt.isPresent()) {
  825. String zoneName = zoneNameOpt.get().toString();
  826. childList.add(zoneName);
  827. }
  828. }
  829. //TODO 开始查询
  830. // 结果集合,存储 childList 对应的组织机构 ID
  831. // 遍历 childList,从 workZonIds 中获取对应的 ID
  832. for (String orgName : childList) {
  833. String orgId = workZonIds.get(orgName);
  834. if (orgId != null) { // 避免空值
  835. childIdList.add(orgId);
  836. }
  837. }
  838. List<Map<String,Object>> newResList = new ArrayList<>();
  839. int index = 0;
  840. for (String orgId:childIdList){
  841. jpTbMHourWater.setOrgId(orgId);
  842. jpTbMHourWater.checkValid();
  843. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterNew(jpTbMHourWater.getIsPage(),
  844. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr()+ " ORDER BY \"Date\",\"Hour\" ASC ");
  845. if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
  846. //TODO 说明要查询的分区不止一个,则&把原来有的数据与新查的数据相加,因为按Date排了序所以一致
  847. for (int i=0;i<newResList.size();i++){
  848. newResList.get(i).put("HourForecastWaterWithdrawals",
  849. parseDouble(newResList.get(i).get("HourForecastWaterWithdrawals")) +
  850. parseDouble(resList.get(i).get("HourForecastWaterWithdrawals")));
  851. newResList.get(i).put("HourForecastActualWaterSupply",
  852. parseDouble(newResList.get(i).get("HourForecastActualWaterSupply")) +
  853. parseDouble(resList.get(i).get("HourForecastActualWaterSupply")));
  854. newResList.get(i).put("WaterWithdrawalsEnergy",
  855. parseDouble(newResList.get(i).get("WaterWithdrawalsEnergy")) +
  856. parseDouble(resList.get(i).get("WaterWithdrawalsEnergy")));
  857. newResList.get(i).put("WaterSupplyEnergy",
  858. parseDouble(newResList.get(i).get("WaterSupplyEnergy")) +
  859. parseDouble(resList.get(i).get("WaterSupplyEnergy")));
  860. newResList.get(i).put("RealWaterWithdrawalsEnergy",
  861. parseDouble(newResList.get(i).get("RealWaterWithdrawalsEnergy")) +
  862. parseDouble(resList.get(i).get("RealWaterWithdrawalsEnergy")));
  863. newResList.get(i).put("RealWaterSupplyEnergy",
  864. parseDouble(newResList.get(i).get("RealWaterSupplyEnergy")) +
  865. parseDouble(resList.get(i).get("RealWaterSupplyEnergy")));
  866. newResList.get(i).put("HourActualWaterWithdrawals",
  867. parseDouble(newResList.get(i).get("HourActualWaterWithdrawals")) +
  868. parseDouble(resList.get(i).get("HourActualWaterWithdrawals")));
  869. newResList.get(i).put("HourActualWaterSupply",
  870. parseDouble(newResList.get(i).get("HourActualWaterSupply")) +
  871. parseDouble(resList.get(i).get("HourActualWaterSupply")));
  872. }
  873. }else {
  874. newResList.addAll(resList);
  875. }
  876. index++;
  877. }
  878. if (!CollectionUtils.isEmpty(newResList)) {
  879. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  880. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  881. responseRes.setResdata(newResList);
  882. }
  883. }else {
  884. //
  885. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwater(jpTbMHourWater.getIsPage(),
  886. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
  887. if (!CollectionUtils.isEmpty(resList)) {
  888. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  889. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  890. responseRes.setResdata(resList);
  891. }
  892. }
  893. return responseRes;
  894. }catch(Exception ex){
  895. responseRes.setResdata(null);
  896. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  897. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  898. return responseRes;
  899. }
  900. }
  901. //TODO 小时水量预测接口
  902. /**
  903. * 传入水厂id及日期,返回指定日期内的小时取水量预测数据和实际小时取水量数据
  904. */
  905. public static ResponseRes selectTbHourWaterList(JPTbMHourWater jpTbMHourWater,Integer level,Map<String, Map<String, List<String>>> result
  906. ,Map<String,String> workZonIds){
  907. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  908. , "2222");
  909. ResponseRes responseRes = new ResponseRes();
  910. List<Map<String, Object>> list = new ArrayList<>();
  911. Map<String, Object> map = new HashMap<>();
  912. map.put("ID", null);
  913. map.put("Date", null);
  914. map.put("Hour", null);
  915. map.put("HourForecastWaterWithdrawals", null);
  916. map.put("HourForecastActualWaterSupply", null);
  917. map.put("WaterWithdrawalsEnergy", null);
  918. map.put("WaterSupplyEnergy", null);
  919. map.put("RealWaterWithdrawalsEnergy", null);
  920. map.put("RealWaterSupplyEnergy", null);
  921. map.put("LastModifyTime", null);
  922. map.put("HourActualWaterWithdrawals", null);
  923. map.put("HourActualWaterSupply ", null);
  924. list.add(map);
  925. responseRes.setResdata(list);
  926. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  927. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  928. try {
  929. if ("water_volume_prediction".equals(databaseName)){
  930. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  931. , "3333");
  932. //TODO 自来水分了二级泵房,要做查询数据处理,点击水厂查询条件时,查询其下的泵房数据 再相加,
  933. //TODO 点击泵房则就查泵房的数据 ,无需做处理
  934. List<String> childList = new ArrayList<>();//要查询的组织机构名称集合
  935. List<String> childIdList = new ArrayList<>();//要查询的组织机构id集合
  936. if (level==1){
  937. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  938. , "4444");
  939. //TODO 一级已经没有数据了(水厂), 查询一级的话则是将其下的供水数据相加
  940. //TODO 查询二级,及其二级带的三级
  941. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  942. if(zoneNameOpt.isPresent()){
  943. String zoneName = zoneNameOpt.get().toString();
  944. Map<String, List<String>> childMap = result.get(zoneName);//二级
  945. Collection<List<String>> child2Map = childMap.values();//三级
  946. // 添加二级组织机构名称(childMap 的 keySet)
  947. childList.addAll(childMap.keySet());
  948. // 添加三级组织机构名称(child2Map 的所有 List<String>)
  949. for (List<String> child2List : child2Map) {
  950. childList.addAll(child2List);
  951. }
  952. }
  953. }else if(level==2){
  954. //TODO 如果是二级,就查询其自身,看看其下还有没有集合,有的话就查其下的所有集合,没有的话就查其自身
  955. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  956. if(zoneNameOpt.isPresent()) {
  957. String zoneName = zoneNameOpt.get().toString();
  958. List<String> childMap = new ArrayList<>();//三级
  959. // 遍历第一级 Map
  960. for (Map.Entry<String, Map<String, List<String>>> entry : result.entrySet()) {
  961. Map<String, List<String>> nestedMap = entry.getValue();
  962. // 检查第二级键
  963. if (nestedMap.containsKey(zoneName)) {
  964. childMap = nestedMap.get(zoneName);
  965. }
  966. }
  967. if(childMap.size()>0) {
  968. // 添三级组织机构名称(childMap 的 keySet)
  969. childList.addAll(childMap);
  970. }else{
  971. childList.add(zoneName);
  972. }
  973. }
  974. }else if(level==3){
  975. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  976. , "5555");
  977. //TODO 如果是三级,就查询其自身
  978. Optional zoneNameOpt = findOrgNameByOrgId(workZonIds,jpTbMHourWater.getOrgId());
  979. if(zoneNameOpt.isPresent()) {
  980. String zoneName = zoneNameOpt.get().toString();
  981. childList.add(zoneName);
  982. }
  983. }
  984. //TODO 开始查询
  985. // 结果集合,存储 childList 对应的组织机构 ID
  986. // 遍历 childList,从 workZonIds 中获取对应的 ID
  987. for (String orgName : childList) {
  988. String orgId = workZonIds.get(orgName);
  989. if (orgId != null) { // 避免空值
  990. childIdList.add(orgId);
  991. }
  992. }
  993. List<Map<String,Object>> newResList = new ArrayList<>();
  994. int index = 0;
  995. for (String orgId:childIdList){
  996. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  997. , "6666");
  998. jpTbMHourWater.setOrgId(orgId);
  999. jpTbMHourWater.checkValid();
  1000. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwater(jpTbMHourWater.getIsPage(),
  1001. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr()+ " ORDER BY \"Date\",\"Hour\" ASC ");
  1002. if(!CollectionUtils.isEmpty(newResList)&&!CollectionUtils.isEmpty(resList)){
  1003. //TODO 说明要查询的分区不止一个,则&把原来有的数据与新查的数据相加,因为按Date排了序所以一致
  1004. for (int i=0;i<newResList.size();i++){
  1005. newResList.get(i).put("HourForecastWaterWithdrawals",
  1006. parseDouble(newResList.get(i).get("HourForecastWaterWithdrawals")) +
  1007. parseDouble(resList.get(i).get("HourForecastWaterWithdrawals")));
  1008. newResList.get(i).put("HourForecastActualWaterSupply",
  1009. parseDouble(newResList.get(i).get("HourForecastActualWaterSupply")) +
  1010. parseDouble(resList.get(i).get("HourForecastActualWaterSupply")));
  1011. newResList.get(i).put("WaterWithdrawalsEnergy",
  1012. parseDouble(newResList.get(i).get("WaterWithdrawalsEnergy")) +
  1013. parseDouble(resList.get(i).get("WaterWithdrawalsEnergy")));
  1014. newResList.get(i).put("WaterSupplyEnergy",
  1015. parseDouble(newResList.get(i).get("WaterSupplyEnergy")) +
  1016. parseDouble(resList.get(i).get("WaterSupplyEnergy")));
  1017. newResList.get(i).put("RealWaterWithdrawalsEnergy",
  1018. parseDouble(newResList.get(i).get("RealWaterWithdrawalsEnergy")) +
  1019. parseDouble(resList.get(i).get("RealWaterWithdrawalsEnergy")));
  1020. newResList.get(i).put("RealWaterSupplyEnergy",
  1021. parseDouble(newResList.get(i).get("RealWaterSupplyEnergy")) +
  1022. parseDouble(resList.get(i).get("RealWaterSupplyEnergy")));
  1023. newResList.get(i).put("HourActualWaterWithdrawals",
  1024. parseDouble(newResList.get(i).get("HourActualWaterWithdrawals")) +
  1025. parseDouble(resList.get(i).get("HourActualWaterWithdrawals")));
  1026. newResList.get(i).put("HourActualWaterSupply",
  1027. parseDouble(newResList.get(i).get("HourActualWaterSupply")) +
  1028. parseDouble(resList.get(i).get("HourActualWaterSupply")));
  1029. }
  1030. }else {
  1031. newResList.addAll(resList);
  1032. }
  1033. index++;
  1034. }
  1035. if (!CollectionUtils.isEmpty(newResList)) {
  1036. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, LogFlagBusiType.BUSI_INTERNAL.toStrValue(), mStrClassName, ""
  1037. , "7777");
  1038. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1039. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1040. responseRes.setResdata(newResList);
  1041. }
  1042. }else {
  1043. //
  1044. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwater(jpTbMHourWater.getIsPage(),
  1045. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
  1046. if (!CollectionUtils.isEmpty(resList)) {
  1047. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1048. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1049. responseRes.setResdata(resList);
  1050. }
  1051. }
  1052. return responseRes;
  1053. }catch(Exception ex){
  1054. responseRes.setResdata(null);
  1055. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  1056. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  1057. return responseRes;
  1058. }
  1059. }
  1060. //TODO 小时取水泵房电耗预测接口
  1061. /**
  1062. * 传入水厂id及日期
  1063. */
  1064. public static ResponseRes selectTbMHourwaterWaterwithdrawals(JPTbMHourWater jpTbMHourWater,String subType){
  1065. ResponseRes responseRes = new ResponseRes();
  1066. //TODO 默认值
  1067. List<InPumpModel> defaultModels = new ArrayList<>();
  1068. InPumpModel entity = new InPumpModel();
  1069. entity.setOrgId(null);
  1070. entity.setPumpId(null);
  1071. entity.setSubType(subType);
  1072. List<Map<String, Object>> defaultRes = new ArrayList<>();
  1073. Map<String, Object> map = new HashMap<>();
  1074. map.put("ID", null);
  1075. map.put("Date", null);
  1076. map.put("Hour", null);
  1077. map.put("PumpID", null);
  1078. map.put("PumpStatus", null);
  1079. map.put("HourForecastWaterWithdrawals", null);
  1080. map.put("PumpWater", null);
  1081. map.put("RealPumpStatus", null);
  1082. map.put("PumpEnergy", null);
  1083. map.put("RealPumpEnergy", null);
  1084. map.put("LastModifyTime", null);
  1085. map.put("orgId", null);
  1086. defaultRes.add(map);
  1087. defaultModels.add(entity);
  1088. responseRes.setResdata(defaultModels);
  1089. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1090. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1091. try {
  1092. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterWaterwithdrawals(jpTbMHourWater.getIsPage(),
  1093. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
  1094. //TODO 按水厂分组
  1095. Map<Object, List<Map<String, Object>>> groupedData =
  1096. resList.stream().collect(Collectors.groupingBy(item -> item.get("orgId")));
  1097. //TODO 查询水厂的取水泵,然后将数据拼接
  1098. List<InPumpModel> inPumpModels = new ArrayList<>();
  1099. for (Object key:groupedData.keySet()) {
  1100. InPumpModel model = new InPumpModel();
  1101. List<Map<String,Object>> zoonList = getWaterTapWaterApi().getZoonInfoList(key.toString(),subType);
  1102. if(!CollectionUtils.isEmpty(zoonList)){
  1103. model.setPumpId(zoonList.get(0).get("uid").toString());
  1104. }
  1105. model.setOrgId(key.toString());
  1106. model.setSubType(subType);
  1107. List<Map<String, Object>> dataList = groupedData.get(key);
  1108. //TODO 将年月日时作为分组条件
  1109. Map<String, List<Map<String, Object>>> dataMap = dataList.stream()
  1110. .collect(Collectors.groupingBy(emp ->
  1111. emp.get("Date") + " " + emp.get("Hour") // 创建复合键
  1112. ));
  1113. model.setDataList(dataMap);
  1114. //TODO 查询相应方案数据
  1115. List<Map<String,Object>> drawalsList = getWaterTapWaterApi().getTbMWaterwithdrawalspump(false,
  1116. 20,0," AND \"orgId\" = '"+key.toString()+"'");
  1117. model.setDrawalsList(drawalsList);
  1118. inPumpModels.add(model);
  1119. }
  1120. if(!CollectionUtils.isEmpty(inPumpModels)){
  1121. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1122. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1123. responseRes.setResdata(inPumpModels);
  1124. }
  1125. return responseRes;
  1126. }catch(Exception ex){
  1127. responseRes.setResdata(null);
  1128. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  1129. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  1130. return responseRes;
  1131. }
  1132. }
  1133. //TODO 小时供水泵房电耗预测接口
  1134. /**
  1135. * 传入水厂id及日期
  1136. */
  1137. public static ResponseRes selectTbMHourwaterWatersupply(JPTbMHourPump jpTbMHourWater,String subType){
  1138. ResponseRes responseRes = new ResponseRes();
  1139. //TODO 默认值
  1140. List<InPumpModel> defaultModels = new ArrayList<>();
  1141. InPumpModel entity = new InPumpModel();
  1142. entity.setOrgId(null);
  1143. entity.setPumpId(null);
  1144. entity.setSubType(subType);
  1145. List<Map<String, Object>> defaultRes = new ArrayList<>();
  1146. Map<String, Object> map = new HashMap<>();
  1147. map.put("ID", null);
  1148. map.put("Date", null);
  1149. map.put("Hour", null);
  1150. map.put("PumpID", null);
  1151. map.put("PumpStatus", null);
  1152. map.put("HourForecastActualWaterSupply", null);
  1153. map.put("PumpWater", null);
  1154. map.put("RealPumpStatus", null);
  1155. map.put("PumpEnergy", null);
  1156. map.put("RealPumpEnergy", null);
  1157. map.put("LastModifyTime", null);
  1158. map.put("orgId", null);
  1159. defaultRes.add(map);
  1160. defaultModels.add(entity);
  1161. responseRes.setResdata(defaultModels);
  1162. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1163. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1164. try {
  1165. //
  1166. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterWatersupply(jpTbMHourWater.getIsPage(),
  1167. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
  1168. if("water_volume_prediction_jiangjin2".equals(databaseName)){
  1169. //TODO 按水厂分组
  1170. Map<Object, List<Map<String, Object>>> groupedData =
  1171. resList.stream().collect(Collectors.groupingBy(item -> item.get("orgId")));
  1172. //TODO 查询水厂的取水泵,然后将数据拼接
  1173. List<InPumpModel> inPumpModels = new ArrayList<>();
  1174. for (Object key : groupedData.keySet()) {
  1175. InPumpModel model = new InPumpModel();
  1176. List<Map<String, Object>> zoonList = getWaterTapWaterApi().getZoonInfoList(key.toString(), subType);
  1177. if (!CollectionUtils.isEmpty(zoonList)) {
  1178. model.setPumpId(zoonList.get(0).get("uid").toString());
  1179. }
  1180. model.setOrgId(key.toString());
  1181. model.setSubType(subType);
  1182. List<Map<String, Object>> dataList = groupedData.get(key);
  1183. //TODO 将年月日时作为分组条件
  1184. Map<String, List<Map<String, Object>>> dataMap = dataList.stream()
  1185. .collect(Collectors.groupingBy(emp ->
  1186. emp.get("Date") + " " + emp.get("Hour") // 创建复合键
  1187. ));
  1188. model.setDataList(dataMap);
  1189. //TODO 查询相应方案数据
  1190. List<Map<String, Object>> drawalsList = getWaterTapWaterApi().getTbMWatersupplypump(false,
  1191. 20, 0, " AND \"orgId\" = '" + key.toString() + "'");
  1192. model.setDrawalsList(drawalsList);
  1193. inPumpModels.add(model);
  1194. }
  1195. if (!CollectionUtils.isEmpty(inPumpModels)) {
  1196. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1197. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1198. responseRes.setResdata(inPumpModels);
  1199. }
  1200. return responseRes;
  1201. }else {
  1202. Map<Object, List<Map<String, Object>>> groupedData =
  1203. resList.stream().collect(Collectors.groupingBy(item -> item.get("orgId")));
  1204. //TODO 查询水厂的取水泵,然后将数据拼接
  1205. List<InPumpModel> inPumpModels = new ArrayList<>();
  1206. for (Object key : groupedData.keySet()) {
  1207. InPumpModel model = new InPumpModel();
  1208. List<Map<String, Object>> zoonList = getWaterTapWaterApi().getZoonInfoList(key.toString(), subType);
  1209. if (!CollectionUtils.isEmpty(zoonList)) {
  1210. model.setPumpId(zoonList.get(0).get("uid").toString());
  1211. }
  1212. model.setOrgId(key.toString());
  1213. model.setSubType(subType);
  1214. List<Map<String, Object>> dataList = groupedData.get(key);
  1215. //TODO 将年月日时作为分组条件
  1216. Map<String, List<Map<String, Object>>> dataMap = dataList.stream()
  1217. .collect(Collectors.groupingBy(emp ->
  1218. emp.get("Date") + " " + emp.get("Hour") // 创建复合键
  1219. ));
  1220. model.setDataList(dataMap);
  1221. //TODO 查询相应方案数据
  1222. List<Map<String, Object>> drawalsList = getWaterTapWaterApi().getTbMWatersupplypump(false,
  1223. 20, 0, " AND \"orgId\" = '" + key.toString() + "'");
  1224. model.setDrawalsList(drawalsList);
  1225. inPumpModels.add(model);
  1226. }
  1227. if (!CollectionUtils.isEmpty(inPumpModels)) {
  1228. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  1229. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  1230. responseRes.setResdata(inPumpModels);
  1231. }
  1232. return responseRes;
  1233. }
  1234. }catch(Exception ex){
  1235. responseRes.setResdata(null);
  1236. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  1237. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  1238. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1239. , mStrClassName
  1240. , mStrClassName
  1241. , String.format("预测泵供水小时数据调用异常 ERROR:{%s} ",
  1242. ex.getLocalizedMessage()));
  1243. return responseRes;
  1244. }
  1245. }
  1246. //TODO 定时任务 定时调用水力模型预测接口,截止今天
  1247. public static void insertYuceDayData(String monthNow){
  1248. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测日数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1249. try {
  1250. String yearStr = "";
  1251. String monthStr = "";
  1252. if(!StringUtils.isEmpty(monthNow)){
  1253. yearStr = monthNow.split("-")[0];
  1254. monthStr = monthNow.split("-")[1];
  1255. }
  1256. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1257. .withMonth(Integer.valueOf(monthStr)).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1258. int days = LocalDateTime.now().getDayOfMonth();//获取月份天数
  1259. for (int i = 1;i<=days;i++) {
  1260. LocalDateTime dateNow = startDate.withDayOfMonth(i);//当前循环时间
  1261. if (dateNow.isAfter(LocalDateTime.now())) {
  1262. break;
  1263. }
  1264. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1265. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1266. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1267. //TODO A
  1268. JP3TPDay tpDay = new JP3TPDay();
  1269. tpDay.setOrgId("");
  1270. tpDay.setSdate(dateStr);
  1271. tpDay.setEndate(dateStr);
  1272. try {
  1273. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
  1274. , mStrClassName
  1275. , mStrClassName
  1276. , String.format("执行预测日数据" + FastJsonUtil.toJSON(tpDay) + "调用"));
  1277. ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1278. .applyCloud3tpServiceApi().dayDataPredictSupply(tpDay);
  1279. if (ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())) {
  1280. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1281. , mStrClassName
  1282. , mStrClassName
  1283. , String.format("预测日数据" + dateStr + "调用失败 ERROR:{%s} ",
  1284. tpRes.getResdata()));
  1285. }
  1286. } catch (Exception ex) {
  1287. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1288. , mStrClassName
  1289. , mStrClassName
  1290. , String.format("预测日数据" + dateStr + "调用异常 ERROR:{%s} ",
  1291. ex.getLocalizedMessage()));
  1292. }
  1293. }
  1294. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测日数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1295. }catch(Exception ex){
  1296. ex.printStackTrace();
  1297. }
  1298. }
  1299. //TODO 截止到未来的今天+3
  1300. public static void insertYuceDayAddData(String monthNow){
  1301. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测日数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1302. try {
  1303. String yearStr = "";
  1304. String monthStr = "";
  1305. if(!StringUtils.isEmpty(monthNow)){
  1306. yearStr = monthNow.split("-")[0];
  1307. monthStr = monthNow.split("-")[1];
  1308. }
  1309. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1310. .withMonth(Integer.valueOf(monthStr)).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1311. List<Map<String,Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0," AND org_name != '井口水厂' AND org_name != '丰收坝水厂' AND org_name != '沙坪坝水厂' AND org_name != '北碚红工水厂' AND org_name != '大溪沟水厂' ");
  1312. if("water_volume_prediction_jiangjin2".equals(databaseName)){
  1313. orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0,"");
  1314. }
  1315. LocalDateTime dateNow = startDate;
  1316. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1317. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1318. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1319. //TODO A
  1320. for (Map<String,Object> config:orgConfig) {
  1321. JP3TPDay tpDay = new JP3TPDay();
  1322. tpDay.setOrgId(config.get("org_id").toString());
  1323. tpDay.setSdate(dateStr);
  1324. // tpDay.setEndate(dateNow.minusDays(-3).toLocalDate().format(formatter2));
  1325. //TODO 预测模型的逻辑是预测当前天往后+3天
  1326. tpDay.setEndate(dateNow.minusDays(0).toLocalDate().format(formatter2));
  1327. try {
  1328. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
  1329. , mStrClassName
  1330. , mStrClassName
  1331. , String.format("执行预测未来日数据" + FastJsonUtil.toJSON(tpDay) + "调用"));
  1332. ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1333. .applyCloud3tpServiceApi().dayDataPredictSupply(tpDay);
  1334. if (ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())) {
  1335. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1336. , mStrClassName
  1337. , mStrClassName
  1338. , String.format("预测日数据" + dateStr + "调用失败 ERROR:{%s} ",
  1339. tpRes.getResdata()));
  1340. }
  1341. } catch (Exception ex) {
  1342. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1343. , mStrClassName
  1344. , mStrClassName
  1345. , String.format("预测日数据" + dateStr + "调用异常 ERROR:{%s} ",
  1346. ex.getLocalizedMessage()));
  1347. }
  1348. }
  1349. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测日数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1350. }catch(Exception ex){
  1351. ex.printStackTrace();
  1352. }
  1353. }
  1354. //TODO 定时任务 定时调用水力模型小时预测接口,截止今天
  1355. public static void insertYuceHourData(String monthNow){
  1356. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测小时数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1357. try {
  1358. //先获取配置项 根据配置项来进行逻辑添加
  1359. String yearStr = "";
  1360. String monthStr ="";
  1361. if(!StringUtils.isEmpty(monthNow)){
  1362. yearStr = monthNow.split("-")[0];
  1363. monthStr = monthNow.split("-")[1];
  1364. }
  1365. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1366. .withMonth(Integer.valueOf(monthStr)).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1367. //TODO 总体逻辑: 先查询指定月上一年的每日平均值,再按平均值的上下啊百分比去插入指定的浮动百分比数据
  1368. int days = LocalDateTime.now().getDayOfMonth();//获取月份天数
  1369. for (int i = 1;i<=days;i++){
  1370. LocalDateTime dateNow = startDate.withDayOfMonth(i);//当前循环时间
  1371. if(dateNow.toLocalDate().isAfter(LocalDateTime.now().toLocalDate())){
  1372. break;
  1373. }
  1374. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1375. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1376. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1377. //TODO A
  1378. JP3TPHour tpHour = new JP3TPHour();
  1379. tpHour.setOrgId("");
  1380. tpHour.setDate(dateStr);
  1381. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
  1382. , mStrClassName
  1383. , mStrClassName
  1384. , String.format("执行预测小时数据" + FastJsonUtil.toJSON(tpHour) + "调用"));
  1385. try {
  1386. ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1387. .applyCloud3tpServiceApi().dayHourPredictSupply(tpHour);
  1388. if(ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())){
  1389. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1390. , mStrClassName
  1391. , mStrClassName
  1392. , String.format("预测小时数据"+dateStr+"调用失败 ERROR:{%s} ",
  1393. tpRes.getResdata()));
  1394. }
  1395. }catch(Exception ex){
  1396. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1397. , mStrClassName
  1398. , mStrClassName
  1399. , String.format("预测小时数据"+dateStr+"调用异常 ERROR:{%s} ",
  1400. ex.getLocalizedMessage()));
  1401. }
  1402. }
  1403. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"调用预测模型小时数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1404. }catch(Exception ex){
  1405. ex.printStackTrace();
  1406. }
  1407. }
  1408. //TODO 截止到未来的今天+3
  1409. public static void insertYuceHourAddData(String monthNow,Integer days){
  1410. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测小时数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1411. try {
  1412. //先获取配置项 根据配置项来进行逻辑添加
  1413. String yearStr = "";
  1414. String monthStr ="";
  1415. if(!StringUtils.isEmpty(monthNow)){
  1416. yearStr = monthNow.split("-")[0];
  1417. monthStr = monthNow.split("-")[1];
  1418. }
  1419. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1420. .withMonth(Integer.valueOf(monthStr)).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1421. //TODO 总体逻辑: 先查询指定月上一年的每日平均值,再按平均值的上下啊百分比去插入指定的浮动百分比数据
  1422. List<Map<String,Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0," AND org_name != '井口水厂' AND org_name != '丰收坝水厂' AND org_name != '沙坪坝水厂' AND org_name != '北碚红工水厂' AND org_name != '大溪沟水厂' ");
  1423. if("water_volume_prediction_jiangjin2".equals(databaseName)){
  1424. orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0,"");
  1425. }
  1426. for (int i = 0;i<days;i++){
  1427. LocalDateTime dateNow = startDate.minusDays(-i);//当前循环时间
  1428. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1429. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1430. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1431. //TODO A
  1432. for (Map<String,Object> org : orgConfig) {
  1433. JP3TPHour tpHour = new JP3TPHour();
  1434. tpHour.setOrgId(org.get("org_id").toString());
  1435. tpHour.setDate(dateStr);
  1436. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
  1437. , mStrClassName
  1438. , mStrClassName
  1439. , String.format("执行未来预测小时数据" + FastJsonUtil.toJSON(tpHour) + "调用"));
  1440. try {
  1441. ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1442. .applyCloud3tpServiceApi().dayHourPredictSupply(tpHour);
  1443. if (ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())) {
  1444. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1445. , mStrClassName
  1446. , mStrClassName
  1447. , String.format("预测小时数据" + dateStr + "调用失败 ERROR:{%s} ",
  1448. tpRes.getResdata()));
  1449. }
  1450. } catch (Exception ex) {
  1451. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1452. , mStrClassName
  1453. , mStrClassName
  1454. , String.format("预测小时数据" + dateStr + "调用异常 ERROR:{%s} ",
  1455. ex.getLocalizedMessage()));
  1456. }
  1457. }
  1458. }
  1459. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"调用预测模型小时数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1460. }catch(Exception ex){
  1461. ex.printStackTrace();
  1462. }
  1463. }
  1464. //TODO 跑+1天
  1465. public static void insertYucePump(String monthNow){
  1466. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测泵组优化小时数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1467. try {
  1468. //先获取配置项 根据配置项来进行逻辑添加
  1469. String yearStr = "";
  1470. String monthStr ="";
  1471. if(!StringUtils.isEmpty(monthNow)){
  1472. yearStr = monthNow.split("-")[0];
  1473. monthStr = monthNow.split("-")[1];
  1474. }
  1475. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1476. .withMonth(Integer.valueOf(monthStr)).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1477. List<Map<String,Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0," AND org_name != '井口水厂' AND org_name != '丰收坝水厂' AND org_name != '沙坪坝水厂' AND org_name != '北碚红工水厂' AND org_name != '大溪沟水厂' ");
  1478. if("water_volume_prediction_jiangjin2".equals(databaseName)) {
  1479. orgConfig = getWaterTapWaterApi().getOrgConfig(false, 0, 0,"");
  1480. }
  1481. //TODO 总体逻辑: 先查询指定月上一年的每日平均值,再按平均值的上下啊百分比去插入指定的浮动百分比数据
  1482. for (int i = 0;i<2;i++){
  1483. LocalDateTime dateNow = startDate.minusDays(-i);//当前循环时间
  1484. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1485. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1486. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1487. //TODO A
  1488. for (Map<String,Object> org : orgConfig) {
  1489. JP3TPHour tpHour = new JP3TPHour();
  1490. tpHour.setOrgId(org.get("org_id").toString());
  1491. tpHour.setDate(dateStr);
  1492. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO
  1493. , mStrClassName
  1494. , mStrClassName
  1495. , String.format("执行未来预测泵组优化小时数据" + FastJsonUtil.toJSON(tpHour) + "调用"));
  1496. try {
  1497. ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1498. .applyCloud3tpServiceApi().dayHourPump(tpHour);
  1499. if (ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())) {
  1500. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1501. , mStrClassName
  1502. , mStrClassName
  1503. , String.format("预测泵小时数据" + dateStr + "调用失败 ERROR:{%s} ",
  1504. tpRes.getResdata()));
  1505. }
  1506. } catch (Exception ex) {
  1507. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1508. , mStrClassName
  1509. , mStrClassName
  1510. , String.format("预测泵小时数据" + dateStr + "调用异常 ERROR:{%s} ",
  1511. ex.getLocalizedMessage()));
  1512. }
  1513. }
  1514. }
  1515. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"调用预测模型泵组优化小时数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1516. }catch(Exception ex){
  1517. ex.printStackTrace();
  1518. }
  1519. }
  1520. //TODO 跑泵组数据插入预测实际值
  1521. public static void insertYucePumpReal(String monthNow,int monthDay){
  1522. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  1523. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加实际值");
  1524. try {
  1525. //先获取配置项 根据配置项来进行逻辑添加
  1526. String yearStr = "";
  1527. String monthStr = "";
  1528. if (!StringUtils.isEmpty(monthNow)) {
  1529. yearStr = monthNow.split("-")[0];
  1530. monthStr = monthNow.split("-")[1];
  1531. }
  1532. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1533. .withMonth(Integer.valueOf(monthStr)).withDayOfMonth(monthDay).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1534. LocalDateTime endDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
  1535. //TODO 查询开始时间开始的原始数据
  1536. List<Map<String,Object>> recordAllRes = getWaterTapApi()
  1537. .getPumpCollectionRecordAllListAll(" WHERE 1=1 " +
  1538. " AND \"time\"::timestamp BETWEEN '"+startDate.format(formatter)+"' "+"AND '"+endDate.format(formatter)+"'");
  1539. for (Map<String,Object> recordAll:recordAllRes){
  1540. //TODO 查询对应Day和hour对应的预测数据是否存在, 存在的话就修改实际值状态
  1541. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbMHourwaterWatersupply(true,
  1542. 1, 0, "AND \"PumpID\" = '"+recordAll.get("device_code")+"' AND \"Date\" = '"+LocalDateTime.parse(recordAll.get("time").toString(), formatter).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
  1543. +"' AND \"Hour\" = '"+LocalDateTime.parse(recordAll.get("time").toString(), formatter).format(DateTimeFormatter.ofPattern("HH:mm:ss"))+"'");
  1544. if(!CollectionUtils.isEmpty(resList)){
  1545. //TODO 说明存在,则修改
  1546. Map<String,Object> oldMap = resList.get(0);
  1547. if(!ObjectUtils.isEmpty(recordAll.get("startup_state"))){
  1548. oldMap.put("RealPumpStatus",recordAll.get("startup_state"));
  1549. }else if (!ObjectUtils.isEmpty(recordAll.get("active_energy"))){
  1550. oldMap.put("RealPumpStatus",1);
  1551. }else{
  1552. oldMap.put("RealPumpStatus",0);
  1553. }
  1554. oldMap.remove("ID");
  1555. int res = getWaterTapApi().insertOrUpdateTbmHourwaterWatersupply(oldMap);
  1556. if(res<0){
  1557. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1558. , mStrClassName
  1559. , mStrClassName
  1560. ,"修改泵实际状态数据失败");
  1561. }
  1562. }
  1563. }
  1564. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"泵数据实际值修改完成");
  1565. }catch(Exception ex){
  1566. ex.printStackTrace();
  1567. }
  1568. }
  1569. //TODO 定时任务 定时添加预测数据 废弃
  1570. public static void insertYuceDataScheduled(String monthNow){
  1571. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测日数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1572. try {
  1573. //先获取配置项 根据配置项来进行逻辑添加
  1574. List<Map<String, Object>> configRes = getWaterTapWaterApi().getWaterYuceConfig(false, 0, 0, "");
  1575. if(!CollectionUtils.isEmpty(configRes)){
  1576. Map<String,Object> config = configRes.get(0);
  1577. Integer isMonth = Integer.valueOf(config.get("is_month").toString());//是否预测指定月份 0 是 1否(判定是否走自添加逻辑)
  1578. String month = config.get("month").toString();//指定预测年月 yyyy-mm
  1579. Double randomCode = Double.valueOf(config.get("random_code").toString());//上下随机石百分比范围
  1580. if(isMonth==0){
  1581. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  1582. String yearStr = month.split("-")[0];
  1583. String monthStr = month.split("-")[1];
  1584. if(!StringUtils.isEmpty(monthNow)){
  1585. yearStr = monthNow.split("-")[0];
  1586. monthStr = monthNow.split("-")[1];
  1587. }
  1588. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1589. .withMonth(Integer.valueOf(monthStr)).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1590. LocalDateTime endDate = startDate.with(TemporalAdjusters.lastDayOfMonth());
  1591. //TODO 总体逻辑: 先查询指定月上一年的每日平均值,再按平均值的上下啊百分比去插入指定的浮动百分比数据
  1592. List<Map<String, Object>> configList = getWaterTapApi().getWaterCollectionConfigList(null);
  1593. List<Map<String,Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0,"");
  1594. if (!CollectionUtils.isEmpty(configList)&&!CollectionUtils.isEmpty(orgConfig)) {
  1595. //TODO 按照组织机构分组
  1596. Map<Object, List<Map<String, Object>>> groupedData =
  1597. configList.stream().collect(Collectors.groupingBy(item -> item.get("org_name")));
  1598. final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
  1599. for (Object key:groupedData.keySet()){
  1600. try {
  1601. ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
  1602. @Override
  1603. public void function() {
  1604. //TODO ①计算水厂指定月每日平均值
  1605. List<Map<String,Object>> recordAllRes = getWaterTapApi()
  1606. .getWaterCollectionRecordAllListAll(" WHERE 1=1 " +
  1607. " AND org_name = '"+key.toString()+"'" +
  1608. " AND \"time\"::timestamp BETWEEN '"+startDate.format(formatter)+"' "+"AND '"+endDate.format(formatter)+"'");
  1609. if(!CollectionUtils.isEmpty(recordAllRes)){
  1610. int days = YearMonth.from(startDate).lengthOfMonth();//获取月份天数
  1611. Double numAge = 0.0;//日平均值
  1612. Double numMonthAll = null;//月总值
  1613. for (int i = 1;i<=days;i++){
  1614. LocalDateTime dateNow = startDate.withDayOfMonth(i);//当前循环时间
  1615. Double numAll = null;//日总值
  1616. //TODO 筛选成当前循环时间的集合
  1617. List<Map<String,Object>> daysRecord = recordAllRes.stream().filter(item ->
  1618. LocalDateTime.parse(item.get("time").toString(),formatter).toLocalDate().equals(dateNow.toLocalDate()))
  1619. .collect(Collectors.toList());
  1620. for (Map<String,Object> mapEntity : daysRecord){
  1621. //TODO 筛选与当前天一样的数据在计算平均值,数据相加除以24小时 (recordAllRes内容为这天每小时的数据)
  1622. if(numAll == null){
  1623. numAll = 0.0;
  1624. }
  1625. numAll += Double.valueOf(mapEntity.get("value").toString());
  1626. }
  1627. if(numMonthAll==null){
  1628. numMonthAll = 0.0;
  1629. }
  1630. numMonthAll+= numAll==null?0.0:numAll;
  1631. }
  1632. if(numMonthAll!=null){
  1633. numAge = numMonthAll/days;
  1634. }
  1635. //TODO ②正式插入或修改日预测数据表
  1636. Optional<String> orgIdOptional = orgConfig.stream()
  1637. .filter(item -> key.toString().replace("(", "(").replace(")", ")")
  1638. .equals(item.get("org_name").toString().replace("(", "(").replace(")", ")")))
  1639. .map(item -> item.get("org_id").toString())
  1640. .findFirst();
  1641. String orgId = orgIdOptional.orElse(null);
  1642. if (!StringUtils.isEmpty(orgId)) {
  1643. //预测比对时间如果不是今年,则变为今年的时间
  1644. for (int i = 1;i<=days;i++) {
  1645. LocalDateTime dateNow = startDate.withDayOfMonth(i);//当前循环时间
  1646. if(dateNow.isAfter(LocalDateTime.now())){
  1647. break;
  1648. }
  1649. Double numAll = null;//日总值
  1650. //TODO 筛选成当前循环时间的集合
  1651. List<Map<String,Object>> daysRecord = recordAllRes.stream().filter(item ->
  1652. LocalDateTime.parse(item.get("time").toString(),formatter).toLocalDate().equals(dateNow.toLocalDate()))
  1653. .collect(Collectors.toList());
  1654. for (Map<String,Object> mapEntity : daysRecord){
  1655. //TODO 筛选与当前天一样的数据在计算平均值,数据相加除以24小时 (recordAllRes内容为这天每小时的数据)
  1656. if(numAll == null){
  1657. numAll = 0.0;
  1658. }
  1659. numAll += Double.valueOf(mapEntity.get("value").toString());
  1660. }
  1661. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1662. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1663. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1664. // //TODO A
  1665. // JP3TPDay tpDay = new JP3TPDay();
  1666. // tpDay.setOrgId(orgId);
  1667. // tpDay.setSdate(dateStr);
  1668. // tpDay.setEndate(dateStr);
  1669. // try {
  1670. // ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1671. // .applyCloud3tpServiceApi().dayDataPredictSupply(tpDay);
  1672. // if(ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())){
  1673. // LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1674. // , mStrClassName
  1675. // , mStrClassName
  1676. // , String.format("预测日数据"+dateStr+"调用失败 ERROR:{%s} ",
  1677. // tpRes.getResdata()));
  1678. // break;
  1679. // }
  1680. // }catch(Exception ex){
  1681. // LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1682. // , mStrClassName
  1683. // , mStrClassName
  1684. // , String.format("预测日数据"+dateStr+"调用异常 ERROR:{%s} ",
  1685. // ex.getLocalizedMessage()));
  1686. // }
  1687. //TODO B
  1688. Map<String, Object> recordAllEntity = new LinkedHashMap<>();//需要添加的实体数据,此处要用有序map
  1689. recordAllEntity.put("Date", dateStr);
  1690. recordAllEntity.put("Month", dateNow.withYear(LocalDateTime.now().getYear()).getMonth().getValue());
  1691. recordAllEntity.put("Week", dateNow.withYear(LocalDateTime.now().getYear()).getDayOfWeek().getValue());
  1692. // recordAllEntity.put("ActualWaterWithdrawals", "");
  1693. //实际从该时间查询结果中得出(当前年当前日的实际数据)
  1694. String newStartDate = dateNow.withYear(LocalDateTime.now().getYear()).format(formatter);
  1695. String newEndDate = dateNow.withYear(LocalDateTime.now().getYear()).minusDays(-1).minusSeconds(1).format(formatter);
  1696. List<Map<String,Object>> newRecordAllRes = getWaterTapApi()
  1697. .getWaterCollectionRecordAllListAll(" WHERE 1=1 " +
  1698. " AND org_name = '"+key.toString()+"'" +
  1699. " AND \"time\"::timestamp BETWEEN '"+newStartDate
  1700. +"' "+"AND '"+newEndDate+"'");
  1701. String actualWaterSupply = null;
  1702. if(!CollectionUtils.isEmpty(newRecordAllRes)){
  1703. actualWaterSupply = String.valueOf(newRecordAllRes.stream()
  1704. .mapToDouble(record -> {
  1705. Object value = record.get("value");
  1706. if (value instanceof Number) {
  1707. return ((Number) value).doubleValue();
  1708. } else if (value instanceof String) {
  1709. try {
  1710. return Double.parseDouble((String) value);
  1711. } catch (NumberFormatException e) {
  1712. // 处理或记录错误,这里简单返回0
  1713. return 0;
  1714. }
  1715. }
  1716. return 0;
  1717. })
  1718. .sum());
  1719. }
  1720. recordAllEntity.put("ActualWaterSupply", actualWaterSupply);
  1721. // recordAllEntity.put("ForecastWaterWithdrawals", "");
  1722. //TODO 随机数逻辑
  1723. int randomUpOrDown = ThreadLocalRandom.current().nextInt(2);//随机向上或者向下 0表示向下 1表示向上
  1724. Double randomWater = randomUpOrDown == 0 ?
  1725. numAge - (numAge * (randomCode / 100)) :
  1726. numAge + (numAge * (randomCode / 100));
  1727. // recordAllEntity.put("ForecastActualWaterSupply", randomWater);
  1728. recordAllEntity.put("isAbnormal", 0);
  1729. recordAllEntity.put("isForecast", 1);
  1730. recordAllEntity.put("LastModifyTime", LocalDateTime.now().format(formatter));
  1731. // 如果找到了org_id,就将其赋值给orgId,否则orgId为null
  1732. recordAllEntity.put("orgId", orgId);
  1733. //TODO 添加or修改
  1734. Integer insertRes = getWaterTapApi().insertOrUpdateTbmWater(recordAllEntity);
  1735. if (insertRes < 1) {
  1736. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1737. , mStrClassName
  1738. , mStrClassName
  1739. , String.format("Batch insertYuceDataScheduled ERROR:{%s} ",
  1740. "新增或修改失败"));
  1741. }
  1742. }
  1743. }
  1744. }
  1745. latch.countDown();
  1746. }
  1747. });
  1748. }catch(Exception ex){
  1749. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1750. , mStrClassName
  1751. , mStrClassName
  1752. , String.format("Batch insertYuceDataScheduled ERROR:{%s} ",
  1753. ex.getLocalizedMessage()));
  1754. }
  1755. }
  1756. try{latch.await();}catch(Exception ex){}
  1757. }
  1758. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测日数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1759. }else{
  1760. }
  1761. }
  1762. }catch(Exception ex){
  1763. ex.printStackTrace();
  1764. }
  1765. }
  1766. //TODO 定时任务 定时添加小时预测数据 转变为之做假泵数据
  1767. public static void insertYuceHourDataScheduled(String monthNow){
  1768. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测小时数据正在进行"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1769. try {
  1770. //先获取配置项 根据配置项来进行逻辑添加
  1771. List<Map<String, Object>> configRes = getWaterTapWaterApi().getWaterYuceConfig(false, 0, 0, "");
  1772. if(!CollectionUtils.isEmpty(configRes)){
  1773. Map<String,Object> config = configRes.get(0);
  1774. Integer isMonth = Integer.valueOf(config.get("is_month").toString());//是否预测指定月份 0 是 1否(判定是否走自添加逻辑)
  1775. String month = config.get("month").toString();//指定预测年月 yyyy-mm
  1776. Double randomCode = Double.valueOf(config.get("random_code").toString());//上下随机石百分比范围
  1777. if(isMonth==0){
  1778. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  1779. String yearStr = month.split("-")[0];
  1780. String monthStr = month.split("-")[1];
  1781. if(!StringUtils.isEmpty(monthNow)){
  1782. yearStr = monthNow.split("-")[0];
  1783. monthStr = monthNow.split("-")[1];
  1784. }
  1785. LocalDateTime startDate = LocalDateTime.now().withYear(Integer.valueOf(yearStr))
  1786. .withMonth(Integer.valueOf(monthStr)).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
  1787. LocalDateTime endDate = startDate.with(TemporalAdjusters.lastDayOfMonth());
  1788. //TODO 总体逻辑: 先查询指定月上一年的每日平均值,再按平均值的上下啊百分比去插入指定的浮动百分比数据
  1789. List<Map<String, Object>> configList = getWaterTapApi().getWaterCollectionConfigList(null);
  1790. List<Map<String,Object>> orgConfig = getWaterTapWaterApi().getOrgConfig(false,0,0,"");
  1791. if (!CollectionUtils.isEmpty(configList)&&!CollectionUtils.isEmpty(orgConfig)) {
  1792. //TODO 按照组织机构分组
  1793. Map<Object, List<Map<String, Object>>> groupedData =
  1794. configList.stream().collect(Collectors.groupingBy(item -> item.get("org_name")));
  1795. final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
  1796. for (Object key:groupedData.keySet()){
  1797. try {
  1798. ThreadTaskMgr.runTask(new TraceRunnable(TraceLogMgr.getTraceId()) {
  1799. @Override
  1800. public void function() {
  1801. //TODO ①计算水厂指定月每日小时平均值
  1802. List<Map<String,Object>> recordAllRes = getWaterTapApi()
  1803. .getWaterCollectionRecordAllListAll(" WHERE 1=1 " +
  1804. " AND org_name = '"+key.toString()+"'" +
  1805. " AND \"time\"::timestamp BETWEEN '"+startDate.format(formatter)+"' "+"AND '"+endDate.format(formatter)+"'");
  1806. if(!CollectionUtils.isEmpty(recordAllRes)){
  1807. int days = YearMonth.from(startDate).lengthOfMonth();//获取月份天数
  1808. for (int i = 1;i<=days;i++){
  1809. LocalDateTime dateNow = startDate.withDayOfMonth(i);//当前循环时间
  1810. if(dateNow.isAfter(LocalDateTime.now().minusDays(-4))){
  1811. break;
  1812. }
  1813. Double numAll = null;//日总值
  1814. Double numAge = 0.0;//日小时平均值
  1815. //TODO 筛选成当前循环时间的集合
  1816. List<Map<String,Object>> daysRecord = recordAllRes.stream().filter(item ->
  1817. LocalDateTime.parse(item.get("time").toString(),formatter).toLocalDate().equals(dateNow.toLocalDate()))
  1818. .collect(Collectors.toList());
  1819. for (Map<String,Object> mapEntity : daysRecord){
  1820. //TODO 筛选与当前天一样的数据在计算平均值,数据相加除以24小时 (recordAllRes内容为这天每小时的数据)
  1821. if(numAll == null){
  1822. numAll = 0.0;
  1823. }
  1824. numAll += Double.valueOf(mapEntity.get("value").toString());
  1825. }
  1826. if (numAll!=null){
  1827. numAge = numAll/24;
  1828. }
  1829. //TODO ②正式插入或修改日预测数据表
  1830. Optional<String> orgIdOptional = orgConfig.stream()
  1831. .filter(item -> key.toString().replace("(", "(").replace(")", ")")
  1832. .equals(item.get("org_name").toString().replace("(", "(").replace(")", ")")))
  1833. .map(item -> item.get("org_id").toString())
  1834. .findFirst();
  1835. String orgId = orgIdOptional.orElse(null);
  1836. if (!StringUtils.isEmpty(orgId)) {
  1837. //预测比对时间如果不是今年,则变为今年的时间
  1838. //TODO 取泵号
  1839. JSONObject pumpItem = (JSONObject)pumpObj.get(orgId);
  1840. JSONArray pumpArray = ((JSONObject)pumpItem.get("outRoom")).getJSONArray("pumps");
  1841. //TODO 一天24小时
  1842. for (int j = 0;j<24;j++) {
  1843. //TODO 数据库操作 A 调用对应时间预测接口 B 在修改实际值
  1844. DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  1845. DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("HH:mm:ss");
  1846. String dateStr = dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate().format(formatter2);
  1847. // 创建一个LocalTime实例,设置为指定小时,分钟和秒数为0
  1848. LocalTime time = LocalTime.of(j, 0, 0);
  1849. // 创建一个DateTimeFormatter用于格式化时间
  1850. String timeStr = time.format(formatter3);
  1851. // //TODO A
  1852. // JP3TPHour tpHour = new JP3TPHour();
  1853. // tpHour.setOrgId(orgId);
  1854. // tpHour.setDate(dateStr);
  1855. // try {
  1856. // ResponseRes<String> tpRes = ServiceMgrProxy.getInstance()
  1857. // .applyCloud3tpServiceApi().dayHourPredictSupply(tpHour);
  1858. // if(ResponseCode.RESULT_BAD.toStrCode().equals(tpRes.getRescode())){
  1859. // LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1860. // , mStrClassName
  1861. // , mStrClassName
  1862. // , String.format("预测小时数据"+dateStr+"调用失败 ERROR:{%s} ",
  1863. // tpRes.getResdata()));
  1864. // break;
  1865. // }
  1866. // }catch(Exception ex){
  1867. // LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1868. // , mStrClassName
  1869. // , mStrClassName
  1870. // , String.format("预测小时数据"+dateStr+"调用异常 ERROR:{%s} ",
  1871. // ex.getLocalizedMessage()));
  1872. // }
  1873. //TODO B
  1874. Map<String, Object> recordAllEntity = new LinkedHashMap<>();//需要添加的实体数据,此处要用有序map
  1875. recordAllEntity.put("Date", dateStr);
  1876. recordAllEntity.put("Hour", timeStr);
  1877. // recordAllEntity.put("HourForecastWaterWithdrawals", null);
  1878. //TODO 随机数逻辑
  1879. int randomUpOrDown = ThreadLocalRandom.current().nextInt(2);//随机向上或者向下 0表示向下 1表示向上
  1880. Double randomWater = randomUpOrDown == 0 ?
  1881. numAge - (numAge * (randomCode / 100)) :
  1882. numAge + (numAge * (randomCode / 100));
  1883. // recordAllEntity.put("HourForecastActualWaterSupply", randomWater);
  1884. // recordAllEntity.put("HourActualWaterWithdrawals", "");
  1885. //实际从该时间查询结果中得出
  1886. List<Map<String,Object>> newRecordAllRes = getWaterTapApi()
  1887. .getWaterCollectionRecordAllListAll(" WHERE 1=1 " +
  1888. " AND org_name = '"+key.toString()+"'" +
  1889. " AND \"time\" = '"+dateNow.withYear(LocalDateTime.now().getYear()).withHour(j).format(formatter)+"' ");
  1890. String hourActualWaterSupply = null;
  1891. if(!CollectionUtils.isEmpty(newRecordAllRes)){
  1892. hourActualWaterSupply = newRecordAllRes.get(0).get("value").toString();
  1893. }
  1894. recordAllEntity.put("HourActualWaterSupply",hourActualWaterSupply);
  1895. recordAllEntity.put("LastModifyTime", LocalDateTime.now().format(formatter));
  1896. // 如果找到了org_id,就将其赋值给orgId,否则orgId为null
  1897. recordAllEntity.put("orgId", orgId);
  1898. // //TODO 添加or修改
  1899. // Integer insertRes = getWaterTapApi().insertOrUpdateTbmHourWater(recordAllEntity);
  1900. // if (insertRes < 1) {
  1901. // LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1902. // , mStrClassName
  1903. // , mStrClassName
  1904. // , String.format("Batch insertYuceDataScheduled ERROR:{%s} ",
  1905. // "新增或修改失败"));
  1906. // }
  1907. //TODO ③ 泵集合数据添加或修改
  1908. // 生成[1, pumpArray.size()]范围内的随机数
  1909. int randomNum = (int) (Math.random() * (pumpArray.size() - 1)) + 1;
  1910. List<Double> splitRandom = splitValueRandomlyWithZeros(Double.valueOf((hourActualWaterSupply==null
  1911. ?"0.0":hourActualWaterSupply)),pumpArray.size(),randomNum);//实际值随机数集合
  1912. List<Double> splitRandomYuce = splitValueRandomlyWithZeros((randomWater==null
  1913. ?0.0:randomWater),pumpArray.size(),randomNum);//预测值随机数集合
  1914. //泵集合
  1915. int kIndex = 0;
  1916. for (Object obj:pumpArray){
  1917. JSONObject itemObj = (JSONObject)obj;
  1918. Map<String,Object> map = new LinkedHashMap<>();
  1919. //TODO 泵状态根据值是否为0设置
  1920. map.put("Date", dateNow.withYear(LocalDateTime.now().getYear()).toLocalDate()
  1921. .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
  1922. // 创建一个LocalTime实例,设置为指定小时,分钟和秒数为0
  1923. // 创建一个DateTimeFormatter用于格式化时间
  1924. map.put("Hour", time.format(formatter3));
  1925. map.put("PumpID",itemObj.get("label"));
  1926. // 设置1的概率为0.7,0的概率为0.3
  1927. ProbabilityAlgorithm algorithm = new ProbabilityAlgorithm(0.7);
  1928. // if(splitRandom.get(kIndex)==0){
  1929. // //TODO 说明泵实际值为0,状态为关
  1930. // map.put("PumpStatus",0);
  1931. // }else{
  1932. // map.put("PumpStatus",1);
  1933. // }
  1934. // map.put("PumpStatus",algorithm.getNextValue());
  1935. // map.put("HourForecastActualWaterSupply",splitRandomYuce.get(kIndex));//预测泵的供水量/
  1936. // map.put("PumpWater",splitRandom.get(kIndex));//实际泵的供水量
  1937. // if(splitRandom.get(kIndex)==0){
  1938. // //TODO 说明泵实际值为0,状态为关
  1939. // map.put("RealPumpStatus",0);
  1940. // }else{
  1941. // map.put("RealPumpStatus",1);
  1942. // }
  1943. // map.put("RealPumpStatus",algorithm.getNextValue());
  1944. map.put("PumpEnergy",splitRandomYuce.get(kIndex)/1000*180);
  1945. map.put("RealPumpEnergy",splitRandom.get(kIndex)/1000*200);
  1946. // map.put("LastModifyTime", LocalDateTime.now().format(formatter));
  1947. map.put("orgId", orgId);
  1948. //TODO 添加or修改 暂时注释
  1949. Integer insertRes2 = getWaterTapApi().insertOrUpdateTbmHourwaterWatersupply(map);
  1950. if (insertRes2 < 1) {
  1951. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1952. , mStrClassName
  1953. , mStrClassName
  1954. , String.format("Batch insertOrUpdateTbmHourwaterWatersupply ERROR:{%s} ",
  1955. "新增或修改失败"));
  1956. }
  1957. kIndex++;
  1958. }
  1959. }
  1960. }
  1961. }
  1962. }
  1963. latch.countDown();
  1964. }
  1965. });
  1966. }catch(Exception ex){
  1967. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_ERROR
  1968. , mStrClassName
  1969. , mStrClassName
  1970. , String.format("Batch insertYuceDataScheduled ERROR:{%s} ",
  1971. ex.getLocalizedMessage()));
  1972. }
  1973. }
  1974. try{latch.await();}catch(Exception ex){}
  1975. }
  1976. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"添加预测小时数据结束"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
  1977. }else{
  1978. }
  1979. }
  1980. }catch(Exception ex){
  1981. ex.printStackTrace();
  1982. }
  1983. }
  1984. //生成指定份额的随机数,并且带有0值
  1985. public static List<Double> splitValueRandomlyWithZeros(double totalValue, int parts, int zeroCount) {
  1986. if (zeroCount >= parts) {
  1987. throw new IllegalArgumentException("Zero count must be less than the number of parts.");
  1988. }
  1989. Random random = new Random();
  1990. List<Double> points = new ArrayList<>();
  1991. int nonZeroParts = parts - zeroCount;
  1992. // 添加初始点
  1993. points.add(0.0);
  1994. // 生成分割点
  1995. for (int i = 0; i < nonZeroParts - 1; i++) {
  1996. points.add(random.nextDouble() * totalValue);
  1997. }
  1998. // 添加终点
  1999. points.add(totalValue);
  2000. // 排序
  2001. Collections.sort(points);
  2002. // 计算每份的大小
  2003. List<Double> splits = new ArrayList<>();
  2004. for (int i = 1; i < points.size(); i++) {
  2005. splits.add(points.get(i) - points.get(i - 1));
  2006. }
  2007. // 添加0值份额
  2008. for (int i = 0; i < zeroCount; i++) {
  2009. splits.add(0.0);
  2010. }
  2011. // 打乱列表,以确保0值分布均匀
  2012. Collections.shuffle(splits);
  2013. return splits;
  2014. }
  2015. /**
  2016. * TODO 水位预测相关
  2017. */
  2018. //TODO 小时取水量预测接口
  2019. /**
  2020. * 传入水厂id及日期,返回指定日期内的小时取水量预测数据和实际小时取水量数据
  2021. */
  2022. public static ResponseRes selectTbHourLevelList(JPTbLevelHourWater jpTbMHourWater){
  2023. ResponseRes responseRes = new ResponseRes();
  2024. List<Map<String, Object>> list = new ArrayList<>();
  2025. Map<String, Object> map = new HashMap<>();
  2026. map.put("id",null);
  2027. map.put("date",null);
  2028. map.put("hour",null);
  2029. map.put("hour_forecast_actual_level",null);
  2030. map.put("hour_actual_water_level",null);
  2031. map.put("last_modify_time",null);
  2032. map.put("device_code",null);
  2033. map.put("site_id",null);
  2034. map.put("zone_id",null);
  2035. list.add(map);
  2036. responseRes.setResdata(list);
  2037. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  2038. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  2039. try {
  2040. //
  2041. List<Map<String, Object>> resList = getWaterTapWaterApi().getTbLevelHourwater(jpTbMHourWater.getIsPage(),
  2042. jpTbMHourWater.getLimit(), jpTbMHourWater.getOffset(), jpTbMHourWater.getForDateStr());
  2043. if(!CollectionUtils.isEmpty(resList)){
  2044. responseRes.setRescode(ResponseCode.RESULT_NORMAL.toStrCode());
  2045. responseRes.setResmsg(ResponseCode.RESULT_NORMAL.toStrMsg());
  2046. responseRes.setResdata(resList);
  2047. }
  2048. return responseRes;
  2049. }catch(Exception ex){
  2050. responseRes.setResdata(null);
  2051. responseRes.setResmsg(ResponseCode.RESULT_BAD.toStrMsg());
  2052. responseRes.setRescode(ResponseCode.RESULT_BAD.toStrCode());
  2053. return responseRes;
  2054. }
  2055. }
  2056. //TODO 重新计算原始小时数据的用电量
  2057. //TODO 逻辑:有小时读数的 按小时读数去算, 没有的话就按额定功率*1h去作为用电量
  2058. public static void initPumpPowerZero(){
  2059. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  2060. //TODO 首先查询出所有的设备
  2061. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"计算原始小时数据的用电量....");
  2062. List<Map<String, Object>> configList = getWaterTapApi().getWaterPumpCollectionConfigList("");
  2063. List<Map<String, Object>> energyList = getWaterTapApi().getWatertPumpEnergy("");
  2064. if (!CollectionUtils.isEmpty(configList) && !CollectionUtils.isEmpty(energyList)) {
  2065. // 按照设备分组
  2066. Map<Object, List<Map<String, Object>>> groupedData = configList.stream()
  2067. .collect(Collectors.groupingBy(item -> item.get("device_code")));
  2068. final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
  2069. ExecutorService executor = Executors.newFixedThreadPool(groupedData.keySet().size()); // 使用线程池
  2070. for (Object config : groupedData.keySet()) {
  2071. try {
  2072. List<Map<String, Object>> recordAll = getWaterTapApi().getWaterPumpRecordAllListAll(
  2073. "WHERE device_code ='" + config + "' " +
  2074. " AND \"time\"::timestamp BETWEEN '" + LocalDateTime.now().minusDays(2).withHour(0).withMinute(0).withSecond(0).withNano(0).format(formatter) + "' " + "AND '" + LocalDateTime.now().format(formatter) + "'" +
  2075. " ORDER BY time ASC ");
  2076. if (CollectionUtils.isEmpty(recordAll)) {
  2077. continue; // 如果设备没有数据,跳过
  2078. }
  2079. // 遍历 recordAll 中的每条记录
  2080. for (int i = 1; i < recordAll.size(); i++) {
  2081. Map<String, Object> currentRecord = recordAll.get(i);
  2082. Map<String, Object> previousRecord = recordAll.get(i - 1);
  2083. Double currentEnergy = (Double) currentRecord.get("active_energy");
  2084. Double previousEnergy = (Double) previousRecord.get("active_energy");
  2085. double powerConsumption = 0.0;
  2086. if (currentEnergy != null && previousEnergy != null) {
  2087. // 情况1:累计电量读数都非空
  2088. powerConsumption = currentEnergy - previousEnergy;
  2089. } else {
  2090. // 情况2:累计电量读数有一个为空
  2091. String deviceCode = (String) currentRecord.get("device_code");
  2092. Optional<Map<String, Object>> targetMap = energyList.stream()
  2093. .filter(map -> deviceCode.equals(map.get("PumpID"))) // 过滤条件
  2094. .findFirst();
  2095. if (targetMap.isPresent()) {
  2096. Map<String, Object> resultMap = targetMap.get();
  2097. Object ratedPower = resultMap.get(deviceCode);
  2098. if (ratedPower != null) {
  2099. powerConsumption = Double.valueOf(ratedPower.toString()) * 1; // 用电量 = 额定功率 × 1
  2100. } else {
  2101. powerConsumption = 0.0; // 额定功率未找到,用电量为 0
  2102. }
  2103. } else {
  2104. powerConsumption = 500 + (Math.random() - 0.5) * 200; // 额定功率未找到,用电量为 0
  2105. }
  2106. }
  2107. // 更新当前记录的用电量字段
  2108. currentRecord.put("power_cons", powerConsumption);
  2109. int res = getWaterTapApi().insertOrUpdateWaterPumpRecordAll(currentRecord);
  2110. if (res <= 0) {
  2111. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"修改小时用电量失败");
  2112. }
  2113. }
  2114. } catch (Exception ex) {
  2115. }
  2116. }
  2117. LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO,mStrClassName, mStrClassName,"修改小时用电量完成");
  2118. }
  2119. }
  2120. }