GetWeather.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  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:29500/etadm_local?user=root&password=taosdata";
  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:29500/etadm_local?user=root&password=taosdata";
  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. //花钱了 硬气 不管他
  227. //Thread.sleep(5000);
  228. }
  229. }
  230. }
  231. conn.close();
  232. String alarm = "电力交易系统在获取日级天气数据时报错, 彩云天气API 额度已用尽";
  233. String description = "接口调用异常";
  234. if (isApiQuotaExhausted) {
  235. //给企业微信发送消息
  236. /* WeixinPush weixinPush = new WeixinPush();
  237. WeixinMessage weixinMessage = new WeixinMessage();
  238. weixinMessage.setToUser("WangHongChen|XiuWei|DouZhi");
  239. //获取今天的ymd
  240. String ymd = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
  241. weixinMessage.setContent(ymd + "日 电力交易系统在获取天气数据时报错, 彩云天气API 额度已用尽");
  242. weixinMessage.setMsgType("text");
  243. weixinMessage.setAgentid(1000009); // 确保 agentid 正确
  244. weixinPush.sendMessage(weixinMessage);
  245. */
  246. weixinPush.sendMessageBot(alarm, description);
  247. } else {
  248. alarm = "电力交易系统彩云天气数据全部下载完毕";
  249. description = "接口调用成功";
  250. weixinPush.sendMessageBot(alarm, description);
  251. log.info("彩云天气数据全部下载完毕");
  252. }
  253. } catch (Exception e) {
  254. e.printStackTrace();
  255. }
  256. }
  257. /*public void analysis24(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
  258. try {
  259. Statement ps = conn.createStatement();
  260. String caiyunBody = HttpUtil.createGet(caiyun24url).execute().charset("utf-8").body();
  261. JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
  262. JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
  263. JSONObject hourly = JSONUtil.parseObj(caiyunResult.get("hourly"));
  264. JSONArray dswrf = JSONUtil.parseArray(hourly.get("dswrf"));
  265. String hefengBody = HttpUtil.createGet(hefeng24url).execute().charset("utf-8").body();
  266. JSONObject jsonObject = JSONUtil.parseObj(hefengBody);
  267. JSONArray hefengList = JSONUtil.parseArray(jsonObject.get("hourly"));
  268. List<HeFengHour> list = new ArrayList<>();
  269. hefengList.forEach(item -> {
  270. JSONObject jsonObject1 = JSONUtil.parseObj(item);
  271. try {
  272. HeFengHour weather = new HeFengHour();
  273. String s = jsonObject1.getStr("fxTime");
  274. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmXXX");
  275. ZonedDateTime zonedDateTime = ZonedDateTime.parse(s, formatter);
  276. Instant instant = zonedDateTime.toInstant();
  277. Timestamp timestamp = Timestamp.from(instant);
  278. weather.setTs(timestamp);
  279. weather.setTemp(new BigDecimal(jsonObject1.getStr("temp")).floatValue());
  280. weather.setAreaCode(String.valueOf(areaCode));
  281. weather.setText(jsonObject1.getStr("text"));
  282. weather.setWindDir(jsonObject1.getStr("windDir"));
  283. weather.setWind360(new BigDecimal(jsonObject1.getStr("wind360")).floatValue());
  284. weather.setWindSpeed(new BigDecimal(jsonObject1.getStr("windSpeed")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
  285. weather.setWindScale(new BigDecimal(jsonObject1.getStr("windScale")).floatValue());
  286. weather.setHumidity(new BigDecimal(jsonObject1.getStr("humidity")).floatValue());
  287. weather.setCloud(new BigDecimal(jsonObject1.getStr("cloud")).floatValue());
  288. weather.setPrecip(new BigDecimal(jsonObject1.getStr("precip")).floatValue());
  289. weather.setDew(new BigDecimal(jsonObject1.getStr("dew")).floatValue());
  290. weather.setPressure(new BigDecimal(jsonObject1.getStr("pressure")).floatValue());
  291. list.add(weather);
  292. } catch (Exception e) {
  293. throw new RuntimeException(e);
  294. }
  295. });
  296. if (!dswrf.isEmpty()) {
  297. if (list.size() != 24) {
  298. log.error("地区:{} 24小时天气数据下载失败,和风天气数据不全", name);
  299. } else {
  300. if (dswrf.size() != 24) {
  301. log.error("地区:{} 24小时天气数据下载失败,心知天气数据不全", name);
  302. } else {
  303. for (int i = 0; i < 24; i++) {
  304. Map ds = (Map) dswrf.get(i);
  305. list.get(i).setDswrf(new BigDecimal(ds.get("value").toString()).floatValue());
  306. }
  307. }
  308. }
  309. }
  310. for (HeFengHour item : list) {
  311. 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() + ")";
  312. int affectedRows = ps.executeUpdate(insertSql);
  313. }
  314. if (ps != null)
  315. ps.close();
  316. } catch (Exception e) {
  317. log.error("地区:{} 24小时天气数据下载失败JSON格式化错误", name);
  318. }
  319. log.info("地区:{} 24小时天气数据下载完成", name);
  320. }
  321. public void analysisDay(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
  322. try {
  323. Statement ps = conn.createStatement();
  324. String caiyunBody = HttpUtil.createGet(caiyun24url).execute().charset("utf-8").body();
  325. JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
  326. JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
  327. JSONObject daily = JSONUtil.parseObj(caiyunResult.get("daily"));
  328. JSONArray dswrf = JSONUtil.parseArray(daily.get("dswrf"));
  329. String hefengBody = HttpUtil.createGet(hefeng24url).execute().charset("utf-8").body();
  330. JSONObject jsonObject = JSONUtil.parseObj(hefengBody);
  331. JSONArray hefengList = JSONUtil.parseArray(jsonObject.get("daily"));
  332. List<HeFengDay> list = new ArrayList<>();
  333. hefengList.forEach(item -> {
  334. JSONObject jsonObject1 = JSONUtil.parseObj(item);
  335. try {
  336. HeFengDay weather = new HeFengDay();
  337. String s = jsonObject1.getStr("fxDate");
  338. LocalDate localDate = LocalDate.parse(s);
  339. // 将 LocalDate 转换为 Instant,然后再转换为 Timestamp
  340. Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay(ZoneOffset.UTC).toLocalDateTime());
  341. weather.setTs(timestamp);
  342. weather.setAreaCode(String.valueOf(areaCode));
  343. weather.setTempMax(new BigDecimal(jsonObject1.getStr("tempMax")).floatValue());
  344. weather.setTempMin(new BigDecimal(jsonObject1.getStr("tempMin")).floatValue());
  345. weather.setTextDay(jsonObject1.getStr("textDay"));
  346. weather.setTextNight(jsonObject1.getStr("textNight"));
  347. weather.setWind360Day(new BigDecimal(jsonObject1.getStr("wind360Day")).floatValue());
  348. weather.setWind360Night(new BigDecimal(jsonObject1.getStr("wind360Night")).floatValue());
  349. weather.setWindDirDay(jsonObject1.getStr("windDirDay"));
  350. weather.setWindDirNight(jsonObject1.getStr("windDirNight"));
  351. weather.setWindScaleDay(new BigDecimal(jsonObject1.getStr("windScaleDay")).floatValue());
  352. weather.setWindScaleNight(new BigDecimal(jsonObject1.getStr("windScaleNight")).floatValue());
  353. weather.setWindSpeedDay(new BigDecimal(jsonObject1.getStr("windSpeedDay")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
  354. weather.setWindSpeedNight(new BigDecimal(jsonObject1.getStr("windSpeedNight")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
  355. weather.setHumidity(new BigDecimal(jsonObject1.getStr("humidity")).floatValue());
  356. weather.setPrecip(new BigDecimal(jsonObject1.getStr("precip")).floatValue());
  357. weather.setPressure(new BigDecimal(jsonObject1.getStr("pressure")).floatValue());
  358. list.add(weather);
  359. } catch (Exception e) {
  360. throw new RuntimeException(e);
  361. }
  362. });
  363. if (!dswrf.isEmpty()) {
  364. if (list.size() != 7) {
  365. log.error("地区:{} 日天气数据下载失败,和风天气数据不全", name);
  366. } else {
  367. for (HeFengDay heFengDay : list) {
  368. Map ds = (Map) dswrf.get(0);
  369. heFengDay.setDswrf(new BigDecimal(ds.get("max").toString()).floatValue());
  370. }
  371. }
  372. }
  373. for (HeFengDay item : list) {
  374. 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() + ")";
  375. int affectedRows = ps.executeUpdate(insertSQL);
  376. }
  377. if (ps != null)
  378. ps.close();
  379. } catch (Exception e) {
  380. log.error("地区:{} 日天气数据下载失败JSON格式化错误", name);
  381. }
  382. log.info("地区:{} 日天气数据下载完成", name);
  383. }*/
  384. public boolean analysis(String caiyun, int areaCode, String name, Connection conn) {
  385. log.info("开始下载地区:{} 的天气数据", name);
  386. try {
  387. Statement ps = conn.createStatement();
  388. String caiyunBody = HttpUtil.createGet(caiyun).execute().charset("utf-8").body();
  389. JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
  390. if (caiyunjsonObject.toString().contains("API quota is exhausted")) {
  391. return true;
  392. }
  393. JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
  394. //小时数据 72小时
  395. /*JSONObject hourly = JSONUtil.parseObj(caiyunResult.get("hourly"));
  396. //小时->温度
  397. JSONArray temperature = JSONUtil.parseArray(hourly.get("temperature"));
  398. //小时->辐照度
  399. JSONArray dswrf = JSONUtil.parseArray(hourly.get("dswrf"));
  400. //小时->风速
  401. JSONArray windSpeed = JSONUtil.parseArray(hourly.get("wind"));
  402. //小时->天气标识
  403. JSONArray skyconHour = JSONUtil.parseArray(hourly.get("skycon"));
  404. //小时->湿度
  405. JSONArray humidityHour = JSONUtil.parseArray(hourly.get("humidity"));
  406. //小时->压强
  407. JSONArray pressureHour = JSONUtil.parseArray(hourly.get("pressure"));*/
  408. //日数据 7d
  409. JSONObject daily = JSONUtil.parseObj(caiyunResult.get("daily"));
  410. //日->辐照度
  411. JSONArray dswrfDay = JSONUtil.parseArray(daily.get("dswrf"));
  412. //日->温度
  413. JSONArray temperatureDay = JSONUtil.parseArray(daily.get("temperature"));
  414. //日->风速 8点到20点
  415. JSONArray windSpeed8Day = JSONUtil.parseArray(daily.get("wind_08h_20h"));
  416. //日->风速 20点到32点
  417. JSONArray windSpeed20Day = JSONUtil.parseArray(daily.get("wind_20h_32h"));
  418. //日->天气描述 8点到20点
  419. JSONArray skycon8 = JSONUtil.parseArray(daily.get("skycon_08h_20h"));
  420. //日->天气描述 20点到32点
  421. JSONArray skycon20 = JSONUtil.parseArray(daily.get("skycon_20h_32h"));
  422. //小时数据写入。 时间 风速 辐照度
  423. /*List<HeFengHour> heFengHourList = new ArrayList<>();
  424. if (windSpeed.size() == 72 && dswrf.size() == 72 && temperature.size() == 72) {
  425. for (int i = 0; i < windSpeed.size(); i++) {
  426. String time = ((JSONObject) windSpeed.get(i)).get("datetime").toString();
  427. HeFengHour heFengHour = new HeFengHour();
  428. heFengHour.setTs(getTimestamp(time));
  429. heFengHour.setWindSpeed(new BigDecimal(((JSONObject) windSpeed.get(i)).get("speed").toString()).floatValue());
  430. heFengHour.setWindSpeedM(new BigDecimal(((JSONObject) windSpeed.get(i)).get("speed").toString()).floatValue() * 1000 / 3600);
  431. heFengHour.setWindScale(speedLevel(((JSONObject) windSpeed.get(i)).get("speed").toString()));
  432. heFengHour.setWind360(new BigDecimal(((JSONObject) windSpeed.get(i)).get("direction").toString()).floatValue());
  433. heFengHour.setHumidity(new BigDecimal(((JSONObject) humidityHour.get(i)).get("value").toString()).floatValue());
  434. heFengHour.setPressure(new BigDecimal(((JSONObject) pressureHour.get(i)).get("value").toString()).floatValue());
  435. heFengHour.setText(skycon(((JSONObject) skyconHour.get(i)).get("value").toString()));
  436. heFengHour.setDswrf(new BigDecimal(((JSONObject) dswrf.get(i)).get("value").toString()).floatValue());
  437. heFengHour.setTemp(new BigDecimal(((JSONObject) temperature.get(i)).get("value").toString()).floatValue());
  438. heFengHourList.add(heFengHour);
  439. }
  440. } else {
  441. log.info("{} 的彩云小时数据不足72小时,不入库!", name);
  442. }*/
  443. //日数据写入
  444. List<HeFengDay> heFengDayList = new ArrayList<>();
  445. if (windSpeed8Day.size() == 7 && windSpeed20Day.size() == 7 && skycon8.size() == 7 && skycon20.size() == 7 && dswrfDay.size() == 7 & temperatureDay.size() == 7) {
  446. for (int i = 0; i < windSpeed8Day.size(); i++) {
  447. String time = ((JSONObject) windSpeed8Day.get(i)).get("date").toString();
  448. //白天风速
  449. Map windspeedDay = (Map) ((JSONObject) windSpeed8Day.get(i)).get("avg");
  450. String windspeedDay1 = windspeedDay.get("speed").toString();
  451. //白天风向
  452. String wind360Day1 = windspeedDay.get("direction").toString();
  453. //夜间风速
  454. Map windspeedNight = (Map) ((JSONObject) windSpeed20Day.get(i)).get("avg");
  455. String windspeedNight1 = windspeedNight.get("speed").toString();
  456. String wind360Night1 = windspeedNight.get("direction").toString();
  457. //辐照度
  458. String dswrf1 = ((JSONObject) dswrfDay.get(i)).get("avg").toString();
  459. //白天天气
  460. String skycon = ((JSONObject) skycon8.get(i)).get("value").toString();
  461. //夜间天气
  462. String skyconN = ((JSONObject) skycon20.get(i)).get("value").toString();
  463. //最高温度
  464. String temperatureMax = ((JSONObject) temperatureDay.get(i)).get("max").toString();
  465. //最低温度
  466. String temperatureMin = ((JSONObject) temperatureDay.get(i)).get("min").toString();
  467. HeFengDay heFengDay = new HeFengDay();
  468. heFengDay.setTs(getTimestamp(time));
  469. heFengDay.setWindSpeedDay(new BigDecimal(windspeedDay1).floatValue());
  470. heFengDay.setWindSpeedMDay(new BigDecimal(windspeedDay1).floatValue() * 1000 / 3600);
  471. heFengDay.setWind360Day(new BigDecimal(wind360Day1).floatValue());
  472. heFengDay.setWindScaleDay(speedLevel(windspeedDay1));
  473. heFengDay.setWindSpeedNight(new BigDecimal(windspeedNight1).floatValue());
  474. heFengDay.setWindSpeedMNight(new BigDecimal(windspeedNight1).floatValue() * 1000 / 3600);
  475. heFengDay.setWind360Night(new BigDecimal(wind360Night1).floatValue());
  476. heFengDay.setWindScaleNight(speedLevel(windspeedNight1));
  477. heFengDay.setDswrf(new BigDecimal(dswrf1).floatValue());
  478. heFengDay.setTextDay(skycon(skycon));
  479. heFengDay.setTextNight(skycon(skyconN));
  480. heFengDay.setTempMax(new BigDecimal(temperatureMax).floatValue());
  481. heFengDay.setTempMin(new BigDecimal(temperatureMin).floatValue());
  482. heFengDayList.add(heFengDay);
  483. }
  484. } else {
  485. log.info("{} 的彩云日数据不足7天,不入库!", name);
  486. }
  487. /*for (HeFengHour item : heFengHourList) {
  488. 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()+ ")";
  489. int affectedRows = ps.executeUpdate(insertSql);
  490. }*/
  491. for (HeFengDay item : heFengDayList) {
  492. 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() + ")";
  493. int affectedRows = ps.executeUpdate(insertSQL);
  494. }
  495. if (ps != null)
  496. ps.close();
  497. } catch (Exception e) {
  498. log.error("彩云天气,地区:{} 日天气数据下载失败JSON格式化错误", name);
  499. return true;
  500. }
  501. log.info("彩云天气,地区:{} 日天气数据下载完成", name);
  502. return false;
  503. }
  504. private Timestamp getTimestamp(String time) {
  505. // 解析字符串为 ZonedDateTime
  506. ZonedDateTime zonedDateTime = ZonedDateTime.parse(time);
  507. // 将 ZonedDateTime 转换为 Instant
  508. Instant instant = zonedDateTime.toInstant();
  509. // 将 Instant 转换为 Timestamp
  510. return Timestamp.from(instant);
  511. }
  512. /**
  513. * 根据代码获取对应天气描述
  514. *
  515. * @param skycon
  516. * @return
  517. */
  518. private String skycon(String skycon) {
  519. switch (skycon) {
  520. case "CLEAR_DAY":
  521. case "CLEAR_NIGHT":
  522. return "晴";
  523. case "PARTLY_CLOUDY_DAY":
  524. case "PARTLY_CLOUDY_NIGHT":
  525. return "多云";
  526. case "CLOUDY":
  527. return "阴";
  528. case "LIGHT_HAZE":
  529. return "轻度雾霾";
  530. case "MODERATE_HAZE":
  531. return "中度雾霾";
  532. case "HEAVY_HAZE":
  533. return "重度雾霾";
  534. case "LIGHT_RAIN":
  535. return "小雨";
  536. case "MODERATE_RAIN":
  537. return "中雨";
  538. case "HEAVY_RAIN":
  539. return "大雨";
  540. case "STORM_RAIN":
  541. return "暴雨";
  542. case "FOG":
  543. return "雾";
  544. case "LIGHT_SNOW":
  545. return "小雪";
  546. case "MODERATE_SNOW":
  547. return "中雪";
  548. case "HEAVY_SNOW":
  549. return "大雪";
  550. case "STORM_SNOW":
  551. return "暴雪";
  552. case "DUST":
  553. return "浮尘";
  554. case "SAND":
  555. return "沙尘";
  556. case "WIND":
  557. return "大风";
  558. }
  559. return "晴";
  560. }
  561. }