ESP32運行MicroPython通過MQTT上報溫溼度到中移OneNET物聯網平臺(附源碼)

前言: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——————​

相關閱讀:

使用ESP32來學習Python之開發環境搭建

ESP32從網絡獲取天氣OLED顯示(附源碼)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章