{"id":14971053,"url":"https://github.com/thingsboard/thingsboard-client-sdk","last_synced_at":"2025-11-29T07:04:30.493Z","repository":{"id":37827341,"uuid":"151122971","full_name":"thingsboard/thingsboard-client-sdk","owner":"thingsboard","description":"Client SDK to connect with ThingsBoard IoT Platform from IoT devices (Arduino, Espressif, etc.)","archived":false,"fork":false,"pushed_at":"2025-01-24T07:26:13.000Z","size":1849,"stargazers_count":181,"open_issues_count":17,"forks_count":131,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-05-23T13:22:40.737Z","etag":null,"topics":["arduino","arduino-library","arduino-nano-rp2040","arduino-nano-rp2040-connect","embedded","esp","esp-idf","esp32","esp8266","esp8266-arduino","espressif","iot","iot-platform","m5stack-library","mcu","mqtt","raspberry-pi-pico-w","rp2040","thingsboard"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thingsboard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-01T16:47:13.000Z","updated_at":"2025-05-23T07:33:51.000Z","dependencies_parsed_at":"2023-12-23T16:45:23.304Z","dependency_job_id":"6c3c3e57-845f-4d20-b922-4c27bb106a2a","html_url":"https://github.com/thingsboard/thingsboard-client-sdk","commit_stats":{"total_commits":598,"total_committers":21,"mean_commits":"28.476190476190474","dds":"0.23578595317725748","last_synced_commit":"1f327a4b0332371da9203955655e23e058ea9407"},"previous_names":["thingsboard/thingsboard-arduino-mqtt-sdk","thingsboard/thingsboard-client-sdk","thingsboard/thingsboard-arduino-sdk"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/thingsboard/thingsboard-client-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thingsboard%2Fthingsboard-client-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thingsboard%2Fthingsboard-client-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thingsboard%2Fthingsboard-client-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thingsboard%2Fthingsboard-client-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thingsboard","download_url":"https://codeload.github.com/thingsboard/thingsboard-client-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thingsboard%2Fthingsboard-client-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27339124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-29T02:00:06.589Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arduino-library","arduino-nano-rp2040","arduino-nano-rp2040-connect","embedded","esp","esp-idf","esp32","esp8266","esp8266-arduino","espressif","iot","iot-platform","m5stack-library","mcu","mqtt","raspberry-pi-pico-w","rp2040","thingsboard"],"created_at":"2024-09-24T13:44:39.151Z","updated_at":"2025-11-29T07:04:30.123Z","avatar_url":"https://github.com/thingsboard.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Client SDK to connect with ThingsBoard IoT Platform from various IoT devices (Arduino, Espressif, etc.)\n\n[![MIT license](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://lbesson.mit-license.org/)\n[![ESP32](https://img.shields.io/badge/ESP-32-green.svg?style=flat-square)](https://www.espressif.com/en/products/socs/esp32)\n[![ESP8266](https://img.shields.io/badge/ESP-8266-blue.svg?style=flat-square)](https://www.espressif.com/en/products/socs/esp8266)\n[![GitHub release](https://img.shields.io/github/release/thingsboard/thingsboard-client-sdk/all.svg?style=flat-square)](https://github.com/thingsboard/thingsboard-client-sdk/releases/)\n[![GitHub downloads](https://img.shields.io/github/downloads/thingsboard/thingsboard-client-sdk/all.svg?style=flat-square)](https://github.com/thingsboard/thingsboard-client-sdk/releases/)\n[![Arduino actions status](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/arduino-compile.yml/badge.svg)](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/arduino-compile.yml)\n[![Espressif IDF v4.4 actions status](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/espidf-compile-v4.4.yml/badge.svg)](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/espidf-compile-v4.4.yml)\n[![Espressif IDF v5.1 actions status](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/espidf-compile-v5.1.yml/badge.svg)](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/espidf-compile-v5.1.yml)\n[![ESP32 actions status](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/esp32-compile.yml/badge.svg)](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/esp32-compile.yml)\n[![ESP8266 actions status](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/esp8266-compile.yml/badge.svg)](https://github.com/thingsboard/thingsboard-client-sdk/actions/workflows/esp8266-compile.yml)\n![GitHub stars](https://img.shields.io/github/stars/thingsboard/thingsboard-client-sdk?style=social)\n\nThis library provides access to the ThingsBoard platform over the `MQTT` or `HTTP(S)` protocols.\n\n## Examples\n\nThe SDK comes with a number of example sketches. See **Files --\u003e Examples --\u003e ThingsBoard** within the Arduino application.\nPlease review the complete guide for `ESP32` Pico Kit `GPIO` control and `DHT22` sensor monitoring available [here](https://thingsboard.io/docs/samples/esp32/gpio-control-pico-kit-dht22-sensor/).\n\n## Supported Frameworks\n\n`ThingsBoardArduinoSDK` does not directly depend on any specific `MQTT Client` or `HTTP Client` implementation, instead any implementation of the `IMQTT_Client` or `IHTTP Client` can be used. Because there are no further dependencies on `Arduino`, besides the client that communicates it allows us to use this library with `Arduino`, when using the `Arduino_MQTT_Client` or with `Espressif IDF` when using the `Espressif_MQTT_Client`.\n\nExample usage for `Espressif` can be found in the `examples/0014-espressif_esp32_send_data` folder, all other code portions can be implemented the same way only initialization of the needed dependencies is slightly different. Meaning internal call to `ThingsBoard` works the same on both `Espressif` and `Arduino`.\n\nThis is also the case, because the only always used dependency that is remaining, is [`ArduinoJson`](https://arduinojson.org/), which despite its name does not require any `Arduino` component. _Please Note:_ you must use `v6.x.x` of this library as `v7.x.x` is not yet supported. Please see [this issue](https://github.com/thingsboard/thingsboard-client-sdk/issues/186#issuecomment-1877641466) for details as to why. \n\n## Installation\n\nThis project can be built with either [PlatformIO](https://platformio.org/), [`ESP IDF Extension`](https://www.espressif.com/) or [Arduino IDE](https://www.arduino.cc/en/software).\n\nThe project can be found in the [PlatformIO Registry](https://registry.platformio.org/libraries/thingsboard/ThingsBoard), [ESP Component registry](https://components.espressif.com/components/thingsboard/thingsboard) or the [Arduino libraries](https://www.arduino.cc/reference/en/libraries/thingsboard/).\n\nA description on how to include the library in you project can be found below for each of the aforementioned possible methods of integrating the project.\n\n#### PlatformIO\n\nTo add an external library, the most important portion is the [`lib_deps`](https://docs.platformio.org/en/latest/projectconf/sections/env/options/library/lib_deps.html) specification, simply add `thingsboard/ThingsBoard`.\nThere are multiple ways to define the version that should be fetched, but the most basic is simply getting the last released version, with the aforementioned line, to learn more see [Package Specifications](https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_install.html#package-specifications).\n\n```\nlib_deps=\n    thingsboard/ThingsBoard\n```\n\n#### ESP IDF Extension\n\nTo add an external library, what needs to be done differs between versions. If an [ESP-IDF](https://github.com/espressif/esp-idf) version after and including `v3.2.0` is used\nthen the project can simply be added over the [Component Manager](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html).\n\nTo do that we can simply call `idf.py add-dependency \u003cDEPENDENCY\u003e`, with the name of the dependency as an argument. Similar to `PlatformIO` there are a multiple way to define the version that should be fetched, but the method below is the most basic to simply get the last released version, to learn more see [Using Component Manager with a Project](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html#using-with-a-project).\n\n```\nidf.py add-dependency \"thingsboard/ThingsBoard\"\n```\n\nIf an [ESP-IDF](https://github.com/espressif/esp-idf) version prior to `v3.2.0` is used then the component has to be added as a `git submodule`.\nMeaning the repository has to first be a `git` project, if that is not the case already simply install `git` and call `git init` in the folder containing your project.\n\nSimilar to the other call there are a multiple way to define the version that should be fetched, but the method below is the most basic to simply get the last released version, to learn more see [Git Submodule Help page](https://git-scm.com/docs/git-submodule).\n\n```\ngit submodule add https://github.com/thingsboard/thingsboard-client-sdk.git components/ThingsBoard\n```\n\n#### Arduino IDE\n\nTo add an external library, we simply have to open `Tools` -\u003e `Manage Libraries` and then search for `ThingsBoard` then press the `install` button for the wanted version. See [how to install library on Arduino IDE](https://arduinogetstarted.com/faq/how-to-install-library-on-arduino-ide) for more detailed information and some troubleshooting if the aforementioned method does not work.\n\n\n## Dependencies\n\nFollowing dependencies are installed automatically or must be installed, too:\n\n**Installed automatically:**\n - [ArduinoJSON](https://github.com/bblanchon/ArduinoJson) — needed for dealing with the `JSON` payload that is sent to and received by `ThingsBoard`. _Please Note:_ you must use `v6.x.x` of this library as `v7.x.x` is not yet supported. Please see [this issue](https://github.com/thingsboard/thingsboard-client-sdk/issues/186#issuecomment-1877641466) for details as to why. \n - [MQTT PubSub Client](https://github.com/thingsboard/pubsubclient) — for interacting with `MQTT`, when using the `Arduino_MQTT_Client` instance as an argument to `ThingsBoard`. Only installed if this library is used over `Arduino IDE` or `PlatformIO` with the Arduino framework.\n - [Arduino Http Client](https://github.com/arduino-libraries/ArduinoHttpClient) — for interacting with `HTTP/S` when using the `Arduino_HTTP_Client` instance as an argument to `ThingsBoardHttp`. Only installed if this library is used over `Arduino IDE` or `PlatformIO` with the Arduino framework.\n\n**Needs to be installed manually:**\n - [MbedTLS Library](https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls) — needed to create hashes for the OTA update for non `Espressif` boards.\n - [Arduino Timer](https://github.com/contrem/arduino-timer) - needed to create non-blocking callback timers for non `Espressif` boards.\n - [WiFiEsp Client](https://github.com/bportaluri/WiFiEsp) — needed when using a `Arduino Uno` with a `ESP8266`.\n - [StreamUtils](https://github.com/bblanchon/StreamUtils) — needed when sending arbitrary amount of payload even if the buffer size is too small to hold that complete payload is wanted, aforementioned feature is automatically enabled if the library is installed.\n\n## Supported ThingsBoard Features\n\nExample implementations for all base features, mentioned above, can be found in the `examples` folder. See the `README.md` in each example folder, to see which boards are supported and which functionality the example shows.\n\n### Over `MQTT`:\n\nAll possible features are implemented over `MQTT` over a specific `IAPI_Implementation` instance:\n\n - [Telemetry data upload](https://thingsboard.io/docs/reference/mqtt-api/#telemetry-upload-api) / `ThingsBoardSized`\n - [Device attribute publish](https://thingsboard.io/docs/reference/mqtt-api/#publish-attribute-update-to-the-server) / `ThingsBoardSized`\n - [Server-side RPC](https://thingsboard.io/docs/reference/mqtt-api/#server-side-rpc) / `Server_Side_RPC`\n - [Client-side RPC](https://thingsboard.io/docs/reference/mqtt-api/#client-side-rpc) / `Client_Side_RPC`\n - [Request attribute values](https://thingsboard.io/docs/reference/mqtt-api/#request-attribute-values-from-the-server) / `Attribute_Request_Callback`\n - [Attribute update subscription](https://thingsboard.io/docs/reference/mqtt-api/#subscribe-to-attribute-updates-from-the-server) / `Shared_Attribute_Update`\n - [Device provisioning](https://thingsboard.io/docs/reference/mqtt-api/#device-provisioning) / `Provision`\n - [Device claiming](https://thingsboard.io/docs/reference/mqtt-api/#claiming-devices) / `ThingsBoardSized`\n - [Firmware OTA update](https://thingsboard.io/docs/reference/mqtt-api/#firmware-api) / `OTA_Firmware_Update`\n\n### Over `HTTP(S)`:\n\nThe remaining features have to be implemented by hand with the `sendGetRequest` or `sendPostRequest` method. See the [ThingsBoard Documentation](https://thingsboard.io/docs/reference/http-api) on how these features could be implemented. This is not done directly in the library, because most features require constant polling, whether an event occurred or not, this would cause massive overhead if it is done for all possible features and therefore not recommended.\n\n - [Telemetry data upload](https://thingsboard.io/docs/reference/http-api/#telemetry-upload-api)\n - [Device attribute publish](https://thingsboard.io/docs/reference/http-api/#publish-attribute-update-to-the-server)\n\n## Troubleshooting\n\nThis troubleshooting guide contains common issues that are well known and can occur if the library is used wrongly. Ensure to read this section before creating a new `GitHub Issue`.\n\n### Enabling internal debug messages\n\nIf the device is causing problems that are not already described in more detail below, it might be useful to enable internal debug messages, which will allow the library to print more information about sent and received messages as well as internal processes. This is disabled per default to decrease the amount of logs and memory for the log strings on the flash.\n\n```cpp\n// If not set the value is 0 per default, meaning it will only print internal error messages,\n// set to 1 to also print debugging messages which might help to discern the exact place where a method fails\n#define THINGSBOARD_ENABLE_DEBUG 1\n#include \u003cThingsBoard.h\u003e\n```\n\n### Not enough space for JSON serialization\n\nThe buffer size for the serialized JSON is fixed to 64 bytes. The SDK will not send data if the size of it is bigger than the configured internal buffer size. Respective logs in the `\"Serial Monitor\"` window will indicate the condition:\n\n```\n[TB] Send buffer size (64) to small for the given payloads size (83), increase with setBufferSize accordingly or install the StreamUtils library\n```\n\nIf that's the case, the buffer size for serialization should be increased. To do so, `setBufferSize()` method can be used or the `send_buffer_size` passed to the constructor can be increased as illustrated below:\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128);\n\nvoid setup() {\n  // Increase internal buffer size after inital creation.\n  tb.setBufferSize(128, 128);\n}\n```\n\nAlternatively, it is possible to enable the mentioned `THINGSBOARD_ENABLE_STREAM_UTILS` option, which sends messages that are bigger than the given buffer size with a method that skips the internal buffer, be aware tough this only works for sent messages. The internal buffer size still has to be big enough to receive the biggest possible message received by the client that is sent by the server.\n\nFor that the only thing that needs to be done is to install the required `StreamUtils` library, see the [Dependencies](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dependencies) section.\n\n### Dynamic ThingsBoard usage\n\nAll internal methods call attempt to utilize the stack as far as possible and completely minimize heap usage, that is the reason why there are places in the library where template arguments are required. If that memory being on the heap is not an issue, it is possible to remove the need to enter those template arguments altogether. Simply enable the `THINGSBOARD_ENABLE_DYNAMIC` option like shown below.\n\n```cpp\n// If not set the value is 0 per default,\n// set to 1 if the MaxResponse template argument should be automatically deduced instead\n#define THINGSBOARD_ENABLE_DYNAMIC 1\n#include \u003cThingsBoard.h\u003e\n```\n\n### Too much data fields must be serialized\n\nThe `sendAttributes` and `sendTelemetry` methods, use the [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/) this requires the `MaxKeyValuePairAmount` template argument to be passed in the method template list. If more key-value pairs are sent than specified, the `\"Serial Monitor\"` window will get a respective log showing an error:\n\n```\n[TB] Unable to serialize key-value json\n[TB] Attempt too enter to many JSON fields into StaticJsonDocument (5), increase (MaxKeyValuePairAmount) (3) accordingly\n```\n\nTo fix the issue we simply have to increase the template argument for the method to the actually required amount.\n\nAlternatively to remove the need for the `MaxKeyValuePairAmount`template argument in the method template list and to ensure the size the method has is always enough to send messages, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This makes the library use the [`DynamicJsonDocument`](https://arduinojson.org/v6/api/dynamicjsondocument/) instead of the default [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/). Be aware though as this places the json structure onto the heap.\n\n------------------------\n\nAdditionally, the [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/) is also used to deserialize the received payload for every kind of response received by the server, besides the `OTA` binary data.\nThis means that if the `MaxResponse` template argument is smaller than the amount of received key-value pairs, the `\"Serial Monitor\"` window will get a respective log showing an error:\n\n```\n[TB] Attempt too enter to many JSON fields into StaticJsonDocument (12), increase (MaxResponse) (8) accordingly\n```\n\nTo fix the issue we simply have to increase the template argument for the method to the actually required amount.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128);\n```\n\nAlternatively to remove the need for the `MaxResponse`template argument in the constructor template list and to ensure the size the buffer should have is always enough to hold received messages, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This makes the library use the [`DynamicJsonDocument`](https://arduinojson.org/v6/api/dynamicjsondocument/) instead of the default [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/). Be aware though as this places the json structure onto the heap.\n\n### Too many subscriptions\n\nThe possible event subscription classes that are passed to internal methods, use arrays which reside on the stack those require the `MaxSubscriptions` template argument to be passed in the constructor template list. The default value is 1, if the method call attempts to subscribe more than that many events in total, the `\"Serial Monitor\"` window will get a respective log showing an error:\n\n```\n[TB] Too many shared attribute update subscriptions, increase MaxSubscriptions or unsubscribe\n```\n\nImportant is that both server-side RPC and request attribute values are temporary, meaning once the request has been received it is deleted, and it is therefore possible to subscribe another event again. However, all other subscriptions like client-side RPC or attribute update subscription are permanent meaning once the event has been subscribed we can only unsubscribe all events to make more room.\n\nAdditionally, every aforementioned type of request has its own array meaning one type of event subscription (client-side RPC) does not affect the possible amount for another event subscription (attribute update subscription). Therefore, the only thing that needs to be done is to increase the size accordingly.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// Initialize used apis with Shared_Attribute_Update API with 1 maximum Shared_Attribute_Update subscription at once\n// Shared_Attribute_Update shared_attr;\n\n// Initialize used apis with Shared_Attribute_Update API with 2 maximum Shared_Attribute_Update subscription at once\nShared_Attribute_Update\u003c2U\u003e shared_attr;\nconst std::array\u003cIAPI_Implementation*, 1U\u003e apis = {\n    \u0026shared_attr\n};\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128, apis);\n```\n\nAlternatively, to remove the need for the `MaxSubscriptions` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This will replace the internal implementation with a growing vector instead, meaning all the subscribed callback data will reside on the heap instead.\n\n### Too many attributes\n\nThe possible attribute values that are passed to the `Shared_Attribute_Callback` or `Attribute_Request_Callback`, use arrays which reside on the stack those require the `MaxAttributes` template argument to be passed in the constructor template list. The default value is 1, if we attempt to subscribe or request more attributes than that, the `\"Serial Monitor\"` window will get a respective log showing a crash:\n\n```\nAssertion `m_size \u003c Capacity' failed.\n```\n\nTherefore, the only thing that needs to be done is to increase the size accordingly.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// Initialize used apis with Shared_Attribute_Update API, 1 maximum Shared_Attribute_Update subscription at once, 1 maximum attribute subscribed per individual subscription\n// Shared_Attribute_Update shared_attr;\n\n// Initialize used apis with Shared_Attribute_Update API, 2 maximum Shared_Attribute_Update subscription at once, 5 maximum attribute subscribed per individual subscription\nShared_Attribute_Update\u003c2U, 5U\u003e shared_attr;\nconst std::array\u003cIAPI_Implementation*, 1U\u003e apis = {\n    \u0026shared_attr\n};\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128, apis);\n```\n\nAlternatively, to remove the need for the `MaxAttributes` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This will replace the internal implementation with a growing vector instead, meaning all the subscribed attribute data will reside on the heap instead.\n\n### Server-side RPC response overflowed\n\nThe possible response in subscribed `RPC_Callback` methods, use the [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/) this requires the `MaxRPC` template argument to be passed in the constructor template list. The default value is 0, if we attempt to return more key-value pairs in the `JSON` than that, the `\"Serial Monitor\"` window will get a respective log showing an error:\n\n```\n[TB] Server-side RPC response overflowed, increase MaxRPC (0)\n```\n\nThe default size is only 0, because if a callback only uses the [`JsonDocument::set()`](https://arduinojson.org/v6/api/jsondocument/set/) method, it does not require additional memory. This is only the case if we attempt to add key-value pairs to the [`JsonDocument`](https://arduinojson.org/v6/api/jsondocument/). Therefore, the only thing that needs to be done is to increase the size accordingly.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// Initialize used apis with Shared_Attribute_Update API, 1 maximum Shared_Attribute_Update subscription at once, 0 maximum attribute serialized in the response\n// Shared_Attribute_Update shared_attr;\n\n// Initialize used apis with Server_Side_RPC API, 2 maximum Server_Side_RPC subscription at once, 1 maximum attribute serialized in the response\nServer_Side_RPC\u003c2U, 1U\u003e rpc;\nconst std::array\u003cIAPI_Implementation*, 1U\u003e apis = {\n    \u0026rpc\n};\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128, apis);\n```\n\nAlternatively, to remove the need for the `MaxRPC` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This will instead expect an additional parameter response size in the `RPC_Callback` constructor argument list, which shows the internal size the [`JsonDocument`](https://arduinojson.org/v6/api/jsondocument/) needs to have to contain the response. Use `JSON_OBJECT_SIZE()` and pass the amount of key value pair to calculate the estimated size. See https://arduinojson.org/v6/assistant/ for more information.\n\n### Server-side RPC response overflowed\n\nThe possible request in subscribed `RPC_Request_Callback` methods, use the [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/) this requires the `MaxRequestRPC` template argument to be passed in the constructor template list. The default value is 1, if we attempt to send more key-value pairs in the `JSON` than that, the `\"Serial Monitor\"` window will get a respective log showing an error:\n\n```\n[TB] Client-side RPC request overflowed, increase MaxRequestRPC (2)\n```\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// Initialize used apis with Shared_Attribute_Update API, 1 maximum Shared_Attribute_Update subscription at once, 1 maximum attribute serialized in the request\n// Shared_Attribute_Update shared_attr;\n\n// Initialize used apis with Server_Side_RPC API, 2 maximum Server_Side_RPC subscription at once, 2 maximum attribute serialized in the request\nClient_Side_RPC\u003c2U, 2U\u003e request_rpc;\nconst std::array\u003cIAPI_Implementation*, 1U\u003e apis = {\n    \u0026request_rpc\n};\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128, apis);\n```\n\nAlternatively, to remove the need for the `MaxRequestRPC` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This makes the library use the [`DynamicJsonDocument`](https://arduinojson.org/v6/api/dynamicjsondocument/) instead of the default [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/). Be aware though as this copies the requests onto the heap.\n\n## Tips and Tricks\n\n### Custom API Implementation Instance\n\nThe `ThingsBoardSized` class instance only supports a minimal subset of the actual API, see the [Supported ThingsBoard Features](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#supported-thingsboard-features) section. But with the usage of the `IAPI_Implementation` base class, it is possible to write an own implementation that implements an additional API implementation or changes the behavior for an already existing API implementation.\n\nFor that a `class` needs to inherit the `API_Implemenatation` class and `override` the needed methods shown below:\n\n```cpp\n#ifndef Custom_API_Implementation_h\n#define Custom_API_Implementation_h\n\n// Local includes.\n#include \"IAPI_Implementation.h\"\n\n\nclass Custom_API_Implementation : public IAPI_Implementation {\n  public:\n    API_Process_Type Get_Process_Type() override {\n        return API_Process_Type::JSON;\n    }\n\n    void Process_Response(char const * topic, uint8_t * payload, unsigned int length) override {\n        // Nothing to do\n    }\n\n    void Process_Json_Response(char const * topic, JsonDocument const \u0026 data) override {\n        // Nothing to do\n    }\n\n    bool Compare_Response_Topic(char const * topic) const override {\n        return true;\n    }\n\n    bool Unsubscribe() override {\n        return true;\n    }\n\n    bool Resubscribe_Topic() override {\n        return true;\n    }\n\n#if !THINGSBOARD_USE_ESP_TIMER\n    void loop() override {\n        // Nothing to do\n    }\n#endif // !THINGSBOARD_USE_ESP_TIMER\n\n    void Initialize() override {\n        // Nothing to do\n    }\n\n    void Set_Client_Callbacks(Callback\u003cvoid, IAPI_Implementation \u0026\u003e::function subscribe_api_callback, Callback\u003cbool, char const * const, JsonDocument const \u0026, size_t const \u0026\u003e::function send_json_callback, Callback\u003cbool, char const * const, char const * const\u003e::function send_json_string_callback, Callback\u003cbool, char const * const\u003e::function subscribe_topic_callback, Callback\u003cbool, char const * const\u003e::function unsubscribe_topic_callback, Callback\u003cuint16_t\u003e::function get_receive_size_callback, Callback\u003cuint16_t\u003e::function get_send_size_callback, Callback\u003cbool, uint16_t, uint16_t\u003e::function set_buffer_size_callback, Callback\u003csize_t *\u003e::function get_request_id_callback) override {\n        // Nothing to do\n    }\n};\n\n#endif // Custom_API_Implementation_h\n```\n\nOnce that has been done it can simply be passed to the `ThingsBoard` instance, either using the constructor or using the `Subscribe_IAPI_Implementation` method.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// Initialize used apis with Custom API\nCustom_IAPI_Implementation custom_api;\nconst std::array\u003cIAPI_Implementation*, 1U\u003e apis = {\n    \u0026custom_api\n};\n\n// The SDK setup with 64 bytes for JSON payload, 8 fields for JSON object and maximal 7 API endpoints subscribed at once\n// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis);\n\n// The SDK setup with 128 bytes for JSON payload and 8 fields for JSON object and maximal 10 API endpoints subscribed at once\nThingsBoardSized\u003c8, 10\u003e tb(mqttClient, 128, 128, apis);\n\n// Optional alternative way to subscribe the Custom API ater the class instance has already been created\n// tb.Subscribe_IAPI_Implementation(custom_api);\n```\n\n### Custom Updater Instance\n\nWhen using the `ThingsBoard` class instance, the class used to flash the binary data onto the device is not hard coded,\nbut instead the `OTA_Update_Callback` class expects an argument, the `IUpdater` implementation.\n\nThanks to it being an interface it allows an arbitrary implementation,\nmeaning as long as the device can flash binary data and supports the C++ STL it supports OTA updates, with the `ThingsBoard` library.\n\nCurrently, implemented in the library itself are the `Arduino_ESP32_Updater`, which is used for flashing the binary data when using a `ESP32` and `Arduino`, the `Arduino_ESP8266_Updater` which is used with the `ESP8266` and `Arduino`, the `Espressif_Updater` which is used with the `ESP32` and the `Espressif IDF` tool chain and lastly the `SDCard_Updater` which is used for both `Arduino` and the `Espressif IDF` to flash binary data onto an already initialized SD card.\n\nIf another device or feature wants to be supported, a custom interface implementation needs to be created.\nFor that a `class` needs to inherit the `IUpdater` interface and `override` the needed methods shown below:\n\n```cpp\n#include \u003cIUpdater.h\u003e\n\nclass Custom_Updater : public IUpdater {\n  public:\n    bool begin(size_t const \u0026 firmware_size) override {\n        return true;\n    }\n  \n    size_t write(uint8_t * payload, size_t const \u0026 total_bytes) override {\n        return total_bytes;\n    }\n  \n    void reset() override {\n        // Nothing to do\n    }\n  \n    bool end() override {\n        return true;\n    }\n};\n```\n\nOnce that has been done it can simply be passed instead of the `Espressif_Updater`, `Arduino_ESP8266_Updater`, `Arduino_ESP32_Updater` or `SDCard_Updater` instance.\n\n```cpp\n// Initalize the Updater client instance used to flash binary to flash memory\nCustom_Updater updater;\n\nconst OTA_Update_Callback callback(CURRENT_FIRMWARE_TITLE, CURRENT_FIRMWARE_VERSION, \u0026updater, \u0026finished_callback, \u0026progress_callback, \u0026update_starting_callback, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE);\n```\n\n### Custom HTTP Instance\n\nWhen using the `ThingsBoardHttp` class instance, the protocol used to send the data to the HTTP broker is not hard coded,\nbut instead the `ThingsBoardHttp` class expects the argument to a `IHTTP_Client` implementation.\n\nThanks to it being an interface it allows an arbitrary implementation,\nmeaning the underlying HTTP client can be whatever the user decides, so it can for example be used to support platforms using `Arduino` or even `Espressif IDF`.\n\nCurrently, implemented in the library itself is the `Arduino_HTTP_Client`, which is simply a wrapper around the [`ArduinoHttpClient`](https://github.com/arduino-libraries/ArduinoHttpClient), see [dependencies](https://github.com/arduino-libraries/ArduinoHttpClient?tab=readme-ov-file#dependencies) for whether the board you are using is supported or not.\n\nIf another device or feature wants to be supported, a custom interface implementation needs to be created.\nFor that a `class` needs to inherit the `IHTTP_Client` interface and `override` the needed methods shown below:\n\n```cpp\n#include \u003cIHTTP_Client.h\u003e\n\nclass Custom_HTTP_Client : public IHTTP_Client {\n  public:\n    void set_keep_alive(bool keep_alive) override {\n        // Nothing to do\n    }\n\n    int connect(char const * host, uint16_t port) override {\n        return 0;\n    }\n\n    void stop() override {\n        // Nothing to do\n    }\n\n    int post(char const * url_path, char const * content_type, char const * request_body) override {\n        return 0;\n    }\n\n    int get_response_status_code() override {\n        return 200;\n    }\n\n    int get(char const * url_path) override {\n        return 0;\n    }\n\n#if THINGSBOARD_ENABLE_STL\n    std::string get_response_body() override {\n        return std::string();\n    }\n#else\n    String get_response_body() override {\n        return String();\n    }\n\n#endif // THINGSBOARD_ENABLE_STL\n};\n```\n\nOnce that has been done it can simply be passed instead of the `Arduino_HTTP_Client` instance.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Http client instance\nCustom_HTTP_Client httpClient(espClient, THINGSBOARD_SERVER, THINGSBOARD_PORT);\n\n// The SDK setup with 8 fields for JSON object\nThingsBoardHttp tb(httpClient, TOKEN, THINGSBOARD_SERVER, THINGSBOARD_PORT);\n```\n\n### Custom MQTT Instance\n\nWhen using the `ThingsBoard` class instance, the protocol used to send the data to the MQTT broker is not hard coded,\nbut instead the `ThingsBoard` class expects the argument to a `IMQTT_Client` implementation.\n\nThanks to it being an interface it allows an arbitrary implementation,\nmeaning the underlying MQTT client can be whatever the user decides, so it can for example be used to support platforms using `Arduino` or even `Espressif IDF`.\n\nCurrently, implemented in the library itself is the `Arduino_MQTT_Client`, which is simply a wrapper around the [`PubSubClient`](https://github.com/thingsboard/pubsubclient), see [compatible Hardware](https://github.com/thingsboard/pubsubclient?tab=readme-ov-file#compatible-hardware) for whether the board you are using is supported or not, useful when using `Arduino`. As well as the `Espressif_MQTT_Client`, which is a simple wrapper around the [`esp-mqtt`](https://github.com/espressif/esp-mqtt), useful when using `Espressif IDF` with a `ESP32`.\n\nIf another device or feature wants to be supported, a custom interface implementation needs to be created.\nFor that a `class` needs to inherit the `IMQTT_Client` interface and `override` the needed methods shown below:\n\n```cpp\n#include \u003cIMQTT_Client.h\u003e\n\nclass Custom_MQTT_Client : public IMQTT_Client {\n  public:\n    void set_data_callback(Callback\u003cvoid, char *, uint8_t *, unsigned int\u003e::function callback) override {\n        // Nothing to do\n    }\n\n    void set_connect_callback(Callback\u003cvoid\u003e::function callback) override {\n        // Nothing to do\n    }\n\n    bool set_buffer_size(uint16_t buffer_size) override {\n        return true;\n    }\n\n    uint16_t get_buffer_size() override {\n        return 0U;\n    }\n\n    void set_server(char const * domain, uint16_t port) override {\n        // Nothing to do\n    }\n\n    bool connect(char const * client_id, char const * user_name, char const * password) override {\n        return true;\n    }\n\n    void disconnect() override {\n        // Nothing to do\n    }\n\n    bool loop() override {\n        return true;\n    }\n\n    bool publish(char const * topic, uint8_t const * payload, size_t const \u0026 length) override {\n        return true;\n    }\n\n    bool subscribe(char const * topic) override {\n        return true;\n    }\n\n    bool unsubscribe(char const * topic) override {\n        return true;\n    }\n\n    bool connected() override {\n        return true;\n    }\n\n#if THINGSBOARD_ENABLE_STREAM_UTILS\n\n    bool begin_publish(char const * topic, size_t const \u0026 length) override {\n        return true;\n    }\n\n    bool end_publish() override {\n        return true;\n    }\n\n    //----------------------------------------------------------------------------\n    // Print interface\n    //----------------------------------------------------------------------------\n\n    size_t write(uint8_t payload_byte) override {\n        return 1U;\n    }\n\n    size_t write(uint8_t const * buffer, size_t const \u0026 size) override {\n        return size;\n    }\n\n#endif // THINGSBOARD_ENABLE_STREAM_UTILS\n};\n```\n\nOnce that has been done it can simply be passed instead of the `Arduino_MQTT_Client` or the `Espressif_MQTT_Client` instance.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nCustom_MQTT_Client mqttClient(espClient);\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32\u003e tb(mqttClient, 128, 128);\n```\n\n### Custom Logger Instance\n\nWhen using the `ThingsBoard` class instance, the class used to print internal warning messages is not hard coded, but instead the `ThingsBoard` class expects the template argument to a `Logger` implementation. See the [Enabling internal debug messages](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#enabling-internal-debug-messages) section if the logger should also receive debug messages.\n\nThanks to it being a template parameter it allows an arbitrary implementation,\nmeaning the underlying Logger client can be whatever the user decides, so it can for example be used to print the messages onto a serial card instead of the serial console.\n\nCurrently, implemented in the library itself is the `DefaultLogger`, which is simply a wrapper around a `printf` call. If the functionality wants to be extended, a custom implementation needs to be created.\nFor that a `class` needs to fulfill the contract and implement the needed methods shown below:\n\n```cpp\nclass CustomLogger {\n  public:\n    template\u003ctypename ...Args\u003e\n    static int printfln(char const * format, Args const \u0026... args) {\n        return 0;\n    }\n};\n```\n\nOnce that has been done it can simply be passed as the last template parameter.\n\n```cpp\n// Initialize underlying client, used to establish a connection\nWiFiClient espClient;\n\n// Initalize the Mqtt client instance\nArduino_MQTT_Client mqttClient(espClient);\n\n// The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object\n// ThingsBoard tb(mqttClient);\n\n// The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object\nThingsBoardSized\u003c32, Default_Response_Amount, CustomLogger\u003e tb(mqttClient, 128, 128);\n```\n\n## Have a question or proposal?\n\nYou are welcome in our [issues](https://github.com/thingsboard/thingsboard-client-sdk/issues) and [Q\u0026A forum](https://groups.google.com/forum/#!forum/thingsboard).\n\n## License\n\nThis code is released under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthingsboard%2Fthingsboard-client-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthingsboard%2Fthingsboard-client-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthingsboard%2Fthingsboard-client-sdk/lists"}