diff --git a/README.md b/README.md index 3af97cb..a0b8432 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,21 @@ # MQTT and Wifi handling for ESP8266 and ESP32 This library is intended to encapsulate the handling of WiFi and MQTT connections of an ESP8266/ESP32. -You just need to provide your credentials and it will manage the following things: +You just need to provide your credentials and it will manage the following things: - Connecting to a WiFi network. - Connecting to a MQTT broker. - Automatically detecting connection lost either from the WiFi client or the MQTT broker and it will retry a connection automatically. -- Subscribing/unsubscrubing to/from MQTT topics by a friendly callback system. +- Subscribing/unsubscribing to/from MQTT topics by a friendly callback system. - Supports a single occurrence of a '+' or '#' wildcard in subscriptions - Provide a callback handling to advise once everything is connected (Wifi and MQTT). - Provide a function to enable printing of useful debug information related to MQTT and Wifi connections. - Provide some other useful utilities for MQTT and Wifi management. - Provide a function to enable an HTTP Update server secured by a password to allow remote update. +- Provide a function to enable OTA secured by a password to allow remote update. ## Dependency -The MQTT communication depends on the PubSubClient Library (https://github.com/knolleary/pubsubclient). +The MQTT communication depends on the [PubSubClient Library](https://github.com/knolleary/pubsubclient). ## Example @@ -46,14 +47,14 @@ void loop() { } ``` -See "SimpleMQTTClient.ino" for the complete example. +See `SimpleMQTTClient.ino` for the complete example. ## Documentation ### Construction -For Wifi and MQTT connection handling (Recommended) : +For Wifi and MQTT connection handling (Recommended): ```c++ EspMQTTClient( const char* wifiSsid, @@ -65,7 +66,7 @@ For Wifi and MQTT connection handling (Recommended) : const short mqttServerPort = 1883); ``` -MQTT connection handling only : +MQTT connection handling only: ```c++ EspMQTTClient( const char* mqttServerIp, @@ -77,7 +78,7 @@ MQTT connection handling only : ### Functions -IMPORTANT : Must be called at each loop() of your sketch +IMPORTANT: Must be called at each loop() of your sketch ```c++ void loop(); ``` @@ -94,12 +95,12 @@ Change the maximum packet size that can be sent over MQTT. The default is 128 by bool setMaxPacketSize(const uint16_t size); ``` -Change the keepalive interval (15 seconds by default) +Change the keep alive interval (15 seconds by default) ```c++ void setKeepAlive(uint16_t keepAliveSeconds); ``` -Enable the display of usefull debugging messages that will output to serial. +Enable debugging messages that will output to serial. ```c++ void enableDebuggingMessages(const bool enabled = true); ``` @@ -140,7 +141,7 @@ bool isMqttConnected(); // Return true if MQTT is connected. bool getConnectionEstablishedCount() // Return the number of time onConnectionEstablished has been called since the beginning. ``` -As ESP8266 does not like to be interrupted too long with the delay() function, this function will allow a delayed execution of a function without interrupting the sketch. +As ESP8266 does not like to be interrupted too long with the `delay()` function, this function will allow a delayed execution of a function without interrupting the sketch. ```c++ void executeDelayed(const long delay, DelayedExecutionCallback callback); ``` @@ -154,7 +155,7 @@ const short getMqttServerPort(); ### Connection established callback -To allow this library to work, you need to implement the onConnectionEstablished() function in your sketch. +To allow this library to work, you need to implement the `onConnectionEstablished()` function in your sketch. ```c++ void onConnectionEstablished() @@ -163,18 +164,18 @@ void onConnectionEstablished() } ``` -In some special cases, like if you want to handle more than one MQTT connection in the same sketch, you can override this callback to another one for the second MQTT client using this function : +In some special cases, like if you want to handle more than one MQTT connection in the same sketch, you can override this callback to another one for the second MQTT client using this function: ```c++ void setOnConnectionEstablishedCallback(ConnectionEstablishedCallback callback); ``` -See exemple "twoMQTTClientHandling.ino" for more details. +See example `twoMQTTClientHandling.ino` for more details. ### Subscribing to topics -The function `subscribe` allow to subscribe to a specific topic. +The function `subscribe` allows subscribing a specific topic. -For exemple, if you want to subscribe to topic `test/mytopic`, you can do this : +For example, if you want to subscribe to topic `test/mytopic`, you can do this: ```c++ void onTestMessageReceived(const String& message) { Serial.print("message received from test/mytopic: " + message); @@ -183,7 +184,7 @@ void onTestMessageReceived(const String& message) { client.subscribe("test/mytopic", onTestMessageReceived); ``` -You can also use lambdas to shorten the code like this : +You can also use lambdas to shorten the code like this: ```c++ client.subscribe("test/mytopic", [](const String& message) { Serial.print("message received from test/mytopic: " + message; @@ -192,9 +193,9 @@ client.subscribe("test/mytopic", [](const String& message) { #### Wildcards -This library also handle MQTT topic wilcards. Most of the time, you will want to see what was the original topic when the callback is called. Here is how to do that. +This library also handle MQTT topic wildcards. Most of the time, you will want to see what was the original topic when the callback is called. Here is how to do that. -Exemple : Subscribe to "wildcardtest/#" and display received topic and message to Serial +Example: Subscribe to `wildcardtest/#` and display received topic and message to Serial ```c++ void onMessageReceived(const String& topic, const String& message) { Serial.println(topic + ": " + message); @@ -203,11 +204,9 @@ void onMessageReceived(const String& topic, const String& message) { client.subscribe("wildcardtest/#", onMessageReceived); ``` -The same thing with lambdas : +The same thing with lambdas: ```c++ client.subscribe("wildcardtest/#", [](const String& topic, const String& message) { Serial.println(topic + ": " + message); }); ``` - - diff --git a/examples/SimpleMQTTClient/SimpleMQTTClient.ino b/examples/SimpleMQTTClient/SimpleMQTTClient.ino index baa66c5..172dda6 100644 --- a/examples/SimpleMQTTClient/SimpleMQTTClient.ino +++ b/examples/SimpleMQTTClient/SimpleMQTTClient.ino @@ -21,9 +21,10 @@ void setup() { Serial.begin(115200); - // Optionnal functionnalities of EspMQTTClient : + // Optional functionalities of EspMQTTClient client.enableDebuggingMessages(); // Enable debugging messages sent to serial output - client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overrited with enableHTTPWebUpdater("user", "password"). + client.enableHTTPWebUpdater(); // Enable the web updater. User and password default to values of MQTTUsername and MQTTPassword. These can be overridded with enableHTTPWebUpdater("user", "password"). + client.enableOTA(); // Enable OTA (Over The Air) updates. Password defaults to MQTTPassword. Port is the default OTA port. Can be overridden with enableOTA("password", port). client.enableLastWillMessage("TestClient/lastwill", "I am going offline"); // You can activate the retain flag by setting the third parameter to true } diff --git a/src/EspMQTTClient.cpp b/src/EspMQTTClient.cpp index 99f5f7c..39b0d9a 100644 --- a/src/EspMQTTClient.cpp +++ b/src/EspMQTTClient.cpp @@ -77,10 +77,11 @@ EspMQTTClient::EspMQTTClient( _mqttClient.setCallback([this](char* topic, uint8_t* payload, unsigned int length) {this->mqttMessageReceivedCallback(topic, payload, length);}); _failedMQTTConnectionAttemptCount = 0; - // Web updater + // HTTP/OTA update related _updateServerAddress = NULL; _httpServer = NULL; _httpUpdater = NULL; + _enableOTA = false; // other _enableSerialLogs = false; @@ -127,6 +128,22 @@ void EspMQTTClient::enableHTTPWebUpdater(const char* address) enableHTTPWebUpdater(_mqttUsername, _mqttPassword, address); } +void EspMQTTClient::enableOTA(const char *password, const uint16_t port) +{ + _enableOTA = true; + + if (_mqttClientName != NULL) + ArduinoOTA.setHostname(_mqttClientName); + + if (password != NULL) + ArduinoOTA.setPassword(password); + else if (_mqttPassword != NULL) + ArduinoOTA.setPassword(_mqttPassword); + + if (port) + ArduinoOTA.setPort(port); +} + void EspMQTTClient::enableMQTTPersistence() { _mqttCleanSession = false; @@ -228,6 +245,9 @@ bool EspMQTTClient::handleWiFi() MDNS.update(); // We need to do this only for ESP8266 #endif } + + if (_enableOTA) + ArduinoOTA.handle(); } // Disconnected since at least one loop() call @@ -352,6 +372,9 @@ void EspMQTTClient::onWiFiConnectionEstablished() if (_enableSerialLogs) Serial.printf("WEB: Updater ready, open http://%s.local in your browser and login with username '%s' and password '%s'.\n", _mqttClientName, _updateServerUsername, _updateServerPassword); } + + if (_enableOTA) + ArduinoOTA.begin(); } void EspMQTTClient::onWiFiConnectionLost() diff --git a/src/EspMQTTClient.h b/src/EspMQTTClient.h index 1567212..1b6e914 100644 --- a/src/EspMQTTClient.h +++ b/src/EspMQTTClient.h @@ -1,6 +1,7 @@ #ifndef ESP_MQTT_CLIENT_H #define ESP_MQTT_CLIENT_H +#include #include #include @@ -11,9 +12,10 @@ #include #include - #define WebServer ESP8266WebServer - #define ESPmDNS ESP8266mDNS + #define DEFAULT_MQTT_CLIENT_NAME "ESP8266" #define ESPHTTPUpdateServer ESP8266HTTPUpdateServer + #define ESPmDNS ESP8266mDNS + #define WebServer ESP8266WebServer #else // for ESP32 @@ -22,6 +24,7 @@ #include #include "ESP32HTTPUpdateServer.h" + #define DEFAULT_MQTT_CLIENT_NAME "ESP32" #define ESPHTTPUpdateServer ESP32HTTPUpdateServer #endif @@ -71,12 +74,13 @@ class EspMQTTClient }; std::vector _topicSubscriptionList; - // HTTP update server related + // HTTP/OTA update related char* _updateServerAddress; char* _updateServerUsername; char* _updateServerPassword; WebServer* _httpServer; ESPHTTPUpdateServer* _httpUpdater; + bool _enableOTA; // Delayed execution related struct DelayedExecutionRecord { @@ -93,40 +97,41 @@ class EspMQTTClient public: EspMQTTClient( - const short mqttServerPort = 1883, // port and client name are swapped here to prevent a collision - const char* mqttClientName = "ESP8266"); // with the MQTT w/o auth constructor + // port and client name are swapped here to prevent a collision with the MQTT w/o auth constructor + const short mqttServerPort = 1883, + const char* mqttClientName = DEFAULT_MQTT_CLIENT_NAME); - // Wifi + MQTT with no MQTT authentification + /// Wifi + MQTT with no MQTT authentification EspMQTTClient( const char* wifiSsid, const char* wifiPassword, const char* mqttServerIp, - const char* mqttClientName = "ESP8266", + const char* mqttClientName = DEFAULT_MQTT_CLIENT_NAME, const short mqttServerPort = 1883); - // Wifi + MQTT with MQTT authentification + /// Wifi + MQTT with MQTT authentification EspMQTTClient( const char* wifiSsid, const char* wifiPassword, const char* mqttServerIp, const char* mqttUsername, const char* mqttPassword, - const char* mqttClientName = "ESP8266", + const char* mqttClientName = DEFAULT_MQTT_CLIENT_NAME, const short mqttServerPort = 1883); - // Only MQTT handling (no wifi), with MQTT authentification + /// Only MQTT handling (no wifi), with MQTT authentification EspMQTTClient( const char* mqttServerIp, const short mqttServerPort, const char* mqttUsername, const char* mqttPassword, - const char* mqttClientName = "ESP8266"); + const char* mqttClientName = DEFAULT_MQTT_CLIENT_NAME); - // Only MQTT handling without MQTT authentification + /// Only MQTT handling without MQTT authentification EspMQTTClient( const char* mqttServerIp, const short mqttServerPort, - const char* mqttClientName = "ESP8266"); + const char* mqttClientName = DEFAULT_MQTT_CLIENT_NAME); ~EspMQTTClient(); @@ -134,11 +139,12 @@ class EspMQTTClient void enableDebuggingMessages(const bool enabled = true); // Allow to display useful debugging messages. Can be set to false to disable them during program execution void enableHTTPWebUpdater(const char* username, const char* password, const char* address = "/"); // Activate the web updater, must be set before the first loop() call. void enableHTTPWebUpdater(const char* address = "/"); // Will set user and password equal to _mqttUsername and _mqttPassword + void enableOTA(const char *password = NULL, const uint16_t port = 0); // Activate OTA updater, must be set before the first loop() call. void enableMQTTPersistence(); // Tell the broker to establish a persistent connection. Disabled by default. Must be called before the first loop() execution void enableLastWillMessage(const char* topic, const char* message, const bool retain = false); // Must be set before the first loop() call. void enableDrasticResetOnConnectionFailures() {_drasticResetOnConnectionFailures = true;} // Can be usefull in special cases where the ESP board hang and need resetting (#59) - // Main loop, to call at each sketch loop() + /// Main loop, to call at each sketch loop() void loop(); // MQTT related