机智云物联网公司研发了一款运行在各种通讯模组上的固件GAgent(GizwitsAgent),它集成了通信协议,可以实现上层应用到产品设备的双向数据通讯[56]。设备数据、GAgent、机智云云端以及手机APP端的关系如图4.11所示。
使用GAgent将系统终端接入机智云需要经过设备上电、配置入网、搜索绑定设备、以及设备数据上报、下发的过程。其中配置入网操作是将一种基于WIFI的物联网设备配置连接上路由器的过程,首先通过手机APP将目标路由的SSID与密码发送给WIFI模块,WIFI模块接收到信息之后连接路由器,连接成功后告知APP,流程图如图4.12所示。
当设备连接路由器配置入网时,可以选择使用Airlink模式或者SoftAP模式。二者在硬件上的最大区别就是有无无线路由器。因为Airlink模式更加贴合用户体验感,所以本系统中使用Airlink模式进行设备配置入网操作。
4.2.2 固件移植
1、选择对应版本下载
首先需要在机智云官网中下载对应的固件版本。机智云公司根据不同类型的通信模块提供不同的固件版本,具体版本清单如图4.13所示。本系统使用乐鑫公司的ESP8266WIFI模块,所以应该下载的版本是GAgentforESP826604020034。
将文件下载、解压后,需要根据通信模块的Flash容量以及系统方案选择具体的烧录文件。其中,根据Flash容量分为8M、16M、32M版本;系统方案分为MCU和SOC版本。结合本系统情况,最终应该选择GAgent_00ESP826_04020034_32Mbit_combine.bin,下载后的GAgentforESP826604020034文件解压后的文件清单如图4.14所示。
2、固件移植
固件移植还需要硬件的支持,将ESP8266WIFI模组与正点原子探索者开发板的USART接口进行连接,进入烧写模式,连接方式如表4.1所示。
在乐鑫官网平台下载烧写工具ESPFLASHDOWNLOADTOOL。打开该软件,添加GAgent_00ESP826_04020034_32Mbit_combine.bin文件,将对应的地址设置为0。在软件中选择正确的串口,点击“START”按钮,开始烧写。当软件界面显示为Download时,表示正在烧写中,需要等待几分钟;当软件界面显示为FINISH时,表示固件烧录成功。在成功烧录固件之后,需要将ESP8266WIFI通信模块的IO_0引脚悬空,再重新上电。
4.3.1 机智云平台应用设置
机智云平台应用设置首先是在开发者中心注册登录账号,之后进行新产品的创建以及技术方案的选定,接着根据系统终端传来的数据以及系统功能创建对应的数据点,最后进行设备和应用开发,步骤如图4.15所示。
(1) 注册开发者账号。在机智云IoT云平台上实现新产品的开发,首先需要在机智云官网的开发者中心注册开发者账号。开发者账号分为个人开发者和企业开发者,二者区别如表4.2所示。个人开发者没有办法开通企业API以及D3规则引擎等功能,也不能直接转成企业账号;企业开发者不仅能享有更多的免费权限和功能,也能同时兼顾个人项目与企业项目。而且在同一个企业账号下,也可以轻松将个人项目中的产品转移到企业项目中。为了系统后期产品以及功能的拓展,直接注册为企业开发者。账号注册成功之后,就可以进入开发者中心。
(2) 创建新产品。在开发者中心点击“创建新产品”,则跳转到创建新产品的详情界面。结合本系统的研究内容,设置产品名称为“毕业设计”,技术方案选择WIFI方案。产品创建成功之后会生成产品基本信息,如图4.16所示。产品基本信息中的ProductKey是产品唯一的标识码,也是设备接入机智云的一个重要参数[58]。ProductSecret是产品密钥,与产品标识码相对应,它是机智云产品授权的证明,是确认用户的身份和权限。
(3) 将设备终端、手机APP端的具体功能与云端连接起来的途径就是创建数据点,三者间的数据传输要遵循数据点协议。该协议是机智云平台上开发的用于数据传输的协议,数据点用于描述产品功能及其参数。所以,数据点是根据具体的系统功能来创建的。根据系统功能,在云端建立的数据点如表4.3所示。
如表4.3所示,每个数据点都有显示名称、标识名、读写类型以及数据类型。其中显示名称是由开发者自定义的每个功能点名称;标识名是每个数据点及其参数传输时的变量名;读写类型有四种,分别为只读、可写、报警和故障。
最常用的是只读与可写两种类型,传感器检测模块检测的数据在手机APP上显示,该数据通常是只读类型,不允许手机APP端进行修改与控制;控制模块各部分元件的控制状态通常是可写类型,允许手机APP端对控制模块进行手动控制,例如关闭照明灯、关闭换气扇等。数据类型也有四种:布尔值、数值、枚举以及扩展类型,在本系统中主要运用数值型以及布尔型,如表4.3所示的温度、湿度等数据就是数值型,换气扇、保温灯等状态数据就是布尔型。
(4) 创建产品之后就可以创建应用。首先确定应用名称,之后就要选择应用平台,ios、Android以及微信。结合本文内容,应用名称定为“毕业设计”,选择Android平台。应用配置中是关于该应用的基本信息,其中AppID是该应用的标识码,AppSecret与其相对应,本系统的应用基本信息如图4.17所示。
4.3.2 推送设置
推送部分使用了机智云平台为开发者提供的D3Engine(DynamicDataDirectorEngine)功能,可以帮助开发者快速实现邮件推送、短信推送以及APP推送甚至是设备控制等功能[57]。
D3Engine界面分为项目列表、配置以及虚拟设备调试,具体内容如图4.18所示。项目列表显示该产品创建的所有项目,显示字段为项目ID、项目名称、动作类型、备注以及是否开启。机智云IoT云平台每天提供免费的动作触发动作100次,每月的免费短信5条。
为了保证这有限的资源能在后续的软件调试中发挥作用,所以在最后的功能调试阶段将“是否开启”按钮设置为开启,其余时间段将其关闭。
配置是为APP绑定具体的推送平台,设置推送功能的具体步骤如下:
(1) 首先需要在极光推送平台进行注册开发者服务并且创建应用,要注意的是该应用名称要与机智云平台上的应用名称相同,否则后期会出现绑定失败的情况。然后进行产品设置,为应用添加应用包名,添加成功后,就可以查看极光平台上应用对应的APPKey和MasterSecret。
(2) 接下来在机智云平台绑定极光推送,在APP推送配置中的编辑推送平台填写相关信息,填写完成后就可以根据具体需求进行推送项目列表的编辑。
(3) 推送列表的编辑界面是图形化的拖拽式操作,如图4.19所示。将需要的项目从左侧项目栏拖拽至操作界面上,选择具体的选项,用线连接就可以实现推送目的。
如图4.19所示,D3Engine左侧项目组成部分分为输入节点、处理方法节点以及触发动作节点三部分。输入节点可以是设备数据以及自定义的JSON格式的数据;处理方式节点分为逻辑规则以及四则运算,逻辑规则为添加一个逻辑条件,四则运算针对数值类型的数据点进行四则表达式运算,需要自定义算法表达式;触发动作节点分为APP推送、HTTP请求、邮件推送、短信推送以及控制设备。
本系统中,用到的触发动作节点主要为邮件推送和短信推送。在APP代码中要注意将极光推送的权限打开,由“false”变为“true”,并且将极光推送的AppKey填到pushInfo中。
(4)邮件推送是当设备满足设置的条件时向指定的邮箱推送一条邮件消息。本系统在无人报警模式开启且有人时设置触发邮件推送,其中具体操作为:在设备数据中选取“设备状态变化”为触发方式,关注“无人报警模式”以及“行人检测”两个数据点,然后在逻辑规则中设置两个数据点都等于1,最后在触发动作中选择邮件,并且编辑邮件主题、邮件内容以及收件人邮箱,达到的效果如图4.20所示。
(5) 短信推送是当设备满足设置的条件时向指定的手机号码推送一条短信消息。本系统在无人报警模式开启且有火时设置触发短信推送,其中具体操作为:在设备数据中选取“设备状态变化”为触发方式,关注“无人报警模式”以及“火焰”两个数据点,然后在逻辑规则中设置“火焰”数据点等于1,最后在触发动作中选择短信推送以及短信内容,达到的效果如图4.21所示。
4.4 手机APP软件设计与实现
本设计选择安卓系统开发手机APP,首先需要进行安卓开发平台的搭建。安卓开发平台搭建好之后,就可以进行手机APP的开发。机智云IoT云平台为了降低设备接入的复杂性,提供了设备接入SDK。开发者可以忽略相对复杂的通信协议,专注于业务逻辑处理以及对应的控制界面设计[58]。本系统中APP设计部分主要分为启动界面、设备绑定界面、设备配网界面、设备控制界面以及密码认证界面。最后为了使用的方便性,将手机APP制作成APK文件。
4.4.1 搭建Android开发平台
首先要进行JAVA-JDK的下载和安装,搭建JAVA开发环境。顺利安装后,设置JAVA_HOME、Path以及CLASS_PATH这三个变量。在控制台里输入java–version以及javac命令可以验证安装是否成功。接着进行AndroidStudio和AndroidSDK软件的下载和安装。最后,打开安装成功的AndroidStudio软件。点击“新建项目”,会生成一个HelloWorld文件,进行编译。如果能成功编译并且生成一个APP运行在手机上,打开该APP能看见一个显示“HelloWorld”的界面,Android开发平台就搭建成功了。AndroidStudio开发平台界面如图4.22所示。
4.4.2 启动界面
启动界面,也叫做欢迎界面。其主要工作是SDK的初始化以及用户匿名登录服务器。SDK初始化首先就是要进行AndroidManifest.xml文件的配置,并对相关权限进行说明,对于Android6.0以上版本需要进行动态适配。接下来注册SDK通用**,该**可以让APP收到来自GizWIFISDK类的响应事件,主要包括用户登录、配置设备、绑定设备等回调接口,所有GizWIFISDK类的相关操作都会在此回调。然后调用startWithAppInfo()方法启动SDK,通过前一步的通用监听可以查看相应事件的通知。
SDK提供多种用户注册以及登录方式,在本系统中采用匿名登录方式。匿名登录方式不需要注册用户账号,每次调用userLoginAnonymous()方法实现匿名登录成功后,再用didUserLogin()这个用户登录结果的回调接口函数来实现回调,得到回调参数uid以及token,并且保存至本地。其中uid是用户唯一的身份标识,token是用户登录服务器成功后生成的一串字符串,是客户端进行请求的一个标识,它的作用相当于是一个令牌。本界面设置的默认停留时间为5S,如果点击跳过按钮,可以直接跳转到设备绑定界面,其流程图如图4.23所示。
在界面设计上,运用了简单的线性布局以及Button组件,将Button组件的显示文字设置为“跳过”,启动界面如图4.24所示。
4.4.3 设备绑定界面
界面初始化后,使用getBoundDevides()方法获取绑定的设备列表,并通过didDiscovered()方法判断列表是否获取成功,如果获取不成功可以通过下拉刷新的操作重新触发进行获取。如果设备列表中的设备未绑定,会触发bindremoteDevice()方法自动绑定设备并通过didBindDevice()方法回调绑定结果,该结果通过弹窗显示。
设备列表中会显示设备状态,通过getNetStatus()方法判断设备为在线或者离线。当设备在线时,通过判断isLAN参数进一步获取当前在线状态为“局域网在线”或者“远程在线”。该参数用于判断设备是小循环还是大循环,小循环指局域网通信,大循环指广域网通信。设备离线时,设备状态显示为“离线”,列表不可点击。
设备在线时,设计相关的点击事件。点击事件分为长按以及短按,当为长按时,进入设备重命名操作。具体表现为:弹出一个文本框,用户输入新设备名称,点击确认可以触发setCustomInfo()方法修改名称,通过didSetCustomInfo()方法回调修改结果,重命名成功后在设备名称中优先显示。当为短按时,触发setSubscribe()方法订阅设备,通过didsetSubscribe()方法回调订阅结果,订阅成功则携带设备信息进入设备控制界面。其具体流程图如图4.25所示。
设备绑定界面的功能主要为显示设备列表,所以需要添加ListView组件。该组件需要构建Adapter文件,用于设置列表的具体显示,其中包含组件设置以及显示位置。Adapter文件采用线性布局方式,采用ImageView组件显示设备图标,采用TextView组件显示设备名称以及状态。
4.4.4 设备配置入网界面
本界面完成初始化之后,会通过getCurrentWIFISSID()方法自动获取手机当前连接的WIFISSID,如果获取不成功会出现弹窗,提示需要连接WiFi。获取成功后才能输入WIFI密码,点击“开始配网”会触发setDeviceOnboardingDeploy()方法开始配置,该方法参数中需要设置配置模式为Airlink,超时时间为60S,配置模组类型为乐鑫模组。通过didDeviceOnboarding()方法实现设备配置结果回调,利用对话框来显示配网结果。
本界面设计采用线性布局,其中涉及到线性布局的嵌套。主要分为三个部分,第一个部分为标题栏,在左边添加一个ImageView组件,用于返回设备绑定界面;第二部分添加一个ImageView组件用于美化界面,占据整个界面的大半空间;第三部分为用户操作部分,需要设置两个EditText组件以及Button组件。其中EditText组件用于输入WIFISSID以及密码,密码输入框需要设置为密码属性;Button组件用于执行配网操作,设置显示文字为“开始配置”。
4.4.5 设备控制界面
设备控制界面能够清晰的展示用户可以使用的主要功能,主要是:显示设备终端监测的环境数据、电气化设备状态、工作模式;设置无人报警模式;切换工作模式;远程控制电气化设备。
从设备绑定界面跳转至设备控制界面过程中,已经携带了设备数据。在界面初始化时,将标题栏显示为设备名称,通过getNetstatus()方法获取设备状态,再次确认设备是否在线。通过didUpdataNetStatus()方法回调设备网络状况,若设备离线则返回设备绑定界面,若设备在线且可控则通过didReceiveData()方法从云端获取设备所有数据。设备数据表现为JSON格式,存储在字典中,需要将整个数据进行解析,分别存储在对应的数据变量中。然后利用handler消息机制更新UI,刷新APP界面。其中,无人报警模式关联着人体感应监测部分的显示文字,该模式开启显示人体感应监测信息;关闭则显示饲养员在场。
当工作模式为手动时,显示当前工作模式为手动、面板状态为解锁。当点击六个电气化设备开关或者复位开关时,首先定义存储数据的字典ConcurrentHashMap,对照云端定义的数据点,将下发的操作指令名称以及下发的值用put()方法放入字典中,用write()方法将数据发送到云端,通过didReceiveData()函数接收操作指令应答。指令操作的确认回复,通过其回调返回。若是点击自动模式按钮,则切换为自动模式。
当工作模式为自动时,显示当前工作模式为手动、面板状态为解锁。六个电气化设备开关只能显示状态,不可点击。若是点击手动模式按钮,则进入密码认证界面。从密码认证界面携带数据返回,通过getExtras()方法将结果从Bundle中取出,再判断系统工作模式。设备控制界面软件流程图如图4.27所示。
在控制界面中,布局复杂,主要使用线性布局以及相对布局。组件由ScrollView、TextView、ImageView、ImageButton、Switch以及CheckBox组成,整个界面主要分为五部分。
第一部分是环境要素的显示,所有数据均为只读。温度、湿度、光照强度以及氨气浓度为数值型数据,具体数值将直接显示;雨滴、火焰监测为布尔型数据,将通过TextView组件显示对应的文字信息。当为0时分别显示为“当前状态:有雨”、“当前状态:无火”;当为1时分别显示为“当前状态:无雨”、“当前状态:有火”,并且当有雨、有火时通过setTextColor()方法将文字颜色转变为红色,起到提醒作用。
第二部分是无人报警模式,该模式主要作用是为了防止蜂鸣器误报警,具体包含一个切换无人报警模式的CheckBox组件以及一个显示行人状态的TextView组件。饲养员可以手动操作无人报警模式,当在现场时关闭该模式;当不在现场时开启该模式,就可以监测是否有他人靠近,起到防盗的效果。当无人报警模式关闭时,TextView组件显示“饲养员在场”。当无人报警模式开启时,将会监测是否有人,有他人靠近时TextView组件显示“当前状态:有人”且文字变为红色;无人靠近时TextView组件显示“当前状态:无人”。
第三部分是系统工作模式,包含两个用来切换系统工作模式的ImageButton组件以及一个用来显示工作模式状态的TextView组件。
第四部分是控制面板,包含一个表示控制面板状态的TextView组件,一个复位按钮的Button组件以及照明灯、保温灯等六个电气化设备的Switch组件。控制面板状态与第三部分的系统工作模式是对应关系:当为自动模式时,控制面板为锁定状态,TextView显示为“当前面板状态:锁定”,六个元件开关均不能点击;当为手动模式时,控制面板为解锁状态,TextView显示为“当前面板状态:解锁”,元件开关可以点击,实现手机APP远程控制。当点击复位按钮时,所有元件全部关闭。其中,通过setClickable()方法来实现Switch组件是否可以点击,当设置为true时,组件可以点击;当设置为false时,组件不能点击,只能显示状态。
第五部分是猪只信息显示,主要包含两个用于显示猪只数量以及所占像素点比重的TextView控件,设备控制界面如图4.28所示。
4.4.6 密码认证界面
控制界面能显示系统的主要功能例如显示环境信息、各控制元件状态以及控制,每个功能还可以开发具体的界面显示以及后续的控制,这需要增加新的界面、完成控制界面与新界面之间的跳转以及界面间的数据传送。Activity是Android四大组件之一,它是一个活动,可以进行界面显示并且执行相应的逻辑任务。在Activity之间传递对象用Intent来完成,Intent是一个将要执行的动作的抽象描述,由Intent来协助完成Android各个组件之间的通讯,并且完成数据间的传输[59]。
密码认证界面需要输入密码,并且进行密码验证,还需要将相应结果返回设备控制界面,该结果还决定着系统模式的切换与否,所以还需要完成界面间的数据传送。利用Bundle对象,将其放入Intent中来完成这两个界面间的数据传送。Bundle类用来携带数据,存放key-value(名值对形式)的值,提供各种数据类型的put()以及get()方法。所以需要新建Intent以及Bundle对象,通过put()操作将数据放入Bundle对象中,通过Intent.putExtras(Bundle)将数据添加到Intent中。当确认按钮被点击时,若文本输入框内输入为正确密码,会将密码放入Bundle中,并且关闭该界面回到上一级界面即设备控制界面;当输入为错误密码时,会有弹窗提示“密码错误,请重新输入”。当取消按钮被点击时,会将“fail”的结果放入Bundle中,并且关闭该界面返回上一级界面即控制界面。
在界面设计上,按照系统需求,该界面需要有文本输入框以及按钮。文本输入框采用EditText组件,显示提示文字设置为“请输入密码”。两个按钮都采用Button组件,分别显示为“确认”、“取消”,密码认证界面如图4.30所示。
4.4.7 APK文件制作
在APP调试阶段,可以通过数据线将手机与电脑连接在一起,将手机设置为调试模式,点击“Runapp”即可运行代码在手机上安装该APP。在APP开发完成后,需要将程序打包成APK(AndroidPackge)文件。因为安卓项目是以包名来作为唯一的标识,当一个手机上安装相同包名的应用时,后面安装的应用就会覆盖前面安装的应用,所以将程序打包,就可以避免这种情况。打包过程中会进行签名,可以确定发布者的身份,也可以保护自己应用的完整性,从而确保程序包中的文件不会被替换。更重要的是,将程序打包成APK文件后,才能将APP发送给别人。
APK文件制作需要在AndroidStudio中完成,制作步骤如下:
(1) 选择调试好的程序在AndroidStudio打开,选择Build中的GenerateSignedBundle/APK,勾选APK。
(2) 第一次打包需要点击“Createnew”新建签名文件,创建签名文件存放路径以及名称,填写签名文件相关信息,例如密码、别名、有效年限等,填写完成点击“Finish”。
(3) 回到选择签名文件界面,填写密码以及别名,选择“Rememberpasswords”,下次打包就可以不用填写了。
(4) 选择生成版本,有release以及debug版本。二者相比,release版本更小、更安全。但是release版本是用在上传应用市场上,所以可以选择debug版本,在使用中做进一步的测试。
(5) 打包成功后会弹出提示信息,在Project目录下可以看到一个APK文件,如图
4.31所示。将该文件发送至手机,就可以进行安装了。
图4.31Project目录中的APK文件
本篇从四个部分介绍了系统软件设计。第一部分为STM32单片机软件程序设计,分为程序开发环境、主程序设计、检测子程序设计、显示子程序设计、自动模式子程序设计以及手动模式子程序设计。第二部分为ESP8266WIFI通信模块固件软件实现,主要介绍了机智云IoT云平台研发的GAgent固件以及移植工作。第三部分为机智云IoT开发平台设计与实现,主要介绍了机智云IoT平台应用设置以及推送功能设置。第四部分为手机APP软件设计与实现,介绍了Android开发平台搭建以及手机APP各界面设计。