【学习笔记】智能家居(2):基于Android平台的智能家居系统设计
摘 要: 为了实现家居生活智能、方便等目的,提出一种基于Android平台的智能家居系统。采用内外网通信方式,使得当家庭宽带不可用时仍能通过内网实现对家居设备的控制。将用户配置信息、设备信息存在网关使得不同客户端能信息共享,实现动态添加、删除动作。采用推送而不是轮询,实时性好。客户端APP功能齐全,云计算的使用实现了外网控制,同时便于未来的系统扩展。
1 系统总体框架图
系统由客户端、云计算中心、网关和家庭设备组成。系统框架如图1所示。
客户端实现对底层设备的控制方式包括:(1)内网控制:客户端使用家庭网络与网关直接通信,由网关控制底层设备;(2)外网控制:客户端与网关不在同一网段内,客户端指令由云服务器转发给对应的网关,再由网关控制底层设备。采用内外网的通信方式,使得家庭宽带网络在不可使用的情况下,仍能通过内网通信实现对设备的控制,同时节省用户数据流量。每次运行客户端软件,会自动获取网关处的配置信息、设备信息。网关同步底层设备状态,当发生改变时由网关转发给客户端,使用户能及时获知底层设备的最新状态。
2 客户端设计与实现
2.1 客户端功能说明
Android客户端功能模块如图2所示。
设备管理是核心模块,包括自定义房间和设备。可添加、删除、修改房间,房间下可添加设备。点击设备管理,通过后台获取当前用户下的所有房间并以JSON格式返回,客户端完成解析并显示在界面上,点击添加图标进入添加房间界面,填写房间名称并将用户ID与房间名称发往网关并保存至数据库。通过长按房间界面实现删除与修改动作。点击房间会显示该房间下的所有设备,可添加设备,长按删除设备,不提供修改设备动作。可以控制单个设备或区域内的所有设备,也可以对某个情景模式关联的设备进行联动控制。
2.2 客户端框架
在Eclipse开发环境下,采用java语言,基于MVC模式对客户端进行设计。视图层View负责生成用户界面,接收输入并显示结果。控制层Controller用于监听用户操作并作出反应。模型层Model定义了各种功能模块,包括通信模块、数据库模块、数据格式的封装和解析模块等,其中通信模块是核心。
2.3 通信模块
通信模块负责客户端和服务器或网关间的消息通信和链路维护。通信方式有:TCP/UDP、Http、MQTT推送。系统的通信协议如图3。过程如下:
(1)第一次使用软件,需在云端完成注册,将用户名和密码以Http方式发到云端,并获得服务器生成的用户ID。同时在家庭WiFi环境下使网关加入局域网:将WiFi的SSID和密码通过加密算法进行加密,将加密序列生成UDP数据包并发送出去,网关获得该包并解析出WiFi相关信息,实现自动连接到路由器。
socket=new DatagramSocket();
sequence=sequence_init(account.toString(),
pswd.toString());//生成加密序列
while(flag){
for(int i=0; i<len; i++){String str = "";
for(int j = 0; j<sequence[i]; j++){str += "a";}
outPacket=new
DatagramPacket(str.getBytes(),str.length(),
InetAddress.getByName(s_gateway),4000);
socket.send(outPacket);}
socket.receive(receive);
(2)绑定网关。网关加入局域网后监听客户端广播的数据包并返回自己的IP地址和TCP通信端口,客户端通过TCP的Socket发送用户ID到网关实现和网关的绑定,同时将用户和网关的唯一标识号发送至云端实现绑定,这样客户端通过外网访问云服务器时,服务器能转发指令给对应的网关。
(3)以后每次使用软件前,都要判断当前网络环境。即判断客户端和网关是否在同一网段内。若客户端没有接收到返回信息,说明它们不在一个网段内,则选择通过Http方式连接云服务器。
(4)采用MQTT实现设备状态的实时更新。订阅客户端所绑定的网关,网关同步底层设备状态,当状态改变时,由网关发送给MQTT server,再推送至客户端。
系统的通信模块活动图如图4所示。
2.4 通信模块实现
2.4.1 Http通信
外网通信方式下,用户登录、获取设备信息等由客户端采用Http建立主动连接,服务器将结果以JSON格式返回。模块中的Http请求用Android-Async-Http网络请求库实现,它是基于Apache HttpClient库之上的一个异步网络请求处理库,网络处理均基于Android的非UI线程,不阻塞UI操作,通过回调方法处理请求结果。
Android-Async-Http使用简单,通过核心类AsyncHttp-
Client的实例就可以执行网络请求,提供put、post等方法。登陆过程如下:
(1)创建AsyncHttpClient的实例
AsyncHttpClient client = new AsyncHttpClient();
(2)创建请求参数的封装对象
RequestParams params = new RequestParams();
params.put("username", userName);
params.put("userpass", userPass);
(3)执行post方法
client.post(url, params,
new AsyncHttpResponseHandler (){
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBody){
if(statusCode == 200){//成功
Toast.makeText(this,new String(responseBody) ).show();}}
Public void onFailure(int statusCode, Header[] headers,
byte[] responseBody Throwable error){
error.printStackTrace();//失败
}}…);
new AsyncHttpResponseHandler()这个实例用于接收请求结果,一般重写onSuccess()和onFailure()方法接收请求成功或失败的消息。onSuccess()方法的参数responseBody为响应内容字节。
2.4.2 MQTT推送
MQTT是基于TCP/IP协议,专为物联网开发的轻量级通信协议。该协议针对网络差、计算能力低的设备做了特殊处理,使其能适应物联网应用场景,有占用宽带小、耗电量少等优势。协议里有两个主要角色:MQTT client和MQTT server。client向server订阅某个话题就能收到发布到该话题的所有消息;client发布消息到某个话题下,则该话题的所有订阅者都能收到。通信时序图如图5所示。
本文通过MQTT实现客户端实时获得设备信息。客户端对应MQTT client,是消息订阅者。当状态改变时,由设备将信息发送给网关,再由网关传递给MQTT server,再推送至订阅了该网关的客户端。使用MQTT,须将mqttv3.jar包加入Android应用程序中,它是IBM提供的MQTT协议的实现。APK调用该jar包提供的API接口,就能建立MQTT client和MQTT server的连接。流程如下:
(1)创建一个MqttClient对象,参数包括MQTT server所在的IP地址和端口号、客户端唯一标识clientid等。
MqttClient client=new MqttClient("tcp://123.57.219.126:
1883",
"test", new MemoryPersistence());
(2)创建MqttConnectOptions的对象并进行设置。用户名和密码用于连接MQTT server时进行验证,心跳时间用于client定时发送心跳包,以便和server保持连接。
MqttConnectOptions options=new MqttConnectOptions();
options.setUserName(userName);//用户名
options.setPassword(passWord.toCharArray());//密码
options.setKeepAliveInterval(20);//心跳时间
(3)给客户端设置回调。
client.setCallback(new MqttCallback() {
public void connectionLost(Throwable cause) {
//连接丢失后,进行重连}
public void deliveryComplete(IMqttDeliveryToken token){
//publish后会执行到这里}
public void messageArrived(String topicNam e,
MqttMessage message) throws Exception {
//subscribe后得到的消息会执行到这里面
Message msg = new Message();
msg.what = 1;
msg.obj = topicName+"---"+message.toString();
//通过handler传递给主线程进行UI更新
handler.sendMessage(msg);}});
(4)连接到MQTT server。
client.connect(options);
(5)订阅某个网关的话题,接收网关发布到该话题下的消息,即设备信息。TOPICS是客户端订阅的话题,设为“gateway-example”。QOS_VALUES代表服务质量保证级别,1表示至少会发送一次消息。
client. subscribe(TOPICS, QOS_VALUES);
MQTT技术可以实现底层设备信息的实时更新,非常适合智能家居这种使用场景。
3 云计算中心
云计算将计算任务分布在大量计算机构成的资源池上,使各种应用系统按需获取计算力、存储空间和信息服务。云计算作为一种新技术受到越来越多的亲睐,很多学校、企业都建立了云计算数据中心。本文采用阿里云ECS(Elastic Compute Service)作为云计算中心,它是一种简单高效、处理能力可弹性伸缩计算服务。服务器开发框架采用Jquery+SpringMVC+Mybatis+Ehcache。Mybatis是一个基于Java的持久层框架,支持普通SQL查询。为了提高Mybatis的性能,需要添加第三方缓存组件支持,目前用的比较多的是Ehcache缓存。Ehcache性能强大、快速简单,具有多种缓存策略。Mybatis与Ehcache整合可以提高性能,提高查询效率,降低数据库压力。
4 功能测试
主要对设备的实时控制和状态值的实时刷新进行了验证。设备用继电器模拟,使用安装Android程序的手机作为客户端进行功能测试。
在外网环境下,当客户端连接服务器后,触发设备开关按钮,可以将控制命令由云中转至网关,再转发至底层设备控制继电器开关,同时设备的最新状态和传感器值也会在客户端进行实时刷新。测试结果如图6,客户端能保持和网关信息同步。
5 结论
本文简要介绍了基于Android平台的智能家居系统设计和关键技术。该系统结合了云计算和MQTT技术,实现远程控制和信息同步,同时提供了内网控制,设备信息存在网关保证用户信息共享。为市场化应用提供一种参考。
◆ ◆ ◆ ◆ ◆◆ ◆ ◆ ◆ ◆◆ ◆ ◆ ◆ ◆◆ ◆ ◆ ◆ ◆