前言:MQTT是當下物聯網用的比較多的協議,本篇聊一聊用esp32通過MQTT連接到中移OneNET物聯網平臺。
OneNET平臺創建產品和設備
1、創建產品:開發者中心-》全部產品-》MQTT物聯網套件(新版)-》添加產品
2、添加設備:產品概況-》設備列表-》添加設備
3、數據流-》數據流模版管理-》添加數據流模版
提示:這裏根據自己要上傳的數據創建。
MQTT.fx客戶端模擬設備上報數據
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、客戶端查看:
ESP32設備連接到OneNET
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——————
相關閱讀: