Explorar el Código

修改 甘肃 日天气数据转为接xmo

xiaowang hace 23 horas
padre
commit
72cc0f3ed2

+ 1 - 0
src/main/java/com/example/getweather/job/Download.java

@@ -17,6 +17,7 @@ public class Download {
     private GetWeather getWeather;
 
     //每天0点下载数据     2025-02-10 应窦哥要求 小时气象源切换为xmo 日的还用彩云
+    //2025-07-14 应窦哥要求 甘肃日的也用彩云
     //@Scheduled(fixedDelay = 600000000)
     @Scheduled(cron = "0 40 6,12 * * ?")
     public void download() {

+ 237 - 86
src/main/java/com/example/getweather/service/GetWeather.java

@@ -1,5 +1,6 @@
 package com.example.getweather.service;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.db.Db;
 import cn.hutool.db.Entity;
 import cn.hutool.http.HttpUtil;
@@ -22,6 +23,7 @@ import java.sql.DriverManager;
 import java.sql.Statement;
 import java.sql.Timestamp;
 import java.time.Instant;
+import java.time.LocalDate;
 import java.time.ZonedDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -178,91 +180,9 @@ public class GetWeather {
         }
     }
 
-
-    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:29500/etadm_local?user=root&password=taosdata";
-            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 static Timestamp convertStringToTimestamp(String dateStr) {
+        LocalDate localDate = LocalDate.parse(dateStr); // 解析 yyyy-MM-dd
+        return Timestamp.valueOf(localDate.atStartOfDay()); // 转换为当天的开始时间
     }
 
     /*public void analysis24(String hefeng24url, String caiyun24url, int areaCode, String name, Connection conn) {
@@ -397,6 +317,119 @@ public class GetWeather {
         log.info("地区:{} 日天气数据下载完成", name);
     }*/
 
+    public void download() {
+        List<String> areaCodes = new ArrayList<>();
+        List<DistrictCodeDO> districtCodeDOList = new ArrayList<>();
+        boolean isApiQuotaExhausted = false; // 引入标志变量
+        String startDate = DateUtil.today();
+        String endDate = DateUtil.offsetDay(DateUtil.date(), 15).toString("yyyy-MM-dd");
+        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:29500/etadm_local?user=root&password=taosdata";
+            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) {
+                //只有甘肃用xmo天气日接口
+                if (code.equals("620000")) {
+                    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 xmoUrl;
+                        //彩云综合数据查询
+                        xmoUrl = "https://weather-api.xm-opt.com/v1/forecastDaily?latitude=" + d.getLat() + "&longitude=" + d.getLng() + "&daily=weather_code,temperature_2m_max,rain_sum,wind_speed_10m_max,wind_direction_10m_dominant,shortwave_radiation_sum&timezone=Asia%2FShanghai&start_date=" + startDate + "&end_date=" + endDate;
+                        isApiQuotaExhausted = analysisXMO(xmoUrl, d.getCode(), d.getName(), conn); // 传递标志变量
+                        if (isApiQuotaExhausted) break; // 检查标志变量
+                        //区
+                        for (DistrictCodeDO q : quList) {
+                            if (isApiQuotaExhausted) break; // 检查标志变量
+                            xmoUrl = "https://weather-api.xm-opt.com/v1/forecastDaily?latitude=" + q.getLat() + "&longitude=" + q.getLng() + "&daily=weather_code,temperature_2m_max,rain_sum,wind_speed_10m_max,wind_direction_10m_dominant,shortwave_radiation_sum&timezone=Asia%2FShanghai&start_date=" + startDate + "&end_date=" + endDate;
+                            isApiQuotaExhausted = analysisXMO(xmoUrl, q.getCode(), q.getName(), conn); // 传递标志变量
+                            if (isApiQuotaExhausted) break; // 检查标志变量
+                            //线程睡5秒 防止请求过快
+                            //花钱了 硬气 不管他
+                            //Thread.sleep(5000);
+                        }
+                    }
+                } else {
+                    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 boolean analysis(String caiyun, int areaCode, String name, Connection conn) {
         log.info("开始下载地区:{} 的天气数据", name);
         try {
@@ -518,6 +551,68 @@ public class GetWeather {
         return false;
     }
 
+    public boolean analysisXMO(String xmoUrl, int areaCode, String name, Connection conn) {
+        log.info("开始下载地区:{} 的天气数据", name);
+        try {
+            Statement ps = conn.createStatement();
+            String body = HttpUtil.createGet(xmoUrl).header("apikey", "c615a8f6-f5dd-4a81-86fe-db2a42862c15").execute().charset("utf-8").body();
+            //String body = HttpUtil.createGet(xmoUrl).header("apikey", "51bcabf8-3a5e-41e9-8bf2-b7676936cb22").execute().charset("utf-8").body();
+            JSONObject jsonObject = JSONUtil.parseObj(body);
+            //log.info("获取到的数据为:{}", body);
+            if (jsonObject.toString().contains("API call limit has been reached")) {
+                return true;
+            }
+            //日数据 7d
+            JSONObject daily = JSONUtil.parseObj(jsonObject.get("daily"));
+            //日期
+            JSONArray date = JSONUtil.parseArray(daily.get("time"));
+            //日->辐照度
+            JSONArray dswrfDay = JSONUtil.parseArray(daily.get("shortwave_radiation_sum"));
+            //日->风速
+            JSONArray windSpeedDay = JSONUtil.parseArray(daily.get("wind_speed_10m_max"));
+            //雨量
+            JSONArray precip = JSONUtil.parseArray(daily.get("rain_sum"));
+            //2m温度
+            JSONArray temp = JSONUtil.parseArray(daily.get("temperature_2m_max"));
+            //10米风向
+            JSONArray direction = JSONUtil.parseArray(daily.get("wind_direction_10m_dominant"));
+            //天气代码
+            JSONArray code = JSONUtil.parseArray(daily.get("weather_code"));
+            //日数据写入
+            List<HeFengDay> heFengDayList = new ArrayList<>();
+            if (date.size() == 16) {
+                for (int i = 0; i < date.size(); i++) {
+                    String time = date.get(i).toString();
+                    HeFengDay heFengDay = new HeFengDay();
+                    heFengDay.setTs(convertStringToTimestamp(time));
+                    heFengDay.setWindSpeedDay(windSpeedDay.get(i) == null ? -0.99f : new BigDecimal(windSpeedDay.get(i).toString()).floatValue());
+                    heFengDay.setWind360Day(direction.get(i).toString() == null ? -0.99f : new BigDecimal(direction.get(i).toString()).floatValue());
+                    heFengDay.setPrecip(precip.get(i) == null ? -0.99f : new BigDecimal(precip.get(i).toString()).floatValue());
+                    heFengDay.setTextDay(ConversionWeatherCodeXmo(code.get(i).toString() == null ? "0" : code.get(i).toString()));
+                    heFengDay.setTempMax(temp.get(i) == null ? -0.99f : new BigDecimal(temp.get(i).toString()).floatValue());
+                    heFengDay.setDswrf(dswrfDay.get(i) == null ? -0.99f : new BigDecimal(dswrfDay.get(i).toString()).floatValue());
+                    heFengDayList.add(heFengDay);
+                }
+            } else {
+                log.info("{} 的曦谋日数据不足16天,不入库!", name);
+            }
+            for (HeFengDay item : heFengDayList) {
+                String insertSQL = "INSERT INTO hefeng_day_unit_" + areaCode + " USING hefeng_day_unit TAGS('" + areaCode + "')  " +
+                        "(ts,wind_speed_day,wind_360_Day,precip,text_day,temp_max,dswrf) values('"
+                        + item.getTs() + "', " + item.getWindSpeedDay() + ", " + item.getWind360Day() + ", " + item.getPrecip() + ", '"
+                        + item.getTextDay() + "', " + item.getTempMax() + ", " + item.getDswrf() + ")";
+                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);
@@ -577,5 +672,61 @@ public class GetWeather {
         return "晴";
     }
 
-
+    private String ConversionWeatherCodeXmo(String code) {
+        switch (code) {
+            case "0":
+                return "晴";
+            case "1":
+                return "多云";
+            case "2":
+                return "少云";
+            case "3":
+                return "阴";
+            case "45":
+                return "雾";
+            case "48":
+                return "冻雾";
+            case "51":
+            case "53":
+            case "55":
+                return "毛毛雨";
+            case "56":
+            case "57":
+                return "冻毛毛雨";
+            case "61":
+                return "小雨";
+            case "63":
+                return "中雨";
+            case "65":
+                return "大雨";
+            case "66":
+            case "67":
+                return "冻雨";
+            case "71":
+                return "小雪";
+            case "73":
+                return "中雪";
+            case "75":
+                return "大雪";
+            case "77":
+                return "雪粒";
+            case "80":
+                return "小阵雨";
+            case "81":
+                return "阵雨";
+            case "82":
+                return "强阵雨";
+            case "85":
+                return "小阵雪";
+            case "86":
+                return "阵雪";
+            case "95":
+                return "雷雨";
+            case "96":
+            case "99":
+                return "雷雨伴有冰雹";
+            default:
+                return "晴"; // 默认返回晴
+        }
+    }
 }

+ 6 - 0
src/main/java/com/example/getweather/service/GetWeatherXmo.java

@@ -143,6 +143,12 @@ public class GetWeatherXmo {
                         xmoUrl = "https://weather-api.xm-opt.com/v1/forecast15Minutes?latitude=" + d.getLat() + "&longitude=" + d.getLng() + "&minutely_15=weather_code,temperature_2m,surface_pressure,relative_humidity_2m,precipitation,cloud_cover,wind_speed_10m,wind_direction_10m,shortwave_radiation&timezone=Asia%2FShanghai&start_date=" + startDate + "&end_date=" + endDate;
                         isApiQuotaExhausted = analysis(xmoUrl, d.getCode(), d.getName(), conn); // 传递标志变量
                         if (isApiQuotaExhausted) break; // 检查标志变量
+                        //区 2025-07-14 只爬镇海区
+                        if (d.getCode() == 330200) {
+                            xmoUrl = "https://weather-api.xm-opt.com/v1/forecast15Minutes?latitude=" + d.getLat() + "&longitude=" + d.getLng() + "&minutely_15=weather_code,temperature_2m,surface_pressure,relative_humidity_2m,precipitation,cloud_cover,wind_speed_10m,wind_direction_10m,shortwave_radiation&timezone=Asia%2FShanghai&start_date=" + startDate + "&end_date=" + endDate;
+                            isApiQuotaExhausted = analysis(xmoUrl, 330211, "镇海区", conn); // 传递标志变量
+                            if (isApiQuotaExhausted) break; // 检查标志变量
+                        }
                     }
                 }
             }