diff --git a/README.md b/README.md index 4af1c17..a055cee 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,12 @@ void loop() { ``` See example for a more complex version. [OnDemandConfigPortal](https://github.com/tzapu/WiFiManager/tree/master/examples/OnDemandConfigPortal) +#### Exiting from the Configuration Portal +Normally, once entered, the configuration portal will continue to loop until WiFi credentials have been successfully entered or a timeout is reached. +If you'd prefer to exit without joining a WiFi network, say becuase you're going to put the ESP into AP mode, then press the "Exit" button +on the main webpage. +If started via `autoConnect` or `startConfigPortal` then it will return `false (portalAbortResult)` + #### Custom Parameters You can use WiFiManager to collect more parameters than just SSID and password. This could be helpful for configuring stuff like MQTT host and port, [blynk](http://www.blynk.cc) or [emoncms](http://emoncms.org) tokens, just to name a few. @@ -189,18 +195,18 @@ This could be helpful for configuring stuff like MQTT host and port, [blynk](htt Usage scenario would be: - load values from somewhere (EEPROM/FS) or generate some defaults - add the custom parameters to WiFiManager using - ```cpp +```cpp // id/name, placeholder/prompt, default, length WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40); wifiManager.addParameter(&custom_mqtt_server); - ``` +``` - if connection to AP fails, configuration portal starts and you can set /change the values (or use on demand configuration portal) - once configuration is done and connection is established [save config callback]() is called - once WiFiManager returns control to your application, read and save the new values using the `WiFiManagerParameter` object. - ```cpp +```cpp mqtt_server = custom_mqtt_server.getValue(); - ``` +``` This feature is a lot more involved than all the others, so here are some examples to fully show how it is done. You should also take a look at adding custom HTML to your form. diff --git a/WiFiManager.cpp b/WiFiManager.cpp index e2c1fb2..90fba72 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -11,6 +11,7 @@ **************************************************************/ #include "WiFiManager.h" +#include "strings_en.h" // PARAMETERS @@ -51,6 +52,12 @@ void WiFiManagerParameter::init(const char *id, const char *placeholder, const c _customHTML = custom; } +WiFiManagerParameter::~WiFiManagerParameter() { + if (_value != NULL) { + delete[] _value; + } +} + const char* WiFiManagerParameter::getValue() { return _value; } @@ -70,19 +77,35 @@ const char* WiFiManagerParameter::getCustomHTML() { return _customHTML; } -void WiFiManager::addParameter(WiFiManagerParameter *p) { - if(_paramsCount + 1 > WIFI_MANAGER_MAX_PARAMS) - { - //Max parameters exceeded! - DEBUG_WM("WIFI_MANAGER_MAX_PARAMS exceeded, increase number (in WiFiManager.h) before adding more parameters!"); - DEBUG_WM("Skipping parameter with ID:"); - DEBUG_WM(p->getID()); - return; +bool WiFiManager::addParameter(WiFiManagerParameter *p) { + + // check param id is valid + for (int i = 0; i < strlen(p->getID()); i++){ + if(!isAlphaNumeric(p->getID()[i])){ + DEBUG_WM("[ERROR] parameter IDs can only contain alpha numeric chars"); + return false; + } + } + + if(_paramsCount == _max_params){ + // resize the params array by increment of WIFI_MANAGER_MAX_PARAMS + _max_params += WIFI_MANAGER_MAX_PARAMS; + DEBUG_WM(F("Updated _max_params:"),_max_params); + WiFiManagerParameter** new_params = (WiFiManagerParameter**)realloc(_params, _max_params * sizeof(WiFiManagerParameter*)); + DEBUG_WM(WIFI_MANAGER_MAX_PARAMS); + DEBUG_WM(_paramsCount); + DEBUG_WM(_max_params); + if (new_params != NULL) { + _params = new_params; + } else { + DEBUG_WM("[ERROR] failed to realloc params, size not increased!"); + return false; + } } _params[_paramsCount] = p; _paramsCount++; - DEBUG_WM("Adding parameter"); - DEBUG_WM(p->getID()); + DEBUG_WM("Added Parameter:",p->getID()); + return true; } // constructors @@ -94,12 +117,22 @@ WiFiManager::WiFiManager():_debugPort(Serial) { if(_debug) debugPlatformInfo(); _usermode = WiFi.getMode(); WiFi.persistent(false); // disable persistent so scannetworks and mode switching do not cause overwrites + + //parameters + _max_params = WIFI_MANAGER_MAX_PARAMS; + _params = (WiFiManagerParameter**)malloc(_max_params * sizeof(WiFiManagerParameter*)); } // destructor WiFiManager::~WiFiManager() { if(_userpersistent) WiFi.persistent(true); // reenable persistent, there is no getter we rely on _userpersistent if(_usermode != WIFI_OFF) WiFi.mode(_usermode); + + // parameters + if (_params != NULL){ + DEBUG_WM(F("freeing allocated params!")); + free(_params); + } DEBUG_WM(F("unloading")); } @@ -110,7 +143,6 @@ boolean WiFiManager::autoConnect() { } boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) { - DEBUG_WM(F("")); DEBUG_WM(F("AutoConnect")); // attempt to connect using saved settings, on fail fallback to AP config portal @@ -122,8 +154,7 @@ boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) { // if already connected, or try stored connect if (WiFi.status() == WL_CONNECTED || connectWifi("", "") == WL_CONNECTED) { //connected - DEBUG_WM(F("IP Address:")); - DEBUG_WM(WiFi.localIP()); + DEBUG_WM(F("IP Address:"),WiFi.localIP()); return true; } // not connected start configportal @@ -132,12 +163,11 @@ boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) { // CONFIG PORTAL bool WiFiManager::startAP(){ - DEBUG_WM(F("Configuring access point with with SSID of ... ")); - DEBUG_WM(_apName); + DEBUG_WM(F("StartAP with SSID of"),_apName); // setup optional soft AP static ip config if (_ap_static_ip) { - DEBUG_WM(F("Custom AP IP/GW/Subnet")); + DEBUG_WM(F("Custom AP IP/GW/Subnet:")); WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn); } @@ -145,7 +175,6 @@ bool WiFiManager::startAP(){ // start soft AP with password or anonymous if (_apPassword != "") { - Serial.println((String)_apPassword.c_str()); ret = WiFi.softAP(_apName.c_str(), _apPassword.c_str());//password option } else { DEBUG_WM(F("AP has anonymous access")); @@ -154,11 +183,10 @@ bool WiFiManager::startAP(){ debugSoftAPConfig(); - if(!ret) DEBUG_WM("There was an error starting the AP"); // @bug startAP returns unreliable success status + if(!ret) DEBUG_WM("[ERROR] There was a problem starting the AP"); // @bug startAP returns unreliable success status delay(500); // slight delay to make sure we get an AP IP - DEBUG_WM(F("AP IP address: ")); - DEBUG_WM(WiFi.softAPIP()); + DEBUG_WM(F("AP IP address:"),WiFi.softAPIP()); // do AP callback if set if ( _apcallback != NULL) { @@ -406,9 +434,8 @@ int WiFiManager::connectWifi(String ssid, String pass) { // Setup static IP config if provided if (_sta_static_ip) { - DEBUG_WM(F("Custom STA IP/GW/Subnet")); WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn); - DEBUG_WM(WiFi.localIP()); + DEBUG_WM(F("Custom STA IP/GW/Subnet:"),WiFi.localIP()); } // make sure sta is on before `begin` so it does not call enablesta->mode while persistent is ON ( which would save WM AP state to eeprom !) @@ -435,8 +462,7 @@ int WiFiManager::connectWifi(String ssid, String pass) { } uint8_t connRes = waitforconx ? waitForConnectResult() : WL_NO_SSID_AVAIL; - DEBUG_WM ("Connection result: "); - DEBUG_WM ( getWLStatusString(connRes) ); + DEBUG_WM ("Connection result:",getWLStatusString(connRes)); // do WPS, if WPS options enabled and not connected and no password was supplied // @todo this seems like wrong place for this, is it a fallback or option? @@ -535,35 +561,36 @@ void WiFiManager::setBreakAfterConfig(boolean shouldBreak) { _shouldBreakAfterConfig = shouldBreak; } +String WiFiManager::getHTTPHead(String title){ + String page; + page += FPSTR(HTTP_HEAD); + page.replace("{v}", title); + page += FPSTR(HTTP_SCRIPT); + page += FPSTR(HTTP_STYLE); + page += _customHeadElement; + page += FPSTR(HTTP_HEAD_END); + return page; +} + /** * HTTPD CALLBACK root or redirect to captive portal */ void WiFiManager::handleRoot() { DEBUG_WM(F("<- HTTP Root")); - if (captivePortal()) { // If captive portal redirect instead of displaying the page. - return; - } + if (captivePortal()) return; // If captive portal redirect instead of displaying the page - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Options"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - page += "

"; - page += configPortalActive ? _apName : WiFi.localIP().toString(); - page += "

"; - page += F("

WiFiManager

"); + String page = getHTTPHead("options"); // @token options + String str = FPSTR(HTTP_ROOT_MAIN); + str.replace("{v}",configPortalActive ? _apName : WiFi.localIP().toString()); // use ip if ap is not active for heading + page += str; page += FPSTR(HTTP_PORTAL_OPTIONS); reportStatus(page); page += FPSTR(HTTP_END); - server->sendHeader("Content-Length", String(page.length())); server->send(200, "text/html", page); // server->close(); // testing reliability fix for content length mismatches during mutiple flood hits - } /** @@ -572,18 +599,10 @@ void WiFiManager::handleRoot() { void WiFiManager::handleWifi(boolean scan) { DEBUG_WM("<- HTTP Wifi"); - - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Config ESP"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - + String page = getHTTPHead("Config ESP"); // @token titlewifi if (scan) { page += getScanItemOut(); } - String pitem = FPSTR(HTTP_FORM_START); pitem.replace("{v}", WiFi_SSID()); page += pitem; @@ -612,7 +631,7 @@ String WiFiManager::getScanItemOut(){ DEBUG_WM(F("Scan done")); if (n == 0) { DEBUG_WM(F("No networks found")); - page += F("No networks found. Refresh to scan again."); + page += F("No networks found. Refresh to scan again."); // @token scannotfound } else { //sort networks @@ -645,7 +664,7 @@ String WiFiManager::getScanItemOut(){ cssid = WiFi.SSID(indices[i]); for (int j = i + 1; j < n; j++) { if (cssid == WiFi.SSID(indices[j])) { - DEBUG_WM("DUP AP: " + WiFi.SSID(indices[j])); + DEBUG_WM("DUP AP:",WiFi.SSID(indices[j])); indices[j] = -1; // set dup aps to index -1 } } @@ -701,7 +720,7 @@ String WiFiManager::getStaticOut(){ String page; if (_sta_show_static_fields || _sta_static_ip) { - // @todo how do we get these settings from memory , wifi_get_ip_info does not seem to reveal if struct ip_info is static or not + // @todo how can we get these settings from memory , wifi_get_ip_info does not seem to reveal if struct ip_info is static or not // @todo move titles to params for i18n String item = FPSTR(HTTP_FORM_LABEL); @@ -709,11 +728,12 @@ String WiFiManager::getStaticOut(){ item.replace("{i}", "ip"); item.replace("{n}", "ip"); item.replace("{p}", "{t}"); - item.replace("{t}", "Static IP"); + item.replace("{t}", "Static IP"); // @token staticip item.replace("{l}", "15"); item.replace("{v}", (_sta_static_ip ? _sta_static_ip.toString() : "")); item.replace("{c}", ""); - + + // actuals as placeholder // IPAddress sta_ip = WiFi.localIP(); // item.replace("{p}", sta_ip.toString()); @@ -724,11 +744,12 @@ String WiFiManager::getStaticOut(){ item.replace("{i}", "gw"); item.replace("{n}", "gw"); item.replace("{p}", "{t}"); - item.replace("{t}", "Static Gateway"); + item.replace("{t}", "Static Gateway"); // @token staticgateway item.replace("{l}", "15"); item.replace("{v}", (_sta_static_gw ? _sta_static_gw.toString() : "")); item.replace("{c}", ""); + // actuals as placeholder // IPAddress sta_gateway = WiFi.gatewayIP(); // item.replace("{p}", sta_gateway.toString()); @@ -739,11 +760,12 @@ String WiFiManager::getStaticOut(){ item.replace("{i}", "sn"); item.replace("{n}", "sn"); item.replace("{p}", "{t}"); - item.replace("{t}", "Subnet"); + item.replace("{t}", "Subnet"); // @token subnet item.replace("{l}", "15"); item.replace("{v}", (_sta_static_sn ? _sta_static_sn.toString() : "")); item.replace("{c}", ""); + // actuals as placeholder // IPAddress sta_subnet = WiFi.subnetMask(); // item.replace("{p}", sta_subnet.toString()); page += item; @@ -759,6 +781,7 @@ String WiFiManager::getParamOut(){ String HTTP_PARAM_temp = FPSTR(HTTP_FORM_LABEL); HTTP_PARAM_temp += FPSTR(HTTP_FORM_PARAM); + bool tok_I = HTTP_PARAM_temp.indexOf("{I}") > 0; bool tok_i = HTTP_PARAM_temp.indexOf("{i}") > 0; bool tok_n = HTTP_PARAM_temp.indexOf("{n}") > 0; bool tok_p = HTTP_PARAM_temp.indexOf("{p}") > 0; @@ -795,6 +818,7 @@ String WiFiManager::getParamOut(){ // if no ID use customhtml for item, else generate from param string if (_params[i]->getID() != NULL) { + if(tok_I)pitem.replace("{I}", "param_"+(String)i); if(tok_i)pitem.replace("{i}", _params[i]->getID()); if(tok_n)pitem.replace("{n}", _params[i]->getID()); if(tok_p)pitem.replace("{p}", "{t}"); @@ -821,52 +845,52 @@ String WiFiManager::getParamOut(){ * HTTPD CALLBACK save form and redirect to WLAN config page again */ void WiFiManager::handleWifiSave() { - DEBUG_WM(F("HTTP WiFi save")); + DEBUG_WM(F("<- HTTP WiFi save ")); + + DEBUG_WM(F("Method:"),server->method() == HTTP_GET ? "GET" : "POST"); //SAVE/connect here _ssid = server->arg("s").c_str(); _pass = server->arg("p").c_str(); //parameters - for (int i = 0; i < _paramsCount; i++) { - if (_params[i] == NULL) { - break; + if(_paramsCount > 0){ + DEBUG_WM("Parameters"); + DEBUG_WM("-----------"); + for (int i = 0; i < _paramsCount; i++) { + if (_params[i] == NULL) { + break; + } + //read parameter from server + String value; + if(server->arg("param_"+(String)i) != NULL) value = server->arg("param_"+(String)i).c_str(); + else value = server->arg(_params[i]->getID()).c_str(); + + //store it in array + value.toCharArray(_params[i]->_value, _params[i]->_length+1); // length+1 null terminated + DEBUG_WM((String)_params[i]->getID() + ":",value); } - //read parameter - String value = server->arg(_params[i]->getID()).c_str(); - //store it in array - value.toCharArray(_params[i]->_value, _params[i]->_length+1); // length+1 null terminated - DEBUG_WM(F("Parameter")); - DEBUG_WM(_params[i]->getID()); - DEBUG_WM(value); + DEBUG_WM("-----------"); } if (server->arg("ip") != "") { - DEBUG_WM(F("static ip")); - DEBUG_WM(server->arg("ip")); //_sta_static_ip.fromString(server->arg("ip")); String ip = server->arg("ip"); optionalIPFromString(&_sta_static_ip, ip.c_str()); + DEBUG_WM(F("static ip:"),ip); } if (server->arg("gw") != "") { - DEBUG_WM(F("static gateway")); - DEBUG_WM(server->arg("gw")); String gw = server->arg("gw"); optionalIPFromString(&_sta_static_gw, gw.c_str()); + DEBUG_WM(F("static gateway:"),gw); } if (server->arg("sn") != "") { - DEBUG_WM(F("static netmask")); - DEBUG_WM(server->arg("sn")); String sn = server->arg("sn"); optionalIPFromString(&_sta_static_sn, sn.c_str()); + DEBUG_WM(F("static netmask:"),sn); } - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Credentials Saved"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); + String page = getHTTPHead("Credentials Saved"); // @token titlewifisaved page += FPSTR(HTTP_SAVED); page += FPSTR(HTTP_END); @@ -882,15 +906,8 @@ void WiFiManager::handleWifiSave() { * HTTPD CALLBACK info page */ void WiFiManager::handleInfo() { - DEBUG_WM(F("HTTP Info")); - - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Info"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - + DEBUG_WM(F("<- HTTP Info")); + String page = getHTTPHead("Info"); // @token titleinfo reportStatus(page); // @todo add versioning here @@ -899,39 +916,39 @@ void WiFiManager::handleInfo() { page += F("

esp8266


"); // subject to rollover! - page += F("
Uptime
"); + page += F("
Uptime
"); // @token uptime page += (String)(millis() / 1000 / 60) + " mins "; page += (String)((millis() / 1000) % 60) + " secs"; - page += F("
Chip ID
"); + page += F("
Chip ID
"); // @token chipid page += WIFI_getChipId(); page += F("
"); - page += F("
Flash Chip ID
"); + page += F("
Flash Chip ID
"); // @token flashid page += ESP.getFlashChipId(); page += F("
"); - page += F("
IDE Flash Size
"); + page += F("
IDE Flash Size
"); // @token flashsize page += ESP.getFlashChipSize(); page += F(" bytes
"); - page += F("
Actual Flash Size
"); + page += F("
Actual Flash Size
"); // @token actualflashsize page += ESP.getFlashChipRealSize(); page += F(" bytes
"); - page += F("
SDK Version
"); + page += F("
SDK Version
"); // @token sdkver page += system_get_sdk_version(); page += F("
"); - page += F("
Core Version
"); + page += F("
Core Version
"); // @token corever page += ESP.getCoreVersion(); page += F("
"); - page += F("
Boot Version
"); + page += F("
Boot Version
"); // @token boot ver page += system_get_boot_version(); page += F("
"); - page += F("
CPU Frequency
"); + page += F("
CPU Frequency
"); // @token cpufreq page += ESP.getCpuFreqMHz(); page += F("MHz
"); @@ -945,12 +962,12 @@ void WiFiManager::handleInfo() { // page += "
"; // page += F(""); - page += F("
Memory - Free Heap
"); + page += F("
Memory - Free Heap
"); // @token freeheap page += ESP.getFreeHeap(); - page += F(" bytes available
"); + page += F(" bytes available"); // @token bytesavail - page += F("
Memory - Sketch Size
"); - page += F("Used/Total bytes
"); + page += F("
Memory - Sketch Size
"); // @token sketchsize + page += F("Used/Total bytes
"); // @token usedtotal page += (ESP.getSketchSize()+ESP.getFreeSketchSpace())-ESP.getFreeSketchSpace(); page += "/"; page += (ESP.getSketchSize()+ESP.getFreeSketchSpace()); @@ -960,15 +977,15 @@ void WiFiManager::handleInfo() { page += (String)(ESP.getSketchSize()+ESP.getFreeSketchSpace()); page += F("'>
"); - page += F("
Last reset reason
"); + page += F("
Last reset reason
"); // @token resetreason page += ESP.getResetReason(); page += F("
"); - page += F("

WiFi


Access Point IP
"); + page += F("

WiFi


Access Point IP
"); // @token apip page += WiFi.softAPIP().toString(); page += F("
"); - page += F("
Access Point MAC
"); + page += F("
Access Point MAC
"); // @token apmac page += WiFi.softAPmacAddress(); page += F("
"); @@ -980,38 +997,40 @@ void WiFiManager::handleInfo() { page += WiFi.BSSIDstr(); page += F(""); - page += F("
Station IP
"); + page += F("
Station IP
"); // @token staip page += WiFi.localIP().toString(); page += F("
"); - page += F("
Station Gateway
"); + page += F("
Station Gateway
"); // @token stagw page += WiFi.gatewayIP().toString(); page += F("
"); - page += F("
Station Subnet
"); + page += F("
Station Subnet
"); // @token stasub page += WiFi.subnetMask().toString(); page += F("
"); - page += F("
DNS Server
"); + page += F("
DNS Server
"); // @token dnss page += WiFi.dnsIP().toString(); page += F("
"); - page += F("
Hostname
"); + page += F("
Hostname
"); // @token hostname page += WiFi.hostname(); page += F("
"); - page += F("
Station MAC
"); + page += F("
Station MAC
"); // @stamac page += WiFi.macAddress(); page += F("
"); - page += F("
Connected
"); - page += WiFi.isConnected() ? "Yes" : "No"; + page += F("
Connected
"); // @token connected + page += WiFi.isConnected() ? "Yes" : "No"; //@token Y,N page += F("
"); page += F("
Autoconnect
"); - page += WiFi.getAutoConnect() ? "Enabled" : "Disabled"; + page += WiFi.getAutoConnect() ? "Enabled" : "Disabled"; // @token enabled,disabled page += F("
"); page += F("
"); + page += FPSTR(HTTP_ERASEBTN); + page += FPSTR(HTTP_HELP); #endif #ifdef ESP32 @@ -1146,42 +1165,30 @@ void WiFiManager::handleInfo() { */ void WiFiManager::handleExit() { DEBUG_WM(F("<- HTTP Exit")); - - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Exit"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - - page += "Exiting"; + String page = getHTTPHead("Exit"); // @token titleexit + page += "Exiting"; // @token exiting server->sendHeader("Content-Length", String(page.length())); server->send(200, "text/html", page); abort = true; } void WiFiManager::reportStatus(String &page){ - + String str; if (WiFi_SSID() != ""){ if (WiFi.status()==WL_CONNECTED){ - page += "
"; - page += F("Connected to "); - page += WiFi.SSID(); - page += F("
with IP "); - page += WiFi.localIP().toString(); - page += F(""); - } else { - page += "
"; - page += "Not Connected to "; - page += WiFi_SSID(); - } - } else { - page += "
"; - page += "No AP set"; + str = FPSTR(HTTP_STATUS_ON); + str.replace("{u}",WiFi.localIP().toString()); + str.replace("{s}",WiFi.SSID()); + } + else { + str = FPSTR(HTTP_STATUS_OFF); + str.replace("{s}",WiFi.SSID()); + } } - page += "
"; + else { + str = FPSTR(HTTP_STATUS_NONE); + } + page += str; } /** @@ -1190,12 +1197,7 @@ void WiFiManager::reportStatus(String &page){ void WiFiManager::handleReset() { DEBUG_WM(F("<- HTTP Reset")); - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Reset"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); + String page = getHTTPHead("Reset"); //@token titlereset page += F("Module will reset in a few seconds."); page += FPSTR(HTTP_END); @@ -1213,45 +1215,36 @@ void WiFiManager::handleReset() { void WiFiManager::handleErase() { DEBUG_WM(F("<- HTTP Erase")); - String page = FPSTR(HTTP_HEAD); - page.replace("{v}", "Erase"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; + String page = getHTTPHead("Erase"); // @token titleerase page += FPSTR(HTTP_HEAD_END); - bool ret = WiFi_eraseConfig(); - if(!ret) DEBUG_WM(F("ERASE FAILED")); - - // bool ret = reset = true; - - if(ret) page += F("Module will reset in a few seconds."); + + if(ret) page += F("Module will reset in a few seconds."); // @token resetting else { - page += F("An Error Occured"); - DEBUG_WM(F("WiFi EraseConfig reported an error")); + page += F("An Error Occured"); // @token erroroccur + DEBUG_WM(F("[ERROR] WiFi EraseConfig failed")); } page += FPSTR(HTTP_END); server->sendHeader("Content-Length", String(page.length())); server->send(200, "text/html", page); - delay(2000); if(ret){ + delay(2000); DEBUG_WM(F("RESETTING ESP")); reboot(); } } void WiFiManager::handleNotFound() { - if (captivePortal()) { // If captive portal redirect instead of displaying the error page. - return; - } - String message = "File Not Found\n\n"; - message += "URI: "; + if (captivePortal()) return; // If captive portal redirect instead of displaying the page + + String message = "File Not Found\n\n"; // @token notfound + message += "URI: "; // @token uri message += server->uri(); - message += "\nMethod: "; + message += "\nMethod: "; // @token method message += ( server->method() == HTTP_GET ) ? "GET" : "POST"; - message += "\nArguments: "; + message += "\nArguments: "; // @token args message += server->args(); message += "\n"; @@ -1352,28 +1345,6 @@ void WiFiManager::DEBUG_WM(Generic text,Genericb textb) { } } -/* - String WiFiManager::getSSID() { - if (_ssid == "") { - DEBUG_WM(F("Reading SSID")); - _ssid = WiFi.SSID(); - DEBUG_WM(F("SSID: ")); - DEBUG_WM(_ssid); - } - return _ssid; - } - - String WiFiManager::getPassword() { - if (_pass == "") { - DEBUG_WM(F("Reading Password")); - _pass = WiFi.psk(); - DEBUG_WM("Password: " + _pass); - //DEBUG_WM(_pass); - } - return _pass; - } -*/ - void WiFiManager::debugSoftAPConfig(){ #ifdef ESP8266 softap_config config; @@ -1396,9 +1367,9 @@ void WiFiManager::debugSoftAPConfig(){ void WiFiManager::debugPlatformInfo(){ #ifdef ESP8266 system_print_meminfo(); - DEBUG_WM("getCoreVersion(): ",ESP.getCoreVersion()); - DEBUG_WM("system_get_sdk_version(): ",system_get_sdk_version()); - DEBUG_WM("system_get_boot_version(): ",system_get_boot_version()); + DEBUG_WM("getCoreVersion():",ESP.getCoreVersion()); + DEBUG_WM("system_get_sdk_version():",system_get_sdk_version()); + DEBUG_WM("system_get_boot_version():",system_get_boot_version()); #elif defined(ESP32) size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_8BIT); DEBUG_WM("Free heap: ", freeHeap); diff --git a/WiFiManager.h b/WiFiManager.h index 67833bb..035fbc5 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -48,43 +48,9 @@ #include #include -const char HTTP_HEAD[] PROGMEM = "{v}"; -// const char HTTP_STYLE[] PROGMEM = ""; -const char HTTP_STYLE[] PROGMEM = ""; - -const char HTTP_SCRIPT[] PROGMEM = ""; -const char HTTP_HEAD_END[] PROGMEM = "
"; -const char HTTP_PORTAL_OPTIONS[] PROGMEM = "




"; -const char HTTP_ITEM[] PROGMEM = ""; -// const char HTTP_ITEM[] PROGMEM = "
{v} {R} {r}% {q} {e}
"; // test all tokens -//const char HTTP_ITEM_PADLOCK[] PROGMEM = ""; -const char HTTP_FORM_START[] PROGMEM = "


"; -const char HTTP_FORM_END[] PROGMEM = "
"; -const char HTTP_FORM_LABEL[] PROGMEM = ""; -const char HTTP_FORM_PARAM_START[] PROGMEM = "
"; -const char HTTP_FORM_PARAM[] PROGMEM = "
"; -const char HTTP_FORM_PARAM_END[] PROGMEM = "
"; -const char HTTP_SCAN_LINK[] PROGMEM = "
"; -const char HTTP_SAVED[] PROGMEM = "
Saving Credentials
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; -const char HTTP_END[] PROGMEM = "
"; - -#define WIFI_MANAGER_MAX_PARAMS 10 +#ifndef WIFI_MANAGER_MAX_PARAMS + #define WIFI_MANAGER_MAX_PARAMS 5 // params will autoincrement and realloc by this amount when max is reached +#endif #define WFM_LABEL_BEFORE 1 #define WFM_LABEL_AFTER 2 @@ -92,10 +58,15 @@ const char HTTP_END[] PROGMEM = "
"; class WiFiManagerParameter { public: + /** + Create custom parameters that can be added to the WiFiManager setup web page + @id is used for HTTP queries and must not contain spaces nor other special characters + */ WiFiManagerParameter(const char *custom); WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length); WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom, int labelPlacement); + ~WiFiManagerParameter(); const char *getID(); const char *getValue(); @@ -161,8 +132,8 @@ class WiFiManager void setAPCallback( void (*func)(WiFiManager*) ); //called when settings have been changed and connection was successful void setSaveConfigCallback( void (*func)(void) ); - //adds a custom parameter - void addParameter(WiFiManagerParameter *p); + //adds a custom parameter, returns false on failure + bool addParameter(WiFiManagerParameter *p); //if this is set, it will exit after config, even if connection is unsuccessful. void setBreakAfterConfig(boolean shouldBreak); //if this is set, portal will be blocking and wait until save or exit, is false user must manually process to handle config portal @@ -193,28 +164,26 @@ class WiFiManager //const int WM_DONE = 0; //const int WM_WAIT = 10; + // ip configs + IPAddress _ap_static_ip; + IPAddress _ap_static_gw; + IPAddress _ap_static_sn; + IPAddress _sta_static_ip; + IPAddress _sta_static_gw; + IPAddress _sta_static_sn; - //const String HTTP_HEAD = "{v}"; - - void setupConfigPortal(); - void startWPS(); - bool startAP(); - - // typedef enum WiFiMode - // { - // WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 - // } WiFiMode_t; - + // defaults + const byte DNS_PORT = 53; String _apName = "no-net"; String _apPassword = ""; String _ssid = ""; String _pass = ""; + + // options flags unsigned long _configPortalTimeout = 0; unsigned long _connectTimeout = 0; unsigned long _configPortalStart = 0; - boolean _userpersistent = true; WiFiMode_t _usermode = WIFI_OFF; - boolean _enableCaptivePortal = true; #ifdef ESP8266 String _wifissidprefix = "ESP"; @@ -224,34 +193,29 @@ class WiFiManager String _wifissidprefix = "WM"; #endif - IPAddress _ap_static_ip; - IPAddress _ap_static_gw; - IPAddress _ap_static_sn; - IPAddress _sta_static_ip; - IPAddress _sta_static_gw; - IPAddress _sta_static_sn; - boolean _sta_show_static_fields = false; - // option parameters - int _paramsCount = 0; int _minimumQuality = -1; boolean _removeDuplicateAPs = true; boolean _shouldBreakAfterConfig = false; boolean _tryWPS = false; boolean _configPortalIsBlocking = true; + boolean _sta_show_static_fields = false; + boolean _enableCaptivePortal = true; + boolean _userpersistent = true; boolean _wifiAutoReconnect = false; const char* _customHeadElement = ""; - //String getEEPROMString(int start, int len); - //void setEEPROMString(int start, int len, String string); + void setupConfigPortal(); + void startWPS(); + bool startAP(); int status = WL_IDLE_STATUS; int connectWifi(String ssid, String pass); uint8_t waitForConnectResult(); uint8_t waitForConnectResult(uint16_t timeout); - String getWLStatusString(uint8_t status); + // webserver handlers void handleRoot(); void handleWifi(boolean scan); void handleWifiSave(); @@ -265,6 +229,8 @@ class WiFiManager boolean configPortalHasTimeout(); boolean stopConfigPortal(); uint8_t handleConfigPortal(); + + // wifi platform abstractions bool WiFi_Mode(WiFiMode_t m); bool WiFi_Mode(WiFiMode_t m,bool persistent); bool WiFi_Disconnect(); @@ -280,14 +246,14 @@ class WiFiManager void debugSoftAPConfig(); + // output helpers String getParamOut(); String getScanItemOut(); String getStaticOut(); - - // DNS server - const byte DNS_PORT = 53; + String getHTTPHead(String title); //helpers + String getWLStatusString(uint8_t status); int getRSSIasQuality(int RSSI); boolean isIp(String str); String toStringIp(IPAddress ip); @@ -296,27 +262,33 @@ class WiFiManager void reportStatus(String &page); void debugPlatformInfo(); + // flags boolean connect; boolean abort; - boolean reset = false; + boolean reset = false; boolean configPortalActive = false; boolean webPortalActive = false; - boolean _debug = true; boolean portalTimeoutResult = false; boolean portalAbortResult = false; boolean storeSTAmode = true; // option store persistent STA mode in connectwifi int timer = 0; + + // WiFiManagerParameter + int _paramsCount = 0; + int _max_params; + WiFiManagerParameter** _params; - void (*_apcallback)(WiFiManager*) = NULL; - void (*_savecallback)(void) = NULL; - - Stream& _debugPort; // debug output stream ref - WiFiManagerParameter* _params[WIFI_MANAGER_MAX_PARAMS]; - + // debugging + boolean _debug = true; + Stream& _debugPort; // debug output stream ref template - void DEBUG_WM(Generic text); + void DEBUG_WM(Generic text); template - void DEBUG_WM(Generic text,Genericb textb); + void DEBUG_WM(Generic text,Genericb textb); + + // callbacks + void (*_apcallback)(WiFiManager*) = NULL; + void (*_savecallback)(void) = NULL; template auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { diff --git a/strings_en.h b/strings_en.h new file mode 100644 index 0000000..15c9a1e --- /dev/null +++ b/strings_en.h @@ -0,0 +1,71 @@ +#ifndef WIFI_MANAGER_OVERRIDE_STRINGS + +// To override the strings below in your project, make the following changes above the line that includes "WiFIManager.h" +// Add the following line: +// #define WIFI_MANAGER_OVERRIDE_STRINGS +// Copy and paste ALL of the const char lines below and modify to suit. + +const char HTTP_HEAD[] PROGMEM = "{v}"; +const char HTTP_SCRIPT[] PROGMEM = ""; +const char HTTP_HEAD_END[] PROGMEM = "
"; +const char HTTP_ROOT_MAIN[] PROGMEM = "

{v}

WiFiManager

"; +const char HTTP_PORTAL_OPTIONS[] PROGMEM = "




"; +const char HTTP_ITEM[] PROGMEM = ""; +// const char HTTP_ITEM[] PROGMEM = "
{v} {R} {r}% {q} {e}
"; // test all tokens +const char HTTP_FORM_START[] PROGMEM = "


"; +const char HTTP_FORM_END[] PROGMEM = "
"; +const char HTTP_FORM_LABEL[] PROGMEM = ""; +const char HTTP_FORM_PARAM_START[] PROGMEM = "
"; +const char HTTP_FORM_PARAM[] PROGMEM = "
"; +const char HTTP_FORM_PARAM_END[] PROGMEM = "
"; +const char HTTP_SCAN_LINK[] PROGMEM = "
"; +const char HTTP_SAVED[] PROGMEM = "
Saving Credentials
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; +const char HTTP_END[] PROGMEM = "
"; +const char HTTP_ERASEBTN[] PROGMEM = "
"; + +const char HTTP_STATUS_ON[] PROGMEM = "
Connected to {s}
with IP {u}
"; +const char HTTP_STATUS_OFF[] PROGMEM = "
Not Connected to {s}
"; +const char HTTP_STATUS_NONE[] PROGMEM = "
No AP set
"; + +const char HTTP_STYLE[] PROGMEM = ""; + +const char HTTP_HELP[] PROGMEM = + "

Available Pages


" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
PageFunction
/Menu page.
/wifiShow WiFi scan results and enter WiFi configuration.(/0wifi noscan)
/wifisaveSave WiFi configuration information and configure device. Needs variables supplied.
/closeClose the configuration server and configuration WiFi network.
/iInformation page
/exitExit Config Portal, configportal will close
/rReboot the device
/eraseErase WiFi configuration and reboot Device. Device will not reconnect to a network until new WiFi configuration data is entered.
" + "

More information about WiFiManager at https://github.com/tzapu/WiFiManager."; + +#endif \ No newline at end of file