前面介绍了如何对NodeMCU进行配网并连接到WIFI,下面到问题就是有了这些之后有什么用?本文将介绍如何连接NodeMCU到公有云(如阿里云,腾讯云),上传数据到云端,订阅云端数据,如何进行设备间通信M2M(Machine to Machine)。
连接到公有云常用方式有MQTT、CoAP、HTTP,NodeMCU通过WIFI连接到网络,使用MQTT方式比较方便,各个平台上都有MQTT客户端,测试也比较方便。
1. MQTT
MQTT的基础知识可以搜到很多,这里不再赘述,只需要了解MQTT使用TCP/IP连接,基于发布/订阅消息模型,可以一对一或者一对多消息通信。具体如何使用各个平台都有相应的工具可以使用,非常方便。
NodeMCU:编译时包含MQTT模块即可以直接作为MQTT客户端使用,最新支持MQTT 3.1版本。
PC端:MQTT.fx客户端,支持Windows、Linux、Mac操作系统,可以快速的连接到云端,并进行数据收发测试。
Android手机端:Android可以直接使用APP(如MQTT Client),如果是自行开发应用各个IOT平台都有相应的SDK提供,并且也有第三方的MQTT SDK可以使用。如果不想要用这些SDK,也可以基于socket通信自行实现协议,MQTT协议比较简单,实现起来也不会很复杂。
2. 连接到阿里云
阿里云作为国内较大的云服务提供商,其IOT云平台功能也非常完善,相关教程比较多,也可以参考上篇中的GitHub代码。这里仅粗略介绍阿里云物联网平台接入方式:
- 注册并登陆物联网平台https://www.aliyun.com/product/iot
- 创建产品:选择设备管理-产品-创建产品,选择直连设备,JSON数据格式。
- 创建设备:选择设备管理-设备-添加设备,输入DeviceName,确认后即可创建成功。
- 设备认证三元组:设备创建成功后,可以获得设备认证三元组ProductKey、DeviceName和DeviceSecret。设备认证三元组就是一个设备的身份证,用于设备连入云平台,不可以泄露。 并且,可以实现设备间隔离,一个设备只能发布和订阅自己的Topic,无法直接通过订阅其他设备的Topic进行设备间通信(设备间通信见章节4)。
- 最后将设备认证三元组填入NodeMCU的代码中,在云平台管理页面就可以看到设备上线了,过程非常简单。接入后云平台管理页面中的设备就和NodeMCU绑定了,相应的消息记录、日志等都可以查询到。
2.1 消息格式
设备的数据上报方式有两种:ICA标准数据格式 (Alink JSON)和透传/自定义,创建产品时选择的是JSON格式,所以默认使用JSON格式上报数据。产品创建成功后,平台会默认几个Topic用于设备的属性及事件的下发及上报。
2.1.1 JSON数据格式
设备的属性可以理解为设备上报的一种数据,这个数据包括设备的信息,如温度、湿度等。
属性上报的Toic由平台创建:/sys/{productKey}/{deviceName}/thing/event/property/post
数据格式为:
{
"id": "123",
"version": "1.0",
"params":
{
"LightStatus": 1
},
"method": "thing.event.property.post"
}
其中,params包含要上报的属性值,具体值的含义由创建的设备确定。
数据上报后,在云平台管理页面相应设备页面中就可以看到对应的属性发生了变化。
2.1.2 新建物模型
在创建产品时,有很多标准的产品类型可以选择,选择标准设备后相应的会默认创建好设备有哪些属性,属性值的范围等,如果需要自定义数据就需要用到自定义物模型,自定义物模型如下:
- 选择设备管理-产品-功能定义
- 选择添加自定义功能
- 对话框中选择类型为属性,设置相应的参数。其中标识符字段将填入上报数据的JSON数据格式中。
- 上报数据后,在设备状态页面可以看到变化。
2.1.3 自定义Topic
如果不想用云平台默认创建的Topic或者数据格式,也可以自定义Topic,并且使用Raw格式上报数据,具体数据格式由设备间自定义。这样就将云平台作为一个基本的MQTT broker来使用,好处是切换云平台只需要改动设备接入部分:
1.选择设备管理-产品- Topic类列表
2.选择创建项目
2.2 生成APP
阿里云IOT平台功能全面,可在线可视化生成APP、WEB应用,数据关联到物联网平台设备的数据,可以快速发布产品。
- 选择开发服务-IoT Studio-新建项目
- 选择移动可视化开发
- 选择数据源配置可以关联设备
2.3 收费规则
阿里云平台在2019-10-15 09:40:09 更新了计费规则,取消了以前的100万条免费消息。。。
3. 连接到腾讯云
对于作为测试用途或者自己制作的小作品,需要用到云服务不多当然是希望越便宜越好,而阿里云IOT已经没有免费的消息流量赠送,所以下面介绍如何接入腾讯云IOT平台,目前腾讯云平台还是有免费的赠送。
腾讯云平台相对阿里云平台功能较为简单,不过该有的功能也都有,接入方式也类似,切换到腾讯云平台不需要更改太多代码。
接入腾讯云平台步骤:
- 注册并登录物联网平台https://cloud.tencent.com/product/iothub
- 进入产品列表页面,选择创建产品,选择节点类型设备,JSON数据格式
- 选择设备列表-新建设备
- 设备认证三元组:设备创建成功后,可以获得设备认证三元组:tproductID、DeviceName和DeviceSecret。
其中,设备密钥显示的是Base64编码的数据,而使用时需要用解码后的数据,需要注意。 - NodeMCU接入平台:腾讯云平台MQTT接入参考:https://cloud.tencent.com/document/product/634/32546,提供了一个Python脚本用于生成接入用的信息。这个脚本需要输入创建设备的产品 ID、设备名称和设备密钥,所以每个设备都要单独生成,只能作为测试用途。
实际使用中,要在NodeMCU代码中实现生成MQTT连接参数功能,大致步骤如下:
i. 填入设备认证三元组
ProductID = "1ZBDK6IHYU"
DeviceName = "Test_Dev"
DeviceSecret = str2hex("5a66a1edb71813a05382be72719d8778 ")
其中,DeviceSecret填入设备密钥Base64解码后的十六进制。
ii. 填入服务器端信息
myMQTThost = ProductID..".iotcloud.tencentdevices.com"
myMQTTport = 1883
iii. 生成MQTT接入参数
myMQTTClientId = ProductID..DeviceName
connid = wifi.sta.getmac()
myMQTTusername = ProductID..DeviceName..";12010126;"..connid..";1599406399"
myMQTTpassword=crypto.toHex(crypto.hmac("sha1",myMQTTusername,DeviceSecret))..";hmacsha1"
其中,myMQTTusername最后数字表示签名过期时间,是从1970年1月1日 00:00:00 UTC 时间至今秒数的 UTF8 字符串,可以设置长一点时间。
iv. MQTT连接
myMQTT=mqtt.Client(myMQTTClientId, 120, myMQTTusername, myMQTTpassword)
myMQTT:connect(myMQTThost, myMQTTport, 0, MQTTSuccess, MQTTFailed)
v. 消息通信
按照JSON格式组织好消息,通过接口myMQTT:publish发布消息即可。
vi. 订阅消息
调用myMQTT:subscribe订阅需要的Topic即可。
从上面可以看到连接到腾讯云IOT平台非常简单,同样云平台提供的功能也比较简单,适合有经验的开发者使用。
4. 设备间通信M2M
为了保证设备数据安全,云平台在服务端会做设备间隔离,设备只能订阅或发布自己的Topic,而设备间通信M2M就需要使用到规则引擎。
使用规则引擎对 Topic 中的数据进行处理,然后转发到云平台其它服务或用户的业务后台服务,而实现M2M只需将数据转发到其他设备的Topic。
以腾讯云IOT平台为例:
- 登录物联网通信控制台,选择规则引擎
- 选择新建规则,填入规则名称
- 规则引擎使用SQL对Topic数据进行处理,规则创建成功后,选择编辑,可以进行SQL语句编辑
- 选择添加行为操作,选择行为类型为“Republish”,选择产品,填写要转发到的Topic。
其中,Topic名称可以直接填写,也可以通过变量获取,使用 ${} 括起来的就代表一个变量名,这个变量名是 SELECT 语句中选取出来的字段内容。
综上,只要在发布消息时带上需要接受消息的Topic名称,通过规则引擎就可以实现设备间通信。
5. 总结
本文介绍了使用MQTT将NodeMCU接入公有云平台(阿里云IOT、腾讯云IOT),发布消息到平台上,并且介绍了使用规则引擎实现设备间通信。通过云平台只要实现设备端的接入就可以将数据发送到云端,并且可以实现设备与PC或手机的通信,非常方便快捷。
使用公有云平台非常方便,但是有时候如果设备无法连接到云平台该怎么办?下一篇将介绍在本地安装MQTT broker,将设备接入本地的MQTT服务器,实现本地设备的互联互通。