跋扈洋

  • 148 主题
  • 290 帖子
  • 1538 积分
  • 身份:版主
  • 论坛新秀
  • E币:299

ESP32 AT固件MQTT 对接阿里物联网平台

2021-1-24 11:08:06 显示全部楼层
一、前言

本文介绍如何使用AT指令MQTT接入阿里云物联网平台,包括一机一密、一型一密两种方式。上车前我们先阅读以下几个文档:

  • AT+MQTT 指令使用
  • MQTT-TCP连接通信
  • 基于MQTT通道的设备动态注册
二、一机一密接入

一机一密认证方法,即为每个设备烧录其唯一的设备证书(ProductKey、DeviceName和DeviceSecret),对安全性要求较高的应优先考虑使用一机一密认证方法接入。
1.创建设备
我们进入阿里物联网平台创建一个产品,创建方法
这里我用模组的MAC地址作为deviceName创建一个设备,三元组为:

[color=rgba(0, 0, 0, 0.75)]DeviceNameProductKeyDeviceSecret
c82b968ebe5ca1gh70UicfDa566b66936eafac4c8fe75316069ba11

通过阅读阿里云文档 MQTT-TCP连接通信得知,我们需要通过MQTT接入需要得到以下几个参数:

  • 接入域名和端口
    公共实例的接入域名:${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com,端口固定为1883
    其中:
  • ${YourProductKey}:请替换为设备所属产品的ProductKey。可登录物联网平台控制台,在对应实例的设备详情页获取。
  • ${YourRegionId}:请参见地域和可用区
    这里我们ProductKey为a1gh70UicfD,地区我选择shanghai,所以我们接入域名为:
    a1gh70UicfD.iot-as-mqtt.cn-shanghai.aliyuncs.com
  • mqttClientId
    mqttClientId由客户端ID(clientId)、安全模式(securemode)、签名算法类型(signmethod)和时间戳(timestamp)拼接而成。
    这里我选择设备MAC地址作为clientId,安全模式选择3(TCP直连模式),签名算法选择hmacmd5,不选时间戳。则得到mqttClientId为:
    c82b968ebe5c|securemode=3,signmethod=hmacmd5|
  • 用户名mqttUsername
    mqttUsername由deviceName和productKey拼接成,由我的三元组可得到mqttUsername为:
    c82b968ebe5c&a1gh70UicfD
  • 密码mqttPassword
    计算方法:sign_hmac(DeviceSecret,content)
    sign_hmac为签名算法,这里我选择hmacmd5;
    DeviceSecret即为三元组中的DeviceSecret;
    content为clientId、deviceName、ProductKey 的拼接:clientIdc82b968ebe5cdeviceNamec82b968ebe5cproductKeya1gh70UicfD 。
    即对clientIdc82b968ebe5cdeviceNamec82b968ebe5cproductKeya1gh70UicfD进行hmacmd5加密,加密密钥为a566b66936eafac4c8fe75316069ba11,加密结果我们可以用在线工具获得mqttPassword为
    7cbf1bf3f2e5cfe950f9c8391253700b

hmacmd5算法也可以用C语言方法实现:HmacMD5算法

到这里我们就已经得到了一机一密所需要的所有连接参数,下面我们用AT指令来实战一下:

  1. AT+CWMODE=1
  2. AT+CWJAP="TP-LINK_B741","cc123456789"
  3. AT+MQTTUSERCFG=0,1,"","","",0,0,""
  4. AT+MQTTUSERNAME=0,"c82b968ebe5c&a1gh70UicfD"
  5. AT+MQTTPASSWORD=0,"7cbf1bf3f2e5cfe950f9c8391253700b"
  6. AT+MQTTCLIENTID=0,"c82b968ebe5c|securemode=3\,signmethod=hmacmd5|"
  7. AT+MQTTCONN=0,"a1gh70UicfD.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883,1
  8. //注意Topic中的ProductKey和DeviceName应根据自己的三元组替换
  9. AT+MQTTSUB=0,"/a1gh70UicfD/c82b968ebe5c/user/get",1  
  10. AT+MQTTPUB=0,"/sys/a1gh70UicfD/c82b968ebe5c/thing/event/property/post","{"method":"thing.event.property.post"\,"id":"198370833"\,"params":{"powerstate":0}\,"version":"1.0.0"}",1,0  

正常交互 LOG 如下:
阿里云平台接收到模组发布的消息日志如下

三、一型一密接入

阅读本章节前请务必先理解前文【二、一机一密接入】。一型一密认证方式下,同一产品下所有设备只需烧录相同的产品证书(ProductKey和ProductSecret)。设备发送激活请求时,物联网平台进行身份确认,认证通过,下发设备接入所需信息。一型一密较一机一密而言,安全性没有一机一密高,但无需为每台设备都烧录不同的三元组,方便生产。
一型一密认证接入,首先我们需要开启动态注册
我再用另一个模组的MAC地址作为deviceName创建一个设备

[color=rgba(0, 0, 0, 0.75)]ProductKeyProductSecretDeviceName
a1gh70UicfDXTQ7IYbKMXnbDuQH30aea41fcbb8

注意区分ProductSecret和DeviceSecret,不要复制错

通过阅读阿里云文档基于MQTT通道的设备动态注册得知,我们动态注册请求需要获取以下参数(均以公共实例为例):

  • 接入域名和端口
    和一机一密一样,接入端口为1883,接入域名为
    a1gh70UicfD.iot-as-mqtt.cn-shanghai.aliyuncs.com
  • mqttClientId
    mqttClientId的拼接参数为
    clientId+"|securemode=2,authType=xxxx,random=xxxx,signmethod=xxxx|"
    其中:
    clientId我使用模组MAC地址30aea41fcbb8 ;
    securemode取固定值2;
    authType:选择一型一密预注册认证方式,值为register
    random:随机数12345
    signmethod:签名算法选择hmacmd5
    即得到mqttClientId为:
    30aea41fcbb8|securemode=2,authType=register,random=12345,signmethod=hmacmd5|
  • mqttUserName
    mqttUsername由deviceName和productKey拼接成,由我的三元组可得到mqttUsername为:
    30aea41fcbb8&a1gh70UicfD
  • mqttPassword:
    计算方法:sign_hmac(productSecret,content)
    sign_hmac为签名算法,这里我选择hmacmd5;
    productSecret即为三元组中的productSecret;
    content为deviceName、productKey、random的拼接:
    deviceName30aea41fcbb8productKeya1gh70UicfDrandom12345
    即对deviceName30aea41fcbb8productKeya1gh70UicfDrandom12345进行hmacmd5加密,加密密钥为XTQ7IYbKMXnbDuQH,加密结果我们可以用在线工具获得mqttPassword为:
    a66c7f87c3c931b12869fe664b470e0e
    hmacmd5算法也可以用C语言方法实现:HmacMD5算法

    动态注册成功返回三元组deviceSecret,productKey,deviceName,接下来我们需要先断开mqtt连接,用返回的三元组重新发起mqtt连接。重新发起的mqtt连接方法步骤和一机一密一模一样,我们按照一机一密的方法得到:
    mqttClientId:12345|securemode=3,signmethod=hmacmd5|
    mqttUserName:30aea41fcbb8&a1gh70UicfD
    mqttPassword:d48294fe16f5904a70691167a54f8d45
    整个AT指令流程为:

  1. AT+CWMODE=1
  2. AT+CWJAP=“AIOT@FAE”,“fae12345678”
  3. AT+MQTTUSERCFG=0,2,"","","",0,0,"" //动态注册只支持使用TLS建立连接,不支持TCP直连
  4. AT+CIPSTAMAC?
  5. AT+MQTTUSERNAME=0,“30aea41fcbb8&a1gh70UicfD”
  6. AT+MQTTPASSWORD=0,“a66c7f87c3c931b12869fe664b470e0e”
  7. AT+MQTTCLIENTID=0,“30aea41fcbb8|securemode=2,authType=register,random=12345,signmethod=hmacmd5|”
  8. AT+MQTTCONN=0,“a1gh70UicfD.iot-as-mqtt.cn-shanghai.aliyuncs.com”,1883,1
  9. AT+MQTTCLEAN=0
  10. AT+MQTTUSERCFG=0,1,"","","",0,0,""
  11. AT+MQTTUSERNAME=0,“30aea41fcbb8&a1gh70UicfD”
  12. AT+MQTTPASSWORD=0,“d48294fe16f5904a70691167a54f8d45”
  13. AT+MQTTCLIENTID=0,“12345|securemode=3,signmethod=hmacmd5|”
  14. AT+MQTTCONN=0,“a1gh70UicfD.iot-as-mqtt.cn-shanghai.aliyuncs.com”,1883,1
  15. AT+MQTTSUB=0,"/sys/a1gh70UicfD/30aea41fcbb8/thing/service/property/set",1
  16. AT+MQTTPUB=0,"/sys/a1gh70UicfD/30aea41fcbb8/thing/event/property/post","{“method”:“thing.event.property.post”,“id”:“198370833”,“params”:{“LightStatus”:0},“version”:“1.0.0”}",1,0

正常交互 LOG 如下:

这样我们就已经连上了。量产的时候可把模组的mac地址表格上传到阿里物联网平台的方式添加设备。具体细节可在阿里云开工单咨询。

四、订阅&发布

通过查询我的阿里云后台,物模型通信 Topic 列表如下图所示

这里我仅以属性的设置和上报为例。

4.1 订阅

设备要接收来自云端下发的属性设置,则应订阅topic:/sys/a1gh70UicfD/30aea41fcbb8/thing/service/property/set

  1. AT+MQTTSUB=0,"/sys/a1gh70UicfD/30aea41fcbb8/thing/service/property/set",1  
  2. //注意topic里面的ProductKey、DeviceName应根据自己的三元组替换掉


订阅成功之后我们在阿里云后台下发一个属性设置给模组


我的模组成功收到了云端下发的属性设置

4.2 发布

设备属性上报,topic应为/sys/a1gh70UicfD/30aea41fcbb8/thing/event/property/post,假如我需要上报工作状态(LightStatus)为0,则指令为

  1. AT+MQTTPUB=0,"/sys/a1gh70UicfD/30aea41fcbb8/thing/event/property/post","{"method":"thing.event.property.post"\,"id":"123"\,"params":{"LightStatus":0}\,"version":"1.0.0"}",1,0
  2. //注意topic里面的ProductKey、DeviceName应根据自己的三元组替换掉

查一下设备日志,可以看到云端已经收到了


设置实时刷新后,后台的工作状态实时显示为我上报的状态

五、总结

一机一密安全性更高、一型一密更方便生产,具体选用哪种方式,需按照实际应用场景而定。



您需要登录后才可以评论 登录 | 立即注册

最新评论

楼层直达:
快速回复
0
1
广告
关闭 热点推荐上一条 /8 下一条
快速回复 返回列表