基于MQTT的智能家居系统的设计与实现

2019-04-03 01:44卢于辉秦会斌
智能物联技术 2019年2期
关键词:家居智能家居客户端

卢于辉,秦会斌

(杭州电子科技大学新型电子器件与材料研究所,浙江杭州310018)

0 引言

结合物联网技术与嵌入式技术,可以将家庭中的各种设备通过APP进行无线控制,实现家居智能化[1]。因此设计一款低成本、高可靠、使用简便、用户体验高的智能家居系统具有很重要的意义。传统的智能化家居系统一旦手机绑定成功,解绑过程比较复杂,需要手机端和硬件端同时操作才能解绑,也不能根据用户需求动态地添加、删除设备,使得用户体验和系统通用性都比较差[2]。

针对传统智能家居出现的问题,本文提出并设计了基于MQTT控制的智能家居系统,可以动态添加、删除设备及实现对设备的近远场控制,同时在设备端增加一键删除功能,手机端和硬件端都可同时删除设备信息。系统通过ESP8266 WIFI模块直接控制家居,不需要额外的MCU,大大减少了成本和体积[3][4]。由于MQTT协议精简、易于实现,在控制功耗和节约带宽上表现出很好的性能[5-7],系统采用MQTT协议进行消息推送。在内网通过基于UDP的SmartConfig等实现了用户的个人信息管理、设备的个人配网绑定,并且无论在内网还是外网都可以随时随地控制家居设备。

1 系统总体架构

1.1 MQTT的优势

MQTT协议最早由IBM公司在1999年提出,是ISO标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。该协议工作在TCP/IP协议族上,属于为硬件性能低下的远程设备以及网络状况糟糕的情况设计的发布/订阅型消息协议。同CoAP、HTTP等其他协议相比,具有以下优势:

(1)每消息的标题可以短至2个字节。同时,对于HTTP,为每个新请求消息重新建立HTTP连接会导致重大的开销,而MQTT所使用的永久连接显著减少了这一开销。

(2)能够从断开等故障中恢复,而且没有进一步的代码需求。相反,HTTP无法原生地实现此目的,需要客户端重试编码,这可能增加幂等性问题。

(3)专门针对低功耗目标而设计。HTTP的设计没有考虑此因素,功耗较高。

(4)HTTP堆栈上,维护数百万个并发连接需要做大量工作来提供支持,而且大多数商业产品都需要为处理这一数量级的永久连接而进行优化。IBM提供了IBM MessageSight单机架装载服务器,经过测试能处理多达100万个通过MQTT并发连接的设备。

MQTT以上的优势再加上其完全开源,国内外的许多云供应商如腾讯、阿里、百度以及Azure、AWS、Bluemix均有对MQTT的支持,已经形成了较好的生态圈。所以,MQTT应用在智能家居中较为方便。

1.2 基于MQTT的智能家居系统架构设计

智能家居系统总体可分为4部分:基于Android平台的客户端、云服务器、WIFI模块、智能家居设备。系统总体框架如图1所示。

图1中WIFI模块通过发送心跳包和云服务器维持长连接,主动上报设备状态,用户通过Android客户端登录家居控制APP配置网络,WIFI模块通过UDP广播获取连接WIFI所需要的用户名和密码,连上WIFI,此时设备和客户端处于同一网段内,Android客户端可以直接对设备进行添加、删除、控制等操作。若客户端和设备不在同一网段时,客户端通过HTTP通信连接到云服务器,云服务器将指令经过MQTT推送机制转发给WIFI模块,从而控制设备。系统通过内网和外网相结合的方式控制设备,有效解决了内网不可用时不能控制设备的问题,确保用户随时随地控制家居设备。

图1 系统总体框架

2 硬件设计

本系统的WIFI模块选用ESP8266,该模块是2015年推出的WIFI芯片,主要由网路模块、控制模块和微处理器模块三部分组成[8]。其电路如图2所示。

2.1 通信部分的固件编程设计

硬件部分采用ESP8266 WIFI模块,完成相关功能需要对其固件进行编程,主要的设计思路如下:

首先让ESP8266进入混杂模式,进而进入SmartConfig模式,在SmartConfig的模式下,通过UDP广播获取连接WIFI所需要的用户名和密码,同时还要获取与之相配对的手机号码,该号码用于告诉云端服务器ESP8266与哪部手机配对。代码和注释如下:

case SC_STATUS_FIND_CHANNEL://开始扫描信道

caseSC_STATUS_GETTING_SSID_PSWD://获取配置模式是微信的AirKiss还是SmartConfig

图2 ESP8266模块电路图

case SC_STATUS_LINK://此状态可以得到WIFI的用户名和密码

接着根据MQTT协议来搭建MQTT客户端,其过程如下:

(1)与MQTT服务器建立TCP连接。

(2)根据MQTT协议进行连接、订阅、设置心跳包等操作,考虑到绑定过程的唯一性,其订阅内容是ESP8266的mac地址。

搭建完MQTT的客户端后,需要搭建另一个客户端,可以与云端服务器进行通信,其过程如下:

(1)与云端服务器建立TCP连接。

(2)通过HTTP的post请求来上传设备信息到云端服务器中。

代码和注释如下:

os_sprintf(databuf,"telphone=%s&type=3&mac="MACSTR"&name=fan&status=0&data1=2&data2=%d&data3=0",telnum,MAC2STR(mac_addr),turnonoff);

//将要传的数据通过字符串的形式给databuf

os_sprintf(buf,"POST/suibian/mqtt/desend.action HTTP/1.1 Host:主机地址 User-Agent:ESP8266 Content-Length:%d Cache-Control:no-cache Content-type:application/x-www-formurlencoded %s",os_strlen(databuf),databuf);

//根据HTTP中的post请求模式,将字符串传递给buf

InterNet_TCP_SendData(buf,0,pCon);

//通过TCP发送请求

2.2 控制部分的固件编程设计

智能家居设备有多种,这里以控制单灯和风扇为例,其他设备类似。

2.2.1 对单灯的控制

主要通过PWM实现对单灯亮度的控制,ESP8266的PWM波产生方式有两种,一种是调用内部的API函数,这种方式产生的PWM波具有较高的调节精度,但缺点是这种精度的调节主要靠后面的窄波,也就是说每个PWM波周期都具有一小段窄波,所以该模式下PWM波的占空比达不到100%。另一种是通过定时器进行软件编程来产生PWM波,该模式下PWM波的占空比可以达到100%,但调节精度要低很多。由于我们所控制的小灯采用的是上拉模式(必须保证占空比100%),其调节精度不需要那么细致,所以采用第二种方法比较合理。

2.2.2 对电机的控制

主要利用PWM波来实现对电机速度的控制。由于ESP8266引脚所产生的PWM波无法驱动电机的转动,故增加L298N驱动模块来驱动电机,同时还增加两个控制引脚来控制电机的正转和反转。以下是PWM转速调整程序:

voidpwm_check_high(void*arg){os_timer_setfn(&PWMTimer_ALL,(os_timer_func_t*)pwm_check_high,NULL);//进行下一次定时

os_timer_arm_us(&PWMTimer_ALL,1000,0);

//周期为1000us

if(HIGH_LOW==1000)

//HIGH_LOW表示高电平的时间,若为1000全高

{gpio_output_set(BIT12,0,BIT12,0);

os_timer_disarm(&PWMTimer_HIGH);}

else if(HIGH_LOW==0)//全为低电平时

{gpio_output_set(0,BIT12,BIT12,0);

os_timer_disarm(&PWMTimer_HIGH);}

else{//0到1000之间

gpio_output_set(BIT12,0,BIT12,0);

os_timer_setfn(&PWMTimer_HIGH,pwm_check_low,NULL);

//从HIGH_LOW时间后开始输出低电平

os_timer_arm_us(&PWMTimer_HIGH,HIGH_LOW,0);}}

2.2.3 一键式解绑的实现

当WiFi模块采集到一段时间的低电平时,触发解绑过程,该过程步骤如下:

马上断开HTTP,断开MQTT,断开WIFI,清除flash内所绑定的电话号码记录,清除WIFI的用户名和密码,进入SmartConfig模式。

3 客户端设计与实现

3.1 客户端功能设计

基于Android的控制客户端主要实现用户个人信息管理、设备信息管理、设备配网连接和设备的远场控制,如图3所示。

图3 客户端功能模块

(1)用户信息管理。手机客户端使用用户手机号码或者QQ、微信、微博等第三方账号进行注册登录,登录成功的用户可以在个人中心管理界面查看和修改个人信息。

(2)设备信息管理。系统暂时采用一对多原则,即一个用户可以拥有多台设备,但一个设备只能归属一个用户。成功添加设备后,用户可以在设备列表界面对设备进行增、删、改、查、分享等一系列操作,应用会自动在云平台服务器对设备的操作进行同步。其中设备的内部信息需要进入控制界面才能进行相应的更改。

(3)设备配网连接。使用ESP官网提供的ESP8266无线WIFI模块,通过基于UDP的SmartConfig协议,当设备和客户端处于同一个局域网时,通过UDP广播将自身连接的WIFI属性传递给ESP8266无线WIFI模块,模块成功连接上网络便自动完成与用户账号的绑定,即设备连接成功。

(4)远近场设备控制。设备的配网必须在同一个局域网之下,但设备的控制没有网络的限制,设备成功添加到用户设备列表后,点击设备,通过相应的控制和触发按扭即可完成对设备的控制,应用集成了多个控制APP,可以对不同的设备进行专一性控制。

3.2 客户端框架

客户端采用MVC架构,将应用的界面显示、逻辑控制和业务处理分离,降低应用的耦合性,增加程序运行的健壮性[9][10],同时方便后期的运行维护。应用中使用的框架有异步网络请求框架、基于UDP的SmartConfig框架、LiteOrm轻量级数据库框架、ShareSDK的三方登录或分享框架以及强大的谷歌MD设计框架。移动端控制设备使用Volley请求框架,可以有效预防用户频繁操作,防止网络请求频繁操作而出现网络故障。

3.3 通信模块的设计与实现

系统采用基于UDP协议的SmartConfig通信和基于TCP的HTTP通信。通信模块设备配网连接流程如图4所示。

图4 通信模块设备配网连接流程图

新用户注册并且登录成功后,设备列表的设备数量为0,需要用户通过SmartConfig将手机连接的有效WIFI信息配置给设备连接网络,最终完成用户与设备的绑定。系统中其他的访问都是基于TCP的HTTP通信的短连接,除控制命令外,访问外端需要携带用户基本信息,向服务器发送验证,验证通过才能完成相应的操作,否则视为违规操作,需要用户重新登陆完成身份的验证,以确保用户和设备信息安全。

3.3.1 UDP通信

客户端通过UDP通信发送WIFI的SSID和密码到ESP8266WIFI模块,进行SmartConfig配对,成功则让模块连接上网。

//获取输入文本

String ssid=etName.getText().toString();

String passwrod=App.getInstance().getUser().getUsername()+etPwd.getText().toString();

boolean isSsidHidden=cbSsid.isChecked();

if(ssid==null||TextUtils.isEmpty(etPwd.get-Text())){

Toast.makeText(this,"请先连接路由器",Toast.LENGTH_SHORT).show();return;}

//本地保存数据

share.edit().putString(ssid,passwrod).commit();

//启动异步任务开启SmartConfig

new ConfigNetWork(this,ssid,bssid,passwrod,isSsidHidden).execute();

3.3.2 HTTP通信

应用中主要采用了两类HTTP通信,一类是常规HTTP请求,另一类是基于Volley的HTTP网络访问。不涉及频繁操作并且需要对身份进行验证的访问采用的是常规HTTP。但对设备的控制采用的是基于Volley的网络访问。Volley小数据量和请求队列等优点保证了用户的每次操作能得到正确的结果,同时也可以预防因用户频繁控制而导致的网络延迟。

RequestParams params=new RequestParams();

params.put("token",App.getInstance().getToken());

params.put("telphone",tel);

params.put("mac",mac);

httpclient.post(Const.MAIN+Const.QUERY_SINGLE_DEVICE,params,new AsyncHttpResponse-Handler());

//携带token查询单个设备

4 云平台的总体设计

云平台由应用服务器、MQTT消息推送服务器和数据库服务器组成,应用服务器主要处理用户登录、注册、设备查询等业务逻辑问题,MQTT消息推送服务器主要负责移动客户端控制设备的命令推送以及设备上线后将设备信息的推送,云平台的架构如图5所示。

图5 云平台的架构

4.1 应用服务器

由于JAVA开发效率高、性能稳定且跨平台,应用服务器后台采用JAVA编写,使用Spring+SpringMVC+Mybatis框架,用户和服务器的交互使用Md5Hash算法进行加密,确保用户信息的安全。加密代码如下:

Public static String md5(String password,String salt){return new Md5Hash(password,salt,2).toString();}//高强度加密算法,不可逆。

4.2 MQTT消息推送服务器的设计

图6 MQTT消息推送服务器发布订阅模式

MQTT发布/订阅模式如图6所示。系统中使用MQTT推送协议完成设备与用户的绑定以及用户控制设备命令的传达。在CentOS系统的服务器上安装Mosquitto,通过订阅和发布来管理所有主题,客户端和设备都可以指定主题(topic)发布消息,服务器代理接收,并将消息转发,当有订阅者订阅操作时,根据主题获取发布的内容。客户端向设备发送控制指令流程如图7所示。

代码和注解如下:

public void SendControlCmd(final String cmd,final String mac){

//手机客户端依据mac向服务器发送设备控制命令

Stringurl="http://106.14.9.111:8080/suibian/mqtt/send.action";//服务器请求地址

int method=Request.Method.POST;

Mapparams=new HashMap<>();

//传递控制参数

params.put("data",cmd);

params.put("topic",mac);

return params;

//服务器将其转发到MQTT代理服务器

Messagemessage=MessageBuilder.withPayload(string).setHeader(MqttHeaders.TOPIC,devic.getTelphone()).build();

//发布主题和内容

mqtt.handleMessage(message);//提交

图7 客户端向设备发送控制指令流程

4.3 数据库服务器设计

数据库使用MySQL和Redis,使用Redis作为MySQL的缓存数据库,减小了MySQL的压力。用户第一次登陆,服务器验证成功后,会签发一个Token,并将Token携带的信息存放在Redis里,同时将Token发送给客户端,客户端收到Token以后将其存放在Cookie里。客户端每次访问服务器都会带着Token,服务器接收到请求后,会去Redis服务器验证Token,如果验证成功,将相关信息返回给客户端。

5 系统测试与界面展示

用户通过客户端登录后,能够根据用户需要动态添加家居设备、管理用户信息,管理WIFI模块下的设备,以及对家居设备进行控制。本测试选用灯和空调作为家居设备,首先通过手机客户端配网连接,WIFI模块通过UDP广播来获取连接WIFI所需要的用户名和密码,连接上网络;手机客户端添加设备(灯和空调),对灯进行打开、关闭、调节亮度操作,对空调进行打开、关闭、调温、调风速操作,实时控制家居设备。设备控制视图如图8所示。

图8 设备控制视图

手机客户端和硬件端都可以解绑,长按硬件端按钮,手机和硬件端同时删除设备信息,快速解绑。

6 结语

本文设计并实现了基于MQTT的智能家居系统,选用ESP8266WIFI模块进行通信和控制,成本低、体积小;采用MQTT推送机制,速度快、实时性好,通过内外网配合的方式通信,时效性高;一键式清除设备,使绑定和解绑过程更加直观和方便。本系统能够动态添加和控制设备,实现对家居设备随时随地控制。

猜你喜欢
家居智能家居客户端
你的手机安装了多少个客户端
你的手机安装了多少个客户端
“人民网+客户端”推出数据新闻
——稳就业、惠民生,“数”读十年成绩单
打造日常家居“氛围感”
基于PLC的智能家居控制系统研究
台北家居
基于Zigbee的无线通信技术在智能家居中的应用
智能家居未来感初体验
新华社推出新版客户端 打造移动互联新闻旗舰
智能家居更贴心