Python使用MQTT协议接入onenet平台

Python使用MQTT协议接入onenet平台

近期由于项目需要,舍弃了onenet官方的物联网开发板,转而使用树莓派接入onenet平台。这里需要先申明一下,本文讲的onenet MQTT协议都是onenet平台新版MQTT协议,对于旧版MQTT协议网上有较多教程,这里不做说明。
如多有小伙伴对新旧协议不太熟悉,建议去官网自行了解

Python使用MQTT协议接入onenet平台_第1张图片
官方链接: link.

新旧协议主要差别在于新版协议引入了安全鉴权环节。下面结合onenet官方文档以及Python MQTT协议包讲一下接入过程。

Python使用MQTT协议接入onenet平台_第2张图片

官方文档给出了两个接入服务地址,一个为加密接口,一个为非加密接口。对于加密接口,在使用时需要加载证书。
onenet产品和设备创建自行了解
后续需要准备参数:设备名称、产品ID、access-key。可以非常方便的在你新建的产品下面找到以上参数。
选用安全方案一进行安全鉴权。

代码如下 。

import paho.mqtt.client as mqtt
import struct
import json
import base64
import hmac
import time
from urllib.parse import quote

DEV_ID="59xxxxxx" #设备ID
PRO_ID = "xxxxxx" #产品ID
DEV_NAME='xxxxx'
accesskey="xxxxxxxxxxxxxxxxxxxxxx40yrd90zlgDl4="

def token(id,access_key):  #官方文档给出的核心秘钥计算算法

    version = '2018-10-31'

    res = 'products/%s' % id  # 通过产品ID访问产品API

    # 用户自定义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

# 当客户端收到来自服务器的CONNACK响应时的回调。也就是申请连接,服务器返回结果是否成功等
def on_connect(client, userdata, flags, rc):
    print("连接结果:" + mqtt.connack_string(rc))
# 从服务器接收发布消息时的回调。
def on_message(client, userdata, msg):
    print(str(msg.payload,'utf-8'))
#当消息已经被发送给中间人,on_publish()回调将会被触发
def on_publish(client, userdata, mid):
    print(str(mid))

def main():
    passw=token(PRO_ID,accesskey)
    print(passw)
    client = mqtt.Client(DEV_NAME,protocol=mqtt.MQTTv311)
    #client.tls_set(certfile='/Users/mryu/PycharmProjects/MyProject/onenet/MQTTS-certificate.pem') #鉴权证书
    client.on_connect = on_connect
    client.on_publish = on_publish
    client.on_message = on_message
    client.connect('183.230.40.96', port=1883, keepalive=120)
    client.username_pw_set(PRO_ID, passw)
    client.loop_forever()

if __name__ == '__main__':
    main()

其中token()函数为官方给出的核心秘钥计算算法,其中id为产品ID,access_key为安全鉴权秘钥,产品页自动生成。返回参数这位计算的核心秘钥。后续需要用到。
其中需要重点注意token()函数中有个有效期 version = ‘2018-10-31’,此参数千万不能随意改变,否则会登陆失败。

根据接入接口连接后,需要使用username_pw_set(PRO_ID, passw)函数传入产品ID和核心秘钥。使用loop_forever()保持连接。

你可能感兴趣的:(我的小实验)