{"id":16991440,"url":"https://github.com/theelims/psychicmqttclient","last_synced_at":"2025-10-14T09:39:38.359Z","repository":{"id":219545267,"uuid":"749198094","full_name":"theelims/PsychicMqttClient","owner":"theelims","description":"Fully featured asynchronous Arduino MQTT client for ESP32 with full support for SSL/TLS and MQTT over websocket","archived":false,"fork":false,"pushed_at":"2025-01-06T00:05:53.000Z","size":95,"stargazers_count":33,"open_issues_count":2,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-18T13:15:36.869Z","etag":null,"topics":["arduino-library","asynchronous","esp32","esp32-arduino","mqtt","mqtt-client","mqtt-smarthome","platformio"],"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/theelims.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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":"2024-01-27T21:17:48.000Z","updated_at":"2025-03-14T15:39:53.000Z","dependencies_parsed_at":"2024-10-28T13:23:51.615Z","dependency_job_id":"01693a97-7e41-46db-aece-2d7afffaec45","html_url":"https://github.com/theelims/PsychicMqttClient","commit_stats":null,"previous_names":["theelims/psychicmqttclient"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theelims%2FPsychicMqttClient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theelims%2FPsychicMqttClient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theelims%2FPsychicMqttClient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theelims%2FPsychicMqttClient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theelims","download_url":"https://codeload.github.com/theelims/PsychicMqttClient/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244978510,"owners_count":20541864,"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","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-library","asynchronous","esp32","esp32-arduino","mqtt","mqtt-client","mqtt-smarthome","platformio"],"created_at":"2024-10-14T03:25:54.743Z","updated_at":"2025-10-14T09:39:38.353Z","avatar_url":"https://github.com/theelims.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PsychicMqttClient\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Continuous Integration](https://github.com/theelims/PsychicMqttClient/actions/workflows/ci.yml/badge.svg)](https://github.com/theelims/PsychicMqttClient/actions/workflows/ci.yml)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/elims/library/PsychicMqttClient.svg)](https://registry.platformio.org/libraries/elims/PsychicMqttClient)\n\nFully featured async MQTT 3.1.1 client for ESP32 with support for SSL/TLS and MQTT over WS. Uses the ESP-IDF MQTT client library under the hood and adds a powerful but easy to use API on top of it. Supports MQTT over TCP, SSL with mbedtls, MQTT over Websocket and MQTT over Websocket Secure.\n\nThere are countless popular MQTT client libraries available for Arduino and ESP32. Like [AsyncMqttClient](https://github.com/marvinroger/async-mqtt-client) by Marvin Roger, [pubsubclient](https://github.com/knolleary/pubsubclient) by knolleary and [arduino-mqtt](https://github.com/256dpi/arduino-mqtt) by 256dpi. They are widely used, but all have their unique limitations. Like not supporting all QoS levels, limited message size and none of them has a practical support for SSL/TLS. Also MQTT over websocket is missing in all of them.\n\nThe API is very similar to [AsyncMqttClient](https://github.com/marvinroger/async-mqtt-client) for the ESP32 by Marvin Roger, so that this library can be used almost as a drop-in replacement. Only minor adjustments are necessary.\n\n## Features\n\n- Supports MQTT 3.1.1 with QoS 0, QoS 1 and QoS 2\n- Compatible with all ESP32 variants (ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6, ...)\n- Supports Arduino 2 (ESP-IDF 4) and Arduino 3 (ESP-IDF 5)\n- Supports MQTT over TCP and MQTT over websocket\n- Full support for SSL/TSL encryption - for both MQTT over TCP and MQTT over WS\n- No limitation in buffer size for transmit and receive messages. Multipart messages are reassembled.\n- Fully asynchronous and non-blocking\n- No dependencies to other libraries\n- Flexible and powerful event-based API\n  - `onTopic()` event which calls a callback every time a message on a specific subscribed topic is received\n- Handles reconnects automatically\n- Automatically embeds a X509 Root CA Bundle into the binary on platformio\n\n\u003e [!IMPORTANT]\n\u003e This library does not compile with the Arduino IDE. It requires the build system of [platformio](https://platformio.org/) or [pioarduino](https://github.com/pioarduino/platform-espressif32).\n\n## Usage\n\nMQTT has never been easier to use. Instantiate the MQTT client, set the server URI, and subscribe to a topic with the `onTopic()` event handler. Easy to use with a lambda function where you can work with the received payload. Connect the MQTT client to the server and you're set. Publish works as expected from any other MQTT client.\n\n```cpp\n#include \u003cPsychicMqttClient.h\u003e\n\nPsychicMqttClient mqttClient;\n\nvoid setup()\n{\n  // Setup Serial, WiFi, ...\n\n  mqttClient.setServer(\"mqtt://mqtt.eclipseprojects.io\");\n\n  mqttClient.onTopic(\"your/topic\", 0, [\u0026](const char *topic, const char *payload, int retain, int qos, bool dup)\n                       {\n                        Serial.printf(\"Received Topic: %s\\r\\n\", topic);\n                        Serial.printf(\"Received Payload: %s\\r\\n\", payload); });\n\n  mqttClient.connect();\n}\n\nvoid loop()\n{\n  // Your logic\n  mqttClient.publish(\"your/topic\", 0, 0, \"Hello World!\");\n}\n```\n\nThe client will handle all the connection details on its own. It will attempt to reconnect automatically, so you don't need to take care of this.\n\n\u003e [!IMPORTANT]\n\u003e No blocking code inside event handler functions. These must return fast. Especially no `delay()`, hardware functions or any other blocking code. Store the results and notify your main loop to take actions. If applicable use FreeRTOS toolings like queues or semaphores to protect against race conditions.\n\n## SSL/TLS Encryption\n\nUsing SSL/TLS encryption can be a little bit tedious, but with this MQTT client this is exceptionally easy. You can include a single PEM certificate in the code, or create a bundle of certificates with a platformio script. These are embedded into the binary and offer you universal SSL/TLS support for a wide range of servers without headaches.\n\n### Single CA Root Certificate\n\nIf you only need to connect to one specific MQTT server, which will never change, directly embedding the certificate into the source file is the easiest method.\n\nYou can get the root certificate directly from the browser. Open the domain of your MQTT server and verify the SSL encryption by pressing on the icon left to the URL. On Chrome press on `Connection is Secure` \u003e `Certificate is Valid` to open the certificate dialog. (Works similar on all other browsers.)\n\n![Chrome Screenshot](docs/resources/Browser_certificate.PNG)\n\nIn the Certificate Viewer select the Root Certificate at the top of the tree and press `Export` or any other way to download it. Open the downloaded file and copy the content into your source file. Format the string that it looks like shown below. Add the quotes and `\\n` line breaks to keep the block format.\n\n```cpp\nconst char *eclipse_root_ca = \"-----BEGIN CERTIFICATE-----\\n\"\n                              \"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\\n\"\n                              \"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\\n\"\n                              \"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\\n\"\n                              \"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\\n\"\n                              \"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\\n\"\n                              \"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\\n\"\n                              \"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\\n\"\n                              \"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\\n\"\n                              \"A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\\n\"\n                              \"T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\\n\"\n                              \"B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\\n\"\n                              \"B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\\n\"\n                              \"KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\\n\"\n                              \"OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\\n\"\n                              \"jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\\n\"\n                              \"qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\\n\"\n                              \"rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\\n\"\n                              \"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\\n\"\n                              \"hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\\n\"\n                              \"ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\\n\"\n                              \"3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\\n\"\n                              \"NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\\n\"\n                              \"ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\\n\"\n                              \"TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\\n\"\n                              \"jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\\n\"\n                              \"oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\\n\"\n                              \"4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\\n\"\n                              \"mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\\n\"\n                              \"emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\\n\"\n                              \"-----END CERTIFICATE-----\\n\";\n```\n\nWhen setting the server URI just add the reference to the root CA certificate:\n\n```cpp\nmqttClient.setCACert(eclipse_root_ca);\n```\n\nThat's it. Your MQTT connection is encrypted now.\n\n### X509 CA Root Certificate Bundles\n\nIf you require universal connectivity to more then one server with different root certificate authorities you can use the python script in the `/scripts` folder. It will either download a standard set of the most popular root CA's or use a set of certificates in \\*.PEM or \\*.DEM file format located in the folder `/ssl_certs`. For the download either the Mozilla collection at [https://curl.se/ca/cacert.pem](https://curl.se/ca/cacert.pem) is used or a collection curated by [Adafruit](https://github.com/adafruit/certificates/) specifically adjusted for the constraints of embedded systems.\n\nCopy the script from the library folder into your platformio project folder `./scripts` so that it can be found. In the `platformio.ini` add the following lines\n\n```ini\nextra_scripts = pre:scripts/generate_cert_bundle.py\n; Source for SSL Cert Store can bei either downloaded from Mozilla with 'mozilla' ('https://curl.se/ca/cacert.pem')\n; or from a curated Adafruit repository with 'adafruit' (https://raw.githubusercontent.com/adafruit/certificates/main/data/roots.pem)\n; or complied from a 'folder' full of *.pem / *.dem files stored in the ./ssl_certs folder\nboard_ssl_cert_source = adafruit\nboard_build.embed_files = src/certs/x509_crt_bundle.bin\n```\n\nand configure `board_ssl_cert_source` to your needs. If you use your own collection copy the \\*.PEM / \\*.DEM certificate files to `./ssl_certs`. The platformio build system will automatically compile the certificates into a binary file and embed them into the final binary. This can be later accessed in your code by\n\n```cpp\nextern const uint8_t rootca_crt_bundle_start[] asm(\"_binary_src_certs_x509_crt_bundle_bin_start\");\nextern const uint8_t rootca_crt_bundle_end[] asm(\"_binary_src_certs_x509_crt_bundle_bin_end\");\n```\n\nTo include the bundle for the MQTT client simply call\n\n```cpp\nmqttClient.setCACertBundle(rootca_crt_bundle_start, rootca_crt_bundle_end - rootca_crt_bundle_start);\n```\n\nwhen configuring the MQTT client instance before connecting.\n\n#### Together with WiFiClientSecure\n\nIf you use WiFiClientSecure in your application, it can be configured to use the X509 certificate bundle as well. In that case you should use WiFiClientSecure to instantiate the certificate bundle before calling `attachArduinoCACertBundle()`.\n\n```cpp\nWiFiClientSecure client;\n#if ESP_ARDUINO_VERSION_MAJOR == 3\nclient.setCACertBundle(rootca_crt_bundle_start, rootca_crt_bundle_end - rootca_crt_bundle_start);\n#else\nclient.setCACertBundle(rootca_crt_bundle_start);\n#endif\n// ...\nmqttClient.attachArduinoCACertBundle();\n```\n\nOtherwise the bundle will be overwritten by the MQTT client with unwanted side effects.\n\n\u003e [!IMPORTANT]  \n\u003e Currently there is a bug in mbedtls which prevents the proper certificate validation for all certificates signed by `Let's encrypt`. For this reason working directly with the ISRG Root X1 CA certificate or the bundle downloaded from Mozilla might result in SSL failing. You need to include the DST Root CA X3 certificate as well. Currently this is only done by the Adafruit repository. You can [read](https://github.com/adafruit/certificates/pull/1) here and [here](https://github.com/espressif/arduino-esp32/issues/8626) about the details.\n\n## Advanced Usage\n\nCheck the [documentation](/documentation.md) or the commented header file and the `FullyFeatured` example for a complete list of all event handlers and configuration options. You can even get access to the ESP-IDF MQTT Clients' configuration object, should you need parameters not broken out to the API.\n\n## License\n\nMIT License\n\nCopyright (c) 2025 elims\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheelims%2Fpsychicmqttclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheelims%2Fpsychicmqttclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheelims%2Fpsychicmqttclient/lists"}