视频讲解: https://www.bilibili.com/video/BV1GK4y1X7Kc/
thingsboard自动创建设备
工作流程汇总如图
设备向”thingboard”发送设备配置请求。请求中包含密钥和机密(预配置设备秘钥名,预配置设备秘钥),请求可选择包括设备生成的设备名称和凭据。如果缺少这些凭据,服务器将生成设备要使用的访问令牌。
拨备请求示例:
{
"deviceName": "DEVICE_NAME",
"provisionDeviceKey": "预配置设备秘钥名",
"provisionDeviceSecret": "预配置设备秘钥"
}
thingsboard使用设备提供响应(响应)验证请求和回复。成功的响应包含设备 ID、凭据类型和token。如果验证不成功,响应将仅包含状态。
{
"provisionDeviceStatus":"SUCCESS",
"credentialsType":"ACCESS_TOKEN",
"accessToken":"sLzc0gDAZPkGMzFVTyUY"
}
{
"credentialsValue":"xvbxcyccSBq9MODwUIOe",
"credentialsType":"ACCESS_TOKEN",
"status":"SUCCESS"
}
在请求验证期间,平台将首先检查所提供的DeviceKey和Device秘钥,以找到相应的设备配置文件。找到配置文件后,平台将使用配置的备用策略来验证设备名称。
- 允许创建新设备- 检查同名设备尚未在 ThingsBoard 中注册。当您在制造过程中不知道唯一设备名称列表(MAC 地址等)时,此策略是有用的,但设备本身可以访问固件中的此信息。它更容易实施,但它不如第二个策略安全。
拨备完成后,ThingsBoard 将更新设备的备件国家服务器属性,并将它设置为拨备值。
设备配置文件配置
您应该配置设备配置文件,以启用配置功能、收集配置设备密钥和提供设备机密。
- 您可以创建新设备配置文件或打开现有设备配置文件。要创建新的,您应该打开设备配置文件页面,然后单击表头中的”+”图标。
- 输入新设备配置文件的名称,然后单击”添加设备配置文件”向导的第 4 步。我们将在本示例中使用名称”设备配置测试”。但是,通常这应该是您的设备型号或类似设备。
- 选择其中一个配给策略,复制拨备密钥和秘密,最后单击”添加”。
from paho.mqtt.client import Client
from json import dumps, loads
RESULT_CODES = {
1: "incorrect protocol version",
2: "invalid client identifier",
3: "server unavailable",
4: "bad username or password",
5: "not authorised",
}
def collect_required_data():
config = {}
print("\n\n", "="*80, sep="")
print(" "*10, "\033[1m\033[94mThingsBoard device provisioning with basic authorization example script.\033[0m", sep="")
print("="*80, "\n\n", sep="")
host = input("Please write your ThingsBoard \033[93mhost\033[0m or leave it blank to use default (thingsboard.cloud): ")
config["host"] = host if host else "thingsboard.cloud"
port = input("Please write your ThingsBoard \033[93mport\033[0m or leave it blank to use default (1883): ")
config["port"] = int(port) if port else 1883
config["provision_device_key"] = input("Please write \033[93mprovision device key\033[0m: ")
config["provision_device_secret"] = input("Please write \033[93mprovision device secret\033[0m: ")
device_name = input("Please write \033[93mdevice name\033[0m or leave it blank to generate: ")
if device_name:
config["device_name"] = device_name
print("\n", "="*80, "\n", sep="")
return config
class ProvisionClient(Client):
PROVISION_REQUEST_TOPIC = "/provision/request"
PROVISION_RESPONSE_TOPIC = "/provision/response"
def __init__(self, host, port, provision_request):
super().__init__()
self._host = host
self._port = port
self._username = "provision"
self.on_connect = self.__on_connect
self.on_message = self.__on_message
self.__provision_request = provision_request
def __on_connect(self, client, userdata, flags, rc): # Callback for connect
if rc == 0:
print("[Provisioning client] Connected to ThingsBoard ")
client.subscribe(self.PROVISION_RESPONSE_TOPIC) # Subscribe to provisioning response topic
provision_request = dumps(self.__provision_request)
print("[Provisioning client] Sending provisioning request %s" % provision_request)
client.publish(self.PROVISION_REQUEST_TOPIC, provision_request) # Publishing provisioning request topic
else:
print("[Provisioning client] Cannot connect to ThingsBoard!, result: %s" % RESULT_CODES[rc])
def __on_message(self, client, userdata, msg):
decoded_payload = msg.payload.decode("UTF-8")
print("[Provisioning client] Received data from ThingsBoard: %s" % decoded_payload)
decoded_message = loads(decoded_payload)
provision_device_status = decoded_message.get("status")
if provision_device_status == "SUCCESS":
self.__save_credentials(decoded_message["credentialsValue"])
else:
print("[Provisioning client] Provisioning was unsuccessful with status %s and message: %s" % (provision_device_status, decoded_message["errorMsg"]))
self.disconnect()
def provision(self):
print("[Provisioning client] Connecting to ThingsBoard (provisioning client)")
self.__clean_credentials()
self.connect(self._host, self._port, 60)
self.loop_forever()
def get_new_client(self):
client_credentials = self.__get_credentials()
new_client = None
if client_credentials:
new_client = Client()
new_client.username_pw_set(client_credentials)
print("[Provisioning client] Read credentials from file.")
else:
print("[Provisioning client] Cannot read credentials from file!")
return new_client
@staticmethod
def __get_credentials():
new_credentials = None
try:
with open("credentials", "r") as credentials_file:
new_credentials = credentials_file.read()
except Exception as e:
print(e)
return new_credentials
@staticmethod
def __save_credentials(credentials):
with open("credentials", "w") as credentials_file:
credentials_file.write(credentials)
@staticmethod
def __clean_credentials():
open("credentials", "w").close()
def on_tb_connected(client, userdata, flags, rc): # Callback for connect with received credentials
if rc == 0:
print("[ThingsBoard client] Connected to ThingsBoard with credentials: %s" % client._username.decode())
data={
"Hello":"Vincent Iot"
}
client.publish('v1/devices/me/telemetry', payload=dumps(data), qos=0)
else:
print("[ThingsBoard client] Cannot connect to ThingsBoard!, result: %s" % RESULT_CODES[rc])
if __name__ == '__main__':
config = collect_required_data()
THINGSBOARD_HOST = config["host"] # ThingsBoard instance host
THINGSBOARD_PORT = config["port"] # ThingsBoard instance MQTT port
PROVISION_REQUEST = {"provisionDeviceKey": config["provision_device_key"], # Provision device key, replace this value with your value from device profile.
"provisionDeviceSecret": config["provision_device_secret"], # Provision device secret, replace this value with your value from device profile.
}
if config.get("device_name") is not None:
PROVISION_REQUEST["deviceName"] = config["device_name"]
provision_client = ProvisionClient(THINGSBOARD_HOST, THINGSBOARD_PORT, PROVISION_REQUEST)
provision_client.provision() # Request provisioned data
tb_client = provision_client.get_new_client() # Getting client with provisioned data
if tb_client:
tb_client.on_connect = on_tb_connected # Setting callback for connect
tb_client.connect(THINGSBOARD_HOST, THINGSBOARD_PORT, 60)
tb_client.loop_forever() # Starting infinity loop
else:
print("Client was not created!")
运行结果
================================================================================
ThingsBoard device provisioning with basic authorization example script.
================================================================================
Please write your ThingsBoard host or leave it blank to use default (thingsboard.cloud): www.vincentisme.com
Please write your ThingsBoard port or leave it blank to use default (1883): 1883
Please write provision device key: 2qvxh8igfbqsbf1bzvg1
Please write provision device secret: qvm7qfeiiy0pv0vtbx30
Please write device name or leave it blank to generate: vincentIot
================================================================================
[Provisioning client] Connecting to ThingsBoard (provisioning client)
[Provisioning client] Connected to ThingsBoard
[Provisioning client] Sending provisioning request {"provisionDeviceKey": "2qvxh8igfbqsbf1bzvg1", "provisionDeviceSecret": "qvm7qfeiiy0pv0vtbx30", "deviceName": "vincentIot"}
[Provisioning client] Received data from ThingsBoard: {"credentialsValue":"iMc83m7ipXBt3RLsqXti","credentialsType":"ACCESS_TOKEN","status":"SUCCESS"}
[Provisioning client] Read credentials from file.
[ThingsBoard client] Connected to ThingsBoard with credentials: iMc83m7ipXBt3RLsqXti