diff --git a/src/main.cpp b/src/main.cpp index 7d1ef7a..bb207a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,9 +3,9 @@ #include #include #include -#include #include #include +#include #define I2C_SDA 25 #define I2C_SCL 26 @@ -17,20 +17,37 @@ #define POWER_CTRL 4 #define USER_BUTTON 35 -// -- Initial name of the Thing. Used e.g. as SSID of the own Access Point. -const char thingName[] = "hiGrow"; - -// -- Initial password to connect to the Thing, when it creates an own Access Point. -const char wifiInitialApPassword[] = "test1234"; - -DNSServer dnsServer; -AsyncWebServer server(80); -IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword); - BH1750 lightMeter; DHT_Unified dht(DHT12_PIN, DHT11); -void wifiConnected(); +#define STRING_LEN 128 +#define BOOL_LEN 1 + +// Configuration specific key. The value should be modified if config structure was changed. +#define CONFIG_VERSION "hgr1" + +// Initial name of the Thing. Used e.g. as SSID of the own Access Point. +const char thingName[] = "hiGrow"; + +// Initial password to connect to the Thing, when it creates an own Access Point. +const char wifiInitialApPassword[] = "test1234"; + +char mqttEnabledValue[BOOL_LEN]; +char mqttServerValue[STRING_LEN]; +char mqttUserNameValue[STRING_LEN]; +char mqttUserPasswordValue[STRING_LEN]; +char mqttTopicValue[STRING_LEN]; +IotWebConfSeparator separator1 = IotWebConfSeparator(); +IotWebConfParameter mqttEnabledParam = IotWebConfParameter("MQTT enabled", "mqttEnabled", mqttEnabledValue, BOOL_LEN, "checkbox"); +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"); +IotWebConfParameter mqttTopicParam = IotWebConfParameter("MQTT topic", "mqttTopic", mqttTopicValue, STRING_LEN); + +DNSServer dnsServer; +AsyncWebServer server(80); +AsyncCallbackWebHandler* rootHandler; +IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION); uint16_t soil = 0; uint32_t salt = 0; @@ -39,10 +56,13 @@ float temperature = 0; float humidity = 0; float lux = 0; +bool needMqttReconnect = false; + /** * Handle web requests to "/" path. */ -void handleRoot(AsyncWebServerRequest *request){ +void handleRoot(AsyncWebServerRequest* request) +{ // -- Let IotWebConf test and handle captive portal requests. if (iotWebConf.handleCaptivePortal(request)) { // -- Captive portal request were already served. @@ -56,7 +76,7 @@ void handleRoot(AsyncWebServerRequest *request){ request->send(200, "text/html", s); } -void handleValues(AsyncWebServerRequest *request) +void handleValues(AsyncWebServerRequest* request) { StaticJsonDocument<200> doc; doc[F("temperature")] = temperature; @@ -75,6 +95,10 @@ void handleValues(AsyncWebServerRequest *request) void wifiConnected() { Serial.println("WiFi was connected."); + if (server.removeHandler(rootHandler)) { + Serial.println("Root handler disabled."); + } + ESPDash.init(server); } uint32_t readSalt() @@ -111,6 +135,29 @@ float readBattery() return battery_voltage; } +void configSaved() +{ + Serial.println("Configuration was updated."); + needMqttReconnect = true; +} + +boolean formValidator(AsyncWebServerRequest* request) +{ + Serial.println("Validating form."); + boolean valid = true; +/* + if (request->arg(mqttServerParam.getId()).length() < 3) { + mqttServerParam.errorMessage = "Please provide at least 3 characters!"; + valid = false; + } + if (request->arg(mqttTopicParam.getId()).length() < 1) { + mqttTopicParam.errorMessage = "Please provide at least 1 character!"; + valid = false; + } +*/ + return valid; +} + void setup() { Serial.begin(115200); @@ -119,17 +166,34 @@ void setup() // Init IotWebConf iotWebConf.setWifiConnectionCallback(&wifiConnected); - iotWebConf.init(); + iotWebConf.addParameter(&separator1); + iotWebConf.addParameter(&mqttEnabledParam); + iotWebConf.addParameter(&mqttServerParam); + iotWebConf.addParameter(&mqttUserNameParam); + iotWebConf.addParameter(&mqttUserPasswordParam); + iotWebConf.addParameter(&mqttTopicParam); + iotWebConf.setConfigSavedCallback(&configSaved); + iotWebConf.setFormValidator(&formValidator); + if (!iotWebConf.init()) { + mqttServerValue[0] = '\0'; + mqttUserNameValue[0] = '\0'; + mqttUserPasswordValue[0] = '\0'; + } iotWebConf.doLoop(); // Init WebServer - server.on("/config", HTTP_GET, [](AsyncWebServerRequest *request) { iotWebConf.handleConfig(request); }); + rootHandler = new AsyncCallbackWebHandler(); + rootHandler->setUri("/"); + rootHandler->setMethod(HTTP_GET); + rootHandler->onRequest(handleRoot); + server.addHandler(rootHandler); + + server.on("/config", HTTP_ANY, [](AsyncWebServerRequest* request) { iotWebConf.handleConfig(request); }); server.on("/values", HTTP_GET, handleValues); - server.onNotFound([](AsyncWebServerRequest *request) { iotWebConf.handleNotFound(request); }); + server.onNotFound([](AsyncWebServerRequest* request) { iotWebConf.handleNotFound(request); }); server.begin(); // Init Dashboard - ESPDash.init(server); ESPDash.addTemperatureCard("temp", "Temperature/C", 0, 0); ESPDash.addHumidityCard("hum", "Humidity/%", 0); ESPDash.addNumberCard("lux", "BH1750/lx", 0); @@ -161,6 +225,11 @@ void loop() static uint64_t timestamp; iotWebConf.doLoop(); + if (needMqttReconnect) { + Serial.println("Reconfigure & reconnect MqTT"); + needMqttReconnect = false; + } + if (millis() - timestamp > 1000) { timestamp = millis(); @@ -198,7 +267,7 @@ void loop() ESPDash.updateNumberCard("salt", (int)salt); ESPDash.updateNumberCard("batt", (int)bat); - Serial.printf("DHTT:%.2f H:%.2f Lux:%.2f Soil:%u Salt:%u Bat:%.2f\n", + Serial.printf("DHTT:%.2f H:%.2f Lux:%.2f Soil:%u Salt:%u Bat:%.2f\r\n", temperature, humidity, lux, soil, salt, bat); } } \ No newline at end of file