a-tuoheng-device/src/main/java/com/ruoyi/device/domain/impl/WeatherDomainImpl.java

210 lines
8.3 KiB
Java
Raw Normal View History

2026-01-30 14:06:38 +08:00
package com.ruoyi.device.domain.impl;
import com.alibaba.fastjson2.JSON;
2026-01-31 10:39:37 +08:00
import com.ruoyi.device.config.DeviceCacheConfig;
2026-01-30 14:06:38 +08:00
import com.ruoyi.device.domain.api.IWeatherDomain;
import com.ruoyi.device.domain.impl.weather.HttpUtils;
import com.ruoyi.device.domain.model.weather.Weather;
import com.ruoyi.device.domain.model.weather.WeatherResponse;
2026-01-30 14:09:55 +08:00
import com.ruoyi.device.domain.config.WeatherProperties;
2026-01-31 10:39:37 +08:00
import lombok.extern.slf4j.Slf4j;
2026-01-30 14:06:38 +08:00
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
2026-01-30 14:09:55 +08:00
import org.springframework.beans.factory.annotation.Autowired;
2026-01-31 10:39:37 +08:00
import org.springframework.cache.annotation.Cacheable;
2026-01-30 14:06:38 +08:00
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
2026-01-31 10:39:37 +08:00
@Slf4j
2026-01-30 14:06:38 +08:00
public class WeatherDomainImpl implements IWeatherDomain {
2026-01-30 14:09:55 +08:00
@Autowired
private WeatherProperties weatherProperties;
2026-01-30 14:06:38 +08:00
2026-01-31 10:39:37 +08:00
@Override
2026-03-03 14:02:02 +08:00
@Cacheable(value = DeviceCacheConfig.WEATHER_CACHE, key = "#dockerDeviceIotId", unless = "#result == null")
2026-01-31 11:02:39 +08:00
public Weather weatherInfo(String lat, String lon, String dockerDeviceIotId) {
log.info("开始获取天气信息 - lat: {}, lon: {}", lat, lon);
2026-01-31 10:39:37 +08:00
String host = weatherProperties.getHost();
String path = weatherProperties.getPath();
String method = "POST";
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "APPCODE " + weatherProperties.getAppcode());
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
Map<String, String> querys = new HashMap<>();
Map<String, String> bodys = new HashMap<>();
bodys.put("lat", lat);
bodys.put("lon", lon);
bodys.put("token", weatherProperties.getToken());
2026-01-31 11:02:39 +08:00
log.info("天气API配置 - host: {}, path: {}, token: {}", host, path, weatherProperties.getToken());
2026-01-31 10:39:37 +08:00
Weather weather = new Weather();
try {
HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
String json = EntityUtils.toString(response.getEntity());
2026-01-31 11:02:39 +08:00
log.info("天气API原始响应 - json: {}", json);
2026-01-31 10:39:37 +08:00
WeatherResponse weatherResponse = JSON.parseObject(json, WeatherResponse.class);
2026-01-31 11:02:39 +08:00
log.info("天气API解析结果 - weatherResponse: {}, code: {}",
weatherResponse != null ? "not null" : "null",
weatherResponse != null ? weatherResponse.getCode() : "N/A");
2026-01-31 10:39:37 +08:00
if (weatherResponse != null && weatherResponse.getCode() == 0) {
String windLevel = weatherResponse.getData().getCondition().getWindLevel();
weather.setWindSpeed(convertWindLevelToSpeed(windLevel));
weather.setEnvironmentTemperature(Double.valueOf(weatherResponse.getData().getCondition().getTemp()));
weather.setEnvironmentHumidity(Double.valueOf(weatherResponse.getData().getCondition().getHumidity()));
String conditionId = weatherResponse.getData().getCondition().getConditionId();
weather.setRainfall(convertConditionIdToRainfall(conditionId));
2026-01-31 11:02:39 +08:00
log.info("天气数据解析成功 - windSpeed: {}, temp: {}, humidity: {}, rainfall: {}",
weather.getWindSpeed(), weather.getEnvironmentTemperature(),
weather.getEnvironmentHumidity(), weather.getRainfall());
} else {
log.warn("天气API返回异常 - weatherResponse: {}, code: {}",
JSON.toJSONString(weatherResponse),
weatherResponse != null ? weatherResponse.getCode() : "null");
2026-01-30 16:16:02 +08:00
}
2026-01-31 11:02:39 +08:00
log.info("lat {} log {} weather {}", lat, lon, JSON.toJSONString(weather));
2026-01-31 10:39:37 +08:00
return weather;
} catch (Exception e) {
2026-01-31 11:02:39 +08:00
log.error("获取天气信息异常 - lat: {}, lon: {}", lat, lon, e);
2026-01-31 10:39:37 +08:00
return null;
}
2026-01-30 14:06:38 +08:00
}
/**
* 根据天气状况ID转换为降雨量等级
* @param conditionId 天气状况ID
* @return 降雨量等级0-无雨1-小雨/小雪2-中雨/中雪3-大雨/大雪
*/
private static Double convertConditionIdToRainfall(String conditionId) {
if (conditionId == null || conditionId.isEmpty()) {
return 0.0; // 默认无雨
}
try {
int id = Integer.parseInt(conditionId);
// 小雨相关:阵雨、小阵雨、局部阵雨、小雨、小雨夹雪、小到中雨
if (id == 15 || id == 16 || id == 17 || id == 18 || id == 19 ||
id == 20 || id == 21 || id == 22 ||
id == 51 || id == 52 || id == 66 ||
id == 86 || id == 91) {
return 1.0; // 小雨
}
// 小雪相关:阵雪、小阵雪、小雪、小到中雪
if (id == 24 || id == 25 ||
id == 58 || id == 59 || id == 71 || id == 72 || id == 73 ||
id == 94) {
return 1.0; // 小雪
}
// 中雨相关:中雨、中到大雨
if (id == 53 || id == 67 || id == 92) {
return 2.0; // 中雨
}
// 中雪相关:中雪
if (id == 60 || id == 61) {
return 2.0; // 中雪
}
// 大雨相关:强阵雨、大雨、暴雨、大暴雨、特大暴雨、大到暴雨
if (id == 23 || id == 54 || id == 55 || id == 56 || id == 57 ||
id == 68 || id == 69 || id == 70 || id == 93) {
return 3.0; // 大雨
}
// 大雪相关:大雪、暴雪
if (id == 62 || id == 63 || id == 74 || id == 75 || id == 76) {
return 3.0; // 大雪
}
// 雷雨相关:雷阵雨、雷电、雷暴、雷阵雨伴有冰雹
if (id == 37 || id == 38 || id == 39 || id == 40 || id == 41 ||
id == 42 || id == 43 || id == 44 || id == 45 ||
id == 87 || id == 88 || id == 89 || id == 90 || id == 599) {
return 1.0; // 雷阵雨按小雨处理
}
// 雨夹雪、冻雨
if (id == 49 || id == 50 || id == 64 || id == 65) {
return 1.0; // 雨夹雪按小雨处理
}
// 冰雹、冰针、冰粒
if (id == 46 || id == 47 || id == 48) {
return 1.0; // 冰雹按小雨处理
}
// 雨(通用)、雪(通用)
if (id == 78 || id == 77) {
return 1.0; // 通用雨/雪按小雨处理
}
// 其他情况(晴天、多云、阴天、雾、霾、沙尘等)
return 0.0; // 无雨
} catch (NumberFormatException e) {
return 0.0; // 解析失败,默认无雨
}
}
/**
* 根据风力等级转换为风速中间值单位m/s
* @param windLevel 风力等级
* @return 风速中间值
*/
private static Double convertWindLevelToSpeed(String windLevel) {
if (windLevel == null || windLevel.isEmpty()) {
return 0.1; // 默认无风的中间值
}
try {
int level = Integer.parseInt(windLevel);
switch (level) {
case 0: // 0-0.2 m/s
return 0.1;
case 1: // 0.3-1.5 m/s
return 0.9;
case 2: // 1.6-3.3 m/s
return 2.45;
case 3: // 3.4-5.4 m/s
return 4.4;
case 4: // 5.5-7.9 m/s
return 6.7;
case 5: // 8-10.7 m/s
return 9.35;
case 6: // 10.8-13.8 m/s
return 12.3;
case 7: // 13.9-17.1 m/s
return 15.5;
case 8: // 17.2-20.7 m/s
return 18.95;
case 9: // 20.8-24.4 m/s
return 22.6;
case 10: // 24.5-28.4 m/s
return 26.45;
case 11: // 28.5-32.6 m/s
return 30.55;
case 12: // 32.6-999.9 m/s (飓风)
return 516.25; // (32.6 + 999.9) / 2
default:
return 0.1; // 未知等级,默认无风
}
} catch (NumberFormatException e) {
return 0.1; // 解析失败,默认无风
}
}
}