diff --git a/.travis.yml b/.travis.yml index ca2ba85..d41a13b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: install: - ln -s $PWD /usr/local/share/arduino/libraries/WiFiManager - arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json" --save-prefs - - arduino --install-library "ArduinoJson" + - arduino --install-library "ArduinoJson:5.13.2" - arduino --install-boards esp8266:esp8266 - arduino --pref "compiler.warning_level=all" --save-prefs # install esp32 diff --git a/README.md b/README.md index 1f355a2..7e53338 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,9 @@ First attempt at a library. Lots more changes and fixes to do. Contributions are - [Wishlist](#wishlist) - [Quick start](#quick-start) - Installing - - [Through Library Manager](#install-through-library-manager) - - [From Github](#checkout-from-github) + - [Arduino - Through Library Manager](#install-through-library-manager) + - [Arduino - From Github](#checkout-from-github) + - [PlatformIO] - [Using](#using) - [Documentation](#documentation) - [Access Point Password](#password-protect-the-configuration-access-point) @@ -46,12 +47,13 @@ First attempt at a library. Lots more changes and fixes to do. Contributions are ## How It Works -- when your ESP starts up, it sets it up in Station mode and tries to connect to a previously saved Access Point +- When your ESP starts up, it sets it up in Station mode and tries to connect to a previously saved Access Point - if this is unsuccessful (or no previous network saved) it moves the ESP into Access Point mode and spins up a DNS and WebServer (default ip 192.168.4.1) - using any wifi enabled device with a browser (computer, phone, tablet) connect to the newly created Access Point - because of the Captive Portal and the DNS server you will either get a 'Join to network' type of popup or get any domain you try to access redirected to the configuration portal - choose one of the access points scanned, enter password, click save - ESP will try to connect. If successful, it relinquishes control back to your app. If not, reconnect to AP and reconfigure. +- There are options to change this behavior or manually start the configportal and webportal independantly as well as run them in non blocking mode. ## How It Looks ![ESP8266 WiFi Captive Portal Homepage](http://i.imgur.com/YPvW9eql.png) ![ESP8266 WiFi Captive Portal Configuration](http://i.imgur.com/oicWJ4gl.png) @@ -67,9 +69,35 @@ First attempt at a library. Lots more changes and fixes to do. Contributions are - [x] add to PlatformIO - [ ] add multiple sets of network credentials - [x] allow users to customize CSS -- [ ] ESP32 support or instructions - [ ] rewrite documentation for simplicity, based on scenarios/goals -- [ ] rely on the SDK's built in auto connect more than forcing a connect + +### Development +- [x] ESP32 support +- [x] rely on the SDK's built in auto connect more than forcing a connect +- [x] add non blocking mode +- [x] easy customization of strings +- [x] hostname support +- [x] fix various bugs and workarounds for esp SDK issues +- [x] additional info page items +- [x] last status display / faiilure reason +- [x] customizeable menu +- [x] seperate custom params page +- [x] ondemand webportal +- [x] complete refactor of code to segment functions +- [x] wiif scan icons or percentage display +- [x] invert class for dark mode +- [x] more template tokens +- [x] progmem for all strings +- [ ] new callbacks +- [ ] new callouts / filters +- [ ] shared web server instance +- [x] latest esp idf/sdk support +- [x] wm is now non persistent, will not erase or change stored esp config on esp8266 +- [x] tons of debugging output / levels +- [ ] disable captiveportal +- [ ] preload wiifscans, faster page loads +- [ ] softap stability fixes when sta is not connected + ## Quick Start @@ -93,14 +121,10 @@ __Github version works with release 2.4.0 or newer of the [ESP8266 core for Ardu ### Using - Include in your sketch ```cpp -#include //ESP8266 Core WiFi Library (you most likely already have this in your sketch) - -#include //Local DNS Server used for redirecting all requests to the configuration portal -#include //Local WebServer used to serve the configuration portal #include //https://github.com/tzapu/WiFiManager WiFi Configuration Magic ``` -- Initialize library, in your setup function add +- Initialize library, in your setup function add, NOTEif you are using non blocking you will make sure you create this in global scope or handle appropriatly , it will not work if in setup and using non blocking mode. ```cpp WiFiManager wifiManager; ``` @@ -240,7 +264,7 @@ wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddr ##### Custom Station (client) Static IP Configuration This will make use the specified IP configuration instead of using DHCP in station mode. ```cpp -wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0)); +wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0)); // optional DNS 4th argument ``` There are a couple of examples in the examples folder that show you how to set a static IP and even how to configure it through the web configuration portal. @@ -252,7 +276,7 @@ You can use this to any html bit to the head of the configuration portal. If you ```cpp wifiManager.setCustomHeadElement(""); ``` -- inject a custom bit of html in the configuration form +- inject a custom bit of html in the configuration/param form ```cpp WiFiManagerParameter custom_text("

This is just a text paragraph

"); wifiManager.addParameter(&custom_text); @@ -263,6 +287,14 @@ Just add the bit you want added as the last parameter to the custom parameter co WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "iot.eclipse", 40, " readonly"); ``` +#### Theming +You can customize certain elements of the default template with some builtin classes +```CPP +wifiManager.setClass("invert"); // dark theme +wifiManager.setScanDispPerc(true); // display percentages instead of graphs for RSSI +``` +There are additional classes in the css you can use in your custom html , see the example template. + #### Filter Networks You can filter networks based on signal quality and show/hide duplicate networks. @@ -279,11 +311,24 @@ wifiManager.setRemoveDuplicateAPs(false); ``` #### Debug -Debug is enabled by default on Serial. To disable add before autoConnect +Debug is enabled by default on `Serial` in non-stable releases. To disable add before autoConnect/startConfigPortal ```cpp wifiManager.setDebugOutput(false); ``` +You can pass in a custom stream via constructor +```CPP +WiFiManager wifiManager(Serial1); +``` + +You can customize the debug level by changing `_debugLevel` in source +options are: +* DEBUG_ERROR +* DEBUG_NOTIFY +* DEBUG_VERBOSE +* DEBUG_DEV +* DEBUG_MAX + ## Troubleshooting If you get compilation errors, more often than not, you may need to install a newer version of the ESP8266 core for Arduino. @@ -295,7 +340,122 @@ If you connect to the created configuration Access Point but the configuration p If trying to connect ends up in an endless loop, try to add `setConnectTimeout(60)` before `autoConnect();`. The parameter is timeout to try connecting in seconds. +I get stuck in ap mode when the power goes out or modem resets, try a setConfigPortalTimeout(seconds). This will cause the configportal to close after no activity, and you can reboot or attempt reconnection in your code. + ## Releases +### 1.0.1 + +### Development Overview + +#### Added Public Methods +`setConfigPortalBlocking` + +`setShowStaticFields` + +`setCaptivePortalEnable` + +`setRestorePersistent` + +`setCaptivePortalClientCheck` + +`setWebPortalClientCheck` + +`startWebPortal` + +`stopWebPortal` + +`process` + +`disconnect` + +`erase` + +` debugSoftAPConfig` + +` debugPlatformInfo` + +`setScanDispPerc` + +`setHostname` + +`setMenu(menu_page_t[])` + +`setWiFiAutoReconnect` + +` setSTAStaticIPConfig(..,dns)` + +`setShowDnsFields` + +`getLastConxResult` + +`getWLStatusString` + +`getModeString` + +`getWiFiIsSaved` + +`setShowInfoErase` + +`setEnableConfigPortal` + +`setCountry` + +`setClass` + +`htmleEtities` + + +#### WiFiManagerParameter +`WiFiManagerParameter(id,label)` + +`WiFiManagerParameter.setValue(value,length)` + +`getParameters` + +`getParametersCount` + + +#### Constructors +`WiFiManager(Stream& consolePort)` + +#### define flags +❗️ **Defines cannot be set in user sketches** +`#define WM_MDNS // use MDNS` + +`#define WM_FIXERASECONFIG // use erase flash fix, esp8266 2.4.0` + +`#define WM_ERASE_NVS // esp32 erase(true) will erase NVS` + +`#include // esp32 info page will show last reset reasons if this file is included` + +#### Changes Overview +- ESP32 support ( fairly stable ) +- complete refactor of strings `strings_en.h` +- adds new tokens for wifiscan, and some classes (left , invert icons, MSG color) +- adds status callout panel default, primary, special colors +- adds tons of info on info page, and erase capability +- adds signal icons, replaces percentage ( has hover titles ) +- adds labels to all inputs (replaces placeholders) +- all html ( and eventually all strings except debug) moved to `strings_en.h` +- added additional debugging, compressed debug lines, debuglevels +- persistent disabled, and restored via de/con-stuctor (uses `setRestorePersistent`) +- should retain all user modes including AP, should not overwrite or persist user modes or configs,even STA (`storeSTAmode`) (BUGGY) +- ⚠️ return values may have changed depending on portal abort, or timeout ( `portalTimeoutResult`,`portalAbortResult`) +- params memory is auto allocated by increment of `WIFI_MANAGER_MAX_PARAMS(5)` when exceeded, user no longer needs to specify this at all. +- addparameter now returns bool, and it returns false if param ID is not alphanum [0-9,A-Z,a-z,_] +- param field ids allow {I} token to use param_n instead of string in case someones wants to change this due to i18n or character issues +- provides `#DEFINE FIXERASECONFIG` to help deal with https://github.com/esp8266/Arduino/pull/3635 +- failure reason reporting on portal +- set esp8266 sta hostname, esp32 sta+ap hostname ( DHCP client id) +- pass in debug stream in constructor WiFiManager(Stream& consolePort) +- you can force ip fields off with showxfields(false) if you set _disableIpFields=true +- param menu/page (setup) added to separate params from wifi page, handled automatically by setMenu +- set custom root menu +- disable configportal on autoconnect +- wm parameters init is now protected, allowing child classes, example included +- wifiscans are precached and async for faster page loads, refresh forces rescan +- adds esp32 gettemperature ( currently commented out, useful for relative measurement only ) + #### 0.12 - removed 204 header response - fixed incompatibility with other libs using isnan and other std:: functions without namespace @@ -314,53 +474,20 @@ If trying to connect ends up in an endless loop, try to add `setConnectTimeout(6 - added an alternative to waitForConnectResult() for debugging - changed `setTimeout(seconds)` to `setConfigPortalTimeout(seconds)` -##### 0.9 - - fixed support for encoded characters in ssid/pass - -##### 0.8 - - made it compile on older versions of ESP8266 core as well, tested down to 2.0.0 - - added simple example for Custom IP - -##### 0.7 - - added static IP in station mode - - added example of persisting custom IP to FS config.json - - more option on portal homepage - - added on PlatformIO - -##### 0.6 - - custom parameters - - prettier - - on demand config portal - - commit #100 :D - -##### 0.5 - - Added to Arduino Boards Manager - Thanks Max - - moved most stuff to PROGMEM - - added signal quality and a nice little padlock to show which networks are encrypted - -##### v0.4 - all of it user contributed changes - Thank you - - added ability to password protect the configuration Access Point - - callback for enter configuration mode - - memory allocation improvements - -##### v0.3 - - removed the need for EEPROM and works with the 2.0.0 and above stable release of the ESP8266 for Arduino IDE package - - removed restart on save of credentials - - updated examples - -##### v0.2 -needs the latest staging version (or at least a recent release of the staging version) to work - -##### v0.1 -works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 of the ESP8266 Arduino library. - - ### Contributions and thanks 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) +The esp8266 and esp32 arduino and idf maintainers! + +[Shawn A aka tablatronix](https://github.com/tablatronix) + +[liebman](https://github.com/liebman) + +[Evgeny Dontsov](https://github.com/dontsovcmc) + +[Chris Marrin](https://github.com/cmarrin) [bbx10](https://github.com/bbx10) @@ -397,3 +524,4 @@ And countless others * https://github.com/chriscook8/esp-arduino-apboot * https://github.com/esp8266/Arduino/tree/master/libraries/DNSServer/examples/CaptivePortalAdvanced * Built by AlexT https://github.com/tzapu + diff --git a/WiFiManager.cpp b/WiFiManager.cpp index e92c1ee..03d5050 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -62,26 +62,24 @@ WiFiManagerParameter::~WiFiManagerParameter() { _length=0; // setting length 0, ideally the entire parameter should be removed, or added to wifimanager scope so it follows } +// @note debug is not available in wmparameter class void WiFiManagerParameter::setValue(const char *defaultValue, int length) { if(!_id){ // Serial.println("cannot set value of this parameter"); return; } - _length = length; - int deflength = strlen(defaultValue); // length actual - // use the defult length if it's longer, - // @todo consider it might be useful to fail, so user knows they were wrong - if(_length < length){ - // Serial.println("defaultValue length mismatch"); - _length = deflength; - } - _value = new char[_length + 1]; - for (int i = 0; i < _length + 1; i++) { - _value[i] = 0; - } + + // if(strlen(defaultValue) > length){ + // // Serial.println("defaultValue length mismatch"); + // // return false; //@todo bail + // } + + _length = length; + _value = new char[_length + 1]; + memset(_value, 0, _length + 1); // explicit null + if (defaultValue != NULL) { strncpy(_value, defaultValue, _length); - _value[_length] = '\0'; // explicit null } } const char* WiFiManagerParameter::getValue() { @@ -150,6 +148,22 @@ bool WiFiManager::addParameter(WiFiManagerParameter *p) { return true; } +/** + * [getParameters description] + * @access public + */ +WiFiManagerParameter** WiFiManager::getParameters() { + return _params; +} + +/** + * [getParametersCount description] + * @access public + */ +int WiFiManager::getParametersCount() { + return _paramsCount; +} + /** * -------------------------------------------------------------------------------- * WiFiManager @@ -317,14 +331,6 @@ bool WiFiManager::startAP(){ _apcallback(this); } - // setup optional soft AP static ip config - if (_ap_static_ip) { - DEBUG_WM(F("Custom AP IP/GW/Subnet:")); - if(!WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn)){ - DEBUG_WM(DEBUG_ERROR,"[ERROR] softAPConfig failed!"); - } - } - #ifdef ESP8266 // @bug workaround for bug #4372 https://github.com/esp8266/Arduino/issues/4372 if(!WiFi.enableAP(true)) { @@ -334,6 +340,15 @@ bool WiFiManager::startAP(){ delay(500); // workaround delay #endif + // setup optional soft AP static ip config + if (_ap_static_ip) { + DEBUG_WM(F("Custom AP IP/GW/Subnet:")); + if(!WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn)){ + DEBUG_WM(DEBUG_ERROR,"[ERROR] softAPConfig failed!"); + } + } + + if(_channelSync){ DEBUG_WM(DEBUG_VERBOSE,"Starting AP on channel:",WiFi.channel()); } @@ -1263,6 +1278,11 @@ void WiFiManager::handleWifiSave() { DEBUG_WM(DEBUG_DEV,F("Method:"),server->method() == HTTP_GET ? (String)FPSTR(S_GET) : (String)FPSTR(S_POST)); handleRequest(); + // @todo use new callback for before paramsaves + if ( _presavecallback != NULL) { + _presavecallback(); + } + //SAVE/connect here _ssid = server->arg(F("s")).c_str(); _pass = server->arg(F("p")).c_str(); @@ -1309,6 +1329,12 @@ void WiFiManager::handleParamSave() { DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP WiFi save ")); DEBUG_WM(DEBUG_DEV,F("Method:"),server->method() == HTTP_GET ? (String)FPSTR(S_GET) : (String)FPSTR(S_POST)); handleRequest(); + + // @todo use new callback for before paramsaves + if ( _presavecallback != NULL) { + _presavecallback(); + } + doParamSave(); // @todo use new callback for paramsaves @@ -1408,6 +1434,7 @@ void WiFiManager::handleInfo() { F("cpufreq"), F("freeheap"), F("lastreset"), + // F("temp"), F("wifihead"), F("apip"), F("apmac"), @@ -1617,6 +1644,14 @@ String WiFiManager::getInfoData(String id){ p.replace(FPSTR(T_1),WiFi.getAutoConnect() ? FPSTR(S_enable) : FPSTR(S_disable)); } #endif + #ifdef ESP32 + else if(id==F("temp")){ + // temperature is not calibrated, varying large offsets are present, use for relative temp changes only + p = FPSTR(HTTP_INFO_temp); + p.replace(FPSTR(T_1),(String)temperatureRead()); + p.replace(FPSTR(T_2),(String)((temperatureRead()+32)*1.8)); + } + #endif return p; } @@ -1852,6 +1887,9 @@ void WiFiManager::resetSettings() { DEBUG_WM(F("SETTINGS ERASED")); WiFi_enableSTA(true,true); // must be sta to disconnect erase + if (_resetcallback != NULL) + _resetcallback(); + #ifdef ESP32 WiFi.disconnect(true,true); #else @@ -1985,6 +2023,22 @@ void WiFiManager::setSaveConfigCallback( std::function func ) { _savecallback = func; } +//start up reset config callback +void WiFiManager::setConfigResetCallback(void(*func)(void)) { + _resetcallback = func; +} + +//sets a custom element to add to head, like a new style tag +/** + * setPreSaveConfigCallback, set a pre save config callback after closing configportal + * @todo only calls if configportal stopped + * @access public + * @param {[type]} void (*func)(void) [description] + */ +void WiFiManager::setPreSaveConfigCallback( std::function func ) { + _presavecallback = func; +} + /** * set custom head html * custom element will be added to head, eg. new style tag etc. diff --git a/WiFiManager.h b/WiFiManager.h index fa18c1c..b591f50 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -13,7 +13,10 @@ #ifndef WiFiManager_h #define WiFiManager_h +#ifdef ESP8266 #include +#endif + #include // #define WM_MDNS // also set MDNS with sethostname @@ -28,8 +31,8 @@ // #include "soc/efuse_reg.h" // include to add efuse chip rev to info, getChipRevision() is almost always the same though, so not sure why it matters. -// #define esp32autoreconnect // implement esp32 autoreconnect event listener kludge -// autoreconnect status WORKING https://github.com/espressif/arduino-esp32/issues/653#issuecomment-405604766 +// #define esp32autoreconnect // implement esp32 autoreconnect event listener kludge, deprecated +// autoreconnect is WORKING https://github.com/espressif/arduino-esp32/issues/653#issuecomment-405604766 #define WM_WEBSERVERSHIM // use webserver shim lib @@ -115,6 +118,11 @@ class WiFiManagerParameter { int getLabelPlacement(); const char *getCustomHTML(); void setValue(const char *defaultValue, int length); + + protected: + void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); + void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom, int labelPlacement); + private: const char *_id; const char *_placeholder; @@ -123,9 +131,6 @@ class WiFiManagerParameter { int _labelPlacement; const char *_customHTML; - void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); - void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom, int labelPlacement); - friend class WiFiManager; }; @@ -169,6 +174,24 @@ class WiFiManager bool erase(); bool erase(bool opt); + //adds a custom parameter, returns false on failure + bool addParameter(WiFiManagerParameter *p); + //returns the list of Parameters + WiFiManagerParameter** getParameters(); + // returns the Parameters Count + int getParametersCount(); + + + //called when AP mode and config portal is started + void setAPCallback( std::function func ); + //called when settings reset have been triggered + void setConfigResetCallback(void(*func)(void)); + //called when settings have been changed and connection was successful + void setSaveConfigCallback( std::function func ); + //called when settings before have been changed and connection was successful + void setPreSaveConfigCallback( std::function func ); + + //sets timeout before AP,webserver loop ends and exits even if there has been no setup. //useful for devices that failed to connect at some point and got stuck in a webserver loop //in seconds setConfigPortalTimeout is a new name for setTimeout, ! not used if setConfigPortalBlocking @@ -189,12 +212,6 @@ class WiFiManager void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn); //sets config for a static IP with DNS void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns); - //called when AP mode and config portal is started - void setAPCallback( std::function func ); - //called when settings have been changed and connection was successful - void setSaveConfigCallback( std::function func ); - //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, @@ -451,6 +468,7 @@ class WiFiManager template void DEBUG_WM(Generic text); + template void DEBUG_WM(wm_debuglevel_t level,Generic text); template @@ -461,6 +479,8 @@ class WiFiManager // callbacks std::function _apcallback; std::function _savecallback; + std::function _presavecallback; + void (*_resetcallback)(void) = NULL; // @todo change to std func template auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { diff --git a/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino b/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino index d209f31..e8be11b 100644 --- a/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino +++ b/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino @@ -54,7 +54,7 @@ void setup() { Serial.setDebugOutput(true); // delay(3000); Serial.println("\n Starting"); - WiFi.setSleepMode(WIFI_NONE_SLEEP); + // WiFi.setSleepMode(WIFI_NONE_SLEEP); //WiFiManager //Local intialization. Once its business is done, there is no need to keep it around @@ -91,7 +91,8 @@ void setup() { WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "", 40); WiFiManagerParameter custom_mqtt_port("port", "mqtt port", "", 6); WiFiManagerParameter custom_token("api_token", "api token", "", 16); - WiFiManagerParameter custom_tokenb("invalid token", "invalid token", "", 0); + WiFiManagerParameter custom_tokenb("invalid token", "invalid token", "", 0); // id is invalid, cannot contain spaces + WiFiManagerParameter custom_ipaddress("input_ip", "input IP", "", 15,"pattern='\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}'"); // callbacks wm.setSaveConfigCallback(saveCallback); @@ -102,6 +103,7 @@ void setup() { wm.addParameter(&custom_mqtt_port); wm.addParameter(&custom_token); wm.addParameter(&custom_tokenb); + wm.addParameter(&custom_ipaddress); custom_html.setValue("test",4); custom_token.setValue("test",4); diff --git a/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino b/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino index 9d283ec..ef8e1eb 100644 --- a/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino +++ b/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino @@ -48,6 +48,7 @@ void doWiFiManager(){ if(digitalRead(TRIGGER_PIN) == LOW && (!portalRunning)) { if(startCP){ Serial.println("Button Pressed, Starting Config Portal"); + wm.setConfigPortalBlocking(false); wm.startConfigPortal(); } else{ diff --git a/examples/Old Examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino b/examples/Old_examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino similarity index 100% rename from examples/Old Examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino rename to examples/Old_examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino diff --git a/examples/Old Examples/AutoConnectWithReset/AutoConnectWithReset.ino b/examples/Old_examples/AutoConnectWithReset/AutoConnectWithReset.ino similarity index 100% rename from examples/Old Examples/AutoConnectWithReset/AutoConnectWithReset.ino rename to examples/Old_examples/AutoConnectWithReset/AutoConnectWithReset.ino diff --git a/examples/Old Examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino b/examples/Old_examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino similarity index 100% rename from examples/Old Examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino rename to examples/Old_examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino diff --git a/examples/Old Examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino b/examples/Old_examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino similarity index 100% rename from examples/Old Examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino rename to examples/Old_examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino diff --git a/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino b/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino index 5850e40..d3cbe3f 100644 --- a/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino +++ b/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino @@ -31,7 +31,7 @@ void checkButton(){ // is configuration portal requested? if(digitalRead(TRIGGER_PIN) == LOW) { - delay(50) + delay(50); if(digitalRead(TRIGGER_PIN) == LOW) { if(!portalRunning){ Serial.println("Button Pressed, Starting Portal"); diff --git a/examples/ParamsChildClass/ParamsChildClass.ino b/examples/ParamsChildClass/ParamsChildClass.ino new file mode 100644 index 0000000..c5d991a --- /dev/null +++ b/examples/ParamsChildClass/ParamsChildClass.ino @@ -0,0 +1,140 @@ +/** + * WiFiManagerParameter child class example + */ +#include // https://github.com/tzapu/WiFiManager +#include +#include + +#define SETUP_PIN 0 + +class IPAddressParameter : public WiFiManagerParameter { +public: + IPAddressParameter(const char *id, const char *placeholder, IPAddress address) + : WiFiManagerParameter("") { + init(id, placeholder, address.toString().c_str(), 16, "", WFM_LABEL_BEFORE); + } + + bool getValue(IPAddress &ip) { + return ip.fromString(WiFiManagerParameter::getValue()); + } +}; + +class IntParameter : public WiFiManagerParameter { +public: + IntParameter(const char *id, const char *placeholder, long value, const uint8_t length = 10) + : WiFiManagerParameter("") { + init(id, placeholder, String(value).c_str(), length, "", WFM_LABEL_BEFORE); + } + + long getValue() { + return String(WiFiManagerParameter::getValue()).toInt(); + } +}; + +class FloatParameter : public WiFiManagerParameter { +public: + FloatParameter(const char *id, const char *placeholder, float value, const uint8_t length = 10) + : WiFiManagerParameter("") { + init(id, placeholder, String(value).c_str(), length, "", WFM_LABEL_BEFORE); + } + + float getValue() { + return String(WiFiManagerParameter::getValue()).toFloat(); + } +}; + +struct Settings { + float f; + int i; + char s[20]; + uint32_t ip; +} sett; + + +void setup() { + pinMode(SETUP_PIN, INPUT_PULLUP); + Serial.begin(9600); + + //Delay to push SETUP button + Serial.println("Press setup button"); + for (int sec = 3; sec > 0; sec--) { + Serial.print(sec); + Serial.print(".."); + delay(1000); + } + + EEPROM.begin( 512 ); + EEPROM.get(0, sett); + Serial.println("Settings loaded"); + + if (digitalRead(SETUP_PIN) == LOW) { + // Button pressed + Serial.println("SETUP"); + + WiFiManager wm; + + sett.s[19] = '\0'; //add null terminator at the end cause overflow + WiFiManagerParameter param_str( "str", "param_string", sett.s, 20); + FloatParameter param_float( "float", "param_float", sett.f); + IntParameter param_int( "int", "param_int", sett.i); + + IPAddress ip(sett.ip); + IPAddressParameter param_ip("ip", "param_ip", ip); + + wm.addParameter( ¶m_str ); + wm.addParameter( ¶m_float ); + wm.addParameter( ¶m_int ); + wm.addParameter( ¶m_ip ); + + //SSID & password parameters already included + wm.startConfigPortal(); + + strncpy(sett.s, param_str.getValue(), 20); + sett.s[19] = '\0'; + sett.f = param_float.getValue(); + sett.i = param_int.getValue(); + + Serial.print("String param: "); + Serial.println(sett.s); + Serial.print("Float param: "); + Serial.println(sett.f); + Serial.print("Int param: "); + Serial.println(sett.i, DEC); + + if (param_ip.getValue(ip)) { + sett.ip = ip; + + Serial.print("IP param: "); + Serial.println(ip); + } else { + Serial.println("Incorrect IP"); + } + + EEPROM.put(0, sett); + if (EEPROM.commit()) { + Serial.println("Settings saved"); + } else { + Serial.println("EEPROM error"); + } + } + else { + Serial.println("WORK"); + + //connect to saved SSID + WiFi.begin(); + + //do smth + Serial.print("String param: "); + Serial.println(sett.s); + Serial.print("Float param: "); + Serial.println(sett.f); + Serial.print("Int param: "); + Serial.println(sett.i, DEC); + Serial.print("IP param: "); + IPAddress ip(sett.ip); + Serial.println(ip); + } +} + +void loop() { +} diff --git a/strings_en.h b/strings_en.h index edbc84e..db8e6bc 100644 --- a/strings_en.h +++ b/strings_en.h @@ -13,7 +13,7 @@ #ifndef WIFI_MANAGER_OVERRIDE_STRINGS // !!! THIS DOES NOT WORK, you cannot define in a sketch, if anyone one knows how to order includes to be able to do this help! -const char HTTP_HEAD_START[] PROGMEM = "{v}"; +const char HTTP_HEAD_START[] PROGMEM = "{v}"; const char HTTP_SCRIPT[] PROGMEM = ""; const char HTTP_HEAD_END[] PROGMEM = "
"; @@ -166,6 +166,7 @@ const char HTTP_INFO_host[] PROGMEM = "
Hostname
{1}
"; const char HTTP_INFO_stamac[] PROGMEM = "
Station MAC
{1}
"; const char HTTP_INFO_conx[] PROGMEM = "
Connected
{1}
"; const char HTTP_INFO_autoconx[] PROGMEM = "
Autoconnect
{1}
"; +const char HTTP_INFO_temp[] PROGMEM = "
Temperature
{1} C° / {2} F°
"; // Strings const char S_y[] PROGMEM = "Yes";