thingsboard-client-sdk: Server-side RPC no longer working with ThingsBoard-arduino-sdk version 0.7.1

I’ve been evaluating serve-side RPC with ThingsBoard-arduino-sdk version 0.7.1 and an ESP32 development board with PlatformIO. I believe I have found a bug. When I test my code, which is heavily inspired on the ‘0002-arduino_rpc’ example, the ESP32 callbacks are never called although I can see that messages are being sent by the ThingsBoard platform.

After reviewing my code, I attempted to revert back to ThingsBoard-arduino-sdk version 0.6.0 and re-test my code, with minor changes using #define, at which point the RPC callbacks are working. See below for terminal debug messages confirming functionality:

Connecting to AP … Attempting to connect to WPA SSID: “YOUR_WIFI_AP” Connecting to: "THINGSBOARD_SERVER " with token “YOUR_ACCESS_TOKEN” Subscribing for RPC… Subscribe done [TB] Callback on_message from topic: v1/devices/me/rpc/request/1725 [TB] received RPC: [TB] example_set_temperature [TB] calling RPC: [TB] example_set_temperature [TB] params: [TB] {“state”:2} Received the set temperature RPC method [TB] response: [TB] {“example_response”:42}

From what I can see, server-side RPC is not working with ThingsBoard-arduino-sdk version 0.7.1 but is working with 0.6.0. Has anyone else seen this problem? More importantly, is there a solution? Please see my code below for additional details:

`// This sketch demonstrates connecting and receiving RPC calls from // ThingsBoard using ThingsBoard SDK. // // Hardware: // - ESP32

#include <Arduino.h> #include <ThingsBoard.h> #include <WiFi.h>

#define WIFI_AP “YOUR_WIFI_AP” #define WIFI_PASSWORD “YOUR_WIFI_PASSWORD”

// See https://thingsboard.io/docs/getting-started-guides/helloworld/ // to understand how to obtain an access token #define TOKEN “YOUR_ACCESS_TOKEN” #define THINGSBOARD_SERVER “thingsboard.cloud”

// Initialize the Ethernet client object WiFiClient espClient; // Initialize ThingsBoard instance ThingsBoard tb(espClient);

void setup() { // initialize serial for debugging Serial.begin(9600);

WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); WiFi.setHostname(“MY_ESP32”); WiFi.begin(WIFI_AP, WIFI_PASSWORD); }

// Processes function for RPC call “example_set_temperature” // RPC_Data is a JSON variant, that can be queried using operator[] // See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details RPC_Response processTemperatureChange(const RPC_Data &data) { Serial.println(“Received the set temperature RPC method”);

// Just an response example return RPC_Response(“example_response”, 42); }

// Processes function for RPC call “example_set_switch” // RPC_Data is a JSON variant, that can be queried using operator[] // See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details RPC_Response processSwitchChange(const RPC_Data &data) { Serial.println(“Received the set switch method”);

// Just an response example return RPC_Response(“example_response”, 22.02); }

//#define THINGSBOARD_VERSION_060 #define THINGSBOARD_VERSION_07X

#ifdef THINGSBOARD_VERSION_060 const size_t callbacks_size = 2; RPC_Callback callbacks[callbacks_size] = { { “example_set_temperature”, processTemperatureChange }, { “example_set_switch”, processSwitchChange } }; #endif

#ifdef THINGSBOARD_VERSION_07X const std::vector<RPC_Callback> callbacks = { { “example_set_temperature”, processTemperatureChange }, { “example_set_switch”, processSwitchChange } }; #endif

bool subscribed = false;

void loop() { delay(100);

while(WiFi.status() != WL_CONNECTED) { Serial.println(“Connecting to AP …”); Serial.print("Attempting to connect to WPA SSID: "); Serial.println(WIFI_AP); delay(1000); }

if (!tb.connected()) { subscribed = false;

// Connect to the ThingsBoard
Serial.print("Connecting to: ");
Serial.print(THINGSBOARD_SERVER);
Serial.print(" with token ");
Serial.println(TOKEN);
if (!tb.connect(THINGSBOARD_SERVER, TOKEN)) {
  Serial.println("Failed to connect, retrying ...");
  return;
}

}

if (!subscribed) { Serial.println(“Subscribing for RPC…”);

#ifdef THINGSBOARD_VERSION_060
  if (!tb.RPC_Subscribe(callbacks, callbacks_size)) {
    Serial.println("Failed to subscribe for RPC");
    return;
  }
#endif

#ifdef THINGSBOARD_VERSION_07X
  if (!tb.RPC_Subscribe(callbacks.cbegin(), callbacks.cend())) {
    Serial.println("Failed to subscribe for RPC");
    return;
  }
#endif

Serial.println("Subscribe done");
subscribed = true;

}

tb.loop(); } `

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (8 by maintainers)

Most upvoted comments

@MathewHDYT , I just tested your suggested change: ThingsBoardSized<256> tb(espClient);. This modification worked perfectly and RPC is now working with version 0.7.1.

Thank you very much for looking into this issue and providing a solution. Also, thanks for the detailed explanation and additional pointers.

Amazing work Mathew!

Okay I have found the issue after trying to integrate some things from the ThingsBoard library in the bare bones example. The problem was the maximum size that PubSubClient has, which is per default only 64 this does not seem to be enough when doing RPC --> Resulting in the message not “arriving”, even tough theoretically a message was received, it was just discarded.

To fix that you can simply use the ThingsBoardSzed class instead. See example below:

// Increased size to 256 bytes instead of default 64, making it possible to handle / receive bigger messages.
ThingsBoardSized<256> tb(espClient);

This should fix your issue and make RPC work again.

Know I also now why it works with the older version. Previously before the rework the PayloadSize of 64 bytes was not even passed to the PubSubClient meaning it always had the default 256 bytes size even if you intended it to be bigger or smaller.

I’ll see if it is somehow possible to receive an error message via. the PubSubClient if a message is discarded to ensure if something like this happens again you at least get a console warning, showing that the PayloadSize is too small.

I’ve added a Pull Request for the PubSubClient library that informs about packet drops because the size is to big. If it is merged something like this should be more easily detected and circumvented in the future.

Thanks a lot as it seems the subscription and callback both work. So I don’t have an idea what could theoretically cause the problem at the moment.

I will try to get your code up and running and I’m hoping I can find some kind of other issue it could be, but right know I can’t think of anything else.

Will inform you once I fixed it or found something that might be worth testing on your end. Sorry for the inconviences.