Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions examples/rpc_example_blockiing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
This sketch demonstrates connecting to Wi-Fi, connecting to ThingsBoard over MQTT,
and handling server-side RPC requests (blocking loop).
"""

import network
import os
from thingsboard_sdk.tb_device_mqtt import TBDeviceMqttClient

WIFI_SSID = "YOUR_SSID"
WIFI_PASSWORD = "YOUR_PASSWORD"

# Thingsboard we want to establish a connection to
THINGSBOARD_HOST = "thingsboard.cloud"
# MQTT port used to communicate with the server, 1883 is the default unencrypted MQTT port,
# whereas 8883 would be the default encrypted SSL MQTT port
THINGSBOARD_PORT = 1883
# See https://thingsboard.io/docs/getting-started-guides/helloworld/
# to understand how to obtain an access token
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"

# Enabling WLAN interface
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
RPC_METHODS = ("Pwd", "Ls")

# Establishing connection to the Wi-Fi
if not wlan.isconnected():
print('Connecting to network...')
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while not wlan.isconnected():
pass

print('Connected! Network config:', wlan.ifconfig())


def server_side_rpc_request_handler(client):
"""
Returns the callback function that ThingsBoard SDK will call when an RPC request arrives.
We wrap it so the callback can use the 'client' instance for sending a response.
"""

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)

# Validate incoming payload type
if not isinstance(request_body, dict):
print("[RPC] bad request format (not a dict)")
return

# Extract method name and parameters from the RPC payload
method = request_body.get("method")
params = request_body.get("params")

# Reject unknown methods
if method not in RPC_METHODS:
reply = {"error": "Unsupported method", "method": method}
# Send RPC response back to ThingsBoard (method name depends on your SDK wrapper)
client.respond_to_server_side_rpc(request_id, reply)
return

# RPC: "Pwd" - return current working directory on the device filesystem
if method == "Pwd":
reply = {"current_directory": os.getcwd()}
client.respond_to_server_side_rpc(request_id, reply)

# RPC: "Ls" - list files in a directory
elif method == "Ls":
try:
# If params is missing/empty, default to root ("/") or current dir
if not params:
params = "/"
# Here we treat params directly as a path string for simplicity.
files = os.listdir(params)
reply = {"path": params, "files": files}
except Exception as e:
reply = {"error": str(e)}

client.respond_to_server_side_rpc(request_id, reply)

return on_server_side_rpc_request


# Initialising client to communicate with ThingsBoard
client = TBDeviceMqttClient(THINGSBOARD_HOST, port=THINGSBOARD_PORT, access_token=ACCESS_TOKEN)
# Register the server-side RPC callback before the main loop
client.set_server_side_rpc_request_handler(server_side_rpc_request_handler(client))
# Connect to ThingsBoard
client.connect()

# Main loop (blocking)
while True:
# wait_for_msg() blocks until an MQTT message arrives.
# This is simplest for an RPC-only demo, but it can block other device logic.
print("Waiting for RPC requests... blocking")
client.wait_for_msg()
114 changes: 114 additions & 0 deletions examples/rpc_example_non_blocking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"""
Non-blocking server-side RPC example for ThingsBoard MicroPython SDK.
The loop keeps running and polls MQTT messages periodically (no hard blocking).
"""

import network
import time
import os
from thingsboard_sdk.tb_device_mqtt import TBDeviceMqttClient

WIFI_SSID = "YOUR_SSID"
WIFI_PASSWORD = "YOUR_PASSWORD"

# Thingsboard we want to establish a connection to
THINGSBOARD_HOST = "thingsboard.cloud"
# MQTT port used to communicate with the server, 1883 is the default unencrypted MQTT port,
# whereas 8883 would be the default encrypted SSL MQTT port
THINGSBOARD_PORT = 1883
# See https://thingsboard.io/docs/getting-started-guides/helloworld/
# to understand how to obtain an access token
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"

# Enabling WLAN interface
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
RPC_METHODS = ("Pwd", "Ls")

# Establishing connection to the Wi-Fi
if not wlan.isconnected():
print('Connecting to network...')
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while not wlan.isconnected():
pass

print('Connected! Network config:', wlan.ifconfig())


def server_side_rpc_request_handler(client):
"""
Returns the callback function that ThingsBoard SDK will call when an RPC request arrives.
We wrap it so the callback can use the 'client' instance for sending a response.
"""

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)

# Validate incoming payload type
if not isinstance(request_body, dict):
print("[RPC] bad request format (not a dict)")
return

# Extract method name and parameters from the RPC payload
method = request_body.get("method")
params = request_body.get("params")

# Reject unknown methods
if method not in RPC_METHODS:
reply = {"error": "Unsupported method", "method": method}
# Send RPC response back to ThingsBoard (method name depends on your SDK wrapper)
client.respond_to_server_side_rpc(request_id, reply)
return

# RPC: "Pwd" - return current working directory on the device filesystem
if method == "Pwd":
reply = {"current_directory": os.getcwd()}
client.respond_to_server_side_rpc(request_id, reply)

# RPC: "Ls" - list files in a directory
elif method == "Ls":
try:
# If params is missing/empty, default to root ("/") or current dir
if not params:
params = "/"
# Here we treat params directly as a path string for simplicity.
files = os.listdir(params)
reply = {"path": params, "files": files}
except Exception as e:
reply = {"error": str(e)}

client.respond_to_server_side_rpc(request_id, reply)

return on_server_side_rpc_request


def safe_check_msg(client):
"""
Non-blocking MQTT poll.
We call the underlying umqtt client to check if a message is ready.
"""
try:
# non-blocking check
client.check_for_msg()
return True
except OSError as e:
print("[MQTT] check_msg OSError:", e)
except Exception as e:
print("[MQTT] check_msg error:", e)
return False


# Initialising client to communicate with ThingsBoard
client = TBDeviceMqttClient(THINGSBOARD_HOST, port=THINGSBOARD_PORT, access_token=ACCESS_TOKEN)
# Register the server-side RPC callback before the main loop
client.set_server_side_rpc_request_handler(server_side_rpc_request_handler(client))
# Connect to ThingsBoard
client.connect()

# Main loop (non-blocking)
while True:
# Non-blocking: poll for incoming MQTT packets, then continue doing other work
safe_check_msg(client)
time.sleep_ms(10)
3 changes: 3 additions & 0 deletions thingsboard_sdk/tb_device_mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def send_rpc_call(self, method, params, callback):
def wait_for_msg(self):
self._client.wait_msg()

def check_for_msg(self):
self._client.check_msg()

@staticmethod
def provision(host, port, provision_request):
provision_client = ProvisionClient(host=host, port=port, provision_request=provision_request)
Expand Down