From 6915ff504d5311c96ceeaa3732e23d229fa09068 Mon Sep 17 00:00:00 2001 From: Andry925 Date: Mon, 2 Feb 2026 19:12:06 +0200 Subject: [PATCH 1/2] add examples for rpc usage --- examples/rpc_example_blockiing.py | 98 +++++++++++++++++++++++ examples/rpc_example_non_blocking.py | 114 +++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 examples/rpc_example_blockiing.py create mode 100644 examples/rpc_example_non_blocking.py diff --git a/examples/rpc_example_blockiing.py b/examples/rpc_example_blockiing.py new file mode 100644 index 0000000..42721bd --- /dev/null +++ b/examples/rpc_example_blockiing.py @@ -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() diff --git a/examples/rpc_example_non_blocking.py b/examples/rpc_example_non_blocking.py new file mode 100644 index 0000000..7fbc18e --- /dev/null +++ b/examples/rpc_example_non_blocking.py @@ -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) From 201989688b3955fb7e0c425221139bbcf28763ef Mon Sep 17 00:00:00 2001 From: Andry925 Date: Mon, 2 Feb 2026 19:12:33 +0200 Subject: [PATCH 2/2] add wrapper for non-blocking waiting for rpc's messages --- thingsboard_sdk/tb_device_mqtt.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/thingsboard_sdk/tb_device_mqtt.py b/thingsboard_sdk/tb_device_mqtt.py index 7d5cd9d..e236029 100644 --- a/thingsboard_sdk/tb_device_mqtt.py +++ b/thingsboard_sdk/tb_device_mqtt.py @@ -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)