视频讲解: https://www.bilibili.com/video/BV1GK4y1X7Kc/

thingsboard自动创建设备

工作流程汇总如图

image.png
设备向”thingboard”发送设备配置请求。请求中包含密钥和机密(预配置设备秘钥名,预配置设备秘钥),请求可选择包括设备生成的设备名称和凭据。如果缺少这些凭据,服务器将生成设备要使用的访问令牌。
拨备请求示例:

  1. {
  2. "deviceName": "DEVICE_NAME",
  3. "provisionDeviceKey": "预配置设备秘钥名",
  4. "provisionDeviceSecret": "预配置设备秘钥"
  5. }

thingsboard使用设备提供响应(响应)验证请求和回复。成功的响应包含设备 ID、凭据类型和token。如果验证不成功,响应将仅包含状态。

  1. {
  2. "provisionDeviceStatus":"SUCCESS",
  3. "credentialsType":"ACCESS_TOKEN",
  4. "accessToken":"sLzc0gDAZPkGMzFVTyUY"
  5. }
  6. {
  7. "credentialsValue":"xvbxcyccSBq9MODwUIOe",
  8. "credentialsType":"ACCESS_TOKEN",
  9. "status":"SUCCESS"
  10. }

在请求验证期间,平台将首先检查所提供的DeviceKeyDevice秘钥,以找到相应的设备配置文件。找到配置文件后,平台将使用配置的备用策略来验证设备名称。

  • 允许创建新设备- 检查同名设备尚未在 ThingsBoard 中注册。当您在制造过程中不知道唯一设备名称列表(MAC 地址等)时,此策略是有用的,但设备本身可以访问固件中的此信息。它更容易实施,但它不如第二个策略安全。

拨备完成后,ThingsBoard 将更新设备的备件国家服务器属性,并将它设置为拨备值。

设备配置文件配置

您应该配置设备配置文件,以启用配置功能、收集配置设备密钥和提供设备机密。

  • 您可以创建新设备配置文件或打开现有设备配置文件。要创建新的,您应该打开设备配置文件页面,然后单击表头中的”+”图标。
  • 输入新设备配置文件的名称,然后单击”添加设备配置文件”向导的第 4 步。我们将在本示例中使用名称”设备配置测试”。但是,通常这应该是您的设备型号或类似设备。
  • 选择其中一个配给策略,复制拨备密钥和秘密,最后单击”添加”。

image.png

image.png

  1. from paho.mqtt.client import Client
  2. from json import dumps, loads
  3. RESULT_CODES = {
  4. 1: "incorrect protocol version",
  5. 2: "invalid client identifier",
  6. 3: "server unavailable",
  7. 4: "bad username or password",
  8. 5: "not authorised",
  9. }
  10. def collect_required_data():
  11. config = {}
  12. print("\n\n", "="*80, sep="")
  13. print(" "*10, "\033[1m\033[94mThingsBoard device provisioning with basic authorization example script.\033[0m", sep="")
  14. print("="*80, "\n\n", sep="")
  15. host = input("Please write your ThingsBoard \033[93mhost\033[0m or leave it blank to use default (thingsboard.cloud): ")
  16. config["host"] = host if host else "thingsboard.cloud"
  17. port = input("Please write your ThingsBoard \033[93mport\033[0m or leave it blank to use default (1883): ")
  18. config["port"] = int(port) if port else 1883
  19. config["provision_device_key"] = input("Please write \033[93mprovision device key\033[0m: ")
  20. config["provision_device_secret"] = input("Please write \033[93mprovision device secret\033[0m: ")
  21. device_name = input("Please write \033[93mdevice name\033[0m or leave it blank to generate: ")
  22. if device_name:
  23. config["device_name"] = device_name
  24. print("\n", "="*80, "\n", sep="")
  25. return config
  26. class ProvisionClient(Client):
  27. PROVISION_REQUEST_TOPIC = "/provision/request"
  28. PROVISION_RESPONSE_TOPIC = "/provision/response"
  29. def __init__(self, host, port, provision_request):
  30. super().__init__()
  31. self._host = host
  32. self._port = port
  33. self._username = "provision"
  34. self.on_connect = self.__on_connect
  35. self.on_message = self.__on_message
  36. self.__provision_request = provision_request
  37. def __on_connect(self, client, userdata, flags, rc): # Callback for connect
  38. if rc == 0:
  39. print("[Provisioning client] Connected to ThingsBoard ")
  40. client.subscribe(self.PROVISION_RESPONSE_TOPIC) # Subscribe to provisioning response topic
  41. provision_request = dumps(self.__provision_request)
  42. print("[Provisioning client] Sending provisioning request %s" % provision_request)
  43. client.publish(self.PROVISION_REQUEST_TOPIC, provision_request) # Publishing provisioning request topic
  44. else:
  45. print("[Provisioning client] Cannot connect to ThingsBoard!, result: %s" % RESULT_CODES[rc])
  46. def __on_message(self, client, userdata, msg):
  47. decoded_payload = msg.payload.decode("UTF-8")
  48. print("[Provisioning client] Received data from ThingsBoard: %s" % decoded_payload)
  49. decoded_message = loads(decoded_payload)
  50. provision_device_status = decoded_message.get("status")
  51. if provision_device_status == "SUCCESS":
  52. self.__save_credentials(decoded_message["credentialsValue"])
  53. else:
  54. print("[Provisioning client] Provisioning was unsuccessful with status %s and message: %s" % (provision_device_status, decoded_message["errorMsg"]))
  55. self.disconnect()
  56. def provision(self):
  57. print("[Provisioning client] Connecting to ThingsBoard (provisioning client)")
  58. self.__clean_credentials()
  59. self.connect(self._host, self._port, 60)
  60. self.loop_forever()
  61. def get_new_client(self):
  62. client_credentials = self.__get_credentials()
  63. new_client = None
  64. if client_credentials:
  65. new_client = Client()
  66. new_client.username_pw_set(client_credentials)
  67. print("[Provisioning client] Read credentials from file.")
  68. else:
  69. print("[Provisioning client] Cannot read credentials from file!")
  70. return new_client
  71. @staticmethod
  72. def __get_credentials():
  73. new_credentials = None
  74. try:
  75. with open("credentials", "r") as credentials_file:
  76. new_credentials = credentials_file.read()
  77. except Exception as e:
  78. print(e)
  79. return new_credentials
  80. @staticmethod
  81. def __save_credentials(credentials):
  82. with open("credentials", "w") as credentials_file:
  83. credentials_file.write(credentials)
  84. @staticmethod
  85. def __clean_credentials():
  86. open("credentials", "w").close()
  87. def on_tb_connected(client, userdata, flags, rc): # Callback for connect with received credentials
  88. if rc == 0:
  89. print("[ThingsBoard client] Connected to ThingsBoard with credentials: %s" % client._username.decode())
  90. data={
  91. "Hello":"Vincent Iot"
  92. }
  93. client.publish('v1/devices/me/telemetry', payload=dumps(data), qos=0)
  94. else:
  95. print("[ThingsBoard client] Cannot connect to ThingsBoard!, result: %s" % RESULT_CODES[rc])
  96. if __name__ == '__main__':
  97. config = collect_required_data()
  98. THINGSBOARD_HOST = config["host"] # ThingsBoard instance host
  99. THINGSBOARD_PORT = config["port"] # ThingsBoard instance MQTT port
  100. PROVISION_REQUEST = {"provisionDeviceKey": config["provision_device_key"], # Provision device key, replace this value with your value from device profile.
  101. "provisionDeviceSecret": config["provision_device_secret"], # Provision device secret, replace this value with your value from device profile.
  102. }
  103. if config.get("device_name") is not None:
  104. PROVISION_REQUEST["deviceName"] = config["device_name"]
  105. provision_client = ProvisionClient(THINGSBOARD_HOST, THINGSBOARD_PORT, PROVISION_REQUEST)
  106. provision_client.provision() # Request provisioned data
  107. tb_client = provision_client.get_new_client() # Getting client with provisioned data
  108. if tb_client:
  109. tb_client.on_connect = on_tb_connected # Setting callback for connect
  110. tb_client.connect(THINGSBOARD_HOST, THINGSBOARD_PORT, 60)
  111. tb_client.loop_forever() # Starting infinity loop
  112. else:
  113. print("Client was not created!")

运行结果

  1. ================================================================================
  2. ThingsBoard device provisioning with basic authorization example script.
  3. ================================================================================
  4. Please write your ThingsBoard host or leave it blank to use default (thingsboard.cloud): www.vincentisme.com
  5. Please write your ThingsBoard port or leave it blank to use default (1883): 1883
  6. Please write provision device key: 2qvxh8igfbqsbf1bzvg1
  7. Please write provision device secret: qvm7qfeiiy0pv0vtbx30
  8. Please write device name or leave it blank to generate: vincentIot
  9. ================================================================================
  10. [Provisioning client] Connecting to ThingsBoard (provisioning client)
  11. [Provisioning client] Connected to ThingsBoard
  12. [Provisioning client] Sending provisioning request {"provisionDeviceKey": "2qvxh8igfbqsbf1bzvg1", "provisionDeviceSecret": "qvm7qfeiiy0pv0vtbx30", "deviceName": "vincentIot"}
  13. [Provisioning client] Received data from ThingsBoard: {"credentialsValue":"iMc83m7ipXBt3RLsqXti","credentialsType":"ACCESS_TOKEN","status":"SUCCESS"}
  14. [Provisioning client] Read credentials from file.
  15. [ThingsBoard client] Connected to ThingsBoard with credentials: iMc83m7ipXBt3RLsqXti

image.png

image.png