GetWeather.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. package com.example.getweather.service;
  2. import cn.hutool.db.Db;
  3. import cn.hutool.db.Entity;
  4. import cn.hutool.http.HttpUtil;
  5. import cn.hutool.json.JSONArray;
  6. import cn.hutool.json.JSONObject;
  7. import cn.hutool.json.JSONUtil;
  8. import com.example.getweather.entity.DistrictCodeDO;
  9. import com.example.getweather.entity.HeFengDay;
  10. import com.example.getweather.util.WeixinPush;
  11. import com.taosdata.jdbc.TSDBDriver;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.validation.annotation.Validated;
  15. import javax.annotation.Resource;
  16. import java.math.BigDecimal;
  17. import java.math.RoundingMode;
  18. import java.sql.Connection;
  19. import java.sql.DriverManager;
  20. import java.sql.Statement;
  21. import java.sql.Timestamp;
  22. import java.time.Instant;
  23. import java.time.ZonedDateTime;
  24. import java.util.*;
  25. import java.util.stream.Collectors;
  26. @Service
  27. @Validated
  28. @Slf4j
  29. public class GetWeather {
  30. @Resource
  31. private WeixinPush weixinPush;
  32. /*public void download() {
  33. List<String> areaCodes = new ArrayList<>();
  34. List<DistrictCodeDO> districtCodeDOList = new ArrayList<>();
  35. try {
  36. List<Entity> dictList = Db.use().findAll("system_dict_data");
  37. for (Entity entity : dictList) {
  38. String name = entity.getStr("label");
  39. if (name.contains("area_code")) {
  40. String code = entity.getStr("value");
  41. String[] s = code.split(",");
  42. areaCodes = Arrays.asList(s);
  43. }
  44. }
  45. List<Entity> districtCodes = Db.use().findAll("jy_district_code");
  46. for (Entity e : districtCodes) {
  47. DistrictCodeDO districtCodeDO = new DistrictCodeDO();
  48. districtCodeDO.setCode(Integer.parseInt(e.getStr("code")));
  49. districtCodeDO.setName(e.getStr("name"));
  50. districtCodeDO.setLevel(Integer.parseInt(e.getStr("level")));
  51. districtCodeDO.setType(Integer.parseInt(e.getStr("type")));
  52. districtCodeDO.setAbname(e.getStr("abname"));
  53. districtCodeDO.setPid(Integer.parseInt(e.getStr("pid")));
  54. districtCodeDO.setLat(!Objects.equals(e.getStr("lat"), "") && e.getStr("lat") != null ? new BigDecimal(e.getStr("lat")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
  55. districtCodeDO.setLng(!Objects.equals(e.getStr("lng"), "") && e.getStr("lng") != null ? new BigDecimal(e.getStr("lng")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
  56. districtCodeDOList.add(districtCodeDO);
  57. }
  58. String jdbcUrl = "jdbc:TAOS://192.168.12.241:19500/etadm_local?user=root&password=qE$#6G0zROoc";
  59. Properties connProps = new Properties();
  60. connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
  61. connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
  62. connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
  63. Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
  64. //省份
  65. for (String code : areaCodes) {
  66. List<DistrictCodeDO> shiList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(code)).collect(Collectors.toList());
  67. //市
  68. for (DistrictCodeDO d : shiList) {
  69. List<DistrictCodeDO> quList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(d.getCode().toString())).collect(Collectors.toList());
  70. log.info("开始下载地区:{} 的天气数据", d.getName());
  71. String hefeng24;
  72. String caiyun24;
  73. String hefengDay;
  74. String caiyunDay;
  75. //!!!!!!!!!!拼的彩云的辐照度!!!!!!!!!!!!!
  76. //和风逐小时数据
  77. hefeng24 = "https://devapi.qweather.com/v7/grid-weather/24h?location=" + d.getLng() + "," + d.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
  78. //彩云逐小时数据
  79. caiyun24 = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + d.getLng() + "," + d.getLat() + "/hourly?hourlysteps=24";
  80. //和风逐日数据
  81. hefengDay = "https://devapi.qweather.com/v7/grid-weather/7d?location=" + d.getLng() + "," + d.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
  82. //彩云逐日数据
  83. caiyunDay = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + d.getLng() + "," + d.getLat() + "/daily?dailysteps=7";
  84. analysis24(hefeng24, caiyun24, d.getCode(), d.getName(), conn);
  85. analysisDay(hefengDay, caiyunDay, d.getCode(), d.getName(), conn);
  86. //区
  87. for (DistrictCodeDO q : quList) {
  88. log.info("开始下载地区:{} 的天气数据", q.getName());
  89. //和风逐小时数据
  90. hefeng24 = "https://devapi.qweather.com/v7/grid-weather/24h?location=" + q.getLng() + "," + q.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
  91. //彩云逐小时数据
  92. caiyun24 = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + q.getLng() + "," + q.getLat() + "/hourly?hourlysteps=24";
  93. //和风逐日数据
  94. hefengDay = "https://devapi.qweather.com/v7/grid-weather/7d?location=" + q.getLng() + "," + q.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
  95. //彩云逐日数据
  96. caiyunDay = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + q.getLng() + "," + q.getLat() + "/daily?dailysteps=7";
  97. analysis24(hefeng24, caiyun24, q.getCode(), q.getName(), conn);
  98. analysisDay(hefengDay, caiyunDay, q.getCode(), q.getName(), conn);
  99. }
  100. }
  101. }
  102. conn.close();
  103. log.info("天气数据全部下载完毕");
  104. } catch (Exception e) {
  105. e.printStackTrace();
  106. }
  107. }*/
  108. /**
  109. * 根据风速获取对应风力等级
  110. * 2025-01-09 改为km/h单位
  111. *
  112. * @param speed 风速,单位为 km/h
  113. * @return 风力等级
  114. */
  115. public static int speedLevel(String speed) {
  116. BigDecimal val = new BigDecimal(speed);
  117. //<0.3 无风 0级
  118. if (val.compareTo(new BigDecimal("1")) < 0) {
  119. return 0;
  120. } else if (val.compareTo(new BigDecimal("6")) < 0) {
  121. //0.3-1.6 微风徐徐 1级
  122. return 1;
  123. } else if (val.compareTo(new BigDecimal("12")) < 0) {
  124. //1.6-3.4 清风 2级
  125. return 2;
  126. } else if (val.compareTo(new BigDecimal("20")) < 0) {
  127. //3.4-5.5 树叶摇摆 3级
  128. return 3;
  129. } else if (val.compareTo(new BigDecimal("29")) < 0) {
  130. //5.5-8.0 树枝摇动 4级
  131. return 4;
  132. } else if (val.compareTo(new BigDecimal("39")) < 0) {
  133. //8.0-10.8 风吹折小树 5级
  134. return 5;
  135. } else if (val.compareTo(new BigDecimal("50")) < 0) {
  136. //10.8-13.9 树枝折断 6级
  137. return 6;
  138. } else if (val.compareTo(new BigDecimal("62")) < 0) {
  139. //13.9-17.2 风吹倒树木 7级
  140. return 7;
  141. } else if (val.compareTo(new BigDecimal("75")) < 0) {
  142. //17.2-20.8 风吹断大树 8级
  143. return 8;
  144. } else if (val.compareTo(new BigDecimal("89")) < 0) {
  145. //20.8-24.5 强风 9级
  146. return 9;
  147. } else if (val.compareTo(new BigDecimal("103")) < 0) {
  148. //24.5-28.5 狂风 10级
  149. return 10;
  150. } else if (val.compareTo(new BigDecimal("117")) < 0) {
  151. //28.5-32.7 暴风 11级
  152. return 11;
  153. } else if (val.compareTo(new BigDecimal("134")) < 0) {
  154. //32.7-37.0 大暴风 12级
  155. return 12;
  156. } else if (val.compareTo(new BigDecimal("150")) < 0) {
  157. //37.0-41.5 飓风 13级
  158. return 13;
  159. } else if (val.compareTo(new BigDecimal("167")) < 0) {
  160. //41.5-46.2 强飓风 14级
  161. return 14;
  162. } else if (val.compareTo(new BigDecimal("184")) < 0) {
  163. //46.2-50.9 猛烈飓风 15级
  164. return 15;
  165. } else if (val.compareTo(new BigDecimal("202")) < 0) {
  166. //50.9-56.1 毁灭性飓风 16级
  167. return 16;
  168. } else {
  169. //56.1-61.3 超级飓风 17级
  170. return 17;
  171. }
  172. }
  173. public void download() {
  174. List<String> areaCodes = new ArrayList<>();
  175. List<DistrictCodeDO> districtCodeDOList = new ArrayList<>();
  176. boolean isApiQuotaExhausted = false; // 引入标志变量
  177. try {
  178. List<Entity> dictList = Db.use().findAll("system_dict_data");
  179. for (Entity entity : dictList) {
  180. String name = entity.getStr("label");
  181. if (name.contains("area_code")) {
  182. String code = entity.getStr("value");
  183. String[] s = code.split(",");
  184. areaCodes = Arrays.asList(s);
  185. }
  186. }
  187. List<Entity> districtCodes = Db.use().findAll("jy_district_code");
  188. for (Entity e : districtCodes) {
  189. DistrictCodeDO districtCodeDO = new DistrictCodeDO();
  190. districtCodeDO.setCode(Integer.parseInt(e.getStr("code")));
  191. districtCodeDO.setName(e.getStr("name"));
  192. districtCodeDO.setLevel(Integer.parseInt(e.getStr("level")));
  193. districtCodeDO.setType(Integer.parseInt(e.getStr("type")));
  194. districtCodeDO.setAbname(e.getStr("abname"));
  195. districtCodeDO.setPid(Integer.parseInt(e.getStr("pid")));
  196. districtCodeDO.setLat(!Objects.equals(e.getStr("lat"), "") && e.getStr("lat") != null ? new BigDecimal(e.getStr("lat")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
  197. districtCodeDO.setLng(!Objects.equals(e.getStr("lng"), "") && e.getStr("lng") != null ? new BigDecimal(e.getStr("lng")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
  198. districtCodeDOList.add(districtCodeDO);
  199. }
  200. String jdbcUrl = "jdbc:TAOS://192.168.12.241:19500/etadm_local?user=root&password=qE$#6G0zROoc";
  201. Properties connProps = new Properties();
  202. connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
  203. connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
  204. connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
  205. Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
  206. //省份
  207. for (String code : areaCodes) {
  208. if (isApiQuotaExhausted) break; // 检查标志变量
  209. List<DistrictCodeDO> shiList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(code)).collect(Collectors.toList());
  210. //市
  211. for (DistrictCodeDO d : shiList) {
  212. if (isApiQuotaExhausted) break; // 检查标志变量
  213. List<DistrictCodeDO> quList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(d.getCode().toString())).collect(Collectors.toList());
  214. String caiyun;
  215. //彩云综合数据查询
  216. caiyun = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + d.getLng() + "," + d.getLat() + "/weather?alert=true&dailysteps=7&hourlysteps=72";
  217. isApiQuotaExhausted = analysis(caiyun, d.getCode(), d.getName(), conn); // 传递标志变量
  218. if (isApiQuotaExhausted) break; // 检查标志变量
  219. //区
  220. for (DistrictCodeDO q : quList) {
  221. if (isApiQuotaExhausted) break; // 检查标志变量
  222. caiyun = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + q.getLng() + "," + q.getLat() + "/weather?alert=true&dailysteps=7&hourlysteps=72";
  223. isApiQuotaExhausted = analysis(caiyun, q.getCode(), q.getName(), conn); // 传递标志变量
  224. if (isApiQuotaExhausted) break; // 检查标志变量
  225. //线程睡5秒 防止请求过快
  226. Thread.sleep(5000);
  227. }
  228. }
  229. }
  230. conn.close();
  231. String alarm = "电力交易系统在获取日级天气数据时报错, 彩云天气API 额度已用尽";
  232. String description = "接口调用异常";
  233. if (isApiQuotaExhausted) {
  234. //给企业微信发送消息
  235. /* WeixinPush weixinPush = new WeixinPush();
  236. WeixinMessage weixinMessage = new WeixinMessage();
  237. weixinMessage.setToUser("WangHongChen|XiuWei|DouZhi");
  238. //获取今天的ymd
  239. String ymd = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
  240. weixinMessage.setContent(ymd + "日 电力交易系统在获取天气数据时报错, 彩云天气API 额度已用尽");
  241. weixinMessage.setMsgType("text");
  242. weixinMessage.setAgentid(1000009); // 确保 agentid 正确
  243. weixinPush.sendMessage(weixinMessage);
  244. */
  245. weixinPush.sendMessageBot(alarm, description);
  246. } else {
  247. alarm = "电力交易系统彩云天气数据全部下载完毕";
  248. description = "接口调用成功";
  249. weixinPush.sendMessageBot(alarm, description);
  250. log.info("彩云天气数据全部下载完毕");
  251. }
  252. } catch (Exception e) {
  253. e.printStackTrace();
  254. }
  255. }
  256. /*public void analysis24(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
  257. try {
  258. Statement ps = conn.createStatement();
  259. String caiyunBody = HttpUtil.createGet(caiyun24url).execute().charset("utf-8").body();
  260. JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
  261. JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
  262. JSONObject hourly = JSONUtil.parseObj(caiyunResult.get("hourly"));
  263. JSONArray dswrf = JSONUtil.parseArray(hourly.get("dswrf"));
  264. String hefengBody = HttpUtil.createGet(hefeng24url).execute().charset("utf-8").body();
  265. JSONObject jsonObject = JSONUtil.parseObj(hefengBody);
  266. JSONArray hefengList = JSONUtil.parseArray(jsonObject.get("hourly"));
  267. List<HeFengHour> list = new ArrayList<>();
  268. hefengList.forEach(item -> {
  269. JSONObject jsonObject1 = JSONUtil.parseObj(item);
  270. try {
  271. HeFengHour weather = new HeFengHour();
  272. String s = jsonObject1.getStr("fxTime");
  273. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmXXX");
  274. ZonedDateTime zonedDateTime = ZonedDateTime.parse(s, formatter);
  275. Instant instant = zonedDateTime.toInstant();
  276. Timestamp timestamp = Timestamp.from(instant);
  277. weather.setTs(timestamp);
  278. weather.setTemp(new BigDecimal(jsonObject1.getStr("temp")).floatValue());
  279. weather.setAreaCode(String.valueOf(areaCode));
  280. weather.setText(jsonObject1.getStr("text"));
  281. weather.setWindDir(jsonObject1.getStr("windDir"));
  282. weather.setWind360(new BigDecimal(jsonObject1.getStr("wind360")).floatValue());
  283. weather.setWindSpeed(new BigDecimal(jsonObject1.getStr("windSpeed")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
  284. weather.setWindScale(new BigDecimal(jsonObject1.getStr("windScale")).floatValue());
  285. weather.setHumidity(new BigDecimal(jsonObject1.getStr("humidity")).floatValue());
  286. weather.setCloud(new BigDecimal(jsonObject1.getStr("cloud")).floatValue());
  287. weather.setPrecip(new BigDecimal(jsonObject1.getStr("precip")).floatValue());
  288. weather.setDew(new BigDecimal(jsonObject1.getStr("dew")).floatValue());
  289. weather.setPressure(new BigDecimal(jsonObject1.getStr("pressure")).floatValue());
  290. list.add(weather);
  291. } catch (Exception e) {
  292. throw new RuntimeException(e);
  293. }
  294. });
  295. if (!dswrf.isEmpty()) {
  296. if (list.size() != 24) {
  297. log.error("地区:{} 24小时天气数据下载失败,和风天气数据不全", name);
  298. } else {
  299. if (dswrf.size() != 24) {
  300. log.error("地区:{} 24小时天气数据下载失败,心知天气数据不全", name);
  301. } else {
  302. for (int i = 0; i < 24; i++) {
  303. Map ds = (Map) dswrf.get(i);
  304. list.get(i).setDswrf(new BigDecimal(ds.get("value").toString()).floatValue());
  305. }
  306. }
  307. }
  308. }
  309. for (HeFengHour item : list) {
  310. String insertSql = " INSERT INTO hefeng_hour_unit_" + areaCode + " USING hefeng_hour_unit TAGS('" + areaCode + "') values('" + item.getTs() + "', " + item.getTemp() + ", '" + item.getText() + "', '" + item.getWindDir() + "', " + item.getWind360() + ", " + item.getWindSpeed() + ", " + item.getWindScale() + ", " + item.getHumidity() + ", " + item.getCloud() + ", " + item.getPrecip() + ", " + item.getDew() + ", " + item.getPressure() + ", " + item.getDswrf() + ")";
  311. int affectedRows = ps.executeUpdate(insertSql);
  312. }
  313. if (ps != null)
  314. ps.close();
  315. } catch (Exception e) {
  316. log.error("地区:{} 24小时天气数据下载失败JSON格式化错误", name);
  317. }
  318. log.info("地区:{} 24小时天气数据下载完成", name);
  319. }
  320. public void analysisDay(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
  321. try {
  322. Statement ps = conn.createStatement();
  323. String caiyunBody = HttpUtil.createGet(caiyun24url).execute().charset("utf-8").body();
  324. JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
  325. JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
  326. JSONObject daily = JSONUtil.parseObj(caiyunResult.get("daily"));
  327. JSONArray dswrf = JSONUtil.parseArray(daily.get("dswrf"));
  328. String hefengBody = HttpUtil.createGet(hefeng24url).execute().charset("utf-8").body();
  329. JSONObject jsonObject = JSONUtil.parseObj(hefengBody);
  330. JSONArray hefengList = JSONUtil.parseArray(jsonObject.get("daily"));
  331. List<HeFengDay> list = new ArrayList<>();
  332. hefengList.forEach(item -> {
  333. JSONObject jsonObject1 = JSONUtil.parseObj(item);
  334. try {
  335. HeFengDay weather = new HeFengDay();
  336. String s = jsonObject1.getStr("fxDate");
  337. LocalDate localDate = LocalDate.parse(s);
  338. // 将 LocalDate 转换为 Instant,然后再转换为 Timestamp
  339. Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay(ZoneOffset.UTC).toLocalDateTime());
  340. weather.setTs(timestamp);
  341. weather.setAreaCode(String.valueOf(areaCode));
  342. weather.setTempMax(new BigDecimal(jsonObject1.getStr("tempMax")).floatValue());
  343. weather.setTempMin(new BigDecimal(jsonObject1.getStr("tempMin")).floatValue());
  344. weather.setTextDay(jsonObject1.getStr("textDay"));
  345. weather.setTextNight(jsonObject1.getStr("textNight"));
  346. weather.setWind360Day(new BigDecimal(jsonObject1.getStr("wind360Day")).floatValue());
  347. weather.setWind360Night(new BigDecimal(jsonObject1.getStr("wind360Night")).floatValue());
  348. weather.setWindDirDay(jsonObject1.getStr("windDirDay"));
  349. weather.setWindDirNight(jsonObject1.getStr("windDirNight"));
  350. weather.setWindScaleDay(new BigDecimal(jsonObject1.getStr("windScaleDay")).floatValue());
  351. weather.setWindScaleNight(new BigDecimal(jsonObject1.getStr("windScaleNight")).floatValue());
  352. weather.setWindSpeedDay(new BigDecimal(jsonObject1.getStr("windSpeedDay")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
  353. weather.setWindSpeedNight(new BigDecimal(jsonObject1.getStr("windSpeedNight")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
  354. weather.setHumidity(new BigDecimal(jsonObject1.getStr("humidity")).floatValue());
  355. weather.setPrecip(new BigDecimal(jsonObject1.getStr("precip")).floatValue());
  356. weather.setPressure(new BigDecimal(jsonObject1.getStr("pressure")).floatValue());
  357. list.add(weather);
  358. } catch (Exception e) {
  359. throw new RuntimeException(e);
  360. }
  361. });
  362. if (!dswrf.isEmpty()) {
  363. if (list.size() != 7) {
  364. log.error("地区:{} 日天气数据下载失败,和风天气数据不全", name);
  365. } else {
  366. for (HeFengDay heFengDay : list) {
  367. Map ds = (Map) dswrf.get(0);
  368. heFengDay.setDswrf(new BigDecimal(ds.get("max").toString()).floatValue());
  369. }
  370. }
  371. }
  372. for (HeFengDay item : list) {
  373. String insertSQL = "INSERT INTO hefeng_day_unit_" + item.getAreaCode() + " USING hefeng_day_unit TAGS('" + item.getAreaCode() + "') values('" + item.getTs() + "', " + item.getTempMax() + ", " + item.getTempMin() + ", '" + item.getTextDay() + "', '" + item.getTextNight() + "', " + item.getWind360Day() + ", '" + item.getWindDirDay() + "', " + item.getWindScaleDay() + ", " + item.getWindSpeedDay() + ", " + item.getWind360Night() + ", '" + item.getWindDirNight() + "', " + item.getWindScaleNight() + ", " + item.getWindSpeedNight() + ", " + item.getHumidity() + ", " + item.getPrecip() + ", " + item.getPressure() + ", " + item.getDswrf() + ")";
  374. int affectedRows = ps.executeUpdate(insertSQL);
  375. }
  376. if (ps != null)
  377. ps.close();
  378. } catch (Exception e) {
  379. log.error("地区:{} 日天气数据下载失败JSON格式化错误", name);
  380. }
  381. log.info("地区:{} 日天气数据下载完成", name);
  382. }*/
  383. public boolean analysis(String caiyun, int areaCode, String name, Connection conn) {
  384. log.info("开始下载地区:{} 的天气数据", name);
  385. try {
  386. Statement ps = conn.createStatement();
  387. String caiyunBody = HttpUtil.createGet(caiyun).execute().charset("utf-8").body();
  388. JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
  389. if (caiyunjsonObject.toString().contains("API quota is exhausted")) {
  390. return true;
  391. }
  392. JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
  393. //小时数据 72小时
  394. /*JSONObject hourly = JSONUtil.parseObj(caiyunResult.get("hourly"));
  395. //小时->温度
  396. JSONArray temperature = JSONUtil.parseArray(hourly.get("temperature"));
  397. //小时->辐照度
  398. JSONArray dswrf = JSONUtil.parseArray(hourly.get("dswrf"));
  399. //小时->风速
  400. JSONArray windSpeed = JSONUtil.parseArray(hourly.get("wind"));
  401. //小时->天气标识
  402. JSONArray skyconHour = JSONUtil.parseArray(hourly.get("skycon"));
  403. //小时->湿度
  404. JSONArray humidityHour = JSONUtil.parseArray(hourly.get("humidity"));
  405. //小时->压强
  406. JSONArray pressureHour = JSONUtil.parseArray(hourly.get("pressure"));*/
  407. //日数据 7d
  408. JSONObject daily = JSONUtil.parseObj(caiyunResult.get("daily"));
  409. //日->辐照度
  410. JSONArray dswrfDay = JSONUtil.parseArray(daily.get("dswrf"));
  411. //日->温度
  412. JSONArray temperatureDay = JSONUtil.parseArray(daily.get("temperature"));
  413. //日->风速 8点到20点
  414. JSONArray windSpeed8Day = JSONUtil.parseArray(daily.get("wind_08h_20h"));
  415. //日->风速 20点到32点
  416. JSONArray windSpeed20Day = JSONUtil.parseArray(daily.get("wind_20h_32h"));
  417. //日->天气描述 8点到20点
  418. JSONArray skycon8 = JSONUtil.parseArray(daily.get("skycon_08h_20h"));
  419. //日->天气描述 20点到32点
  420. JSONArray skycon20 = JSONUtil.parseArray(daily.get("skycon_20h_32h"));
  421. //小时数据写入。 时间 风速 辐照度
  422. /*List<HeFengHour> heFengHourList = new ArrayList<>();
  423. if (windSpeed.size() == 72 && dswrf.size() == 72 && temperature.size() == 72) {
  424. for (int i = 0; i < windSpeed.size(); i++) {
  425. String time = ((JSONObject) windSpeed.get(i)).get("datetime").toString();
  426. HeFengHour heFengHour = new HeFengHour();
  427. heFengHour.setTs(getTimestamp(time));
  428. heFengHour.setWindSpeed(new BigDecimal(((JSONObject) windSpeed.get(i)).get("speed").toString()).floatValue());
  429. heFengHour.setWindSpeedM(new BigDecimal(((JSONObject) windSpeed.get(i)).get("speed").toString()).floatValue() * 1000 / 3600);
  430. heFengHour.setWindScale(speedLevel(((JSONObject) windSpeed.get(i)).get("speed").toString()));
  431. heFengHour.setWind360(new BigDecimal(((JSONObject) windSpeed.get(i)).get("direction").toString()).floatValue());
  432. heFengHour.setHumidity(new BigDecimal(((JSONObject) humidityHour.get(i)).get("value").toString()).floatValue());
  433. heFengHour.setPressure(new BigDecimal(((JSONObject) pressureHour.get(i)).get("value").toString()).floatValue());
  434. heFengHour.setText(skycon(((JSONObject) skyconHour.get(i)).get("value").toString()));
  435. heFengHour.setDswrf(new BigDecimal(((JSONObject) dswrf.get(i)).get("value").toString()).floatValue());
  436. heFengHour.setTemp(new BigDecimal(((JSONObject) temperature.get(i)).get("value").toString()).floatValue());
  437. heFengHourList.add(heFengHour);
  438. }
  439. } else {
  440. log.info("{} 的彩云小时数据不足72小时,不入库!", name);
  441. }*/
  442. //日数据写入
  443. List<HeFengDay> heFengDayList = new ArrayList<>();
  444. if (windSpeed8Day.size() == 7 && windSpeed20Day.size() == 7 && skycon8.size() == 7 && skycon20.size() == 7 && dswrfDay.size() == 7 & temperatureDay.size() == 7) {
  445. for (int i = 0; i < windSpeed8Day.size(); i++) {
  446. String time = ((JSONObject) windSpeed8Day.get(i)).get("date").toString();
  447. //白天风速
  448. Map windspeedDay = (Map) ((JSONObject) windSpeed8Day.get(i)).get("avg");
  449. String windspeedDay1 = windspeedDay.get("speed").toString();
  450. //白天风向
  451. String wind360Day1 = windspeedDay.get("direction").toString();
  452. //夜间风速
  453. Map windspeedNight = (Map) ((JSONObject) windSpeed20Day.get(i)).get("avg");
  454. String windspeedNight1 = windspeedNight.get("speed").toString();
  455. String wind360Night1 = windspeedNight.get("direction").toString();
  456. //辐照度
  457. String dswrf1 = ((JSONObject) dswrfDay.get(i)).get("avg").toString();
  458. //白天天气
  459. String skycon = ((JSONObject) skycon8.get(i)).get("value").toString();
  460. //夜间天气
  461. String skyconN = ((JSONObject) skycon20.get(i)).get("value").toString();
  462. //最高温度
  463. String temperatureMax = ((JSONObject) temperatureDay.get(i)).get("max").toString();
  464. //最低温度
  465. String temperatureMin = ((JSONObject) temperatureDay.get(i)).get("min").toString();
  466. HeFengDay heFengDay = new HeFengDay();
  467. heFengDay.setTs(getTimestamp(time));
  468. heFengDay.setWindSpeedDay(new BigDecimal(windspeedDay1).floatValue());
  469. heFengDay.setWindSpeedMDay(new BigDecimal(windspeedDay1).floatValue() * 1000 / 3600);
  470. heFengDay.setWind360Day(new BigDecimal(wind360Day1).floatValue());
  471. heFengDay.setWindScaleDay(speedLevel(windspeedDay1));
  472. heFengDay.setWindSpeedNight(new BigDecimal(windspeedNight1).floatValue());
  473. heFengDay.setWindSpeedMNight(new BigDecimal(windspeedNight1).floatValue() * 1000 / 3600);
  474. heFengDay.setWind360Night(new BigDecimal(wind360Night1).floatValue());
  475. heFengDay.setWindScaleNight(speedLevel(windspeedNight1));
  476. heFengDay.setDswrf(new BigDecimal(dswrf1).floatValue());
  477. heFengDay.setTextDay(skycon(skycon));
  478. heFengDay.setTextNight(skycon(skyconN));
  479. heFengDay.setTempMax(new BigDecimal(temperatureMax).floatValue());
  480. heFengDay.setTempMin(new BigDecimal(temperatureMin).floatValue());
  481. heFengDayList.add(heFengDay);
  482. }
  483. } else {
  484. log.info("{} 的彩云日数据不足7天,不入库!", name);
  485. }
  486. /*for (HeFengHour item : heFengHourList) {
  487. String insertSql = " INSERT INTO hefeng_hour_unit_" + areaCode + " USING hefeng_hour_unit TAGS('" + areaCode + "') values('" + item.getTs() + "', " + item.getTemp() + ", '" + item.getText() + "', '" + item.getWindDir() + "', " + item.getWind360() + ", " + item.getWindSpeed() + ", " + item.getWindScale() + ", " + item.getHumidity() + ", " + item.getCloud() + ", " + item.getPrecip() + ", " + item.getDew() + ", " + item.getPressure() + ", " + item.getDswrf() +", " + item.getWindSpeedM()+ ")";
  488. int affectedRows = ps.executeUpdate(insertSql);
  489. }*/
  490. for (HeFengDay item : heFengDayList) {
  491. String insertSQL = "INSERT INTO hefeng_day_unit_" + areaCode + " USING hefeng_day_unit TAGS('" + areaCode + "') values('" + item.getTs() + "', " + item.getTempMax() + ", " + item.getTempMin() + ", '" + item.getTextDay() + "', '" + item.getTextNight() + "', " + item.getWind360Day() + ", '" + item.getWindDirDay() + "', " + item.getWindScaleDay() + ", " + item.getWindSpeedDay() + ", " + item.getWind360Night() + ", '" + item.getWindDirNight() + "', " + item.getWindScaleNight() + ", " + item.getWindSpeedNight() + ", " + item.getHumidity() + ", " + item.getPrecip() + ", " + item.getPressure() + ", " + item.getDswrf() + ", " + item.getWindSpeedMDay() + ", " + item.getWindSpeedMNight() + ")";
  492. int affectedRows = ps.executeUpdate(insertSQL);
  493. }
  494. if (ps != null)
  495. ps.close();
  496. } catch (Exception e) {
  497. log.error("彩云天气,地区:{} 日天气数据下载失败JSON格式化错误", name);
  498. return true;
  499. }
  500. log.info("彩云天气,地区:{} 日天气数据下载完成", name);
  501. return false;
  502. }
  503. private Timestamp getTimestamp(String time) {
  504. // 解析字符串为 ZonedDateTime
  505. ZonedDateTime zonedDateTime = ZonedDateTime.parse(time);
  506. // 将 ZonedDateTime 转换为 Instant
  507. Instant instant = zonedDateTime.toInstant();
  508. // 将 Instant 转换为 Timestamp
  509. return Timestamp.from(instant);
  510. }
  511. /**
  512. * 根据代码获取对应天气描述
  513. *
  514. * @param skycon
  515. * @return
  516. */
  517. private String skycon(String skycon) {
  518. switch (skycon) {
  519. case "CLEAR_DAY":
  520. case "CLEAR_NIGHT":
  521. return "晴";
  522. case "PARTLY_CLOUDY_DAY":
  523. case "PARTLY_CLOUDY_NIGHT":
  524. return "多云";
  525. case "CLOUDY":
  526. return "阴";
  527. case "LIGHT_HAZE":
  528. return "轻度雾霾";
  529. case "MODERATE_HAZE":
  530. return "中度雾霾";
  531. case "HEAVY_HAZE":
  532. return "重度雾霾";
  533. case "LIGHT_RAIN":
  534. return "小雨";
  535. case "MODERATE_RAIN":
  536. return "中雨";
  537. case "HEAVY_RAIN":
  538. return "大雨";
  539. case "STORM_RAIN":
  540. return "暴雨";
  541. case "FOG":
  542. return "雾";
  543. case "LIGHT_SNOW":
  544. return "小雪";
  545. case "MODERATE_SNOW":
  546. return "中雪";
  547. case "HEAVY_SNOW":
  548. return "大雪";
  549. case "STORM_SNOW":
  550. return "暴雪";
  551. case "DUST":
  552. return "浮尘";
  553. case "SAND":
  554. return "沙尘";
  555. case "WIND":
  556. return "大风";
  557. }
  558. return "晴";
  559. }
  560. }