From 33a5e5b3cb81e960e10d7ae8d4b3a2940d38660b Mon Sep 17 00:00:00 2001 From: Pablo Sanchez Date: Thu, 18 Feb 2016 23:29:00 -0500 Subject: [PATCH 1/9] Added an option to the WiFiManagerParameter so that a parameter can be read-only. This is done in a way that does not break an existing program by having a constructor for either way. If a "1" is added to the end of the parameter list then the field becomes readonly. The HTML will add the "readonly" option. --- WiFiManager.cpp | 28 +++++++++++++++++++++++++--- WiFiManager.h | 5 ++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/WiFiManager.cpp b/WiFiManager.cpp index 45ffb9f..227b989 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -12,7 +12,8 @@ #include "WiFiManager.h" -WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) { + +WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, int rofield) { _id = id; _placeholder = placeholder; _length = length; @@ -23,6 +24,25 @@ WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placehold if (defaultValue != NULL) { strncpy(_value, defaultValue, length); } + if (rofield == 0) { + _rofield = " readonly"; + } else { + _rofield = ""; + } +} + +WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) { + _id = id; + _placeholder = placeholder; + _length = length; + _value = new char[length + 1]; + for (int i = 0; i < length; i++) { + _value[i] = 0; + } + if (defaultValue != NULL) { + strncpy(_value, defaultValue, length); + } + _rofield = ""; } const char* WiFiManagerParameter::getValue() { @@ -37,6 +57,9 @@ const char* WiFiManagerParameter::getPlaceholder() { int WiFiManagerParameter::getValueLength() { return _length; } +const char* WiFiManagerParameter::getRofield() { + return _rofield; +} WiFiManager::WiFiManager() { } @@ -415,6 +438,7 @@ void WiFiManager::handleWifi(boolean scan) { snprintf(parLength, 2, "%d", _params[i]->getValueLength()); pitem.replace("{l}", parLength); pitem.replace("{v}", _params[i]->getValue()); + pitem.replace("{r}", _params[i]->getRofield()); page += pitem; } @@ -679,5 +703,3 @@ String WiFiManager::toStringIp(IPAddress ip) { res += String(((ip >> 8 * 3)) & 0xFF); return res; } - - diff --git a/WiFiManager.h b/WiFiManager.h index 512d51f..ae501c6 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -28,7 +28,7 @@ const char HTTP_PORTAL_OPTIONS[] PROGMEM = "
Scan"; @@ -40,16 +40,19 @@ const char HTTP_END[] PROGMEM = ""; class WiFiManagerParameter { public: WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length); + WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, int rofield); const char *getID(); const char *getValue(); const char *getPlaceholder(); int getValueLength(); + const char *getRofield(); private: const char *_id; const char *_placeholder; char *_value; int _length; + const char *_rofield; friend class WiFiManager; }; From 99031ce133cc7b1094e23ee5d0d4ce4c36f0aab9 Mon Sep 17 00:00:00 2001 From: Shawn A Date: Fri, 26 Feb 2016 16:02:35 -0600 Subject: [PATCH 2/9] Jump to form for password entry If you have a long list of APs, the password field gets focuses on click, but this happens below the fold, this jumps to the form so you can see it. Added id to form instead of jumping to the #p field because it makes the input too close to the top of page, a well known issue of anchor links. --- WiFiManager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WiFiManager.h b/WiFiManager.h index 512d51f..57c9fb1 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -25,9 +25,9 @@ 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 = "
{v} {r}%
"; +const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; +const char HTTP_HEAD[] PROGMEM = "{v}"; +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 = "
{v} {r}%
"; //const char HTTP_ITEM_PADLOCK[] PROGMEM = ""; -const char HTTP_FORM_START[] PROGMEM = "


"; -const char HTTP_FORM_PARAM[] PROGMEM = "
"; -const char HTTP_FORM_END[] PROGMEM = "
"; -const char HTTP_SCAN_LINK[] PROGMEM = "
"; - -const char HTTP_SAVED[] PROGMEM = "
Credentials Saved
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; -const char HTTP_END[] PROGMEM = "
"; +const char HTTP_FORM_START[] PROGMEM = "


"; +const char HTTP_FORM_PARAM[] PROGMEM = "
"; +const char HTTP_FORM_END[] PROGMEM = "
"; +const char HTTP_SCAN_LINK[] PROGMEM = "
"; +const char HTTP_SAVED[] PROGMEM = "
Credentials Saved
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 class WiFiManagerParameter { public: WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length); - WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, int rofield); + WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); + WiFiManagerParameter(const char *custom); const char *getID(); const char *getValue(); const char *getPlaceholder(); int getValueLength(); - const char *getRofield(); + const char *getCustomHTML(); private: const char *_id; const char *_placeholder; char *_value; int _length; - const char *_rofield; + const char *_customHTML; + + void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); friend class WiFiManager; }; @@ -173,11 +175,11 @@ class WiFiManager template auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { - return obj->fromString(s); + return obj->fromString(s); } auto optionalIPFromString(...) -> bool { - DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); - return false; + DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); + return false; } }; From 7f11a5d144e30d38cf1ceec0a5091c3b1eea6793 Mon Sep 17 00:00:00 2001 From: Alex Tudorache Date: Fri, 4 Mar 2016 15:00:49 +0200 Subject: [PATCH 7/9] added custom head element, like style/css --- README.md | 1 + WiFiManager.cpp | 90 ++++++++++++++++++++++++++++--------------------- WiFiManager.h | 48 +++++++++++++++----------- 3 files changed, 81 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index a052fdf..f65dae2 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,7 @@ works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 o The support and help I got from the community has been nothing short of phenomenal. I can't thank you guys enough. This is my first real attept in developing open source stuff and I must say, now I understand why people are so dedicated to it, it is because of all the wonderful people involved. __THANK YOU__ + [Shawn A](https://github.com/tablatronix) [Maximiliano Duarte](https://github.com/domonetic) diff --git a/WiFiManager.cpp b/WiFiManager.cpp index 44cb18d..8014f66 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -12,8 +12,24 @@ #include "WiFiManager.h" - -WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, int rofield) { +WiFiManagerParameter::WiFiManagerParameter(const char *custom) { + _id = NULL; + _placeholder = NULL; + _length = 0; + _value = NULL; + + _customHTML = custom; +} + +WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) { + init(id, placeholder, defaultValue, length, ""); +} + +WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom) { + init(id, placeholder, defaultValue, length, custom); +} + +void WiFiManagerParameter::init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom) { _id = id; _placeholder = placeholder; _length = length; @@ -24,25 +40,8 @@ WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placehold if (defaultValue != NULL) { strncpy(_value, defaultValue, length); } - if (rofield == 0) { - _rofield = " readonly"; - } else { - _rofield = ""; - } -} -WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) { - _id = id; - _placeholder = placeholder; - _length = length; - _value = new char[length + 1]; - for (int i = 0; i < length; i++) { - _value[i] = 0; - } - if (defaultValue != NULL) { - strncpy(_value, defaultValue, length); - } - _rofield = ""; + _customHTML = custom; } const char* WiFiManagerParameter::getValue() { @@ -57,8 +56,8 @@ const char* WiFiManagerParameter::getPlaceholder() { int WiFiManagerParameter::getValueLength() { return _length; } -const char* WiFiManagerParameter::getRofield() { - return _rofield; +const char* WiFiManagerParameter::getCustomHTML() { + return _customHTML; } WiFiManager::WiFiManager() { @@ -348,6 +347,7 @@ void WiFiManager::handleRoot() { page.replace("{v}", "Options"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); + page += _customHeadElement; page += FPSTR(HTTP_HEAD_END); page += "

"; page += _apName; @@ -367,6 +367,7 @@ void WiFiManager::handleWifi(boolean scan) { page.replace("{v}", "Config ESP"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); + page += _customHeadElement; page += FPSTR(HTTP_HEAD_END); if (scan) { @@ -379,11 +380,11 @@ void WiFiManager::handleWifi(boolean scan) { //sort networks /*int indices[n]; - for (int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { indices[i] = i; - } + } - for (int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) { //int temp = indices[j]; @@ -392,19 +393,19 @@ void WiFiManager::handleWifi(boolean scan) { std::swap(indices[i], indices[j]); } } - } + } */ int indices[n]; for (int i = 0; i < n; i++) { indices[i] = i; } - std::sort(indices, indices+n, [](const int & a, const int & b) -> bool - { - return WiFi.RSSI(a) > WiFi.RSSI(b); + std::sort(indices, indices + n, [](const int & a, const int & b) -> bool + { + return WiFi.RSSI(a) > WiFi.RSSI(b); }); - - + + //display networks in page for (int i = 0; i < n; i++) { DEBUG_WM(WiFi.SSID(indices[i])); @@ -443,13 +444,17 @@ void WiFiManager::handleWifi(boolean scan) { } String pitem = FPSTR(HTTP_FORM_PARAM); - pitem.replace("{i}", _params[i]->getID()); - pitem.replace("{n}", _params[i]->getID()); - pitem.replace("{p}", _params[i]->getPlaceholder()); - snprintf(parLength, 2, "%d", _params[i]->getValueLength()); - pitem.replace("{l}", parLength); - pitem.replace("{v}", _params[i]->getValue()); - pitem.replace("{r}", _params[i]->getRofield()); + if (_params[i]->getID() != NULL) { + pitem.replace("{i}", _params[i]->getID()); + pitem.replace("{n}", _params[i]->getID()); + pitem.replace("{p}", _params[i]->getPlaceholder()); + snprintf(parLength, 2, "%d", _params[i]->getValueLength()); + pitem.replace("{l}", parLength); + pitem.replace("{v}", _params[i]->getValue()); + pitem.replace("{c}", _params[i]->getCustomHTML()); + } else { + pitem = _params[i]->getCustomHTML(); + } page += pitem; } @@ -546,6 +551,7 @@ void WiFiManager::handleWifiSave() { page.replace("{v}", "Credentials Saved"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); + page += _customHeadElement; page += FPSTR(HTTP_HEAD_END); page += FPSTR(HTTP_SAVED); page += FPSTR(HTTP_END); @@ -565,6 +571,7 @@ void WiFiManager::handleInfo() { page.replace("{v}", "Info"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); + page += _customHeadElement; page += FPSTR(HTTP_HEAD_END); page += F("
"); page += F("
Chip ID
"); @@ -604,6 +611,7 @@ void WiFiManager::handleReset() { page.replace("{v}", "Info"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); + page += _customHeadElement; page += FPSTR(HTTP_HEAD_END); page += F("Module will reset in a few seconds."); page += FPSTR(HTTP_END); @@ -671,6 +679,12 @@ void WiFiManager::setSaveConfigCallback( void (*func)(void) ) { _savecallback = func; } +//sets a custom element to add to head, like a new style tag +void WiFiManager::setCustomHeadElement(const char* element) { + _customHeadElement = element; +} + + template diff --git a/WiFiManager.h b/WiFiManager.h index a2fbba8..c9f1746 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -22,40 +22,42 @@ #include -const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; -const char HTTP_HEAD[] PROGMEM = "{v}"; -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 = "
{v} {r}%
"; +const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; +const char HTTP_HEAD[] PROGMEM = "{v}"; +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 = "
{v} {r}%
"; //const char HTTP_ITEM_PADLOCK[] PROGMEM = ""; -const char HTTP_FORM_START[] PROGMEM = "


"; -const char HTTP_FORM_PARAM[] PROGMEM = "
"; -const char HTTP_FORM_END[] PROGMEM = "
"; -const char HTTP_SCAN_LINK[] PROGMEM = "
"; - -const char HTTP_SAVED[] PROGMEM = "
Credentials Saved
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; -const char HTTP_END[] PROGMEM = "
"; +const char HTTP_FORM_START[] PROGMEM = "


"; +const char HTTP_FORM_PARAM[] PROGMEM = "
"; +const char HTTP_FORM_END[] PROGMEM = "
"; +const char HTTP_SCAN_LINK[] PROGMEM = "
"; +const char HTTP_SAVED[] PROGMEM = "
Credentials Saved
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 class WiFiManagerParameter { public: + 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, int rofield); + WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); const char *getID(); const char *getValue(); const char *getPlaceholder(); int getValueLength(); - const char *getRofield(); + const char *getCustomHTML(); private: const char *_id; const char *_placeholder; char *_value; int _length; - const char *_rofield; + const char *_customHTML; + + void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); friend class WiFiManager; }; @@ -103,6 +105,10 @@ class WiFiManager //if this is set, it will exit after config, even if connection is unsucessful. void setBreakAfterConfig(boolean shouldBreak); //if this is set, try WPS setup when starting (this will delay config portal for up to 2 mins) + //TODO + //if this is set, customise style + void setCustomHeadElement(const char* element); + private: std::unique_ptr dnsServer; @@ -136,6 +142,8 @@ class WiFiManager boolean _shouldBreakAfterConfig = false; boolean _tryWPS = false; + const char* _customHeadElement = ""; + //String getEEPROMString(int start, int len); //void setEEPROMString(int start, int len, String string); @@ -173,11 +181,11 @@ class WiFiManager template auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { - return obj->fromString(s); + return obj->fromString(s); } auto optionalIPFromString(...) -> bool { - DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); - return false; + DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); + return false; } }; From b99487785d2c8319df1223b204e1bba2b321f3f3 Mon Sep 17 00:00:00 2001 From: Alex Tudorache Date: Sat, 5 Mar 2016 17:47:12 +0200 Subject: [PATCH 8/9] fix for auto connect racing issue --- WiFiManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WiFiManager.cpp b/WiFiManager.cpp index 8014f66..56590a3 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -220,7 +220,11 @@ int WiFiManager::connectWifi(String ssid, String pass) { WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn); DEBUG_WM(WiFi.localIP()); } - + //fix for auto connect racing issue + if (WiFi.status() == WL_CONNECTED) { + DEBUG_WM("Already connected. Bailing out."); + return WL_CONNECTED; + } //check if we have ssid and pass and force those, if not, try with last saved values if (ssid != "") { WiFi.begin(ssid.c_str(), pass.c_str()); From 566bcbe0632c2c501995a7a9d6c3490bb0d33e5b Mon Sep 17 00:00:00 2001 From: Alex Tudorache Date: Tue, 8 Mar 2016 07:46:06 +0200 Subject: [PATCH 9/9] attempt to fix not connecting issues and endless loops --- WiFiManager.cpp | 17 +++++++++++++---- WiFiManager.h | 4 +++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/WiFiManager.cpp b/WiFiManager.cpp index 56590a3..25f5823 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -151,8 +151,8 @@ boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) { boolean WiFiManager::startConfigPortal(char const *apName, char const *apPassword) { //setup AP - WiFi.mode(WIFI_AP); - DEBUG_WM("SET AP"); + WiFi.mode(WIFI_AP_STA); + DEBUG_WM("SET AP STA"); _apName = apName; _apPassword = apPassword; @@ -229,8 +229,17 @@ int WiFiManager::connectWifi(String ssid, String pass) { if (ssid != "") { WiFi.begin(ssid.c_str(), pass.c_str()); } else { - DEBUG_WM("Using last saved values, should be faster"); - WiFi.begin(); + if(WiFi.SSID()) { + DEBUG_WM("Using last saved values, should be faster"); + //trying to fix connection in progress hanging + ETS_UART_INTR_DISABLE(); + wifi_station_disconnect(); + ETS_UART_INTR_ENABLE(); + + WiFi.begin(); + } else { + DEBUG_WM("No saved credentials"); + } } int connRes = waitForConnectResult(); diff --git a/WiFiManager.h b/WiFiManager.h index c9f1746..0902e86 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -20,7 +20,9 @@ #undef min #undef max #include - +extern "C" { + #include "user_interface.h" +} const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; const char HTTP_HEAD[] PROGMEM = "{v}";