云平台对接(OneNET)

简介

本节介绍如何使用 RT-Thread MicroPython 来将设备接入 OneNET 云平台,本次示例使用的接入协议为 MQTT。

准备工作

  • 首先需要安装 urequests 模块和 umqtt.simple 模块,安装方法参考 HttpClient MQTT 章节。
  • 本章实例代码在最后一节的附录中,可以在添加必要的注册信息后复制到 main.py 文件中在 MSH 中使用 python 命令来执行。

    产品创建

  • 想要将开发板接入 OneNET 云平台,首先要进行产品的创建,创建分为两步,第一步是注册一个用户账号,第二步是创建一个基于特定协议的产品。

    用户注册

  • 为了使用 OneNET 设备云的强大功能,首先要在 OneNET 上注册开发者账号,来创建专属的“开发者中心 。

    产品创建

  • 接下来需要在 OneNET 平台上创建产品。这里要注意的是在最后选择设备接入方式和设备接入协议时,因为本次示例使用的是 MQTT 协议,所以要在设备接入方式中选择公开协议,设备接入协议选择 MQTT。
    1525764833130

硬件接入

本章节将介绍如何将设备接入到 OneNET 云平台上。并且演示一个云平台向设备发送命令,设备向云平台返回命令发送次数的示例。

设备的注册和接入

  • 成功创建设备之后,将得到的产品 ID 记录下来供后面推送数据使用。
    1525765493792

  • 将设备的正式环境注册码记录下来用于注册新的设备。
    1525765209683

  • 接下来打开例程中的 main.py,修改 sn 为设备唯一标识码,product_id 为上面得到的6位产品 ID,regKey 为上面记录下来的正式环境注册码。
    1525766961043

  • 在开发板中运行 main.py 即可在 OneNET 上看到我们注册的设备。
    1525767092149

  • 名为 DeviceRT_Thread_Test_Product 的设备已经注册完毕并且上线。
    1525767167244

云平台向设备发送命令

  • 可以通过发送命令功能来给开发板发送几组命令。
    1525767264155

1525767369050

  • 可以在设备端看到云平台下发的数据,同时设备端会上传命令发送次数的数据
    1525767520609

设备向云平台上传数据

  • 点击数据流管理功能来查看设备端上传的数据
    1525767621708

  • 可以在数据流管理中看到设备端上传的的命令发送次数 switch
    1525767740215

  • 这里的 switch 数据是在 mqtt.py 的 pubData 函数里面修改的,可以通过 value 对象的内容来给云平台上传不同的数据。
    1525774755758

  • 至此设备和 OneNET 云平台就对接好了。

    添加独立应用

  • 为了方便使用还可以给设备添加独立的应用,效果如下图:
    1525768143233

代码讲解

  • 通过修改 value 对象来修改向服务器发送的数据,这里是发送到特殊的系统 topic $dp
    1525774792209

  • 给服务器发送数据的触发条件是收到服务器下发的命令,这样就没有保证会一直有数据发送到服务器,所以在没有数据交换的一段时间后,MQTT 连接有可能断开。
    1525768433046

附录示例代码

  1. import urequests as requests
  2. from umqtt.simple import MQTTClient
  3. import ujson as json
  4. import time
  5.  
  6. class Register():
  7. def __init__(self, url='', title='', sn='', mac=''):
  8. self.url = url
  9. self.title = title
  10. self.sn = sn
  11. self.mac = mac
  12. self.sock = None
  13. self.tjson = {}
  14. self.erron = 0
  15. self.key = ''
  16. self.device_id = ''
  17.  
  18. def regist(self):
  19. assert self.url is not None, "Url is not set"
  20. _, _, host, path = self.url.split('/', 3)
  21. if host == '':
  22. return
  23. device = {"mac":self.mac} if self.sn == '' else {"sn":self.sn}
  24. if self.title != '':
  25. device['title'] = self.title
  26. jdata = json.dumps(device)
  27.  
  28. resp = requests.post(self.url, data=jdata)
  29. if resp:
  30. self.tjson = resp.json()
  31. if self.tjson['errno'] == 0:
  32. self.key = self.tjson['data']['key']
  33. self.device_id = self.tjson['data']['device_id']
  34. return 0
  35. else:
  36. return -1
  37.  
  38. class OneNetMqtt:
  39. failed_count = 0
  40.  
  41. def __init__(self, client_id='', username='', password=''):
  42. self.server = "183.230.40.39"
  43. self.client_id = client_id
  44. self.username = username
  45. self.password = password
  46. self.topic = "topic_sub" # 填入测试 topic
  47. self.mqttClient = MQTTClient(self.client_id, self.server,6002,self.username,self.password)
  48. self.cmd_times = 0 # publish count
  49.  
  50. def pubData(self, t):
  51. value = {'datastreams':[{"id":"switch","datapoints":[{"value": self.cmd_times }]}]}
  52. jdata = json.dumps(value)
  53. jlen = len(jdata)
  54. bdata = bytearray(jlen+3)
  55. bdata[0] = 1 # publish data in type of json
  56. bdata[1] = int(jlen / 256) # data lenght
  57. bdata[2] = jlen % 256 # data lenght
  58. bdata[3:jlen+4] = jdata.encode('ascii') # json data
  59. print('publish data', str(self.cmd_times + 1))
  60. try:
  61. self.mqttClient.publish('$dp', bdata) # $dp 为特殊系统 topic,可以通过这个 topic 给系统推送信息,但是不能订阅这个 topic
  62. self.cmd_times += 1
  63. self.failed_count = 0
  64. except Exception as ex:
  65. self.failed_count += 1
  66. print('publish failed:', ex.message())
  67. if self.failed_count >= 3:
  68. print('publish failed three times, esp resetting...')
  69. reset()
  70.  
  71. def sub_callback(self, topic, msg):
  72. print((topic,msg))
  73. cmd = msg.decode('ascii').split(" ")
  74. print('sub_callback')
  75.  
  76. def connect(self):
  77. self.mqttClient.set_callback(self.sub_callback)
  78. self.mqttClient.connect()
  79. self.mqttClient.subscribe(self.topic)
  80. print("Connected to %s, subscribed to %s topic." % (self.server, self.topic))
  81. try:
  82. while True:
  83. self.mqttClient.check_msg()
  84. print("pubdata")
  85. self.pubData('x')
  86.  
  87. finally:
  88. self.mqttClient.disconnect()
  89. print('MQTT closed')
  90.  
  91. def main():
  92. sn = 'RT_Thread_Test_Product' #1、填入设备唯一标识符
  93. title = 'Device' + sn
  94. product_id = 'XXXXX' #2、填入创建设备时获得的产品 ID
  95. regKey = 'XXXXXXXX' #3、填入正式环境注册码
  96. url = 'http://api.heclouds.com/register_de?register_code=' + regKey
  97.  
  98. reg = Register(url=url, title=title, sn=sn) #根据上面的信息注册设备,如果已经注册不再重复注册
  99. if reg.regist()==0:
  100. MQTT = OneNetMqtt(client_id=reg.device_id, username=product_id, password=reg.key) #开启 MQTT 服务
  101. MQTT.connect()
  102. else:
  103. print('Error: No Client ID!')
  104.  
  105. if __name__ == "__main__":
  106. main()

评论

原文: https://www.rt-thread.org/document/site/submodules/micropython/docs/09-Net_Programming_Guide/05-Cloud-OneNET/