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

210 lines
8.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.device.domain.impl;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.device.config.DeviceCacheConfig;
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;
import com.ruoyi.device.domain.config.WeatherProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class WeatherDomainImpl implements IWeatherDomain {
@Autowired
private WeatherProperties weatherProperties;
@Override
@Cacheable(value = DeviceCacheConfig.WEATHER_CACHE, key = "#dockerDeviceIotId", unless = "#result == null")
public Weather weatherInfo(String lat, String lon, String dockerDeviceIotId) {
log.info("开始获取天气信息 - lat: {}, lon: {}", lat, lon);
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());
log.info("天气API配置 - host: {}, path: {}, token: {}", host, path, weatherProperties.getToken());
Weather weather = new Weather();
try {
HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
String json = EntityUtils.toString(response.getEntity());
log.info("天气API原始响应 - json: {}", json);
WeatherResponse weatherResponse = JSON.parseObject(json, WeatherResponse.class);
log.info("天气API解析结果 - weatherResponse: {}, code: {}",
weatherResponse != null ? "not null" : "null",
weatherResponse != null ? weatherResponse.getCode() : "N/A");
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));
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");
}
log.info("lat {} log {} weather {}", lat, lon, JSON.toJSONString(weather));
return weather;
} catch (Exception e) {
log.error("获取天气信息异常 - lat: {}, lon: {}", lat, lon, e);
return null;
}
}
/**
* 根据天气状况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; // 解析失败,默认无风
}
}
}