【Python】使用Python模拟设备接入阿里云物联网的MQTT服务器

8 篇文章 4 订阅

前言

由于阿里云物联网套件关于设备认证的文档不够详细,笔者差不多摸索了几天才连接上MQTT。下面是使用Python模拟设备接入阿里云的MQTT。

概述

阿里云物联网套件提供两种接入方式:

  1. MQTT客户端域名直连(资源受限设备推荐)
  2. 先HTTPS发送授权后再连接MQTT(一些特殊增值服务,比如设备级别的引流)

本文主要介绍第一种接入方式,TCP直连,并提供Python代码示例。

主要参数

连接域名

<ProductKey>.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883

MQTT Connect报文参数

1、mqttClientId

mqttClientId = "<ClientId>"+"|securemode=3,signmethod=hmacsha1,timestamp=132323232|"

2、mqttUsername

使用&拼接<DeviceName><ProductKey>

mqttUsername = "<DeviceName>&<ProductKey>"

3、mqttPassword

把以下参数按字典键名排序,再把键名都拼接起来(没有分隔符)生成content,然后以DeviceSecret为盐,对content进行hma_sha1加密,最后二进制转为十六进制字符串表示。

  • clientId
  • deviceName
  • productKey
  • timestamp
mqttPassword = hmac_sha1(DeviceSecret, content).toHexString();

示例

假设

  • clientId = 12345
  • deviceName = device
  • productKey = pk
  • timestamp = 789
  • signmethod = hmacsha1

content拼接结果:clientId12345deviceNamedeviceproductKeypktimestamp789

注意:不用拼接signmethod参数。

对content以DeviceSecret为盐进行hmacsha1加签后,再转为十六进制字符串,最后结果:FAFD82A3D602B37FB0FA8B7892F24A477F851A14

注意:不需要base64。

最后总结一下生成的参数:

  • mqttHost = "pk.iot-as-mqtt.cn-shanghai.aliyuncs.com"
  • mqttPort = 1883
  • mqttClientId = "12345|securemode=3,signmethod=hmacsha1,timestamp=789|"
  • mqttUsername = "device&pk"
  • mqttPassword = "FAFD82A3D602B37FB0FA8B7892F24A477F851A14"

参数说明

参数描述
ProductKey产品Key。从iot套件控制台获取
DeviceName设备名称。从iot套件控制台获取
DeviceSecret设备密码,从iot套件控制台获取
signmethod算法类型,hmacmd5hmacsha1
clientId客户端自表示id,建议mac或sn
timestamp当前时间毫秒值,可选
securemode目前安全模式,可选值有2(TLS直连模式)、3(TCP直连模式)

示例代码

填写自己的ProductKeyClientIdDeviceNameDeviceSecret

#!/usr/bin/python3
# coding=utf-8


import datetime
import time
import hmac
import hashlib
import math

# 测试加密开关,=1表示不进行连接
TEST = 0

ProductKey = ""
ClientId = "12345"  # 自定义clientId
DeviceName = ""
DeviceSecret = ""

# signmethod
signmethod = "hmacsha1"
# signmethod = "hmacmd5"

# 当前时间毫秒值
us = math.modf(time.time())[0]
ms = int(round(us * 1000))
timestamp = str(ms)

data = "".join(("clientId", ClientId, "deviceName", DeviceName,
                "productKey", ProductKey, "timestamp", timestamp
                ))
# print(round((time.time() * 1000)))
print("data:", data)

if "hmacsha1" == signmethod:
    ret = hmac.new(bytes(DeviceSecret, encoding="utf-8"),
                   bytes(data, encoding="utf-8"),
                   hashlib.sha1).hexdigest()
elif "hmacmd5" == signmethod:
    ret = hmac.new(bytes(DeviceSecret, encoding="utf-8"),
                   bytes(data, encoding="utf-8"),
                   hashlib.md5).hexdigest()
else:
    raise ValueError

sign = ret
print("sign:", sign)

# ======================================================

strBroker = ProductKey + ".iot-as-mqtt.cn-shanghai.aliyuncs.com"
port = 1883

client_id = "".join((ClientId,
                     "|securemode=3",
                     ",signmethod=", signmethod,
                     ",timestamp=", timestamp,
                     "|"))
username = "".join((DeviceName, "&", ProductKey))
password = sign

print("="*30)
print("client_id:", client_id)
print("username:", username)
print("password:", password)
print("="*30)

def secret_test():
    DeviceSecret = "secret"
    data = "clientId12345deviceNamedeviceproductKeypktimestamp789"
    ret = hmac.new(bytes(DeviceSecret, encoding="utf-8"),
                   bytes(data, encoding="utf-8"),
                   hashlib.sha1).hexdigest()
    print("test:", ret)


# ======================================================
# MQTT Initialize.--------------------------------------

try:
    import paho.mqtt.client as mqtt
except ImportError:
    print("MQTT client not find. Please install as follow:")
    print("pip install paho-mqtt")


# ======================================================
def on_connect(mqttc, obj, flags, rc):
    print("OnConnetc, rc: " + str(rc))

    mqttc.subscribe("test", 0)

def on_publish(mqttc, obj, mid):
    print("OnPublish, mid: " + str(mid))


def on_subscribe(mqttc, obj, mid, granted_qos):
    print("Subscribed: " + str(mid) + " " + str(granted_qos))


def on_log(mqttc, obj, level, string):
    print("Log:" + string)


def on_message(mqttc, obj, msg):
    curtime = datetime.datetime.now()
    strcurtime = curtime.strftime("%Y-%m-%d %H:%M:%S")
    print(strcurtime + ": " + msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
    on_exec(str(msg.payload))


def on_exec(strcmd):
    print("Exec:", strcmd)
    strExec = strcmd


# =====================================================
if __name__ == '__main__':
    if TEST:
        secret_test()
        exit(0)

    mqttc = mqtt.Client(client_id)
    mqttc.username_pw_set(username, password)
    mqttc.on_message = on_message
    mqttc.on_connect = on_connect
    mqttc.on_publish = on_publish
    mqttc.on_subscribe = on_subscribe
    mqttc.on_log = on_log

    mqttc.connect(strBroker, port, 120)
    mqttc.loop_forever()

参考资料


终于知道之前为什么总是连接不上了!!!是因为之前官方文档对password加密的字段多了「signmethodhmacsha1」字符串!


好饿啊,早知道不做物联网了

以下是使用Python连接阿里云物联网设备并接收数据的代码示例: ```python import paho.mqtt.client as mqtt import ssl # 阿里云物联网平台的设备信息 product_key = "your_product_key" device_name = "your_device_name" device_secret = "your_device_secret" # MQTT连接参数 endpoint = product_key + ".iot-as-mqtt.cn-shanghai.aliyuncs.com" port = 1883 client_id = "python_mqtt_client" username = device_name + "&" + product_key password = "Signature|" + device_secret # MQTT连接回调函数 def on_connect(client, userdata, flags, rc): print("Connected with result code " + str(rc)) # 订阅设备的Topic client.subscribe("/" + product_key + "/" + device_name + "/user/get") # MQTT消息接收回调函数 def on_message(client, userdata, msg): print(msg.topic + " " + str(msg.payload)) # 创建MQTT客户端并连接 client = mqtt.Client(client_id=client_id, clean_session=False) client.username_pw_set(username, password) client.on_connect = on_connect client.on_message = on_message client.tls_set(ca_certs=None, certfile=None, keyfile=None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) client.connect(endpoint, port, keepalive=60) # 循环等待接收MQTT消息 client.loop_forever() ``` 在这个示例中,我们使用Python的paho-mqtt库来连接阿里云物联网平台的MQTT服务器,通过设备密钥进行身份验证,并订阅了设备的Topic。当接收到设备消息时,会调用on_message回调函数进行处理。 需要注意的是,为了保证数据的安全性,我们使用了TLS连接。在连接时需要设置tls_set()方法的参数,其中包括设备证书和服务器证书等信息。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值