package com.ld.igds.timer;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.ld.igds.constant.Constant;
|
import com.ld.igds.constant.RedisConst;
|
import com.ld.igds.data.ConfigData;
|
import com.ld.igds.io.constant.ProtocolEnum;
|
import com.ld.igds.models.WeatherConf;
|
import com.ld.igds.models.WeatherInfo;
|
import com.ld.igds.timer.rk.RkData;
|
import com.ld.igds.timer.rk.RkDto;
|
import com.ld.igds.timer.rk.RkResult;
|
import com.ld.igds.util.HttpUtils;
|
import com.ld.igds.util.RedisUtil;
|
import com.ld.igds.weather.CoreWeatherService;
|
import com.ld.igds.weather.WeatherUtil;
|
import com.ld.igds.weather.notify.NotifyWeatherService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpMethod;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.stereotype.Component;
|
import org.springframework.web.client.RestTemplate;
|
|
import javax.annotation.Resource;
|
import java.nio.charset.StandardCharsets;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
|
/**
|
* @author: andy.jia
|
* @description: 气象信息获取定时器
|
* @version: <p>
|
* <p>
|
* 风正致远购买外网气象服务:
|
* 气象服务:http://www.yiketianqi.com/
|
*
|
*
|
* <p> 建大仁科的4G协议
|
*/
|
@Slf4j
|
@Component
|
public class WeatherTimerService {
|
|
@Resource(name = NotifyWeatherService.BEAN_ID)
|
private NotifyWeatherService notifyService;
|
|
@Resource(name = CoreWeatherService.BEAN_ID)
|
private CoreWeatherService weatherService;
|
|
@Autowired
|
private ConfigData configData;
|
@Autowired
|
private RedisUtil redisUtil;
|
@Autowired
|
private RestTemplate restTemplate;
|
|
public static String DEFAULT_URL = "https://v0.yiketianqi.com/api?unescape=1&version=v61&appid=49421971&appsecret=JmJE48Fv&cityid={cityid}";
|
public static String DEFAULT_APP_ID = "49421971";
|
public static String DEFAULT_APP_SECRET = "JmJE48Fv";
|
|
/**
|
* 建大仁科4G平台缓存key
|
*/
|
public static String RK_WEATHER_V30_4G = "RK_WEATHER_V30_4G";
|
|
|
/**
|
* 定时获取气象信息,请注意,由于气象支持外网和自定义气象站,系统默认只执行其中一种方式
|
*/
|
public void doExe() {
|
|
log.info("===========================系统定时获获取气象信息======================");
|
|
// 获取气象信息配置
|
List<WeatherConf> list = weatherService.getConfData(null, null);
|
|
if (null == list || list.isEmpty()) return;
|
|
Date date = new Date();
|
|
for (WeatherConf conf : list) {
|
|
if (null == conf.getWanTag()) conf.setWanTag(Constant.YN_N);
|
if (null == conf.getProtocol()) conf.setProtocol(ProtocolEnum.TCP_DEFAULT.getCode());
|
|
|
//调用风正致远默认外网气象
|
if (Constant.YN_Y.equals(conf.getWanTag())) {
|
getWeatherByWeb(date, conf);
|
continue;
|
}
|
|
//调用建大仁科的气象
|
if (ProtocolEnum.RK_WEATHER_V30.getCode().equals(conf.getProtocol())) {
|
getWeatherByRkV30(date, conf);
|
continue;
|
}
|
|
|
}
|
}
|
|
/**
|
* 系统调用风正致远购买的外网天气气象协议
|
*
|
* @param date
|
* @param conf
|
* @return
|
*/
|
public WeatherInfo getWeatherByWeb(Date date, WeatherConf conf) {
|
|
if (StringUtils.isEmpty(conf.getCityId())) return null;
|
|
try {
|
|
if (null != configData.getWeatherPath()) {
|
DEFAULT_URL = configData.getWeatherPath();
|
}
|
|
String url = DEFAULT_URL.replace("{cityid}", conf.getCityId())
|
.replace("{appid}", DEFAULT_APP_ID)
|
.replace("{appsecret}", DEFAULT_APP_SECRET);
|
|
log.info("气象调用获取-url = {}", url);
|
|
String result = HttpUtils.doGet(url);
|
if (null == result) {
|
log.error("当前外网获取气象信息失败……");
|
return null;
|
}
|
|
WeatherWebDto dto = JSON.parseObject(result, WeatherWebDto.class);
|
|
if (StringUtils.isNotEmpty(dto.getErrcode())) {
|
log.error("当前外网获取气象信息异常:{}", dto.getErrmsg());
|
return null;
|
}
|
log.info("气象返回结果={}", dto.toString());
|
|
WeatherInfo info = new WeatherInfo();
|
info.setId(WeatherUtil.buildWeatherId(conf.getDeptId(), date));
|
info.setAirLevel(dto.getAir_level());
|
info.setCompanyId(conf.getCompanyId());
|
info.setDeptId(conf.getDeptId());
|
info.setHumidity(dto.getHumidity());
|
info.setPm25(dto.getAir_pm25());
|
info.setPressure(dto.getPressure());
|
info.setSource(WeatherUtil.SOURCE_02);
|
info.setTemp(dto.getTem());
|
info.setWeather(dto.getWea());
|
info.setWindDirection(dto.getWin());
|
info.setWindSpeed(dto.getWin_speed());
|
info.setWindMeter(dto.getWin_meter());
|
info.setCity(dto.getCity());
|
info.setUpdateTime(date);
|
|
notifyService.notify(info);
|
return info;
|
} catch (Exception e) {
|
log.error("气象信息获取异常:{}", e.getMessage(), e);
|
}
|
return null;
|
}
|
|
/**
|
* 根据建大仁科云V30协议获取气象信息
|
*
|
* @param date
|
* @param conf
|
*/
|
private void getWeatherByRkV30(Date date, WeatherConf conf) {
|
|
//若用户、密码、IP地址有一为空则返回
|
if (StringUtils.isEmpty(conf.getAccount())
|
|| StringUtils.isEmpty(conf.getPassword())
|
|| StringUtils.isEmpty(conf.getIp())) {
|
return;
|
}
|
|
//获取身份认证token
|
String token = getToken(conf);
|
|
//设置请求头参数
|
HttpHeaders httpHeaders = new HttpHeaders();
|
httpHeaders.set("authorization", token);
|
|
String url = conf.getIp() + "/api/data/getRealTimeData";
|
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
|
HttpEntity<String> ans = restTemplate.exchange(url, HttpMethod.GET,
|
new HttpEntity<>(null, httpHeaders), String.class);
|
String body = ans.getBody();
|
log.debug("-----当前建大仁科平台获取气象信息-----,返回数据={}", body);
|
RkResult response = JSONObject.parseObject(body, RkResult.class);
|
if (StringUtils.isEmpty(response.getCode()) || !"1000".equals(response.getCode())) {
|
log.error("当前建大仁科平台获取气象信息失败......");
|
return;
|
}
|
List<JSONObject> result = JSON.parseArray(JSONObject.toJSONString(response.getData()), JSONObject.class);
|
|
JSONArray lists = (JSONArray) result.get(0).get("dataItem");
|
List<RkDto> list = JSON.parseArray(JSONObject.toJSONString(lists), RkDto.class);
|
if (null == list || list.isEmpty()) {
|
return;
|
}
|
WeatherInfo info = new WeatherInfo();
|
info.setId(WeatherUtil.buildWeatherId(conf.getDeptId(), date));
|
info.setCompanyId(conf.getCompanyId());
|
info.setDeptId(conf.getDeptId());
|
info.setSource(WeatherUtil.SOURCE_01);
|
|
List<RkData> dataList;
|
List<RkData> weatherList = new ArrayList<>();
|
//根据地址判断选项
|
for (RkDto rkDto : list) {
|
//温湿度
|
if ("11".equals(rkDto.getNodeId())) {
|
dataList = rkDto.getRegisterItem();
|
for (RkData rkData : dataList) {
|
//温度
|
if ("1".equals(rkData.getRegisterId())) {
|
info.setTemp(rkData.getData());
|
}
|
//湿度
|
if ("2".equals(rkData.getRegisterId())) {
|
info.setHumidity(rkData.getData());
|
}
|
}
|
}
|
//风力风速
|
if ("1".equals(rkDto.getNodeId())) {
|
dataList = rkDto.getRegisterItem();
|
for (RkData rkData : dataList) {
|
//风力
|
if ("1".equals(rkData.getRegisterId())) {
|
info.setWindSpeed(rkData.getData() + "级");
|
}
|
//风速
|
if ("2".equals(rkData.getRegisterId())) {
|
info.setWindMeter(rkData.getData());
|
}
|
}
|
}
|
//风向
|
if ("2".equals(rkDto.getNodeId())) {
|
dataList = rkDto.getRegisterItem();
|
for (RkData rkData : dataList) {
|
//风向
|
if ("1".equals(rkData.getRegisterId())) {
|
info.setWindDirection(rkData.getData());
|
}
|
}
|
}
|
//大气压
|
if ("14".equals(rkDto.getNodeId())) {
|
dataList = rkDto.getRegisterItem();
|
for (RkData rkData : dataList) {
|
//大气压
|
if ("2".equals(rkData.getRegisterId())) {
|
info.setPressure(rkData.getData());
|
}
|
}
|
}
|
//雨量
|
if ("21".equals(rkDto.getNodeId())) {
|
dataList = rkDto.getRegisterItem();
|
for (RkData rkData : dataList) {
|
// //瞬时雨量
|
// if("1".equals(rkData.getRegisterId())){
|
// info.setRainfall(rkData.getData());
|
// }
|
//当前雨量
|
if ("2".equals(rkData.getRegisterId())) {
|
info.setRainfall(rkData.getData());
|
}
|
}
|
}
|
//有无雨雪
|
if ("16".equals(rkDto.getNodeId())) {
|
weatherList = rkDto.getRegisterItem();
|
}
|
}
|
for (RkData rkData : weatherList) {
|
//天气
|
if ("1".equals(rkData.getRegisterId())) {
|
info.setWeather(rkData.getData());
|
//有雨雪时判断当前雨量
|
if ("有雨雪".equals(rkData.getData())) {
|
Double rainfall = Double.valueOf(info.getRainfall());
|
if (rainfall <= 10) {
|
info.setWeather("小雨");
|
}
|
if (rainfall > 10 && rainfall <= 25) {
|
info.setWeather("中雨");
|
}
|
if (rainfall > 25 && rainfall <= 50) {
|
info.setWeather("大雨");
|
}
|
if (rainfall > 50) {
|
info.setWeather("暴雨");
|
}
|
}
|
}
|
}
|
info.setUpdateTime(date);
|
info.setCity(conf.getCity());
|
notifyService.notify(info);
|
}
|
|
/**
|
* 获取身份认证的授权accessToken
|
*
|
* @param conf
|
* @return
|
*/
|
private String getToken(WeatherConf conf) {
|
//默认先从缓存获取
|
String key = RedisConst.buildKey(conf.getCompanyId(), RK_WEATHER_V30_4G, conf.getAccount());
|
String token = (String) redisUtil.get(key);
|
|
//若缓存获取为空,则通过接口获取token
|
if (null == token) {
|
String url = conf.getIp() + "/api/getToken?loginName=" + conf.getAccount() + "&password=" + conf.getPassword();
|
RkResult response = restTemplate.getForObject(url, RkResult.class);
|
if (null == response) {
|
log.error("当前建大仁科平台获取身份认证信息失败...");
|
return null;
|
}
|
log.info("获取的身份认证信息={}", response);
|
|
if (StringUtils.isEmpty(response.getCode()) || !"1000".equals(response.getCode())) {
|
log.error("当前建大仁科平台获取身份认证信息失败......");
|
return null;
|
}
|
JSONObject result = JSON.parseObject(JSONObject.toJSONString(response.getData()));
|
if (null == result) {
|
return null;
|
}
|
token = (String) result.get("token");
|
|
//将token存入缓存,
|
redisUtil.set(key, token, 2 * 60 * 60);
|
}
|
return token;
|
}
|
|
|
}
|