|
@@ -0,0 +1,580 @@
|
|
|
+package com.example.getweather.service;
|
|
|
+
|
|
|
+import cn.hutool.db.Db;
|
|
|
+import cn.hutool.db.Entity;
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import cn.hutool.json.JSONArray;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.example.getweather.entity.DistrictCodeDO;
|
|
|
+import com.example.getweather.entity.HeFengDay;
|
|
|
+import com.example.getweather.util.WeixinPush;
|
|
|
+import com.taosdata.jdbc.TSDBDriver;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.validation.annotation.Validated;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.sql.Connection;
|
|
|
+import java.sql.DriverManager;
|
|
|
+import java.sql.Statement;
|
|
|
+import java.sql.Timestamp;
|
|
|
+import java.time.Instant;
|
|
|
+import java.time.ZonedDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+@Validated
|
|
|
+@Slf4j
|
|
|
+public class GetWeather {
|
|
|
+ @Resource
|
|
|
+ private WeixinPush weixinPush;
|
|
|
+ /*public void download() {
|
|
|
+
|
|
|
+ List<String> areaCodes = new ArrayList<>();
|
|
|
+ List<DistrictCodeDO> districtCodeDOList = new ArrayList<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<Entity> dictList = Db.use().findAll("system_dict_data");
|
|
|
+ for (Entity entity : dictList) {
|
|
|
+ String name = entity.getStr("label");
|
|
|
+ if (name.contains("area_code")) {
|
|
|
+ String code = entity.getStr("value");
|
|
|
+ String[] s = code.split(",");
|
|
|
+ areaCodes = Arrays.asList(s);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Entity> districtCodes = Db.use().findAll("jy_district_code");
|
|
|
+ for (Entity e : districtCodes) {
|
|
|
+ DistrictCodeDO districtCodeDO = new DistrictCodeDO();
|
|
|
+ districtCodeDO.setCode(Integer.parseInt(e.getStr("code")));
|
|
|
+ districtCodeDO.setName(e.getStr("name"));
|
|
|
+ districtCodeDO.setLevel(Integer.parseInt(e.getStr("level")));
|
|
|
+ districtCodeDO.setType(Integer.parseInt(e.getStr("type")));
|
|
|
+ districtCodeDO.setAbname(e.getStr("abname"));
|
|
|
+ districtCodeDO.setPid(Integer.parseInt(e.getStr("pid")));
|
|
|
+ districtCodeDO.setLat(!Objects.equals(e.getStr("lat"), "") && e.getStr("lat") != null ? new BigDecimal(e.getStr("lat")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
|
|
|
+ districtCodeDO.setLng(!Objects.equals(e.getStr("lng"), "") && e.getStr("lng") != null ? new BigDecimal(e.getStr("lng")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
|
|
|
+ districtCodeDOList.add(districtCodeDO);
|
|
|
+ }
|
|
|
+ String jdbcUrl = "jdbc:TAOS://192.168.12.241:19500/etadm_local?user=root&password=qE$#6G0zROoc";
|
|
|
+ Properties connProps = new Properties();
|
|
|
+ connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
|
|
+ connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
|
|
+ connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
|
+ Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
|
|
|
+ //省份
|
|
|
+ for (String code : areaCodes) {
|
|
|
+ List<DistrictCodeDO> shiList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(code)).collect(Collectors.toList());
|
|
|
+ //市
|
|
|
+ for (DistrictCodeDO d : shiList) {
|
|
|
+ List<DistrictCodeDO> quList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(d.getCode().toString())).collect(Collectors.toList());
|
|
|
+ log.info("开始下载地区:{} 的天气数据", d.getName());
|
|
|
+ String hefeng24;
|
|
|
+ String caiyun24;
|
|
|
+ String hefengDay;
|
|
|
+ String caiyunDay;
|
|
|
+ //!!!!!!!!!!拼的彩云的辐照度!!!!!!!!!!!!!
|
|
|
+ //和风逐小时数据
|
|
|
+ hefeng24 = "https://devapi.qweather.com/v7/grid-weather/24h?location=" + d.getLng() + "," + d.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
|
|
|
+ //彩云逐小时数据
|
|
|
+ caiyun24 = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + d.getLng() + "," + d.getLat() + "/hourly?hourlysteps=24";
|
|
|
+ //和风逐日数据
|
|
|
+ hefengDay = "https://devapi.qweather.com/v7/grid-weather/7d?location=" + d.getLng() + "," + d.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
|
|
|
+ //彩云逐日数据
|
|
|
+ caiyunDay = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + d.getLng() + "," + d.getLat() + "/daily?dailysteps=7";
|
|
|
+ analysis24(hefeng24, caiyun24, d.getCode(), d.getName(), conn);
|
|
|
+ analysisDay(hefengDay, caiyunDay, d.getCode(), d.getName(), conn);
|
|
|
+ //区
|
|
|
+ for (DistrictCodeDO q : quList) {
|
|
|
+ log.info("开始下载地区:{} 的天气数据", q.getName());
|
|
|
+ //和风逐小时数据
|
|
|
+ hefeng24 = "https://devapi.qweather.com/v7/grid-weather/24h?location=" + q.getLng() + "," + q.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
|
|
|
+ //彩云逐小时数据
|
|
|
+ caiyun24 = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + q.getLng() + "," + q.getLat() + "/hourly?hourlysteps=24";
|
|
|
+ //和风逐日数据
|
|
|
+ hefengDay = "https://devapi.qweather.com/v7/grid-weather/7d?location=" + q.getLng() + "," + q.getLat() + "&key=54d9633382814e148836ce6be2d003fb";
|
|
|
+ //彩云逐日数据
|
|
|
+ caiyunDay = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + q.getLng() + "," + q.getLat() + "/daily?dailysteps=7";
|
|
|
+ analysis24(hefeng24, caiyun24, q.getCode(), q.getName(), conn);
|
|
|
+ analysisDay(hefengDay, caiyunDay, q.getCode(), q.getName(), conn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ conn.close();
|
|
|
+ log.info("天气数据全部下载完毕");
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据风速获取对应风力等级
|
|
|
+ * 2025-01-09 改为km/h单位
|
|
|
+ *
|
|
|
+ * @param speed 风速,单位为 km/h
|
|
|
+ * @return 风力等级
|
|
|
+ */
|
|
|
+ public static int speedLevel(String speed) {
|
|
|
+ BigDecimal val = new BigDecimal(speed);
|
|
|
+ //<0.3 无风 0级
|
|
|
+ if (val.compareTo(new BigDecimal("1")) < 0) {
|
|
|
+ return 0;
|
|
|
+ } else if (val.compareTo(new BigDecimal("6")) < 0) {
|
|
|
+ //0.3-1.6 微风徐徐 1级
|
|
|
+ return 1;
|
|
|
+ } else if (val.compareTo(new BigDecimal("12")) < 0) {
|
|
|
+ //1.6-3.4 清风 2级
|
|
|
+ return 2;
|
|
|
+ } else if (val.compareTo(new BigDecimal("20")) < 0) {
|
|
|
+ //3.4-5.5 树叶摇摆 3级
|
|
|
+ return 3;
|
|
|
+ } else if (val.compareTo(new BigDecimal("29")) < 0) {
|
|
|
+ //5.5-8.0 树枝摇动 4级
|
|
|
+ return 4;
|
|
|
+ } else if (val.compareTo(new BigDecimal("39")) < 0) {
|
|
|
+ //8.0-10.8 风吹折小树 5级
|
|
|
+ return 5;
|
|
|
+ } else if (val.compareTo(new BigDecimal("50")) < 0) {
|
|
|
+ //10.8-13.9 树枝折断 6级
|
|
|
+ return 6;
|
|
|
+ } else if (val.compareTo(new BigDecimal("62")) < 0) {
|
|
|
+ //13.9-17.2 风吹倒树木 7级
|
|
|
+ return 7;
|
|
|
+ } else if (val.compareTo(new BigDecimal("75")) < 0) {
|
|
|
+ //17.2-20.8 风吹断大树 8级
|
|
|
+ return 8;
|
|
|
+ } else if (val.compareTo(new BigDecimal("89")) < 0) {
|
|
|
+ //20.8-24.5 强风 9级
|
|
|
+ return 9;
|
|
|
+ } else if (val.compareTo(new BigDecimal("103")) < 0) {
|
|
|
+ //24.5-28.5 狂风 10级
|
|
|
+ return 10;
|
|
|
+ } else if (val.compareTo(new BigDecimal("117")) < 0) {
|
|
|
+ //28.5-32.7 暴风 11级
|
|
|
+ return 11;
|
|
|
+ } else if (val.compareTo(new BigDecimal("134")) < 0) {
|
|
|
+ //32.7-37.0 大暴风 12级
|
|
|
+ return 12;
|
|
|
+ } else if (val.compareTo(new BigDecimal("150")) < 0) {
|
|
|
+ //37.0-41.5 飓风 13级
|
|
|
+ return 13;
|
|
|
+ } else if (val.compareTo(new BigDecimal("167")) < 0) {
|
|
|
+ //41.5-46.2 强飓风 14级
|
|
|
+ return 14;
|
|
|
+ } else if (val.compareTo(new BigDecimal("184")) < 0) {
|
|
|
+ //46.2-50.9 猛烈飓风 15级
|
|
|
+ return 15;
|
|
|
+ } else if (val.compareTo(new BigDecimal("202")) < 0) {
|
|
|
+ //50.9-56.1 毁灭性飓风 16级
|
|
|
+ return 16;
|
|
|
+ } else {
|
|
|
+ //56.1-61.3 超级飓风 17级
|
|
|
+ return 17;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void download() {
|
|
|
+ List<String> areaCodes = new ArrayList<>();
|
|
|
+ List<DistrictCodeDO> districtCodeDOList = new ArrayList<>();
|
|
|
+ boolean isApiQuotaExhausted = false; // 引入标志变量
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<Entity> dictList = Db.use().findAll("system_dict_data");
|
|
|
+ for (Entity entity : dictList) {
|
|
|
+ String name = entity.getStr("label");
|
|
|
+ if (name.contains("area_code")) {
|
|
|
+ String code = entity.getStr("value");
|
|
|
+ String[] s = code.split(",");
|
|
|
+ areaCodes = Arrays.asList(s);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Entity> districtCodes = Db.use().findAll("jy_district_code");
|
|
|
+ for (Entity e : districtCodes) {
|
|
|
+ DistrictCodeDO districtCodeDO = new DistrictCodeDO();
|
|
|
+ districtCodeDO.setCode(Integer.parseInt(e.getStr("code")));
|
|
|
+ districtCodeDO.setName(e.getStr("name"));
|
|
|
+ districtCodeDO.setLevel(Integer.parseInt(e.getStr("level")));
|
|
|
+ districtCodeDO.setType(Integer.parseInt(e.getStr("type")));
|
|
|
+ districtCodeDO.setAbname(e.getStr("abname"));
|
|
|
+ districtCodeDO.setPid(Integer.parseInt(e.getStr("pid")));
|
|
|
+ districtCodeDO.setLat(!Objects.equals(e.getStr("lat"), "") && e.getStr("lat") != null ? new BigDecimal(e.getStr("lat")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
|
|
|
+ districtCodeDO.setLng(!Objects.equals(e.getStr("lng"), "") && e.getStr("lng") != null ? new BigDecimal(e.getStr("lng")).setScale(6, RoundingMode.HALF_UP).doubleValue() : 0d);
|
|
|
+ districtCodeDOList.add(districtCodeDO);
|
|
|
+ }
|
|
|
+ String jdbcUrl = "jdbc:TAOS://192.168.12.241:19500/etadm_local?user=root&password=qE$#6G0zROoc";
|
|
|
+ Properties connProps = new Properties();
|
|
|
+ connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
|
|
|
+ connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
|
|
|
+ connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
|
|
+ Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
|
|
|
+ //省份
|
|
|
+ for (String code : areaCodes) {
|
|
|
+ if (isApiQuotaExhausted) break; // 检查标志变量
|
|
|
+ List<DistrictCodeDO> shiList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(code)).collect(Collectors.toList());
|
|
|
+ //市
|
|
|
+ for (DistrictCodeDO d : shiList) {
|
|
|
+ if (isApiQuotaExhausted) break; // 检查标志变量
|
|
|
+ List<DistrictCodeDO> quList = districtCodeDOList.stream().filter(item -> item.getPid().toString().equals(d.getCode().toString())).collect(Collectors.toList());
|
|
|
+ String caiyun;
|
|
|
+ //彩云综合数据查询
|
|
|
+ caiyun = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + d.getLng() + "," + d.getLat() + "/weather?alert=true&dailysteps=7&hourlysteps=72";
|
|
|
+ isApiQuotaExhausted = analysis(caiyun, d.getCode(), d.getName(), conn); // 传递标志变量
|
|
|
+ if (isApiQuotaExhausted) break; // 检查标志变量
|
|
|
+ //区
|
|
|
+ for (DistrictCodeDO q : quList) {
|
|
|
+ if (isApiQuotaExhausted) break; // 检查标志变量
|
|
|
+ caiyun = "https://api.caiyunapp.com/v2.6/SRQIFijX5MGtdmhe/" + q.getLng() + "," + q.getLat() + "/weather?alert=true&dailysteps=7&hourlysteps=72";
|
|
|
+ isApiQuotaExhausted = analysis(caiyun, q.getCode(), q.getName(), conn); // 传递标志变量
|
|
|
+ if (isApiQuotaExhausted) break; // 检查标志变量
|
|
|
+ //线程睡5秒 防止请求过快
|
|
|
+ Thread.sleep(5000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ conn.close();
|
|
|
+ String alarm = "电力交易系统在获取日级天气数据时报错, 彩云天气API 额度已用尽";
|
|
|
+ String description = "接口调用异常";
|
|
|
+ if (isApiQuotaExhausted) {
|
|
|
+ //给企业微信发送消息
|
|
|
+ /* WeixinPush weixinPush = new WeixinPush();
|
|
|
+ WeixinMessage weixinMessage = new WeixinMessage();
|
|
|
+ weixinMessage.setToUser("WangHongChen|XiuWei|DouZhi");
|
|
|
+ //获取今天的ymd
|
|
|
+ String ymd = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
|
|
|
+ weixinMessage.setContent(ymd + "日 电力交易系统在获取天气数据时报错, 彩云天气API 额度已用尽");
|
|
|
+ weixinMessage.setMsgType("text");
|
|
|
+ weixinMessage.setAgentid(1000009); // 确保 agentid 正确
|
|
|
+ weixinPush.sendMessage(weixinMessage);
|
|
|
+ */
|
|
|
+ weixinPush.sendMessageBot(alarm, description);
|
|
|
+ } else {
|
|
|
+ alarm = "电力交易系统彩云天气数据全部下载完毕";
|
|
|
+ description = "接口调用成功";
|
|
|
+ weixinPush.sendMessageBot(alarm, description);
|
|
|
+ log.info("彩云天气数据全部下载完毕");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*public void analysis24(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
|
|
|
+ try {
|
|
|
+ Statement ps = conn.createStatement();
|
|
|
+ String caiyunBody = HttpUtil.createGet(caiyun24url).execute().charset("utf-8").body();
|
|
|
+ JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
|
|
|
+ JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
|
|
|
+ JSONObject hourly = JSONUtil.parseObj(caiyunResult.get("hourly"));
|
|
|
+ JSONArray dswrf = JSONUtil.parseArray(hourly.get("dswrf"));
|
|
|
+
|
|
|
+ String hefengBody = HttpUtil.createGet(hefeng24url).execute().charset("utf-8").body();
|
|
|
+ JSONObject jsonObject = JSONUtil.parseObj(hefengBody);
|
|
|
+ JSONArray hefengList = JSONUtil.parseArray(jsonObject.get("hourly"));
|
|
|
+ List<HeFengHour> list = new ArrayList<>();
|
|
|
+ hefengList.forEach(item -> {
|
|
|
+ JSONObject jsonObject1 = JSONUtil.parseObj(item);
|
|
|
+ try {
|
|
|
+ HeFengHour weather = new HeFengHour();
|
|
|
+ String s = jsonObject1.getStr("fxTime");
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmXXX");
|
|
|
+ ZonedDateTime zonedDateTime = ZonedDateTime.parse(s, formatter);
|
|
|
+ Instant instant = zonedDateTime.toInstant();
|
|
|
+ Timestamp timestamp = Timestamp.from(instant);
|
|
|
+ weather.setTs(timestamp);
|
|
|
+ weather.setTemp(new BigDecimal(jsonObject1.getStr("temp")).floatValue());
|
|
|
+ weather.setAreaCode(String.valueOf(areaCode));
|
|
|
+ weather.setText(jsonObject1.getStr("text"));
|
|
|
+ weather.setWindDir(jsonObject1.getStr("windDir"));
|
|
|
+ weather.setWind360(new BigDecimal(jsonObject1.getStr("wind360")).floatValue());
|
|
|
+ weather.setWindSpeed(new BigDecimal(jsonObject1.getStr("windSpeed")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
|
|
|
+ weather.setWindScale(new BigDecimal(jsonObject1.getStr("windScale")).floatValue());
|
|
|
+ weather.setHumidity(new BigDecimal(jsonObject1.getStr("humidity")).floatValue());
|
|
|
+ weather.setCloud(new BigDecimal(jsonObject1.getStr("cloud")).floatValue());
|
|
|
+ weather.setPrecip(new BigDecimal(jsonObject1.getStr("precip")).floatValue());
|
|
|
+ weather.setDew(new BigDecimal(jsonObject1.getStr("dew")).floatValue());
|
|
|
+ weather.setPressure(new BigDecimal(jsonObject1.getStr("pressure")).floatValue());
|
|
|
+ list.add(weather);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!dswrf.isEmpty()) {
|
|
|
+ if (list.size() != 24) {
|
|
|
+ log.error("地区:{} 24小时天气数据下载失败,和风天气数据不全", name);
|
|
|
+ } else {
|
|
|
+ if (dswrf.size() != 24) {
|
|
|
+ log.error("地区:{} 24小时天气数据下载失败,心知天气数据不全", name);
|
|
|
+ } else {
|
|
|
+ for (int i = 0; i < 24; i++) {
|
|
|
+ Map ds = (Map) dswrf.get(i);
|
|
|
+ list.get(i).setDswrf(new BigDecimal(ds.get("value").toString()).floatValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (HeFengHour item : list) {
|
|
|
+ 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() + ")";
|
|
|
+ int affectedRows = ps.executeUpdate(insertSql);
|
|
|
+ }
|
|
|
+ if (ps != null)
|
|
|
+ ps.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("地区:{} 24小时天气数据下载失败JSON格式化错误", name);
|
|
|
+ }
|
|
|
+ log.info("地区:{} 24小时天气数据下载完成", name);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void analysisDay(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
|
|
|
+ try {
|
|
|
+ Statement ps = conn.createStatement();
|
|
|
+ String caiyunBody = HttpUtil.createGet(caiyun24url).execute().charset("utf-8").body();
|
|
|
+ JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
|
|
|
+ JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
|
|
|
+ JSONObject daily = JSONUtil.parseObj(caiyunResult.get("daily"));
|
|
|
+ JSONArray dswrf = JSONUtil.parseArray(daily.get("dswrf"));
|
|
|
+
|
|
|
+ String hefengBody = HttpUtil.createGet(hefeng24url).execute().charset("utf-8").body();
|
|
|
+ JSONObject jsonObject = JSONUtil.parseObj(hefengBody);
|
|
|
+ JSONArray hefengList = JSONUtil.parseArray(jsonObject.get("daily"));
|
|
|
+ List<HeFengDay> list = new ArrayList<>();
|
|
|
+ hefengList.forEach(item -> {
|
|
|
+ JSONObject jsonObject1 = JSONUtil.parseObj(item);
|
|
|
+ try {
|
|
|
+ HeFengDay weather = new HeFengDay();
|
|
|
+ String s = jsonObject1.getStr("fxDate");
|
|
|
+ LocalDate localDate = LocalDate.parse(s);
|
|
|
+ // 将 LocalDate 转换为 Instant,然后再转换为 Timestamp
|
|
|
+ Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay(ZoneOffset.UTC).toLocalDateTime());
|
|
|
+ weather.setTs(timestamp);
|
|
|
+ weather.setAreaCode(String.valueOf(areaCode));
|
|
|
+ weather.setTempMax(new BigDecimal(jsonObject1.getStr("tempMax")).floatValue());
|
|
|
+ weather.setTempMin(new BigDecimal(jsonObject1.getStr("tempMin")).floatValue());
|
|
|
+ weather.setTextDay(jsonObject1.getStr("textDay"));
|
|
|
+ weather.setTextNight(jsonObject1.getStr("textNight"));
|
|
|
+ weather.setWind360Day(new BigDecimal(jsonObject1.getStr("wind360Day")).floatValue());
|
|
|
+ weather.setWind360Night(new BigDecimal(jsonObject1.getStr("wind360Night")).floatValue());
|
|
|
+ weather.setWindDirDay(jsonObject1.getStr("windDirDay"));
|
|
|
+ weather.setWindDirNight(jsonObject1.getStr("windDirNight"));
|
|
|
+ weather.setWindScaleDay(new BigDecimal(jsonObject1.getStr("windScaleDay")).floatValue());
|
|
|
+ weather.setWindScaleNight(new BigDecimal(jsonObject1.getStr("windScaleNight")).floatValue());
|
|
|
+ weather.setWindSpeedDay(new BigDecimal(jsonObject1.getStr("windSpeedDay")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
|
|
|
+ weather.setWindSpeedNight(new BigDecimal(jsonObject1.getStr("windSpeedNight")).divide(new BigDecimal("3.6"), 2, RoundingMode.HALF_UP).floatValue());
|
|
|
+ weather.setHumidity(new BigDecimal(jsonObject1.getStr("humidity")).floatValue());
|
|
|
+ weather.setPrecip(new BigDecimal(jsonObject1.getStr("precip")).floatValue());
|
|
|
+ weather.setPressure(new BigDecimal(jsonObject1.getStr("pressure")).floatValue());
|
|
|
+ list.add(weather);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!dswrf.isEmpty()) {
|
|
|
+ if (list.size() != 7) {
|
|
|
+ log.error("地区:{} 日天气数据下载失败,和风天气数据不全", name);
|
|
|
+ } else {
|
|
|
+ for (HeFengDay heFengDay : list) {
|
|
|
+ Map ds = (Map) dswrf.get(0);
|
|
|
+ heFengDay.setDswrf(new BigDecimal(ds.get("max").toString()).floatValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (HeFengDay item : list) {
|
|
|
+ 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() + ")";
|
|
|
+ int affectedRows = ps.executeUpdate(insertSQL);
|
|
|
+ }
|
|
|
+ if (ps != null)
|
|
|
+ ps.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("地区:{} 日天气数据下载失败JSON格式化错误", name);
|
|
|
+ }
|
|
|
+ log.info("地区:{} 日天气数据下载完成", name);
|
|
|
+ }*/
|
|
|
+
|
|
|
+ public boolean analysis(String caiyun, int areaCode, String name, Connection conn) {
|
|
|
+ log.info("开始下载地区:{} 的天气数据", name);
|
|
|
+ try {
|
|
|
+ Statement ps = conn.createStatement();
|
|
|
+ String caiyunBody = HttpUtil.createGet(caiyun).execute().charset("utf-8").body();
|
|
|
+ JSONObject caiyunjsonObject = JSONUtil.parseObj(caiyunBody);
|
|
|
+ if (caiyunjsonObject.toString().contains("API quota is exhausted")) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ JSONObject caiyunResult = JSONUtil.parseObj(caiyunjsonObject.get("result"));
|
|
|
+ //小时数据 72小时
|
|
|
+ /*JSONObject hourly = JSONUtil.parseObj(caiyunResult.get("hourly"));
|
|
|
+ //小时->温度
|
|
|
+ JSONArray temperature = JSONUtil.parseArray(hourly.get("temperature"));
|
|
|
+ //小时->辐照度
|
|
|
+ JSONArray dswrf = JSONUtil.parseArray(hourly.get("dswrf"));
|
|
|
+ //小时->风速
|
|
|
+ JSONArray windSpeed = JSONUtil.parseArray(hourly.get("wind"));
|
|
|
+ //小时->天气标识
|
|
|
+ JSONArray skyconHour = JSONUtil.parseArray(hourly.get("skycon"));
|
|
|
+ //小时->湿度
|
|
|
+ JSONArray humidityHour = JSONUtil.parseArray(hourly.get("humidity"));
|
|
|
+ //小时->压强
|
|
|
+ JSONArray pressureHour = JSONUtil.parseArray(hourly.get("pressure"));*/
|
|
|
+ //日数据 7d
|
|
|
+ JSONObject daily = JSONUtil.parseObj(caiyunResult.get("daily"));
|
|
|
+ //日->辐照度
|
|
|
+ JSONArray dswrfDay = JSONUtil.parseArray(daily.get("dswrf"));
|
|
|
+ //日->温度
|
|
|
+ JSONArray temperatureDay = JSONUtil.parseArray(daily.get("temperature"));
|
|
|
+ //日->风速 8点到20点
|
|
|
+ JSONArray windSpeed8Day = JSONUtil.parseArray(daily.get("wind_08h_20h"));
|
|
|
+ //日->风速 20点到32点
|
|
|
+ JSONArray windSpeed20Day = JSONUtil.parseArray(daily.get("wind_20h_32h"));
|
|
|
+ //日->天气描述 8点到20点
|
|
|
+ JSONArray skycon8 = JSONUtil.parseArray(daily.get("skycon_08h_20h"));
|
|
|
+ //日->天气描述 20点到32点
|
|
|
+ JSONArray skycon20 = JSONUtil.parseArray(daily.get("skycon_20h_32h"));
|
|
|
+ //小时数据写入。 时间 风速 辐照度
|
|
|
+ /*List<HeFengHour> heFengHourList = new ArrayList<>();
|
|
|
+ if (windSpeed.size() == 72 && dswrf.size() == 72 && temperature.size() == 72) {
|
|
|
+ for (int i = 0; i < windSpeed.size(); i++) {
|
|
|
+ String time = ((JSONObject) windSpeed.get(i)).get("datetime").toString();
|
|
|
+ HeFengHour heFengHour = new HeFengHour();
|
|
|
+ heFengHour.setTs(getTimestamp(time));
|
|
|
+ heFengHour.setWindSpeed(new BigDecimal(((JSONObject) windSpeed.get(i)).get("speed").toString()).floatValue());
|
|
|
+ heFengHour.setWindSpeedM(new BigDecimal(((JSONObject) windSpeed.get(i)).get("speed").toString()).floatValue() * 1000 / 3600);
|
|
|
+ heFengHour.setWindScale(speedLevel(((JSONObject) windSpeed.get(i)).get("speed").toString()));
|
|
|
+ heFengHour.setWind360(new BigDecimal(((JSONObject) windSpeed.get(i)).get("direction").toString()).floatValue());
|
|
|
+ heFengHour.setHumidity(new BigDecimal(((JSONObject) humidityHour.get(i)).get("value").toString()).floatValue());
|
|
|
+ heFengHour.setPressure(new BigDecimal(((JSONObject) pressureHour.get(i)).get("value").toString()).floatValue());
|
|
|
+ heFengHour.setText(skycon(((JSONObject) skyconHour.get(i)).get("value").toString()));
|
|
|
+ heFengHour.setDswrf(new BigDecimal(((JSONObject) dswrf.get(i)).get("value").toString()).floatValue());
|
|
|
+ heFengHour.setTemp(new BigDecimal(((JSONObject) temperature.get(i)).get("value").toString()).floatValue());
|
|
|
+ heFengHourList.add(heFengHour);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.info("{} 的彩云小时数据不足72小时,不入库!", name);
|
|
|
+ }*/
|
|
|
+ //日数据写入
|
|
|
+ List<HeFengDay> heFengDayList = new ArrayList<>();
|
|
|
+ if (windSpeed8Day.size() == 7 && windSpeed20Day.size() == 7 && skycon8.size() == 7 && skycon20.size() == 7 && dswrfDay.size() == 7 & temperatureDay.size() == 7) {
|
|
|
+ for (int i = 0; i < windSpeed8Day.size(); i++) {
|
|
|
+ String time = ((JSONObject) windSpeed8Day.get(i)).get("date").toString();
|
|
|
+ //白天风速
|
|
|
+ Map windspeedDay = (Map) ((JSONObject) windSpeed8Day.get(i)).get("avg");
|
|
|
+ String windspeedDay1 = windspeedDay.get("speed").toString();
|
|
|
+ //白天风向
|
|
|
+ String wind360Day1 = windspeedDay.get("direction").toString();
|
|
|
+ //夜间风速
|
|
|
+ Map windspeedNight = (Map) ((JSONObject) windSpeed20Day.get(i)).get("avg");
|
|
|
+ String windspeedNight1 = windspeedNight.get("speed").toString();
|
|
|
+ String wind360Night1 = windspeedNight.get("direction").toString();
|
|
|
+ //辐照度
|
|
|
+ String dswrf1 = ((JSONObject) dswrfDay.get(i)).get("avg").toString();
|
|
|
+ //白天天气
|
|
|
+ String skycon = ((JSONObject) skycon8.get(i)).get("value").toString();
|
|
|
+ //夜间天气
|
|
|
+ String skyconN = ((JSONObject) skycon20.get(i)).get("value").toString();
|
|
|
+ //最高温度
|
|
|
+ String temperatureMax = ((JSONObject) temperatureDay.get(i)).get("max").toString();
|
|
|
+ //最低温度
|
|
|
+ String temperatureMin = ((JSONObject) temperatureDay.get(i)).get("min").toString();
|
|
|
+ HeFengDay heFengDay = new HeFengDay();
|
|
|
+ heFengDay.setTs(getTimestamp(time));
|
|
|
+ heFengDay.setWindSpeedDay(new BigDecimal(windspeedDay1).floatValue());
|
|
|
+ heFengDay.setWindSpeedMDay(new BigDecimal(windspeedDay1).floatValue() * 1000 / 3600);
|
|
|
+ heFengDay.setWind360Day(new BigDecimal(wind360Day1).floatValue());
|
|
|
+ heFengDay.setWindScaleDay(speedLevel(windspeedDay1));
|
|
|
+ heFengDay.setWindSpeedNight(new BigDecimal(windspeedNight1).floatValue());
|
|
|
+ heFengDay.setWindSpeedMNight(new BigDecimal(windspeedNight1).floatValue() * 1000 / 3600);
|
|
|
+ heFengDay.setWind360Night(new BigDecimal(wind360Night1).floatValue());
|
|
|
+ heFengDay.setWindScaleNight(speedLevel(windspeedNight1));
|
|
|
+ heFengDay.setDswrf(new BigDecimal(dswrf1).floatValue());
|
|
|
+ heFengDay.setTextDay(skycon(skycon));
|
|
|
+ heFengDay.setTextNight(skycon(skyconN));
|
|
|
+ heFengDay.setTempMax(new BigDecimal(temperatureMax).floatValue());
|
|
|
+ heFengDay.setTempMin(new BigDecimal(temperatureMin).floatValue());
|
|
|
+ heFengDayList.add(heFengDay);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.info("{} 的彩云日数据不足7天,不入库!", name);
|
|
|
+ }
|
|
|
+ /*for (HeFengHour item : heFengHourList) {
|
|
|
+ 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()+ ")";
|
|
|
+ int affectedRows = ps.executeUpdate(insertSql);
|
|
|
+ }*/
|
|
|
+ for (HeFengDay item : heFengDayList) {
|
|
|
+ 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() + ")";
|
|
|
+ int affectedRows = ps.executeUpdate(insertSQL);
|
|
|
+ }
|
|
|
+ if (ps != null)
|
|
|
+ ps.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("彩云天气,地区:{} 日天气数据下载失败JSON格式化错误", name);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ log.info("彩云天气,地区:{} 日天气数据下载完成", name);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Timestamp getTimestamp(String time) {
|
|
|
+ // 解析字符串为 ZonedDateTime
|
|
|
+ ZonedDateTime zonedDateTime = ZonedDateTime.parse(time);
|
|
|
+ // 将 ZonedDateTime 转换为 Instant
|
|
|
+ Instant instant = zonedDateTime.toInstant();
|
|
|
+ // 将 Instant 转换为 Timestamp
|
|
|
+ return Timestamp.from(instant);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据代码获取对应天气描述
|
|
|
+ *
|
|
|
+ * @param skycon
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String skycon(String skycon) {
|
|
|
+ switch (skycon) {
|
|
|
+ case "CLEAR_DAY":
|
|
|
+ case "CLEAR_NIGHT":
|
|
|
+ return "晴";
|
|
|
+ case "PARTLY_CLOUDY_DAY":
|
|
|
+ case "PARTLY_CLOUDY_NIGHT":
|
|
|
+ return "多云";
|
|
|
+ case "CLOUDY":
|
|
|
+ return "阴";
|
|
|
+ case "LIGHT_HAZE":
|
|
|
+ return "轻度雾霾";
|
|
|
+ case "MODERATE_HAZE":
|
|
|
+ return "中度雾霾";
|
|
|
+ case "HEAVY_HAZE":
|
|
|
+ return "重度雾霾";
|
|
|
+ case "LIGHT_RAIN":
|
|
|
+ return "小雨";
|
|
|
+ case "MODERATE_RAIN":
|
|
|
+ return "中雨";
|
|
|
+ case "HEAVY_RAIN":
|
|
|
+ return "大雨";
|
|
|
+ case "STORM_RAIN":
|
|
|
+ return "暴雨";
|
|
|
+ case "FOG":
|
|
|
+ return "雾";
|
|
|
+ case "LIGHT_SNOW":
|
|
|
+ return "小雪";
|
|
|
+ case "MODERATE_SNOW":
|
|
|
+ return "中雪";
|
|
|
+ case "HEAVY_SNOW":
|
|
|
+ return "大雪";
|
|
|
+ case "STORM_SNOW":
|
|
|
+ return "暴雪";
|
|
|
+ case "DUST":
|
|
|
+ return "浮尘";
|
|
|
+ case "SAND":
|
|
|
+ return "沙尘";
|
|
|
+ case "WIND":
|
|
|
+ return "大风";
|
|
|
+ }
|
|
|
+ return "晴";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|