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:

*

* 风正致远购买外网气象服务: * 气象服务:http://www.yiketianqi.com/ * * *

建大仁科的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 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 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 result = JSON.parseArray(JSONObject.toJSONString(response.getData()), JSONObject.class); JSONArray lists = (JSONArray) result.get(0).get("dataItem"); List 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 dataList; List 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; } }