物联网设备获取实时天气DEMO代码解读,希望对你有用

[摘要]之前我们给大家介绍了如何实现设备对天气信息的实时采集。本文将从代码逻辑层面为您解释这个实时天气应用程序的演示。

本文承接【物联网最佳实践】设备获取实时天气信息,为您解读实时天气演示的代码逻辑,帮助您开发自己的实时天气应用。

服务逻辑

在看代码之前,我们先了解一下这个设备获取实时天气应用的业务逻辑。

物联网设备获取实时天气DEMO代码解读,希望对你有用

1.首先,应用需要从物联网平台订阅设备数据变更通知,这样当设备上报数据时,平台会将数据推送给应用。

2~3.然后,设备需要向平台上报一条包含城市代码的数据,平台推送给应用。

4~5.收到包含城市代码的数据后,应用程序根据城市代码查询城市名称,然后查询相应城市的天气信息缓存。

6~8.如果查询缓存未命中或者缓存中的天气信息已经缓存超过一个小时,应该从天气平台查询最新的天气信息并写入缓存。

9~10.通过物联网平台将天气信息应用到设备上。

代码实现

让我们看看这个演示程序是如何用JAVA实现这个业务逻辑的。

首先看作为应用入口的主要功能Main函数。

public static void main(String[] args) throws Exception {
   //------------调用订阅数据变化接口-------------------
   SubscribeDataChange.subscribe();
   System.out.println("正在搭建消息接收服务器。");
   //------------启动上报数据接收服务器-------------------
   SpringApplication.run(Main.class);
   System.out.println("消息接收服务器搭建完成。");
}

这个Main函数一共做了两件事,

一是调用物联网平台订阅借口,订阅设备数据的变化;其次,启动了一个消息接受服务器(基于SpringBoot框架)。

当订阅设备数据更改时,Main函数调用SubscribeDataChange类的subscribe方法:

public static void subscribe() throws Exception{
   /**---------------------initialize northApiClient------------------------*/
   NorthApiClient northApiClient = AuthUtil.initApiClient();
   SubscriptionManagement subscriptionManagement = new SubscriptionManagement(northApiClient);
   /**---------------------get accessToken at first------------------------*/
   Authentication authentication = new Authentication(northApiClient);
   AuthOutDTO authOutDTO = authentication.getAuthToken();
   String accessToken = authOutDTO.getAccessToken();
   /**---------------------sub deviceAdded notification------------------------*/
   //note: 10.X.X.X is a LAN IP, not a public IP, so subscription callbackUrl's IP cannot be 10.X.X.X
   String callbackUrl = PropertyUtil.getProperty("subscription_CallbackUrl");//this is a test callbackUrl
   SubscriptionDTO subDTO = subDeviceData(subscriptionManagement, "deviceDataChanged", callbackUrl, accessToken);
}private static SubscriptionDTO subDeviceData(SubscriptionManagement subscriptionManagement, String notifyType, String callbackUrl, String accessToken) {
       SubDeviceDataInDTO sddInDTO = new SubDeviceDataInDTO();
       sddInDTO.setNotifyType(notifyType);
       sddInDTO.setCallbackUrl(callbackUrl);       try {
          SubscriptionDTO subDTO = subscriptionManagement.subDeviceData(sddInDTO, null, accessToken);
          System.out.println("上报数据订阅成功"+subDTO.toString());          return subDTO;
       } catch (NorthApiException e) {
          System.out.println("订阅接口已使用,若是重复订阅请忽略"+e.toString());
      }
      return null;
}

该方法通过华为云设备管理服务的北向应用的SDK完成了物联网平台的接入鉴权和设备数据变化通知的订阅。

Main函数执行完之后,应用处于等待调用的状态,等待平台推送设备数据上来。

当应用收到了平台推送的设备数据后,会调用handleDeviceDataChanged方法,这个方法由设备管理服务北向应用SDK定义,我们需要重写它来实现我们的业务逻辑。

@Overridepublic void handleDeviceDataChanged(NotifyDeviceDataChangedDTO body) {
   String cityCode = body.getService().getData().get("areaCode").asText();
   //------------查询天气-------------------
   Map  apiBody = null;   try {
      apiBody = WeatherUtil.getApiBody(cityCode);
   } catch (IOException e) {
      e.printStackTrace();
   } catch (ParseException e) {
      e.printStackTrace();
   }try {
      System.out.println("正在下发命令给设备。");
      //------------调用下发命令接口-------------------
      InvokeDeviceService.invocation(apiBody);
   } catch (Exception e) {
      e.printStackTrace();
   }
   System.out.println("命令下发已完成。");
}

在这种方法中,应用程序首先通过城市代码查询天气,然后通过发出命令将查询到的天气发送给设备。发出命令和通过调用设备管理服务北向应用SDK的接口进行订阅是一样的,所以本文不展开。我们展开来看一下应用城市代码查询天气的具体过程。

public static Map getApiBody(String cityCode) throws IOException, ParseException {
    Map cityCodeName = new HashMap();
    cityCodeName.put("755", "深圳");
    cityCodeName.put("20", "广州");
    cityCodeName.put("10", "北京");
    cityCodeName.put("21", "上海");
    String cityName = cityCodeName.get(cityCode);
    System.out.println("接收到设备上报的数据,设备上报的cityCode是"+cityCode+",对应的城市名是"+cityName+"。");

首先,应用程序根据城市代码查询城市名称。在这个DEMO中,我们现场构造了一个cityCodeName,写出了几个主要城市的城市代码和城市名的对应关系。但是在实际应用中,这个关系表要维护在一个持久化的数据库中,可以从这里的数据库中读取。

File file=new File("cache/"+cityName+"dateTime"+".txt");
Boolean isWeatherCur = false;if(!file.exists()){
    System.out.println("缓存没有天气数据,正在调用天气查询接口获取天气信息。");
    SimpleDateFormat sdf=new SimpleDateFormat("yy/MM/dd HH:mm:ss");
    String str=sdf.format(new Date());
    ReadWrTxt.writeFile(cityName+"dateTime",str);
}else{
    String fileDateTime = ReadWrTxt.readFile(cityName+"dateTime");
    SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
    String nowTime=format.format(new Date());
    Date d1 = format.parse(nowTime);
    Date d2 = format.parse(fileDateTime);    long diff = d1.getTime() - d2.getTime();    long diffMinutes = TimeUnit.MILLISECONDS.toMinutes(diff);    if(diffMinutes=0){
        System.out.println("读取缓存天气数据成功。");
        isWeatherCur = true;
    }else {
        System.out.println("天气数据缓存超过一个小时,已过期,正在调用天气查询接口获取天气信息。");
        SimpleDateFormat sdf=new SimpleDateFormat("yy/MM/dd HH:mm:ss");        String str=sdf.format(new Date());        ReadWrTxt.writeFile(cityName+"dateTime",str);    }}

然后应用判断是否缓存了城市的天气数据,缓存时间是否超过一个小时。这里,我们采用一种简单的方法。缓存是一个txt文件。文件名直接包含城市名,天气信息和缓存时间保存在一个文件中。程序通过判断缓存时间txt文件是否存在来判断天气信息是否已经缓存,然后读取缓存时间文件来判断缓存是否超时。开发自己的应用时,建议不要使用txt文件作为缓存,而使用redis等缓存数据库。

File weatherFile=new File("cache/"+cityName+"weather"+".txt");
Map apiBodySave = null;if(!weatherFile.exists()||!isWeatherCur){
    //------------调用天气查询接口,这里使用的是华为APIG SDK-------------------
    apiBodySave= Weather.getApiBody(cityName);
    String apiBodyStr = apiBodySave.toString();
    ReadWrTxt.writeFile(cityName+"weather",apiBodyStr);
}
String fileApiBodyStr = ReadWrTxt.readFile(cityName+"weather");
fileApiBodyStr = fileApiBodyStr.replace("{","");
fileApiBodyStr = fileApiBodyStr.replace("}","");
fileApiBodyStr = fileApiBodyStr.replaceAll(" ","");
String[] afterSplit = fileApiBodyStr.split(",");
Map apiBody = new HashMap();for (String ele: afterSplit) {
    String[] keyVal = ele.split("=");
    keyVal[1]=keyVal[1].trim();
    apiBody.put(keyVal[0], keyVal[1]);
}return apiBody;}

如果该城市的天气信息没有缓存或者缓存过期,通过华为云APIG调用天气平台的天气查询借口,缓存天气信息。如果已经缓存,且天气信息未过期,则跳过这一步,直接读取缓存的天气信息并返回。

至此,设备获取实时天气的业务逻辑已经开启,剩下的实现细节本文不再赘述。有兴趣可以参考之前的博客自己下载演示研究代码。

作者:华为云专家  我是卤蛋

本文章来源于互联网,如有侵权,请联系删除!

相关推荐: 分享一个 物联网大数据平台软件开发架构案例

物联网大数据平台软件开发架构案例解析   有人说物联网是引领信息技术的第三次浪潮。 第一次浪潮是个人电脑的出现,开创了信息时代的第一次革命,此次浪潮成就了微软、IBM等巨头。 第二次浪潮是以信息传输为特征的互联网及移动互联网,实现了计算机与人的联通,此次浪潮成…