ThingsBoard is an open-source IoT platform for data collection, processing, visualization, and device management. This project is a Python library that provides convenient client SDK for both Device and Gateway APIs.
SDK supports:
- Unencrypted and encrypted (TLS v1.2) connection
- QoS 0 and 1 (MQTT only)
- Automatic reconnect
- All Device MQTT APIs provided by ThingsBoard
- All Gateway MQTT APIs provided by ThingsBoard
- Most Device HTTP APIs provided by ThingsBoard
- Device Claiming
- Firmware updates
The Device MQTT API and the Gateway MQTT API are base on the Paho MQTT library. The Device HTTP API is based on the Requests library.
To install using pip:
pip3 install tb-mqtt-clientClient initialization and telemetry publishing
fromtb_device_mqttimportTBDeviceMqttClient, TBPublishInfotelemetry= {"temperature": 41.9, "enabled": False, "currentFirmwareVersion": "v1.2.2"}
# Initialize ThingsBoard clientclient=TBDeviceMqttClient("127.0.0.1", username="A1_TEST_TOKEN")
# Connect to ThingsBoardclient.connect()
# Sending telemetry without checking the delivery statusclient.send_telemetry(telemetry) # Sending telemetry and checking the delivery status (QoS = 1 by default)result=client.send_telemetry(telemetry)
# get is a blocking call that awaits delivery status success=result.get() ==TBPublishInfo.TB_ERR_SUCCESS# Disconnect from ThingsBoardclient.disconnect()TLS connection to localhost. See https://thingsboard.io/docs/user-guide/mqtt-over-ssl/ for more information about client and ThingsBoard configuration.
fromtb_device_mqttimportTBDeviceMqttClientimportsocketclient=TBDeviceMqttClient(socket.gethostname())
client.connect(tls=True,
ca_certs="mqttserver.pub.pem",
cert_file="mqttclient.nopass.pem")
client.disconnect()fromtb_device_httpimportTBHTTPDeviceclient=TBHTTPDevice('https://thingsboard.example.com', 'secret-token')
client.connect()
client.send_telemetry({'temperature': 41.9}, queued=False)TBDeviceMqttClient provides access to Device MQTT APIs of ThingsBoard platform. It allows to publish telemetry and attribute updates, subscribe to attribute changes, send and receive RPC commands, etc. Use TBHTTPClient for the Device HTTP API.
You can subscribe to attribute updates from the server. The following example demonstrates how to subscribe to attribute updates from the server.
importtimefromtb_device_mqttimportTBDeviceMqttClientdefon_attributes_change(result, *args):
print(result)
client=TBDeviceMqttClient("127.0.0.1", username="A1_TEST_TOKEN")
client.connect()
client.subscribe_to_attribute("uploadFrequency", on_attributes_change)
client.subscribe_to_all_attributes(on_attributes_change)
whileTrue:
time.sleep(1)Note: The HTTP API only allows a subscription to updates for all attribute.
importtimefromtb_device_httpimportTBHTTPClientclient=TBHTTPClient('https://thingsboard.example.com', 'secret-token')
defcallback(data):
print(data)
# ...# Subscribeclient.subscribe('attributes', callback)
whileTrue:
time.sleep(1)You can send multiple telemetry messages at once. The following example demonstrates how to send multiple telemetry messages at once.
fromtb_device_mqttimportTBDeviceMqttClient, TBPublishInfoimporttimetelemetry_with_ts= {"ts": int(round(time.time() *1000)), "values": {"temperature": 42.1, "humidity": 70}}
client=TBDeviceMqttClient("127.0.0.1", username="A1_TEST_TOKEN")
# we set maximum amount of messages sent to send them at the same time. it may stress memory but increases performanceclient.max_inflight_messages_set(100)
client.connect()
results= []
result=Trueforiinrange(0, 100):
results.append(client.send_telemetry(telemetry_with_ts))
fortmp_resultinresults:
result&=tmp_result.get() ==TBPublishInfo.TB_ERR_SUCCESSprint("Result "+str(result))
client.disconnect()Unsupported, the HTTP API does not allow the packing of values.
You can request attributes from the server. The following example demonstrates how to request attributes from the server.
importtimefromtb_device_mqttimportTBDeviceMqttClientIS_ATTR_RECEIVED=Falsedefon_attributes_change(result, *args):
globalIS_ATTR_RECEIVEDprint('Received attribute: ', result)
IS_ATTR_RECEIVED=Trueclient=TBDeviceMqttClient("127.0.0.1", username="A1_TEST_TOKEN")
client.connect()
client.request_attributes(["configuration", "targetFirmwareVersion"], callback=on_attributes_change)
whilenotIS_ATTR_RECEIVED:
time.sleep(1)fromtb_device_httpimportTBHTTPClientclient=TBHTTPClient('https://thingsboard.example.com', 'secret-token')
client_keys= ['attr1', 'attr2']
shared_keys= ['shared1', 'shared2']
data=client.request_attributes(client_keys=client_keys, shared_keys=shared_keys)
print('Received attributes: ', data)You can respond to RPC calls from the server. The following example demonstrates how to respond to RPC calls from the server. Please install psutil using 'pip install psutil' command before running the example.
importtimefromtb_device_mqttimportTBDeviceMqttClienttry:
importpsutilexceptImportError:
print("Please install psutil using 'pip install psutil' command")
exit(1)
# dependently of request method we send different data backdefon_server_side_rpc_request(request_id, request_body):
print(request_id, request_body)
ifrequest_body["method"] =="getCPULoad":
client.send_rpc_reply(request_id, {"CPU percent": psutil.cpu_percent()})
elifrequest_body["method"] =="getMemoryUsage":
client.send_rpc_reply(request_id, {"Memory": psutil.virtual_memory().percent})
client=TBDeviceMqttClient("127.0.0.1", username="A1_TEST_TOKEN")
client.set_server_side_rpc_request_handler(on_server_side_rpc_request)
client.connect()
whileTrue:
time.sleep(1)You can use HTTP API client in case you want to use HTTP API instead of MQTT API.
importtimefromtb_device_httpimportTBHTTPClientclient=TBHTTPClient('https://thingsboard.example.com', 'secret-token')
defcallback(data):
rpc_id=data['id']
# ... do something with data['params'] and data['method']...response_params= {'result': 1}
client.send_rpc(name='rpc_response', rpc_id=rpc_id, params=response_params)
# Subscribeclient.subscribe('rpc', callback)
whileTrue:
time.sleep(1)TBGatewayMqttClient extends TBDeviceMqttClient, thus has access to all it's APIs as a regular device. Besides, gateway is able to represent multiple devices connected to it. For example, sending telemetry or attributes on behalf of other, constrained, device. See more info about the gateway here:
importtimefromtb_gateway_mqttimportTBGatewayMqttClientgateway=TBGatewayMqttClient("127.0.0.1", username="TEST_GATEWAY_TOKEN")
gateway.connect()
gateway.gw_connect_device("Test Device A1")
gateway.gw_send_telemetry("Test Device A1", {"ts": int(round(time.time() *1000)), "values": {"temperature": 42.2}})
gateway.gw_send_attributes("Test Device A1", {"firmwareVersion": "2.3.1"})
gateway.gw_disconnect_device("Test Device A1")
gateway.disconnect()You can request attributes from the server. The following example demonstrates how to request attributes from the server.
importtimefromtb_gateway_mqttimportTBGatewayMqttClientdefcallback(result, exception):
ifexceptionisnotNone:
print("Exception: "+str(exception))
else:
print(result)
gateway=TBGatewayMqttClient("127.0.0.1", username="TEST_GATEWAY_TOKEN")
gateway.connect()
gateway.gw_request_shared_attributes("Test Device A1", ["temperature"], callback)
whileTrue:
time.sleep(1)You can respond to RPC calls from the server. The following example demonstrates how to respond to RPC calls from the server. Please install psutil using 'pip install psutil' command before running the example.
importtimefromtb_gateway_mqttimportTBGatewayMqttClienttry:
importpsutilexceptImportError:
print("Please install psutil using 'pip install psutil' command")
exit(1)
defrpc_request_response(request_id, request_body):
# request body contains id, method and other parametersprint(request_body)
method=request_body["data"]["method"]
device=request_body["device"]
req_id=request_body["data"]["id"]
# dependently of request method we send different data backifmethod=='getCPULoad':
gateway.gw_send_rpc_reply(device, req_id, {"CPU load": psutil.cpu_percent()})
elifmethod=='getMemoryLoad':
gateway.gw_send_rpc_reply(device, req_id, {"Memory": psutil.virtual_memory().percent})
else:
print('Unknown method: '+method)
gateway=TBGatewayMqttClient("127.0.0.1", username="TEST_GATEWAY_TOKEN")
gateway.connect()
# now rpc_request_response will process rpc requests from serversgateway.gw_set_server_side_rpc_request_handler(rpc_request_response)
# without device connection it is impossible to get any messagesgateway.gw_connect_device("Test Device A1")
whileTrue:
time.sleep(1)There are more examples for both device and gateway in corresponding folders.
This project is released under Apache 2.0 License.
