概述
MicroPython Client SDK是用于MicroPython项目客户端集成的软件开发套件。允许您使用MQTT协议将MicroPython设备连接到ThingsBoard,发送遥测数据、属性并接收RPC调用。SDK提供简洁易用的API,便于开发者将MicroPython设备与平台集成。
MicroPython Client SDK支持以下功能:
- 使用MQTT协议连接ThingsBoard。
- 向ThingsBoard发送属性。
- 向ThingsBoard发送遥测数据。
- 从ThingsBoard接收RPC调用。
- 从ThingsBoard请求客户端和共享属性。
- 订阅ThingsBoard的属性更新。
- 设备认领。
- 设备预配置。
安装
要安装MicroPython Client SDK,可使用mip包管理器。在REPL或代码中运行以下命令:
1
2
3
import mip
mip.install('github:thingsboard/thingsboard-micropython-client-sdk')
建议使用以下代码片段,以确保SDK正确安装和导入,并避免每次运行代码时重复安装:
1
2
3
4
5
6
7
8
try:
from thingsboard_sdk.tb_device_mqtt import TBDeviceMqttClient
print("thingsboard-micropython-client-sdk package already installed.")
except ImportError:
print("Installing thingsboard-micropython-client-sdk package...")
mip.install('github:thingsboard/thingsboard-micropython-client-sdk')
from thingsboard_sdk.tb_device_mqtt import TBDeviceMqttClient
方法
简介
MicroPython Client SDK提供TBDeviceMqttClient类,用于连接ThingsBoard并发送数据。
该类设计简洁,便于MicroPython或ThingsBoard新手使用。
connect
使用MQTT协议连接ThingsBoard。在向ThingsBoard发送任何数据前需调用此方法。
创建TBDeviceMqttClient实例时需提供连接凭证。调用connect后,客户端的self.connected将设为True。
方法语法
client.connect(timeout=10)
参数
| Arguments | Default value | Description |
|---|---|---|
| timeout | 10 | (可选)建立与ThingsBoard连接的超时时间。 |
使用示例
1
2
3
4
5
6
7
8
# Default connecting
client.connect()
# Connecting with custom timeout
client.connect(timeout=20)
# Connecting with waiting for connection result
result = client.connect(timeout=20)
disconnect
断开与ThingsBoard的连接。连接后即可调用。建议在不再需要发送数据或需释放资源时调用。
调用后需再次调用connect才能发送数据。调用disconnect后,self.connected将设为False。
方法语法
client.disconnect()
使用示例
1
2
3
4
5
client.connect()
# some tasks with ThingsBoard
client.disconnect()
send_attributes
向ThingsBoard发送属性。连接后即可调用。支持以键值对形式发送。
方法语法
client.send_attributes(data)
参数
| Arguments | Description |
|---|---|
| data | (必填)将作为属性发送至ThingsBoard的数据。 |
使用示例
1
2
attributes = {"sensorModel": "DHT-22", "attribute_2": "value"}
client.send_attributes(attributes)
send_telemetry
向ThingsBoard发送遥测数据。连接后即可调用。支持以键值对、列表等格式发送。也支持按时间戳分组,便于发送历史数据。
方法语法
client.send_telemetry(data)
Arguments
| Arguments | Description |
|---|---|
| data | (必填)将作为遥测发送至ThingsBoard的数据。 |
使用示例
1
2
3
4
5
6
7
8
9
# Sending telemetry data in dictionary format
telemetry = {"temperature": 25.5, "humidity": 60}
client.send_telemetry(telemetry)
# Sending telemetry data grouped by timestamps
from time import time
telemetry = [{"ts": 1451649600000, "values": {"temperature": 42.2, "humidity": 71}},
{"ts": 1451649601000, "values": {"temperature": 42.3, "humidity": 72}}]
client.send_telemetry(telemetry)
request_attributes
从ThingsBoard请求客户端和共享属性。连接后即可调用。支持同时请求两种属性。可通过属性键列表指定要请求的属性。收到请求的属性后,将调用提供的回调函数并传入结果;若未找到,则传入空结果。
方法语法
client.request_attributes(client_keys=None, shared_keys=None, callback=None)
参数
| Arguments | Description |
|---|---|
| client_keys | (可选)要从ThingsBoard请求的客户端属性键列表。 |
| shared_keys | (可选)要从ThingsBoard请求的共享属性键列表。 |
| callback | (可选)收到请求属性时调用的回调函数,应接受result和exception两个参数。 |
使用示例
1
2
3
4
5
6
7
8
9
def on_attributes_change(result, exception=None):
# This is a callback function that will be called when client receive the response from the server
if exception is not None:
print("Exception: " + str(exception))
else:
print(result)
client.request_attributes(client_keys=["atr1", "atr2"], callback=on_attributes_change)
claim_device
使用此方法触发设备认领流程。通过传入唯一密钥,设备将自动关联到用户账户。这简化了设备上线流程,用户无需平台级别权限即可激活硬件。
更多信息请参见文档的设备认领章节。
方法语法
client.claim_device(secret_key, duration_ms=None)
Arguments
| Arguments | Description |
|---|---|
| secret_key | (必填)在ThingsBoard上用于认领设备的密钥。 |
| duration_ms | (可选)认领码有效时长(毫秒)。不提供则有效期为无限,直至被用于认领设备。 |
使用示例
1
2
3
4
5
# Claiming a device with a claim code that will be valid indefinitely until it is used to claim a device
client.claim_device("my_claim_code")
# Claiming a device with a claim code that will be valid for 60 seconds
client.claim_device("my_claim_code", duration_ms=60000)
subscribe_to_attribute
订阅ThingsBoard的属性更新。通过属性键指定要订阅的共享属性。订阅的属性值更新时,将调用提供的回调并传入新值。
方法返回订阅ID,可用于unsubscribe_from_attribute取消订阅。
方法语法
client.subscribe_to_attribute(key, callback)
参数
| Arguments | Description |
|---|---|
| key | (必填)要订阅的ThingsBoard共享属性键。 |
| callback | (必填)订阅属性在ThingsBoard上更新时触发的回调,须接受result和*args两个参数。 |
使用示例
1
2
3
4
5
def callback(result, *args):
print("Received data: %r", result)
sub_id = client.subscribe_to_attribute("frequency", callback)
subscribe_to_all_attributes
订阅ThingsBoard全部共享属性更新。服务端任意共享属性修改时,SDK会触发指定回调并传入更新后的数据。
方法返回订阅ID,可用于unsubscribe_from_attribute取消订阅。
方法语法
client.subscribe_to_all_attributes(callback)
参数
| Arguments | Description |
|---|---|
| callback | (必填)服务端推送共享属性变更时触发,回调接收包含修改后键值对的result对象及*args。 |
使用示例
1
2
3
4
5
def callback(result, *args):
print("Received data: %r", result)
sub_id = client.subscribe_to_all_attributes(callback)
unsubscribe_from_attribute
终止共享属性更新的现有订阅。需传入subscribe_to_attribute或subscribe_to_all_attributes返回的subscription_id。取消后,相关回调在服务端变更时不再触发。
方法语法
client.unsubscribe_from_attribute(subscription_id)
参数
| Arguments | Description |
|---|---|
| subscription_id | (必填)通过subscribe_to_attribute或subscribe_to_all_attributes订阅时返回的订阅ID。 |
使用示例
1
2
3
4
5
6
7
# Subscribing to attribute updates
def callback(result, *args):
print("Received data: %r", result)
sub_id = client.subscribe_to_attribute("frequency", callback)
# Unsubscribing from attribute updates
client.unsubscribe_from_attribute(sub_id)
set_server_side_rpc_request_handler
配置处理ThingsBoard发起的远程过程调用请求的处理器。应在建立连接后调用。收到请求时,SDK执行指定处理器并传入:
request_id- RPC请求的唯一标识符,用于发送响应。request_body- 包含命令详情的字典,通常含方法名和params。
方法语法
client.set_server_side_rpc_request_handler(handler)
参数
| Arguments | Description |
|---|---|
| handler | 定义ThingsBoard发起远程命令时执行的逻辑,函数接收request_id和request_body两个参数。 |
使用示例
1
2
3
4
def handler(request_id, request_body):
print("Received RPC request with ID: %s and body: %r", request_id, request_body)
client.set_server_side_rpc_request_handler(handler)
send_rpc_reply
响应来自ThingsBoard的RPC请求。在RPC处理器中使用此方法向服务器返回数据。需要初始请求的request_id和包含结果的response对象。不调用此方法可能导致ThingsBoard仪表板上出现request timeout错误。
方法语法
client.send_rpc_reply(request_id, response)
参数
| Arguments | Description |
|---|---|
| request_id | (必填)收到的RPC请求ID,用于发送回复。 |
| response | (必填)作为RPC回复发送的数据。 |
使用示例
1
2
3
4
5
def handler(request_id, request_body):
print("Received RPC request with ID: %s and body: %r", request_id, request_body)
client.send_rpc_reply(request_id, {"status": "success"})
client.set_server_side_rpc_request_handler(handler)
get_provision_request
静态方法,根据输入参数构造设备预配置请求。返回的预配置请求应通过provision方法发送至ThingsBoard。
方法语法
TBDeviceMqttClient.get_provision_request(provision_key, provision_secret)
参数
| Arguments | Description |
|---|---|
| provision_key | (必填)预配置设备密钥,需从已配置的设备配置文件中获取。 |
| provision_secret | (必填)预配置设备密文,需从已配置的设备配置文件中获取。 |
| device_name | (可选)设备在ThingsBoard中的名称。 |
| access_token | (可选)设备在ThingsBoard中的访问令牌。 |
| client_id | (可选)设备在ThingsBoard中的客户端ID。 |
| username | (可选)设备在ThingsBoard中的用户名。 |
| password | (可选)设备在ThingsBoard中的密码。 |
| hash | (可选)设备在ThingsBoard中的X509公钥哈希值。 |
| gateway | (可选)标识预配置请求是否为网关设备。不提供则默认为普通设备。 |
使用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Forming provision request with required arguments
provision_request = TBDeviceMqttClient.get_provision_request("my_provision_key", "my_provision_secret")
# Forming provision request with specified device name
provision_request = TBDeviceMqttClient.get_provision_request("my_provision_key", "my_provision_secret", device_name="My Device")
# Forming provision request with specified access token
provision_request = TBDeviceMqttClient.get_provision_request("my_provision_key", "my_provision_secret", access_token="my_access_token")
# Forming provision request with specified client ID, username, and password
provision_request = TBDeviceMqttClient.get_provision_request("my_provision_key", "my_provision_secret", client_id="my_client_id", username="my_username", password="my_password")
# Forming provision request for a gateway device
provision_request = TBDeviceMqttClient.get_provision_request("my_provision_key", "my_provision_secret", gateway=True)
provision
向ThingsBoard发送设备预配置请求。方法参数应为通过get_provision_request静态方法构造的预配置请求。请求成功后,设备将在ThingsBoard上完成预配置,并关联到拥有预配置密钥和密文的账户。请求失败则抛出异常。
方法语法
client.provision(host, port, provision_request)
参数
| Arguments | Description |
|---|---|
| host | (必填)ThingsBoard服务器主机地址。 |
| port | (必填)ThingsBoard服务器端口。 |
| provision_request | (必填)发送至ThingsBoard的预配置请求,应通过get_provision_request静态方法构造。 |
使用示例
1
2
3
4
# Forming provision request
provision_request = TBDeviceMqttClient.get_provision_request("my_provision_key", "my_provision_secret")
# Sending provision request to ThingsBoard for device provisioning
provisioned_credentials = client.provision("thingsboard.cloud", 1883, provision_request)
概念
简介
本节介绍MicroPython Client SDK的核心概念,如连接ThingsBoard、发送和接收数据。理解这些概念有助于在项目中有效使用SDK。
让我们通过以下代码示例回顾MicroPython Client SDK的核心概念:
连接ThingsBoard
使用MicroPython Client SDK连接ThingsBoard时,实例化TBDeviceMqttClient并传入host、port和access token。初始化后调用connect()建立MQTT会话。连接成功后即可发送遥测或订阅更新。推荐使用以下最小代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import network
from thingsboard_sdk.tb_device_mqtt import TBDeviceMqttClient
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Establishing connection to the Wi-Fi
if not wlan.isconnected():
print('Connecting to network...')
wlan.connect("YOUR_SSID", "YOUR_PASSWORD")
while not wlan.isconnected():
pass
print('Connected! Network config:', wlan.ifconfig())
client = TBDeviceMqttClient(host="thingsboard.cloud", port=1883, access_token="YOUR_ACCESS_TOKEN")
client.connect()
while True:
# some tasks with ThingsBoard
与ThingsBoard通信前,设备需先建立网络连接:
- 网络模块初始化Wi-Fi实例,使用STA_IF(站点接口)连接至现有接入点。
TBDeviceMqttClient是主类,需要ThingsBoard host和在设备页面生成的唯一Access Token。
处理服务端RPC
远程过程调用允许ThingsBoard向设备发送命令(如“打开LED”或“重置”)。要处理这些命令,需通过set_server_side_rpc_request_handler设置处理器。收到服务端RPC请求时该处理器会被调用,函数应接受request_id和request_body,分别对应请求ID和请求数据。
1
2
3
4
5
6
7
8
9
# This callback will be called when an RPC request is received from ThingsBoard.
def on_server_side_rpc_request(request_id, request_body):
# request_id: numeric id from the MQTT topic
# request_body: decoded JSON dict, typically {"method": "...", "params": ...}
print("[RPC] id:", request_id, "body:", request_body)
client.send_rpc_reply(request_id, "ok")
client.set_server_side_rpc_request_handler(on_server_side_rpc_request)
SDK不会“等待”命令,而是通过回调on_server_side_rpc_request处理:
- 使用set_server_side_rpc_request_handler()指定收到RPC时执行的函数。
- 收到RPC时,SDK自动将
request_id和request_body传入处理器。 - send_rpc_reply()告知服务器RPC已收到并处理成功。
非阻塞循环
SDK实现中最关键的是主循环。在MicroPython中,使用time.sleep_ms()期间设备无法处理传入消息。
client.check_for_msg()是通信的“心跳”:
- 检查MQTT缓冲区中的传入消息。
- 封装在
safe_check_msg()中,确保网络中断(如OSError)时程序不崩溃,仅记录错误并在下一轮重试。
遥测与数据流
SDK提供向ThingsBoard发送遥测的方法,可使用send_telemetry()以键值对、列表等格式发送。SDK也支持按时间戳分组,便于发送历史数据。
1
2
3
4
5
6
# Main loop (non-blocking)
while True:
# Non-blocking: poll for incoming MQTT packets, then continue doing other work
safe_check_msg()
client.send_telemetry({"CPU": 12.0})
time.sleep_ms(50)
将其置于主循环后,设备将持续上报状态。采用非阻塞方式,设备可同时发送遥测和接收RPC命令,互不阻塞。
示例
更多MicroPython Client SDK使用示例见GitHub上thingsboard-micropython-client-sdk仓库的examples目录。
故障排查
-
Mip安装失败OSError: -202
设备未联网或网络异常时可能出现此错误。请确保设备已连接互联网且网络正常。可尝试重启设备后再次运行安装命令。
建议先建立互联网连接再执行安装命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
import network import mip # Enabling WLAN interface wlan = network.WLAN(network.STA_IF) wlan.active(True) # Establishing connection to the Wi-Fi if not wlan.isconnected(): print('Connecting to network...') wlan.connect("YOUR_WIFI_SSID", "YOUR_WIFI_PASSWORD") while not wlan.isconnected(): pass mip.install('github:thingsboard/thingsboard-micropython-client-sdk')