KprAimWaterCollecationBizFun.java 135 KB

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