WIFI MQTT接入ONE NET云平台
-
- 一、本例程实现功能介绍
- 二、云平台操作流程
- 三、硬件接线图、材料清单
- 四、完整代码&代码解析
- 五、代码实验现象
前言:MQTT是一种基于TCP物联网通信协议广泛应用于物联网领域,基本上所有云平台都支持设备MQTT协议访问,所以如果您的设备支持MQTT连接可以轻松连接各云平台(如ONE NET、阿里云、腾讯云等)。CORE提供的MQTT库函数也很简单,您只需按照云平台的规则调用MQTT对传入参数进行相应调整后,库函数可与各云平台对接。
一、本例程实现功能介绍
CORE向云端(ONE NET)上传温湿度数据,接受云下发的命令数据控制CORE电路板上LED2灯的亮灭。
二、云平台操作流程
在ONE NET云平台官网(https://open.iot.10086.cn)注册并登录开发者账户 注册账号: https://open.iot.10086.cn/doc/easy-manual/ 产品相当于一个集合,下面可以有成千上万的相同功能的设备。
产品创作方法: https://open.iot.10086.cn/doc/mqtt/book/get-start/product&device/createProduct.html
下图是我创建的产品概况: 产品名称为: “mqtt_test”
产品ID:“353255”,该值在后面的代码解析中会提到,是设备和云端建立连接时的必要参数
access_key:我们不能在这里使用这个值,但您必须在未来开发客户端和云平台之间的对接 设备相当于特定的硬件实物。
设备创建方法: https://open.iot.10086.cn/doc/mqtt/book/get-start/product&device/createDevice.html
注:设备名称必须是唯一的,产品可以包含在设备名称中SN码,MAC地址,唯一ID等等来保证唯一性。 下图是我创建的设备的详细信息: 设备名称为: “TestDevice在后面的代码分析中会提到,001是设备与云连接的必要参数
设备key为: HNC7fq0yREOYs3uQoWREmZJjbwW8kiT6mxsDoh/dyW4= ,该值将在后面的代码分析中提到,这是设备与云连接的必要参数 到目前为止,我们已经完成了产品的创建,并在产品中创建了一个设备。在下一个示例代码中,我们将在创建的产品和设备中使用一些关键参数。
三、硬件接线图、材料清单
四、完整代码&代码解析
代码功能:CORE每9秒到云端(ONE NET)上传温湿度数据,接受云下发的数据控制CORE电路板上LED2灯的亮灭。
--路由器连接参数 ap_ssid = "MyRouterName" --路由器账号 ap_passwd = "MyRouterPswd123" --路由器密码 --MQTT服务器地址(适用于ONE NET平台) server_addr = "183.230.40.96" --OneNet服务器ip地址,也可以写成"mqtts.heclouds.com"(推荐) server_port = 1883 --MQTT 连接参数(适用于ONE NET平台) mqtt_con_clientID = "TestDevice001" mqtt_con_username = "353255" mqtt_con_password = "version=2018-10-31&res=products/353255/devices/TestDevice001&et=1893427200&method=md5&sign=/5RJwGwytPWvVDB04K7rnw==" --MQTT topic相关参数(适用于ONE NET平台) mqtt_sub_topic = "$sys/353255/TestDevice001/cmd/request/ "--订阅用 mqtt_pub_topic = "$sys/353255/TestDevice001/dp/post/json" --发布用 --配置D9为普通输出,控制LED2 LIB_GpioOutputConfig("D9","STANDARD") --使能系统10毫秒定时器开始工作 LIB_10msTimerConfig("ENABLE") --初始化esp8266 Wifi心跳包间隔时间为模块180秒,最好是值的三倍MQTT的KeepAlive时间 LIB_WifiTcpConfig("UART0","D5",ap_ssid,ap_passwd,server_addr,server_port,180) --180 --配置MQTT底层为WIFI传输(esp8266),并按照如下参数进行MQTT连接,KeepAlive时间=60秒 LIB_MQTTConfig("WIFI",mqtt_con_clientID,mqtt_con_username,mqtt_con_password,"60",mqtt_sub_topic,"QOS0") --设置sht3x
传感器占用SCL0和SDA0引脚,以每秒出10个数据的频率工作,"HIGH"表示最高精度 LIB_Sht3xConfig("IIC0","10","HIGH") --变量初始化 cnt_10ms = 0 pub_id = 0 temprature = 0.00 humidity = 0.00 --定义10ms中断回调函数 function LIB_10msTimerCallback() cnt_10ms = cnt_10ms + 1 end --开始大循环 while(GC(1) == true) do sht3x_flag,temp,humi = LIB_Sht3xGetResult() --如果传感器有新的温湿度数据产生 if sht3x_flag == 1 then temprature = temp humidity = humi end --查询是否收到服务器下发的cmd数据(已订阅的"$sys/353255/TestDevice001/cmd/request/+") recv_flag,topic,data = LIB_MqttRecvSub() if recv_flag == 1 then --根据json路径"$.LED"解析服务器下发的json文本,并执行LED亮灭操作 Json_Val = LIB_JsonParse(data, "$.LED") --服务器下发的是"{"LED":0}" if Json_Val == "0" then LIB_GpioWrite("D9",1) --LED2灭 --服务器下发的是"{"LED":1}" elseif Json_Val == "1" then LIB_GpioWrite("D9",0) --LED2亮 --服务器下发的是"{"LED":2}" elseif Json_Val == "2" then LIB_GpioToggle("D9") --LED2亮灭切换 else LIB_GpioWrite("D9",1) --LED2灭 end --根据收到的topic中的cmdid应答服务器, --将收到的topic中"request"替换成"response"后作为应答topic发给服务器 topic = string.gsub(topic,"request","response") --应答内容可自定义,这里为"Got it!" LIB_MqttSendPub("QOS0", topic, "Got it!") --延时2秒是为了保证本次publish不被之后的publish覆盖,所以该延时太少可能导致LIB_MqttSendPub失败 LIB_DelayMs(2000) end --每9秒发送温湿度度数据给server if cnt_10ms >= 900 then cnt_10ms = 0 pub_id = pub_id + 1 json_str = string.format("{\"id\":%d, \"dp\":{\"temperatrue\":[{\"v\": %.2f,}], \"humidity\":[{\"v\":%.2f,}]}}", pub_id, temprature, humidity) --注意json_str的总长度不要超过250字节 LIB_MqttSendPub("QOS0", mqtt_pub_topic, json_str) --publish end end
--路由器连接参数
ap_ssid = "MyRouterName" --路由器账号
ap_passwd = "MyRouterPswd123" --路由器密码
ap_ssid和ap_passwd请使用你自己的路由器账号密码。
--MQTT服务器地址(适用于ONE NET平台)
server_addr = "183.230.40.96" --OneNet服务器ip地址,也可以写成"mqtts.heclouds.com"(推荐)
server_port = 1883
server_addr和server_port是中国移动物联网(ONE NET)MQTT服务的固定IP地址和端口号,请不要改动它。
--MQTT 连接参数(适用于ONE NET平台)
mqtt_con_clientID = "TestDevice001"
mqtt_con_username = "353255"
mqtt_con_password = "version=2018-10-31&res=products%2F353255%2Fdevices%2FTestDevice001&et=1893427200&method=md5&sign=%2F5RJwGwytPWvVDB04K7rnw%3D%3D"
mqtt_con_clientID、mqtt_con_username、mqtt_con_password 这三个参数是设备和服务端建立mqtt连接时所必须的三个参数,如果你曾接入过多个物联网云平台,你会发现它们的异同往往都在这三个参数上。这里我们介绍ONE NET云平台下关于这三个参数的定义规则: ① mqtt_con_clientID: 设备和服务端建立mqtt连接时,clientID用来标识设备的唯一性,我这里我们使用的是设备名称“TestDevice001”,设备名称应具有唯一性,比如可以用您定义的SN序列号等,这里是我在创建该设备时起的名字"TestDevice001"。 ② mqtt_con_username:设备和服务端建立mqtt连接时,username用来认证连接的用户名,该值为产品ID ③ mqtt_con_password:设备和服务端建立mqtt连接时,password用来认证连接的密码。该密码的计算途径有两种:一种是通过电脑生成,一种是通过代码生成(python)。关于计算原理,请参考此处。当然您也可以不用花精力去看这些,直接看接下来的例子即可。这里的例子我们仅介绍通过电脑软件的生成方法,软件下载地址。
下图为我使用token.exe电脑软件生成password的方法:
下面介绍各个参数的来源,products、devices、md5这三个词汇固定不变
上图中的“353255”即是我们在创建产品时云平台自动赋予的产品ID。 上图中的“TestDevice001”即是我们在前面创建设备时我们给设备起的具有唯一性的设备名称。 上图中的“1893427200”表示将要生成的password的有效期,Unix时间戳,有效期截至为2030/1/1 0:0:0。 上图中的“HNC7fq0yREOYs3uQoWREmZJjbwW8kiT6mxsDoh/dyW4=”即是我们在前面创建设备时云平台自动赋予设备的设备key。 上图中的“version=2018-10-31&res=products%2F353255%2Fdevices%2FTestDevice001&et=1893427200&method=md5&sign=%2F5RJwGwytPWvVDB04K7rnw%3D%3D” 即是生成结果(设备和服务端建立连接所需要的password)。
订阅和发布路径:
--MQTT topic相关参数(适用于ONE NET平台)
mqtt_sub_topic = "$sys/353255/TestDevice001/cmd/request/+"--订阅用
mqtt_pub_topic = "$sys/353255/TestDevice001/dp/post/json" --发布用
mqtt_sub_topic是用来给设备订阅服务器的命令消息(比如控制LED等) mqtt_pub_topic是用来给设备向服务器发布消息(比如温湿度)
这两个字符串的中包含的”353255“和“TestDevice001”分别是产品ID和设备名称,其他部分保持固定不变即可
注意:这两个路径的结构由ONE NET云平台定义,其结构不可随意更改,如果感兴趣可以参考此处,设备命令Topic簇、数据点Topic簇。
--根据收到的topic中的cmdid应答服务器,
--将收到的topic中"request"替换成"response"后作为应答topic发给服务器
topic = string.gsub(topic,"request","response")
--应答内容可自定义,这里为"Got it!"
LIB_MqttSendPub("QOS0", topic, "Got it!")
ONE NET平台中的关于设备如何应答平台下发的cmd命令的格式已做了定义,可以参考设备命令Topic簇。
下面举个例子来说明: 如果服务器下发cmd的topic为: s y s / 353255 / T e s t D e v i c e 001 / c m d / r e q u e s t / 33 f f e a 0 a − e 5 f 1 − 49 d 6 − a 626 − f f e e 1 b b d 93 e f 那 么 我 们 应 答 的 t o p i c 应 该 为 : sys/353255/TestDevice001/cmd/request/33ffea0a-e5f1-49d6-a626-ffee1bbd93ef 那么我们应答的topic应该为: sys/353255/TestDevice001/cmd/request/33ffea0a−e5f1−49d6−a626−ffee1bbd93ef那么我们应答的topic应该为:sys/353255/TestDevice001/cmd/response/33ffea0a-e5f1-49d6-a626-ffee1bbd93ef
云平台会自动为每条下发的cmd分配一个cmd id, 例子中的33ffea0a-e5f1-49d6-a626-ffee1bbd93ef即为cmdid。
--每9秒发送温湿度度数据给server
if cnt_10ms >= 900 then
cnt_10ms = 0
pub_id = pub_id + 1
json_str = string.format("{\"id\":%d, \"dp\":{\"temperatrue\":[{\"v\": %.2f,}], \"humidity\":[{\"v\":%.2f,}]}}", pub_id, temprature, humidity)
--注意json_str的总长度不要超过250字节
LIB_MqttSendPub("QOS0", mqtt_pub_topic, json_str) --publish
end
每9秒向云平台pulish一次本地的温湿度数据,数据内容必须是json格式, 例如:{“id”:1, “dp”:{“temperatrue”:[{“v”: 32.50,}], “humidity”:[{“v”:56.00,}]}} pub_id为pulish消息的标识符,每次发送时需递增加1 其他部分代码已有详细注释,这里就不赘述了。
五、代码实验现象
按照上面的接线方式将CORE和ESP8266无线模块、SHT30传感器连接就位,然后将上面的完整代码拷贝入Core的TF卡中的main.lua文件,完成Core的代码更新。 从ONE NET开发者控制台界面中进入对应的产品 ,然后在产品界面中鼠标点击进入“设备列表” 后可以看到我们刚刚创建的一个设备硬件实例“TestDevice001”,如下图: STEP 3 查看设备的温湿度数据: STEP 4 从云平台下发cmd指令控制CORE上的LED2灯的亮灭:
Ⅰ 鼠标点击进入在对应的设备的“更多操作”中的“下发命令” -->
Ⅱ 然后在弹出的界面中的命令内容中输入“{“LED”:2}”,超时时间5秒,返回结果中选择String格式
Ⅲ 最后点击发送,待设备成功收到命令并返回正确的应答后(应答消息中包含“Got it”),我们就可以看到Core电路板上的LED2灯珠由亮变灭或者由灭变亮了。