前言:MQTT是当下物联网用的比较多的协议,本篇聊一聊用esp32通过MQTT连接到中移OneNET物联网平台。
1、创建产品:开发者中心-》全部产品-》MQTT物联网套件(新版)-》添加产品
2、添加设备:产品概况-》设备列表-》添加设备
3、数据流-》数据流模版管理-》添加数据流模版
提示:这里根据自己要上传的数据创建。
1、MQTT服务器地址:183.230.40.96
2、端口号:1883
3、图中Client ID、User name、Password根据官网的提示依此是:
Password可以使用官网提供的工具生成(https://open.iot.10086.cn/doc/mqtt/book/manual/auth/tool.html),也可以使用python脚本生成。
官方工具生成:
时间戳:https://tool.chinaz.com/Tools/unixtime.aspx,这个时间不能比当前时间小,比如输入1672735919,表示的是2023/1/3 16:51:59,到这个时间后mqtt服务器就会拒绝访问。
Python脚本生成:官方给你的脚本稍微有点问题,修改之后下:
import base64
import hmac
import time
from urllib.parse import quote
def token(id,devicename,access_key):
version = '2018-10-31'
#res = res = 'products/%s' % id # 通过产品ID访问产品API
#修改如下
res = 'products/%s/devices/%s' %( id ,devicename)
# 用户自定义token过期时间
et = str(int(time.time()) + 3600)
# 签名方法,支持md5、sha1、sha256
method = 'sha1'
# 对access_key进行decode
key = base64.b64decode(access_key)
# 计算sign
org = et + '\n' + method + '\n' + res + '\n' + version
sign_b = hmac.new(key=key, msg=org.encode(), digestmod=method)
sign = base64.b64encode(sign_b.digest()).decode()
# value 部分进行url编码,method/res/version值较为简单无需编码
sign = quote(sign, safe='')
res = quote(res, safe='')
# token参数拼接
token = 'version=%s&res=%s&et=%s&method=%s&sign=%s' % (version, res, et, method, sign)
return token
if __name__ == '__main__':
id = '329104'
devicename='my_mqtt_device'
access_key = 'PSbr2krSLrLfZ9BZ4GWv9y8Ys657ZHDAuxO31y55B9k='
print(token(id,devicename,access_key))
只需要提供产品id、设备名称devicename、access_key(key)就可计算出,这里要注意一下脚本里面默认的时间戳是当前时间往后1h,也就是1h之后,mqtt服务器就拒绝访问了,可以自行更改。如果没有安装python,可以使用在线编程工具。
4、正确输入参数之后,连接到服务器:
5、上报数据,OneNET提供了3个topic:
其中{pid}是产品id,{device-name}是设备名称;$sys/{pid}/{device-name}/dp/post/json用于发布,上报数据,数据格式仅支持json格式,其余两个是上报数据之后的响应,客户端可以订阅。
上报数据之后,上报成功或者失败,平台都会返回系统通知,可以订阅主题查看:
6、下发数据,OneNET提供了4个topic:
其中{pid}和{device-name}的含义同上,{cmdid}为平台为该命令自动创建的唯一标识,在客户端订阅的时候可以使用通配符+或者#代替{cmdid}。
下发数据,不必使用json格式。
7、客户端查看:
1、创建设备,方法和上面一样,命令为esp32_mqtt_device
2、计算password
3、发布和订阅主题
publish_TOPIC = '$sys/329104/esp32_mqtt_device/dp/post/json',用于上报数据
subscribe_TOPIC ='$sys/329104/esp32_mqtt_device/dp/post/json/+',用于接收平台对上报数据的相应。
4、micropython脚本编写
from umqtt.simple import MQTTClient
from machine import Pin
import network
import time
import machine
import dht
from machine import Timer
SSID="**********" # wifi名称
PASSWORD="*********" # wifi密码
SERVER ='183.230.40.96'
CLIENT_ID = "esp32_mqtt_device" #设备名称
#PORT=1883
username='329104' #产品ID
password='version=2018-10-31&res=products%2F329104%2Fdevices%2Fesp32_mqtt_device&et=1618323601&method=sha1&sign=ss36MphhbXRi3EFAPhqLEYFw0VQ%3D'
publish_TOPIC = '$sys/329104/esp32_mqtt_device/dp/post/json'
subscribe_TOPIC ='$sys/329104/esp32_mqtt_device/dp/post/json/+'
client=None
mydht=None
def sub_cb(topic, msg):
print((topic, msg))
def connectWifi(ssid,passwd):
global wlan
wlan=network.WLAN(network.STA_IF) #create a wlan object
wlan.active(True) #Activate the network interface
wlan.disconnect() #Disconnect the last connected WiFi
wlan.connect(ssid,passwd) #connect wifi
while(wlan.ifconfig()[0]=='0.0.0.0'):
time.sleep(1)
print(wlan.ifconfig())
def apptimerevent(mytimer):
try:
sensordata=ReadTemHum()
mymessage='{"id": 123,"dp": {"CurrentTemperature": [{ "v": %d,}],"CurrentHumidity": [{"v": %d,}]}}'%(sensordata[0],sensordata[1])
client.publish(topic=publish_TOPIC,msg= mymessage, retain=False, qos=0)
except Exception as ex_results2:
print('exception',ex_results2)
mytimer.deinit()
# finally:
# machine.reset()
# #Catch exceptions,stop program if interrupted accidentally in the 'try'
def ReadTemHum():
mydht.measure()
tem=mydht.temperature()
hum=mydht.humidity()
data=[tem,hum]
print(data)
return data
if __name__=='__main__':
try:
mydht=dht.DHT11(machine.Pin(4))
connectWifi(SSID,PASSWORD)
client = MQTTClient(CLIENT_ID, SERVER,0,username,password,60) #create a mqtt client
print(client)
client.set_callback(sub_cb) #set callback
client.connect() #connect mqtt
client.subscribe(subscribe_TOPIC) #client subscribes to a topic
mytimer=Timer(0)
mytimer.init(mode=Timer.PERIODIC, period=5000,callback=apptimerevent)
while True:
client.wait_msg() #wait message
except Exception as ex_results:
print('exception1',ex_results)
finally:
if(client is not None):
client.disconnect()
wlan.disconnect()
wlan.active(False)
5、查看数据
日志查看:日志查询-》输入查询时间和设备ID。
6、设备通过串口打印平台响应:
——————END——————
相关阅读:
使用ESP32来学习Python之开发环境搭建
ESP32从网络获取天气OLED显示(附源码)