【我的物联网成长记19】物联网智慧路灯应用代码解析(上)

网友投稿 628 2022-05-30

相信不少同学都做过“基于物联网平台构建智慧路灯应用”这个微认证,在这个微认证中,我们构建并部署了一个智慧路灯应用,这个应用拥有一个web界面,可以注册路灯设备,可以获取路灯设备的状态和上报的环境亮度数据并显示到界面上,还可以控制路灯的开关。

在微认证中,这个应用的源码是公开的,但不需要修改就可以直接使用,所以很多同学可能并没有仔细看过这个应用时怎么实现的。所以本文就带各位同学一起看下这个应用具体的设计与实现,以及探讨下如果想要修改这个应用的功能要怎么改,想要开发其他设备的应用要怎么开发。

整体架构

智慧路灯的源码在华为云软件开发平台作为公开示例模板公开,做过微认证的同学已经都已经按照模板创建了自己的代码仓库,接下来就是把代码下到本地用本地的IDE打开,方便查看。

展开代码的目录后我们可以看出来这是一个基于Springboot工程模板创建的web应用.

所以,该应用的主要功能代码都位于main文件夹下,其中java文件夹下是后端代码,resources文件夹下是前端代码和资源。

接下来让我们一边回忆该应用的使用流程,一边查看对应的代码是如何实现的。

Web页面

使用智慧路灯应用的第一步是通过IP和端口访问智慧路灯应用。我们通过浏览器访问应用的时候实际上就是访问了index.html这个文件。

打开index.html,可以看到就是个标准的html页面,定义了页面上显示的各个组件。也就是,如果我们想要修改智慧路灯应用界面上显示的内容,修改这个文件就可以了。

而这个页面的行为和交互则是通过.js文件定义,和业务相关的主要代码都在common.js,也就是想要修改该web页面的交互行为,需要修改common.js。

参数设置

首次访问智慧路灯应用以及点击“参数设置”按钮时,会弹出参数设置窗口,这个窗口的行为由openSetParamsDialog()函数控制。

这个函数的功能是从后台获取数据作为默认值显示在设置窗口,以及在用户点击确认后将设置的数据保存到后台。

获取后台数据的函数是getDeviceParas(),可以看到这里的后台其实就是浏览器的本体缓存,以及若后台没有存储数据时则返回空值。

将设置的数据保存到后台的函数是onSetParamsDialogConfirm(),先读取输入框的值,再写入本地存储,最后调用postDeviceParas()将数据传到后端供后端使用。

通过查看TempDatabase类可以看到该类是个单纯的数据存储类,paras这是ParameterConfiguration类的一个实例,再查看ParameterConfiguration类可以看到它也是个单纯的数据存储类,所以该方法就是将用户设计参数保存到内存中,供本应用运行时调用。

然后让我们继续顺藤摸瓜,去看下subscribeDataChange类的subscribeDataChange()方法。

这个方法是个调用接口的方法,首先通过调用LoginService类的login()方法获取accessToken,然后再调用设备接入的的创建订阅接口。创建订阅接口用于应用向平台订阅设备数据,是物联网应用向物联网平台获取数据的一种方法,本文不进行详述,感兴趣的同学可以查看我们之前的博文。

(这段代码相对较多,截图就只截关键部分了,后面相同的情况不再说明)

通过对比订阅函数和接口文档,我们可以看出来函数中的accessToken对应接口中的X-Auth-Token,所以login()方法对应IAM服务的获取用户Token接口。

注册设备

参数设置成功后,我们需要输入设备标识,然后点击注册设备。

设备标识是设备的唯一标识码,一般用设备的MAC或IMEI,如果是虚拟设备可以随意输入一串数字。

通过查看index页面源码,我们可以看到用户点击注册设备后应用会调用common.js中的regDevice( btn )函数,携带的参数就是用户输入的设备标识。这个方法会先检查你是否设置了参数,然后再调用/register-device接口。

【我的物联网成长记19】物联网智慧路灯应用代码解析(上)

/register-device接口对应RegisterDevice类的registerDevice(@RequestBody DeviceRegisterVerifyCode deviceRegisterVerifyCode)函数,然后这个函数又调用了registerDirectConnectedDevice类的registerDirectDevice(DeviceRegisterVerifyCode deviceInfo)函数,调用了物联网平台的创建设备接口。

然后让我们看回common.js中的regDevice( btn )函数,可以看到注册设备成功后它先移除了toggle-block的hide属性,将页面上剩下的部分(状态查看和路灯控制)显示了出来,然后调用了openDialogRegister(states,title,deviceId,secret)函数,并传入了接口返回的设备Id和密钥,实现了弹窗显示。最后,这个函数调用了initTickTimer()函数,在initTickTimer()函数中,我们终于看到了DIS相关的内容。

这个函数是一个定时任务,循环检查用户设置的数据获取方法,并调用对应函数。

当数据获取方法是DIS时,该函数调用getDis()函数。getDis()函数调用/get-dis接口,并根据返回值设置界面显示值。

/get-dis接口对应GetDis类的getDIsData()函数,这个函数通过集成DIS的SDK,实现了从DIS通道或获取最新数据。这部分的实现可以直接参考DIS的文档,本文不进行详述。设备上报的数据从物联网平台转发至DIS通道则是基于数据转发规则,本文也不进行详述。(眼尖的同学可能会发现这个函数的最后有一行createDeviceCommand.runSetCommand(slMsg);这行代码涉及到这个应用的命令下发机制,此处暂不讲解)

当数据获取方法是订阅推送时,被循环调用的是getSub()函数。getSub()函数调用/get-device-data接口,并根据返回值设置界面显示值。

/get-device-data接口对应GetDevData类的getDeviceData()函数,这个函数直接获取了TempDatabase中的slMsg(存储了环境光强和开关状态)并返回,那这个slMsg的值又是哪来的?

这时候让我们回想一下订阅推送的机制:应用订阅后,物联网平台作为客户端推送通知给应用指定的callbackURL。没错,这个数据是物联网平台主动推送上来了,所以在这个应用中应该会有一个对应callbackURL接口的函数。

从subscribeDataChange()函数中我们可以找到callbackURL的后缀“/v1.0.0/messageReceiver”,通过在代码中搜索我们找到了PushReceiver类中的pushrReceiver(@RequestBody String jsonString)函数。这个函数解析了物联网平台推送的数据,并存到了slMsg中。

至此,我们的应用已经实现了设备的注册和设备上报数据的获取。在下期博客中,我将会为同学们介绍智慧路灯应用三种路灯控制模式的实现。

IoT 智慧路灯 物联网 IoT web应用开发

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python openpyxl 处理Excel使用指南
下一篇:Ext常用组件
相关文章