/** * IotWebConf06MqttApp.ino -- IotWebConf is an ESP8266/ESP32 * non blocking WiFi/AP web configuration library for Arduino. * https://github.com/prampec/IotWebConf * * Copyright (C) 2018 Balazs Kelemen * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ /** * Example: MQTT Demo Application * Description: * All IotWebConf specific aspects of this example are described in * previous examples, so please get familiar with IotWebConf before * starting this example. So nothing new will be explained here, * but a complete demo application will be build. * It is also expected from the reader to have a basic knowledge over * MQTT to understand this code. * * This example starts an MQTT client with the configured * connection settings. * Will post the status changes of the D2 pin in channel "/test/status". * Receives messages appears in channel "/test/action", and writes them to serial. * This example also provides the firmware update option. * (See previous examples for more details!) * * Software setup for this example: * This example utilizes Joel Gaehwiler's MQTT library. * https://github.com/256dpi/arduino-mqtt * * Hardware setup for this example: * - An LED is attached to LED_BUILTIN pin with setup On=LOW. * - [Optional] A push button is attached to pin D2, the other leg of the * button should be attached to GND. */ #include #include // -- Initial name of the Thing. Used e.g. as SSID of the own Access Point. const char thingName[] = "testThing"; // -- Initial password to connect to the Thing, when it creates an own Access Point. const char wifiInitialApPassword[] = "smrtTHNG8266"; #define STRING_LEN 128 // -- Configuration specific key. The value should be modified if config structure was changed. #define CONFIG_VERSION "mqt1" // -- When CONFIG_PIN is pulled to ground on startup, the Thing will use the initial // password to buld an AP. (E.g. in case of lost password) #define CONFIG_PIN D2 // -- Status indicator pin. // First it will light up (kept LOW), on Wifi connection it will blink, // when connected to the Wifi it will turn off (kept HIGH). #define STATUS_PIN LED_BUILTIN // -- Callback method declarations. void wifiConnected(); void configSaved(); boolean formValidator(); void mqttMessageReceived(String &topic, String &payload); DNSServer dnsServer; WebServer server(80); HTTPUpdateServer httpUpdater; WiFiClient net; MQTTClient mqttClient; char mqttServerValue[STRING_LEN]; char mqttUserNameValue[STRING_LEN]; char mqttUserPasswordValue[STRING_LEN]; IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION); IotWebConfParameter mqttServerParam = IotWebConfParameter("MQTT server", "mqttServer", mqttServerValue, STRING_LEN); IotWebConfParameter mqttUserNameParam = IotWebConfParameter("MQTT user", "mqttUser", mqttUserNameValue, STRING_LEN); IotWebConfParameter mqttUserPasswordParam = IotWebConfParameter("MQTT password", "mqttPass", mqttUserPasswordValue, STRING_LEN, "password"); boolean needMqttConnect = false; boolean needReset = false; int pinState = HIGH; unsigned long lastReport = 0; unsigned long lastMqttConnectionAttempt = 0; void setup() { Serial.begin(115200); Serial.println(); Serial.println("Starting up..."); iotWebConf.setStatusPin(STATUS_PIN); iotWebConf.setConfigPin(CONFIG_PIN); iotWebConf.addParameter(&mqttServerParam); iotWebConf.addParameter(&mqttUserNameParam); iotWebConf.addParameter(&mqttUserPasswordParam); iotWebConf.setConfigSavedCallback(&configSaved); iotWebConf.setFormValidator(&formValidator); iotWebConf.setWifiConnectionCallback(&wifiConnected); iotWebConf.setupUpdateServer(&httpUpdater); // -- Initializing the configuration. boolean validConfig = iotWebConf.init(); if (!validConfig) { mqttServerValue[0] = '\0'; mqttUserNameValue[0] = '\0'; mqttUserPasswordValue[0] = '\0'; } // -- Set up required URL handlers on the web server. server.on("/", handleRoot); server.on("/config", []{ iotWebConf.handleConfig(); }); server.onNotFound([](){ iotWebConf.handleNotFound(); }); mqttClient.begin(mqttServerValue, net); mqttClient.onMessage(mqttMessageReceived); Serial.println("Ready."); } void loop() { // -- doLoop should be called as frequently as possible. iotWebConf.doLoop(); mqttClient.loop(); if (needMqttConnect) { if (connectMqtt()) { needMqttConnect = false; } } else if ((iotWebConf.getState() == IOTWEBCONF_STATE_ONLINE) && (!mqttClient.connected())) { Serial.println("MQTT reconnect"); connectMqtt(); } if (needReset) { Serial.println("Rebooting after 1 second."); iotWebConf.delay(1000); ESP.restart(); } unsigned long now = millis(); if ((500 < now - lastReport) && (pinState != digitalRead(CONFIG_PIN))) { pinState = 1 - pinState; // invert pin state as it is changed lastReport = now; Serial.print("Sending on MQTT channel '/test/status' :"); Serial.println(pinState == LOW ? "ON" : "OFF"); mqttClient.publish("/test/status", pinState == LOW ? "ON" : "OFF"); } } /** * Handle web requests to "/" path. */ void handleRoot() { // -- Let IotWebConf test and handle captive portal requests. if (iotWebConf.handleCaptivePortal()) { // -- Captive portal request were already served. return; } String s = ""; s += "IotWebConf 06 MQTT AppMQTT App demo"; s += "
    "; s += "
  • MQTT server: "; s += mqttServerValue; s += "
"; s += "Go to configure page to change values."; s += "\n"; server.send(200, "text/html", s); } void wifiConnected() { needMqttConnect = true; } void configSaved() { Serial.println("Configuration was updated."); needReset = true; } boolean formValidator() { Serial.println("Validating form."); boolean valid = true; int l = server.arg(mqttServerParam.getId()).length(); if (l < 3) { mqttServerParam.errorMessage = "Please provide at least 3 characters!"; valid = false; } return valid; } boolean connectMqtt() { unsigned long now = millis(); if (1000 > now - lastMqttConnectionAttempt) { // Do not repeat within 1 sec. return false; } Serial.println("Connecting to MQTT server..."); if (!connectMqttOptions()) { lastMqttConnectionAttempt = now; return false; } Serial.println("Connected!"); mqttClient.subscribe("/test/action"); return true; } /* // -- This is an alternative MQTT connection method. boolean connectMqtt() { Serial.println("Connecting to MQTT server..."); while (!connectMqttOptions()) { iotWebConf.delay(1000); } Serial.println("Connected!"); mqttClient.subscribe("/test/action"); return true; } */ boolean connectMqttOptions() { boolean result; if (mqttUserPasswordValue[0] != '\0') { result = mqttClient.connect(iotWebConf.getThingName(), mqttUserNameValue, mqttUserPasswordValue); } else if (mqttUserNameValue[0] != '\0') { result = mqttClient.connect(iotWebConf.getThingName(), mqttUserNameValue); } else { result = mqttClient.connect(iotWebConf.getThingName()); } return result; } void mqttMessageReceived(String &topic, String &payload) { Serial.println("Incoming: " + topic + " - " + payload); }