写点什么

基于 IOT 物联网设计的智能家居系统 - 智慧门锁

作者:DS小龙哥
  • 2022 年 3 月 17 日
  • 本文字数:6461 字

    阅读完需:约 21 分钟

1. 前言

近年来,在智能化、自动化高新技术的驱动下,智能家居工作进入了飞速展开时期。根据国家相关部委推动智慧城市建设布置,以及各地方政府的安排,我国发动智慧城市建设和在建智慧城市的城市数量逾越 500 个。跟着各地智慧城市建设提速,相关商场规划将有望扩容至千亿,甚至万亿等级。


智能家居是以住宅为平台,利用综合布线技术、网络通信技术、 安全防范技术、自动控制技术、音视频技术将家居生活有关的设施集成,构建高效的住宅设施与家庭日程事务的管理系统,提升家居安全性、便利性、舒适性、艺术性,并实现环保节能的居住环境。


智能家居可以说是一个自动化的物联网系统,你可以用这个系统享受更高效、更有趣的服务(懒人的福利),比如你可以让你通过你的手机或智能音响控制你空调的温度,控制你的扫地机器人扫地,控制你家的窗帘,或者当你离开家的时候家里的台灯,吊顶灯,床头灯都会自动关闭,智能音响会自动说对你说一路顺风,提高自己的生活体验。


智能家居是一个大框架,里面包含了家庭里所有的电器设备智能化,智能门窗、智能门锁、智能电视、智能影像、智能插座、智能空调、智能电饭煲、智能热水器等等。


这篇文章采用智能家居里的典范--智能门锁,来介绍如何让锁变得智能


实现的核心: 将家里的门锁通过 WIFI,通过 MQTT 协议连接上华为云 IOT 物联网平台,再开发一个配套的手机 APP,完成远程开锁关锁的功能。华为云 IOT 服务器的响应速度非常快,在手机端点击开锁、关锁后,实体设备可以快速响应。


使用华为云物联网云平台完成智能门锁这个需求时,需要了解三个部分的知识点:


(1)如何通过华为云 IOT 物联网平台创建产品,创建设备。?


(2)如何让设备登录到华为云 IOT 平台(获取 MQTT 协议三元组信息) ?


(3)开发手机 APP,开发电脑桌面软件、微信小程序时,如何与华为云 IOT 云平台进行对接?


接下来,下面就陆续介绍整个产品的开发过程,解决这 3 个疑问,文章里图片、文字描述、代码都会贴出来,只要认真看一遍,就可以对现在的智能家居、物联网、云平台这些概念有个了解了。


2. 设备硬件介绍

当前产品是做一个智能家居里的系列产品--智能门锁。为了模拟真实设备硬件,采用步进电机模拟门锁,STM32+ESP8266 作为主控芯片和联网设备。


整体思路:


在华为云 IOT 物联网平台构建智能锁项目,配置好云端,设备端通过 ESP8266 连接华为物联网平台,实现数据上报,交互,实现远程开锁、关锁、获取锁的状态等功能,不用担心忘记出门关锁,也不用担心忘记带钥匙无法开门的情况。


ESP8266 是物联网解决方案里比较热门的 WIFI 设备,支持串口+AT 指令控制,任意支持串口的单片机都可以使用 ESP8266 快速实现联网。



步进电机采用常规 28BYJ-48 来模拟当做门锁的电机,驱动板采用 ULN2003。


3. 创建华为云 IOT 云端设备

登录官网: https://www.huaweicloud.com/


直接搜索物联网,打开页面。



选择设备接入:



选择免费试用:



在产品页面,点击右上角创建产品:



填上产品信息:



得到产品 ID,保存好 ID,点击查看详情:


产品ID为:61b9ba3a2b2aa20288c1e7f1.
复制代码



点击设备页面,注册设备:



填充信息进行注册:



保存设备密匙和设备 ID,点击保存关闭会自动下载文件保存,后面生成密码和登录账号需要使用



关闭后就看到创建好的设备了:



点击产品页面,选择刚才创建的产品:



选择自定义模型---创建数据模型服务:




选择新增属性,创建设备的属性


4. 创建 MQTT 登录账号和密匙

设备创建完成接来下生成 MQTT 登录账号、密匙,方便设备登录云端平台。


官网工具地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/



打开刚才创建设备时,下载的密匙文件,把内容复制出来对应的填进去,生成即可。


5. 拼接主题订阅与发布的格式

官方文档介绍: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html



在产品页面可以,看到主题的全部格式:



总结的格式如下:


格式: $oc/devices/{device_id}/sys/messages/down//订阅主题: 平台下发消息给设备$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down

格式: $oc/devices/{device_id}/sys/properties/report//设备上报数据$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report
上属性的数据格式://上报的属性消息 (一次可以上报多个属性,在json里增加就行了){"services": [{"service_id": "lock","properties":{"门锁":1}}]}
复制代码


上面属性里的服务 ID 和属性里的名称,在设备页面,影子设备页面查看。


6. MQTT 客户端模拟设备登录云端

下面使用 MQTT 客户端模拟设备登录服务器测试,看设备创建的是否 OK。


服务器的 IP 地址是: 121.36.42.100


端口号是: 1883


打开 MQTT 客户端软件,按照提示,输入相关参数后,点击连接,然后再点击订阅主题,发布主题即可:



查看云端服务器的情况: 可以看到设备已经在线了,并且收到上传的数据。



修改一下锁的状态,上报属性再查看:



发现云端的状态也已经改变,现在设备上报已经 OK。



接下来测试命令下发,实现远程开锁关锁的功能:


打开产品页面,新增加命令:





命令添加成功:



在设备页面,选择同步命令下发:




点击确定后,查看 MQTT 客户端,发现已经收到数据了:



$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497/sys/commands/request_id=88e2626f-290d-405e-962d-51554445a8fd{"paras":{"lock":1},"service_id":"lock","command_name":"lock"}
复制代码


设备端解析收到的数据,就可以完成多步进电机的控制,完成开锁关锁。

7. 开发硬件设备端

在前面章节里完成产品的云端创建、设备创建、设备模拟登录,开锁关锁测试。本小节,就使用真实设备完成上云,登录华为云 IOT 平台,实现数据通信。


设备端使用的 STM32 作为主控芯片,IDE 采用 keil5,下面贴出了工程核心代码。




工程是 keil5 工程,代码非常多,下面只贴出了 main 函数里的代码。


main 函数代码如下:


#include "stm32f10x.h"#include "led.h"#include "delay.h"#include "key.h"#include "usart.h"#include <string.h>#include "timer.h"#include "bluetooth.h"#include "esp8266.h"#include "mqtt.h"
//华为物联网服务器的设备信息#define MQTT_ClientID "61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510"#define MQTT_UserName "61b9ba3a2b2aa20288c1e7f1_QQ1126626497"#define MQTT_PassWord "385ce91dfe7da5b7431868d5d87e7998163c493344040935d5a00024d6324242"
//订阅与发布的主题#define SET_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down" //订阅#define POST_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report" //发布
char mqtt_message[200];//上报数据缓存区
int main(){ u32 time_cnt=0; u32 i; u8 key; LED_Init(); BEEP_Init(); KEY_Init(); USART1_Init(115200); TIMER1_Init(72,20000); //超时时间20ms USART2_Init(9600);//串口-蓝牙 TIMER2_Init(72,20000); //超时时间20ms USART3_Init(115200);//串口-WIFI TIMER3_Init(72,20000); //超时时间20ms USART1_Printf("正在初始化WIFI请稍等.\n"); if(ESP8266_Init()) { USART1_Printf("ESP8266硬件检测错误.\n"); } else { //非加密端口 USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode("CMCC-Cqvn","99pu58cb","121.36.42.100",1883,1)); } //2. MQTT协议初始化 MQTT_Init(); //3. 连接华为服务器 while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)) { USART1_Printf("服务器连接失败,正在重试...\n"); delay_ms(500); } USART1_Printf("服务器连接成功.\n"); //3. 订阅主题 if(MQTT_SubscribeTopic(SET_TOPIC,0,1)) { USART1_Printf("主题订阅失败.\n"); } else { USART1_Printf("主题订阅成功.\n"); } while(1) { key=KEY_Scan(0); if(key==2) { time_cnt=0; sprintf(mqtt_message,"{\"services\": [{\"service_id\": \"lock\",\"properties\":{\"门锁\":1}}]}"); MQTT_PublishData(POST_TOPIC,mqtt_message,0); USART1_Printf("发送状态1\r\n"); } else if(key==3) { time_cnt=0; sprintf(mqtt_message,"{\"services\": [{\"service_id\": \"lock\",\"properties\":{\"门锁\":0}}]}"); MQTT_PublishData(POST_TOPIC,mqtt_message,0); USART1_Printf("发送状态0\r\n"); }
if(USART3_RX_FLAG) { USART3_RX_BUFFER[USART3_RX_CNT]='\0'; for(i=0;i<USART3_RX_CNT;i++) { USART1_Printf("%c",USART3_RX_BUFFER[i]); } USART3_RX_CNT=0; USART3_RX_FLAG=0; }
//定时发送心跳包,保持连接 delay_ms(10); time_cnt++; if(time_cnt==500) { MQTT_SentHeart();//发送心跳包 time_cnt=0; } }}
复制代码

8. 开发手机 APP

8.1 功能介绍

为了更方便的完成智能门锁开锁、关锁的操作,与设备完成交互,还需要开发一个配套的手机 APP,官方提供了应用侧开发的 API 接口、SDK 接口,为了方便通用一点,这里采用了 API 接口完成数据交互,上位机软件采用 QT 开发。QT 支持跨平台开发,所有就可以顺便一起开发出 Android、IOS、windows、Linux 等平台的终端软件。还可以通过 wasm 技术,开发 web 网页程序,非常强大的框架。


下面就介绍上位机开发的流程,如何交互等等。


帮助文档地址: https://support.huaweicloud.com/usermanual-iothub/iot_01_0045.html



在文档页面可以看到,提供的接口有,创建产品、创建设备、查询设备属性,查询设备消息等等。


在设计手机 APP 时,可以直接通过提供的 API 接口,创建产品,设备,这样设备端就可以直接注册登录。

4.2 查询设备属性接口

设备属性就是设备上传的传感器状态数据信息,应用侧提供了 API 接口,可以主动向设备端下发请求指令;设备端收到指令之后需要按照约定的数据格式上报数据;所以,要实现应用层与设备端的数据交互,需要应用层与设备端配合才能完成。


下面分别介绍应用测和设备测的实现流程。


(1)应用层下发的指令


帮助文档地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html


接口的在线调试地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ListProperties


如果请求参数和返回值不清楚,写代码前,先使用在线调试接口体验一下,验证数据交互是否 OK。



请求参数里比较总要的两个必填参数,是设备 ID 和服务 ID,这两个参数在第 3 章节就介绍过如何获取了,在产品页面创建自定义属性时可以看到服务 ID。



请求接口总结:


请求方法 GETURI地址  /v5/iot/{project_id}/devices/{device_id}/properties传输协议 HTTPS
拼接好的地址: https://iotda.cn-north-4.myhuaweicloud.com/v5/iot/0e5957be8a00f53c2fa7c0045e4d8fbf/devices/61df9a6bc7fb24029b0c160d_1126626497/properties?service_id=1126626497
其中的project_id和device_id需要根据自己的设备信息修改。

请求头:{ "User-Agent": "API Explorer", "X-Auth-Token": "******", 这个是鉴权用的token "Content-Type": "application/json"}

响应体(设备上传的数据){ "response": { "services": [ { "service_id": "lock", "properties": { "lock": 1 } }, } ] }}
复制代码


请求头里需要填X-Subject-Token参数,这个参数只要是访问任何华为云都需要填,获取具体的流程可以看这里。https://bbs.huaweicloud.com/blogs/317759 翻到第 3 小节。


(2)设备上传数据


应用层向设备端请求查询设备属性时,设备端会收到如下的消息:


$oc/devices/61df9a6bc7fb24029b0c160d_1126626497/sys/properties/get/request_id=336bcb57-0e0a-44d0-90f7-31386cb54a3c{"service_id":"1126626497"}
复制代码


这个消息里有一个主要参数request_id请求 ID,设备端需要解析出这个参数,给应用层响应数据时,需要带上这个 ID。


这个请求属性详细帮助文档看这里: https://support.huaweicloud.com/api-iothub/iot_06_v5_3011.html



设备响应的数据格式:


主题格式: $oc/devices/{device_id}/sys/properties/get/response/request_id={request_id}
示 例:$oc/devices/61df9a6bc7fb24029b0c160d_1126626497/sys/properties/get/response/request_id=336bcb57-0e0a-44d0-90f7-31386cb54a3c
响应的数据格式:{"services": [{"service_id": "healthy","properties":{"HeartRate":127}}]}
复制代码


响应的数据格式可以看这里的介绍: https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html


4.3 在线 API 调试结合设备模拟

下面使用 MQTT 客户端与在线 API 接口联合模拟一下接口效果:


(1)先打开调试页面: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ListProperties


然后填好设备 DI 和服务 ID:



(2)、打开 MQTT 客户端,登录华为云物联网平台(也就是模拟设备上线):



(3)、打开在线 API 调试页面,点击调试: 点击后可以看到页面上已经在等待客户端的响应了。



(4)、MQTT 客户端响应详细


按照前面说的响应格式,拼接好接口,数据。然后发布主题。



(5)、应用层收到客户端响应,调试成功


调试成功后,响应体里收到的就是设备端上传的设备属性数据。


4.4 应用层核心代码

/*功能: 获取token*/void Widget::GetToken(){    //表示获取token    function_select=3;
QString requestUrl; QNetworkRequest request;
//设置请求地址 QUrl url;
//获取token请求地址 requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens") .arg(SERVER_ID);
//自己创建的TCP服务器,测试用 //requestUrl="http://10.0.0.6:8080";
//设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
//构造请求 url.setUrl(requestUrl);
request.setUrl(url);
QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":" "{\"user\":{\"domain\": {" "\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}}," "\"scope\":{\"project\":{\"name\":\"%4\"}}}}") .arg(MAIN_USER) .arg(IAM_USER) .arg(IAM_PASSWORD) .arg(SERVER_ID);
//发送请求 manager->post(request, text.toUtf8());}
//查询设备属性void Widget::Get_device_properties(){ //表示获取token function_select=0;
QString requestUrl; QNetworkRequest request;
//设置请求地址 QUrl url;
//获取token请求地址 requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices/%3/properties?service_id=%4") .arg(SERVER_ID) .arg(PROJECT_ID) .arg(device_id) .arg(service_id);
//自己创建的TCP服务器,测试用 //requestUrl="http://10.0.0.6:8080";
//设置数据提交格式 request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
//设置token request.setRawHeader("X-Auth-Token",Token);
//构造请求 url.setUrl(requestUrl);
request.setUrl(url);
//发送请求 manager->get(request);}
复制代码

4.5 上位机运行效果


到此,智能门锁完成。

发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于IOT物联网设计的智能家居系统-智慧门锁_物联网_DS小龙哥_InfoQ写作平台