diff --git a/.travis.yml b/.travis.yml index d41a13b..7da81e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,38 +5,39 @@ before_install: - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16" - sleep 3 - export DISPLAY=:1.0 - - wget http://downloads.arduino.cc/arduino-1.8.5-linux64.tar.xz - - tar xf arduino-1.8.5-linux64.tar.xz - - sudo mv arduino-1.8.5 /usr/local/share/arduino + - wget http://downloads.arduino.cc/arduino-1.8.8-linux64.tar.xz + - tar xf arduino-1.8.8-linux64.tar.xz + - sudo mv arduino-1.8.8 /usr/local/share/arduino - sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino 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 --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json,http://dl.espressif.com/dl/package_esp32_index.json" --save-prefs - arduino --install-library "ArduinoJson:5.13.2" - arduino --install-boards esp8266:esp8266 - arduino --pref "compiler.warning_level=all" --save-prefs # install esp32 - - pushd . - - mkdir -p ~/Arduino/hardware/espressif - - cd ~/Arduino/hardware/espressif - - git clone https://github.com/espressif/arduino-esp32.git esp32 - - cd esp32 - - git submodule update --init --recursive - - cd tools - - python2 get.py - - popd + - arduino --install-boards esp32:esp32 + # - pushd . + # - mkdir -p ~/Arduino/hardware/espressif + # - cd ~/Arduino/hardware/espressif + # - git clone https://github.com/espressif/arduino-esp32.git esp32 + # - cd esp32 + # - git submodule update --init --recursive + # - cd tools + # - python2 get.py + # - popd # esp32 needs WebServer_tng for now - - git clone https://github.com/bbx10/WebServer_tng.git /usr/local/share/arduino/libraries/WebServer_tng + # - git clone https://github.com/bbx10/WebServer_tng.git /usr/local/share/arduino/libraries/WebServer_tng script: - "echo $PWD" - "echo $HOME" - "ls $PWD" - source $TRAVIS_BUILD_DIR/travis/common.sh - - arduino --board esp8266:esp8266:generic:CpuFrequency=80,CrystalFreq=26,FlashFreq=40,FlashMode=qio,FlashSize=4M1M,led=2,LwIPVariant=v2mss536,Debug=Serial,DebugLevel=CORE --save-prefs + - arduino --board esp8266:esp8266:generic:xtal=80,eesz=4M1M,FlashMode=qio,FlashFreq=80,dbg=Serial,lvl=CORE --save-prefs - build_examples - - arduino --board espressif:esp32:esp32doit-devkit-v1:FlashFreq=80,DebugLevel=info --save-prefs + - arduino --board esp32:esp32:esp32:FlashFreq=80,FlashSize=4M,DebugLevel=info --save-prefs # some examples fail (SPIFFS defines differ esp32 vs esp8266) so we exclude them - build_examples # - arduino -v --verbose-build --verify $PWD/examples/AutoConnect/AutoConnect.ino diff --git a/README.md b/README.md index 7e53338..fb03403 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -## Current development going on here :arrow_right: [Development Branch](https://github.com/tzapu/WiFiManager/tree/development) # WiFiManager ESP8266 WiFi Connection manager with fallback web configuration portal diff --git a/WiFiManager.cpp b/WiFiManager.cpp index 66c5631..95d5496 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -12,6 +12,8 @@ #include "WiFiManager.h" +#if defined(ESP8266) || defined(ESP32) + #ifdef ESP32 uint8_t WiFiManager::_lastconxresulttmp = WL_IDLE_STATUS; #endif @@ -195,7 +197,7 @@ void WiFiManager::WiFiManagerInit(){ WiFiManager::~WiFiManager() { _end(); // parameters - // @todo belongs to wifimanagerparameter + // @todo below belongs to wifimanagerparameter if (_params != NULL){ DEBUG_WM(DEBUG_DEV,F("freeing allocated params!")); free(_params); @@ -212,6 +214,7 @@ WiFiManager::~WiFiManager() { void WiFiManager::_begin(){ if(_hasBegun) return; + _hasBegun = true; _usermode = WiFi.getMode(); #ifndef ESP32 @@ -228,7 +231,7 @@ void WiFiManager::_end(){ // AUTOCONNECT boolean WiFiManager::autoConnect() { - String ssid = _wifissidprefix + "_" + String(WIFI_getChipId(),HEX); + String ssid = getDefaultAPName(); return autoConnect(ssid.c_str(), NULL); } @@ -357,30 +360,35 @@ bool WiFiManager::startAP(){ } //@todo add callback here if needed to modify ap but cannot use setAPStaticIPConfig + //@todo rework wifi channelsync as it will work unpredictably when not connected in sta + + int32_t channel = 0; + if(_channelSync) channel = WiFi.channel(); + else channel = _apChannel; - if(_channelSync){ - DEBUG_WM(DEBUG_VERBOSE,"Starting AP on channel:",WiFi.channel()); + if(channel>0){ + DEBUG_WM(DEBUG_VERBOSE,"Starting AP on channel:",channel); } // start soft AP with password or anonymous if (_apPassword != "") { - if(_channelSync){ - ret = WiFi.softAP(_apName.c_str(), _apPassword.c_str(),WiFi.channel()); + if(channel>0){ + ret = WiFi.softAP(_apName.c_str(), _apPassword.c_str(),channel); } else{ ret = WiFi.softAP(_apName.c_str(), _apPassword.c_str());//password option } } else { DEBUG_WM(DEBUG_VERBOSE,F("AP has anonymous access!")); - if(_channelSync){ - ret = WiFi.softAP(_apName.c_str(),"",WiFi.channel()); + if(channel>0){ + ret = WiFi.softAP(_apName.c_str(),"",channel); } else{ ret = WiFi.softAP(_apName.c_str()); } } - if(_debugLevel > DEBUG_DEV) debugSoftAPConfig(); + if(_debugLevel >= DEBUG_DEV) debugSoftAPConfig(); if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] There was a problem starting the AP"); // @todo add softAP retry here @@ -500,7 +508,7 @@ void WiFiManager::setupConfigPortal() { } boolean WiFiManager::startConfigPortal() { - String ssid = _wifissidprefix + "_" + String(WIFI_getChipId(),HEX); + String ssid = getDefaultAPName(); return startConfigPortal(ssid.c_str(), NULL); } @@ -518,7 +526,10 @@ boolean WiFiManager::startConfigPortal(char const *apName, char const *apPasswo _apName = apName; // @todo check valid apname ? _apPassword = apPassword; - if(_apName == "") _apName = _wifissidprefix + "_" + String(WIFI_getChipId(),HEX); + DEBUG_WM(DEBUG_VERBOSE,F("Starting Config Portal")); + + if(_apName == "") _apName = getDefaultAPName(); + if(!validApPassword()) return false; // HANDLE issues with STA connections, shutdown sta if not connected, or else this will hang channel scanning and softap will not respond @@ -769,7 +780,9 @@ uint8_t WiFiManager::connectWifi(String ssid, String pass) { */ bool WiFiManager::wifiConnectNew(String ssid, String pass){ bool ret = false; - DEBUG_WM(F("Connecting to new AP:"),ssid); + DEBUG_WM(F("CONNECTED:"),WiFi.status() == WL_CONNECTED); + DEBUG_WM(F("Connecting to NEW AP:"),ssid); + DEBUG_WM(DEBUG_DEV,F("Using Password:"),pass); WiFi_enableSTA(true,storeSTAmode); // storeSTAmode will also toggle STA on in default opmode (persistent) if true (default) WiFi.persistent(true); ret = WiFi.begin(ssid.c_str(), pass.c_str()); @@ -785,7 +798,8 @@ bool WiFiManager::wifiConnectNew(String ssid, String pass){ */ bool WiFiManager::wifiConnectDefault(){ bool ret = false; - DEBUG_WM(F("Connecting to saved AP:"),WiFi_SSID()); + DEBUG_WM(F("Connecting to SAVED AP:"),WiFi_SSID(true)); + DEBUG_WM(DEBUG_DEV,F("Using Password:"),WiFi_psk(true)); ret = WiFi_enableSTA(true,storeSTAmode); if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] wifi enableSta failed"); ret = WiFi.begin(); @@ -800,10 +814,12 @@ bool WiFiManager::wifiConnectDefault(){ * @return bool success */ bool WiFiManager::setSTAConfig(){ + DEBUG_WM(F("STA static IP:"),_sta_static_ip); bool ret = true; if (_sta_static_ip) { + DEBUG_WM(DEBUG_VERBOSE,F("Custom static IP/GW/Subnet/DNS")); if(_sta_static_dns) { - DEBUG_WM(DEBUG_VERBOSE,F("Custom STA IP/GW/Subnet/DNS")); + DEBUG_WM(DEBUG_VERBOSE,F("Custom static DNS")); ret = WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn, _sta_static_dns); } else { @@ -934,7 +950,7 @@ void WiFiManager::handleRoot() { server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length())); server->send(200, FPSTR(HTTP_HEAD_CT), page); // server->close(); // testing reliability fix for content length mismatches during mutiple flood hits WiFi_scanNetworks(); // preload wifiscan - if(_preloadwifiscan) WiFi_scanNetworks((unsigned)20000,true); // preload wifiscan throttled, async + if(_preloadwifiscan) WiFi_scanNetworks(_scancachetime,true); // preload wifiscan throttled, async // @todo buggy, captive portals make a query on every page load, causing this to run every time in addition to the real page load // I dont understand why, when you are already in the captive portal, I guess they want to know that its still up and not done or gone // if we can detect these and ignore them that would be great, since they come from the captive portal redirect maybe there is a refferer @@ -1046,17 +1062,18 @@ bool WiFiManager::WiFi_scanNetworks(bool force,bool async){ if(force || _numNetworks == 0 || (millis()-_lastscan > 60000)){ int8_t res; _startscan = millis(); - if(async){ - DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC started")); + if(async && _asyncScan){ #ifdef ESP8266 - #ifndef WM_NOASYNC // no async available < 2.4.0 - using namespace std::placeholders; // for `_1` - WiFi.scanNetworksAsync(std::bind(&WiFiManager::WiFi_scanComplete,this,_1)); + #ifndef WM_NOASYNC // no async available < 2.4.0 + DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC started")); + using namespace std::placeholders; // for `_1` + WiFi.scanNetworksAsync(std::bind(&WiFiManager::WiFi_scanComplete,this,_1)); + #else + res = WiFi.scanNetworks(); + #endif #else - res = WiFi.scanNetworks(); - #endif - #else - res = WiFi.scanNetworks(true); + DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC started")); + res = WiFi.scanNetworks(true); #endif return false; } @@ -1160,7 +1177,7 @@ String WiFiManager::WiFiManager::getScanItemOut(){ if(tok_e) item.replace(FPSTR(T_e), encryptionTypeStr(enc_type)); if(tok_r) item.replace(FPSTR(T_r), (String)rssiperc); // rssi percentage 0-100 if(tok_R) item.replace(FPSTR(T_R), (String)WiFi.RSSI(indices[i])); // rssi db - if(tok_q) item.replace(FPSTR(T_q), (String)round(map(rssiperc,0,100,1,4))); //quality icon 1-4 + if(tok_q) item.replace(FPSTR(T_q), (String)int(round(map(rssiperc,0,100,1,4)))); //quality icon 1-4 if(tok_i){ if (enc_type != WM_WIFIOPEN) { item.replace(FPSTR(T_i), F("l")); @@ -1982,6 +1999,7 @@ void WiFiManager::setSaveConnectTimeout(unsigned long seconds) { */ void WiFiManager::setDebugOutput(boolean debug) { _debug = debug; + if(_debug && _debugLevel == DEBUG_DEV) debugPlatformInfo(); } /** @@ -2252,6 +2270,14 @@ bool WiFiManager::setHostname(const char * hostname){ return true; } +/** + * set the soft ao channel, ignored if channelsync is true and connected + * @param int32_t wifi channel, 0 to disable + */ +void WiFiManager::setWiFiAPChannel(int32_t channel){ + _apChannel = channel; +} + /** * toggle showing erase wifi config button on info page * @param boolean enabled @@ -2341,6 +2367,14 @@ bool WiFiManager::getWiFiIsSaved(){ return WiFi_hasAutoConnect(); } +String WiFiManager::getDefaultAPName(){ + String hostString = String(WIFI_getChipId(),HEX); + hostString.toUpperCase(); + // char hostString[16] = {0}; + // sprintf(hostString, "%06X", ESP.getChipId()); + return _wifissidprefix + "_" + hostString; +} + /** * setCountry * @since $dev @@ -2357,9 +2391,29 @@ void WiFiManager::setCountry(String cc){ void WiFiManager::setClass(String str){ _bodyClass = str; } - + // HELPERS +/** + * getWiFiSSID + * @since $dev + * @param bool persistent + * @return String + */ +String WiFiManager::getWiFiSSID(bool persistent){ + return WiFi_SSID(persistent); +} + +/** + * getWiFiPass + * @since $dev + * @param bool persistent + * @return String + */ +String WiFiManager::getWiFiPass(bool persistent){ + return WiFi_psk(persistent); +} + // DEBUG // @todo fix DEBUG_WM(0,0); template @@ -2401,13 +2455,17 @@ void WiFiManager::DEBUG_WM(wm_debuglevel_t level,Generic text,Genericb textb) { * @return {[type]} [description] */ void WiFiManager::debugSoftAPConfig(){ + wifi_country_t country; + #ifdef ESP8266 softap_config config; wifi_softap_get_config(&config); + wifi_get_country(&country); #elif defined(ESP32) wifi_config_t conf_config; esp_wifi_get_config(WIFI_IF_AP, &conf_config); // == ESP_OK wifi_ap_config_t config = conf_config.ap; + esp_wifi_get_country(&country); #endif DEBUG_WM(F("SoftAP Configuration")); @@ -2419,6 +2477,7 @@ void WiFiManager::debugSoftAPConfig(){ DEBUG_WM(F("authmode: "),config.authmode); DEBUG_WM(F("ssid_hidden: "),config.ssid_hidden); DEBUG_WM(F("max_connection: "),config.max_connection); + DEBUG_WM(F("country: "),(String)country.cc); DEBUG_WM(F("beacon_interval: "),(String)config.beacon_interval + "(ms)"); DEBUG_WM(FPSTR(D_HR)); } @@ -2531,23 +2590,29 @@ String WiFiManager::getModeString(uint8_t mode){ } bool WiFiManager::WiFiSetCountry(){ + if(_wificountry == "") return false; // skip not set bool ret = false; #ifdef ESP32 - // @todo check if wifi is init, no idea how, doesnt seem to be exposed - if(_wificountry == "") return ret; // skip not set - else if(WiFi.getMode() == WIFI_MODE_NULL); // exception if wifi not init! + // @todo check if wifi is init, no idea how, doesnt seem to be exposed atm ( might be now! ) + if(WiFi.getMode() == WIFI_MODE_NULL); // exception if wifi not init! else if(_wificountry == "US") ret = esp_wifi_set_country(&WM_COUNTRY_US) == ESP_OK; else if(_wificountry == "JP") ret = esp_wifi_set_country(&WM_COUNTRY_JP) == ESP_OK; else if(_wificountry == "CN") ret = esp_wifi_set_country(&WM_COUNTRY_CN) == ESP_OK; else DEBUG_WM(DEBUG_ERROR,"[ERROR] country code not found"); - if(ret) DEBUG_WM(DEBUG_VERBOSE,"esp_wifi_set_country: " + _wificountry); - else DEBUG_WM(DEBUG_ERROR,"[ERROR] esp_wifi_set_country failed"); + #elif defined(ESP8266) + // if(WiFi.getMode() == WIFI_OFF); // exception if wifi not init! + if(_wificountry == "US") ret = wifi_set_country(&WM_COUNTRY_US); + else if(_wificountry == "JP") ret = wifi_set_country(&WM_COUNTRY_JP); + else if(_wificountry == "CN") ret = wifi_set_country(&WM_COUNTRY_CN); + else DEBUG_WM(DEBUG_ERROR,"[ERROR] country code not found"); #endif + + if(ret) DEBUG_WM(DEBUG_VERBOSE,"esp_wifi_set_country: " + _wificountry); + else DEBUG_WM(DEBUG_ERROR,"[ERROR] esp_wifi_set_country failed"); return ret; } - // set mode ignores WiFi.persistent bool WiFiManager::WiFi_Mode(WiFiMode_t m,bool persistent) { bool ret; @@ -2603,7 +2668,8 @@ bool WiFiManager::WiFi_enableSTA(bool enable,bool persistent) { if(enable) { if(persistent) DEBUG_WM(DEBUG_DEV,F("enableSTA PERSISTENT ON")); return WiFi_Mode(newMode,persistent); - } else { + } + else { return WiFi_Mode(newMode,persistent); } } else { @@ -2657,24 +2723,70 @@ uint8_t WiFiManager::WiFi_softap_num_stations(){ } bool WiFiManager::WiFi_hasAutoConnect(){ - return WiFi_SSID() != ""; + return WiFi_SSID(true) != ""; } -String WiFiManager::WiFi_SSID(){ - #ifdef ESP8266 - return WiFi.SSID(); - #elif defined(ESP32) - //@todo , workaround only when not connected +String WiFiManager::WiFi_SSID(bool persistent) const{ + + #ifdef ESP8266 + struct station_config conf; + if(persistent) wifi_station_get_config_default(&conf); + else wifi_station_get_config(&conf); + + char tmp[33]; //ssid can be up to 32chars, => plus null term + memcpy(tmp, conf.ssid, sizeof(conf.ssid)); + tmp[32] = 0; //nullterm in case of 32 char ssid + return String(reinterpret_cast(tmp)); + + #elif defined(ESP32) + if(persistent){ + wifi_config_t conf; + esp_wifi_get_config(WIFI_IF_STA, &conf); + return String(reinterpret_cast(conf.sta.ssid)); + } + else { + if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ + return String(); + } + wifi_ap_record_t info; + if(!esp_wifi_sta_get_ap_info(&info)) { + return String(reinterpret_cast(info.ssid)); + } + return String(); + } + #endif +} + +String WiFiManager::WiFi_psk(bool persistent) const { + #ifdef ESP8266 + struct station_config conf; + + if(persistent) wifi_station_get_config_default(&conf); + else wifi_station_get_config(&conf); + + char tmp[65]; //psk is 64 bytes hex => plus null term + memcpy(tmp, conf.password, sizeof(conf.password)); + tmp[64] = 0; //null term in case of 64 byte psk + return String(reinterpret_cast(tmp)); + + #elif defined(ESP32) + // only if wifi is init + if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ + return String(); + } wifi_config_t conf; esp_wifi_get_config(WIFI_IF_STA, &conf); - return String(reinterpret_cast(conf.sta.ssid)); - #endif + return String(reinterpret_cast(conf.sta.password)); + #endif } #ifdef ESP32 void WiFiManager::WiFiEvent(WiFiEvent_t event,system_event_info_t info){ - if(!_hasBegun) return; - DEBUG_WM(DEBUG_VERBOSE,"[EVENT]",event); + if(!_hasBegun){ + // DEBUG_WM(DEBUG_VERBOSE,"[ERROR] WiFiEvent, not ready"); + return; + } + // DEBUG_WM(DEBUG_VERBOSE,"[EVENT]",event); if(event == SYSTEM_EVENT_STA_DISCONNECTED){ DEBUG_WM(DEBUG_VERBOSE,"[EVENT] WIFI_REASON:",info.disconnected.reason); if(info.disconnected.reason == WIFI_REASON_AUTH_EXPIRE || info.disconnected.reason == WIFI_REASON_AUTH_FAIL){ @@ -2698,6 +2810,7 @@ void WiFiManager::WiFi_autoReconnect(){ WiFi.setAutoReconnect(_wifiAutoReconnect); #elif defined(ESP32) // if(_wifiAutoReconnect){ + // @todo move to seperate method, used for event listener now DEBUG_WM(DEBUG_VERBOSE,"ESP32 event handler enabled"); using namespace std::placeholders; WiFi.onEvent(std::bind(&WiFiManager::WiFiEvent,this,_1,_2)); @@ -2818,3 +2931,5 @@ void WiFiManager::handleUpdateDone() { ESP.restart(); } } +#endif + diff --git a/WiFiManager.h b/WiFiManager.h index 5b49519..2c2d664 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -10,9 +10,12 @@ * @license MIT */ + #ifndef WiFiManager_h #define WiFiManager_h +#if defined(ESP8266) || defined(ESP32) + #ifdef ESP8266 #include #endif @@ -123,7 +126,6 @@ class WiFiManagerParameter { void setValue(const char *defaultValue, int length); protected: - void init(const char *id, const char *label, const char *defaultValue, int length, const char *custom); void init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement); private: @@ -166,6 +168,7 @@ class WiFiManager // get the AP name of the config portal, so it can be used in the callback String getConfigPortalSSID(); + int getRSSIasQuality(int RSSI); // erase wifi credentials void resetSettings(); @@ -253,6 +256,9 @@ class WiFiManager bool setHostname(const char * hostname); // show erase wifi onfig button on info page, true void setShowInfoErase(boolean enabled); + // set ap channel + void setWiFiAPChannel(int32_t channel); + // set custom menu // set custom menu items and order @@ -267,6 +273,11 @@ class WiFiManager // check if the module has a saved ap to connect to bool getWiFiIsSaved(); + // helper to get saved ssid, if persistent get stored, else get current if connected + String getWiFiPass(bool persistent = false); + // helper to get saved password, if persistent get stored, else get current if connected + String getWiFiSSID(bool persistent = false); + // debug output the softap config void debugSoftAPConfig(); // debug output platform info and versioning @@ -277,7 +288,8 @@ class WiFiManager void setCountry(String cc); // set body class (invert) void setClass(String str); - + String getDefaultAPName(); + std::unique_ptr dnsServer; #if defined(ESP32) && defined(WM_WEBSERVERSHIM) @@ -326,7 +338,8 @@ class WiFiManager bool _disableSTA = false; // disable sta when starting ap, always bool _disableSTAConn = true; // disable sta when starting ap, if sta is not connected ( stability ) - bool _channelSync = false; // use wifi channel when starting ap + bool _channelSync = false; // use same wifi sta channel when starting ap + int32_t _apChannel = 0; // channel to use for ap #ifdef ESP32 static uint8_t _lastconxresulttmp; // tmp var for esp32 callback @@ -338,8 +351,8 @@ class WiFiManager // parameter options int _minimumQuality = -1; // filter wifiscan ap by this rssi - int _staShowStaticFields = 0; // ternary always show static ip fields, only if not set in code, never(cannot change ips via web!) - int _staShowDns = 0; // ternary always show dns, only if not set in code, never(cannot change dns via web!) + int _staShowStaticFields = 0; // ternary 1=always show static ip fields, 0=only if set, -1=never(cannot change ips via web!) + int _staShowDns = 0; // ternary 1=always show dns, 0=only if set, -1=never(cannot change dns via web!) boolean _removeDuplicateAPs = true; // remove dup aps from wifiscan boolean _shouldBreakAfterConfig = false; // stop configportal on save failure boolean _configPortalIsBlocking = true; // configportal enters blocking loop @@ -359,7 +372,9 @@ class WiFiManager // internal options boolean _preloadwifiscan = true; // preload wifiscan if true - boolean _disableIpFields = false; // edge case, if true, showxFields(false) forces ip fields off instead of default show when set + boolean _asyncScan = false; + unsigned int _scancachetime = 30000; // ms cache time for background scans + boolean _disableIpFields = false; // modify function of setShow_X_Fields(false), forces ip fields off instead of default show if set, eg. _staShowStaticFields=-1 String _wificountry = ""; // country code, @todo define in strings lang @@ -425,7 +440,8 @@ class WiFiManager uint8_t WiFi_softap_num_stations(); bool WiFi_hasAutoConnect(); void WiFi_autoReconnect(); - String WiFi_SSID(); + String WiFi_SSID(bool persistent = false) const; + String WiFi_psk(bool persistent = false) const; bool WiFi_scanNetworks(); bool WiFi_scanNetworks(bool force,bool async); bool WiFi_scanNetworks(unsigned int cachetime,bool async); @@ -445,7 +461,6 @@ class WiFiManager String getHTTPHead(String title); String getMenuOut(); //helpers - int getRSSIasQuality(int RSSI); boolean isIp(String str); String toStringIp(IPAddress ip); boolean validApPassword(); @@ -512,3 +527,5 @@ class WiFiManager }; #endif + +#endif \ No newline at end of file diff --git a/examples/Advanced/Advanced.ino b/examples/Advanced/Advanced.ino index 267bcbb..6e4ff73 100644 --- a/examples/Advanced/Advanced.ino +++ b/examples/Advanced/Advanced.ino @@ -10,6 +10,7 @@ WiFiManager wm; // global wm instance WiFiManagerParameter custom_field; // global param ( for non blocking w params ) void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP Serial.begin(115200); Serial.setDebugOutput(true); delay(3000); diff --git a/examples/AutoConnect/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino b/examples/AutoConnect/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino index 35b32ed..6b1a7af 100644 --- a/examples/AutoConnect/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino +++ b/examples/AutoConnect/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino @@ -77,6 +77,7 @@ void setupSpiffs(){ } void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); Serial.println(); diff --git a/examples/AutoConnect/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino b/examples/AutoConnect/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino index 532ceec..ba46843 100644 --- a/examples/AutoConnect/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino +++ b/examples/AutoConnect/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino @@ -5,7 +5,12 @@ //for LED status #include Ticker ticker; -int LED = BUILTIN_LED; + +#ifndef LED_BUILTIN +#define LED_BUILTIN 13 // ESP32 DOES NOT DEFINE LED_BUILTIN +#endif + +int LED = LED_BUILTIN; void tick() { @@ -24,6 +29,7 @@ void configModeCallback (WiFiManager *myWiFiManager) { } void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); diff --git a/examples/Basic/Basic.ino b/examples/Basic/Basic.ino index 26ec6d4..daaee37 100644 --- a/examples/Basic/Basic.ino +++ b/examples/Basic/Basic.ino @@ -1,12 +1,16 @@ #include // https://github.com/tzapu/WiFiManager void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP + // put your setup code here, to run once: Serial.begin(115200); + + // WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it. //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm; - + //reset settings - wipe credentials for testing //wm.resetSettings(); diff --git a/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino b/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino index 6d32e23..3b6419e 100644 --- a/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino +++ b/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino @@ -1,5 +1,7 @@ /** * This is a kind of unit test for DEV for now + * It contains many of the public methods + * */ #include // https://github.com/tzapu/WiFiManager #include @@ -7,6 +9,56 @@ #define TRIGGER_PIN 0 const char* modes[] = { "NULL", "STA", "AP", "STA+AP" }; +unsigned long mtime = 0; + +// // #define MYOLED + +// #include +// #include +// #include +// #ifdef MYOLED + +// #define SCREEN_WIDTH 128 // OLED display width, in pixels +// #define SCREEN_HEIGHT 32 // OLED display height, in pixels + +// // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) +// #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) +// Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + +// void init_oled(){ +// Wire.begin(SCL,SDA); // begin(sda, scl) SWAP! +// // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally +// if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 +// Serial.println(F("SSD1306 allocation failed")); +// } + +// display.clearDisplay(); +// display.setTextSize(1); // Normal 1:1 pixepl scale +// display.setTextColor(WHITE); // Draw white text +// display.setCursor(0,0); // Start at top-left corner +// display.display(); +// } + +// void print_oled(String str,uint8_t size){ +// display.clearDisplay(); +// display.setTextSize(size); +// display.setTextColor(WHITE); +// display.setCursor(0,0); +// display.println(str); +// display.display(); +// } +// #else +// void print_oled(String str,uint8_t size){ +// (void)str; +// (void)size; +// } +// #endif + +void print_oled(String str,uint8_t size){ + (void)str; + (void)size; +} + WiFiManager wm; bool TEST_CP = false; // always start the configportal bool TEST_NET = true; // do a network test, get ntp time @@ -20,6 +72,9 @@ void saveWifiCallback(){ //gets called when WiFiManager enters configuration mode void configModeCallback (WiFiManager *myWiFiManager) { Serial.println("[CALLBACK] configModeCallback fired"); + #ifdef ESP8266 + print_oled("WiFiManager Waiting\nIP: " + WiFi.softAPIP().toString() + "\nSSID: " + WiFi.softAPSSID(),1); + #endif // myWiFiManager->setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); // Serial.println(WiFi.softAPIP()); //if you used auto generated SSID, print it @@ -42,13 +97,18 @@ void handleRoute(){ } void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); - Serial.setDebugOutput(true); + // Serial.setDebugOutput(true); // delay(3000); Serial.println("\n Starting"); // WiFi.setSleepMode(WIFI_NONE_SLEEP); // disable sleep, can improve ap stability + #ifdef OLED + init_oled(); + #endif + print_oled(F("Starting..."),2); wm.debugPlatformInfo(); //Local intialization. Once its business is done, there is no need to keep it around @@ -72,6 +132,9 @@ void setup() { 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}'"); // custom input attrs (ip mask) + const char _customHtml_checkbox[] = "type=\"checkbox\""; + WiFiManagerParameter custom_checkbox("checkbox", "my checkbox", "T", 2, _customHtml_checkbox, WFM_LABEL_AFTER); + // callbacks wm.setAPCallback(configModeCallback); wm.setWebServerCallback(bindServerCallback); @@ -85,6 +148,7 @@ void setup() { wm.addParameter(&custom_token); wm.addParameter(&custom_tokenb); wm.addParameter(&custom_ipaddress); + wm.addParameter(&custom_checkbox); custom_html.setValue("test",4); custom_token.setValue("test",4); @@ -105,15 +169,14 @@ void setup() { // wm.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); // wm.setAPStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); - // WiFi.mode(WIFI_STA); - // const wifi_country_t COUNTRY_US{"US",1,11,WIFI_COUNTRY_POLICY_AUTO}; - // const wifi_country_t COUNTRY_CN{"CN",1,13,WIFI_COUNTRY_POLICY_AUTO}; - // const wifi_country_t COUNTRY_JP{"JP",1,14,WIFI_COUNTRY_POLICY_AUTO}; - // esp_wifi_set_country(&COUNTRY_US); - - // wm.setCountry("US"); + // set country + wm.setCountry("US"); // setting wifi country seems to improve OSX soft ap connectivity, may help others as well - // wm.setConfigPortalTimeout(120); + // set channel + wm.setWiFiAPChannel(13); + + // set configrportal timeout + wm.setConfigPortalTimeout(120); // wm.startConfigPortal("AutoConnectAP", "password"); //fetches ssid and pass and tries to connect @@ -121,10 +184,14 @@ void setup() { //here "AutoConnectAP" //and goes into a blocking loop awaiting configuration + print_oled(F("Connecting..."),2); if(!wm.autoConnect("AutoConnectAP")) { Serial.println("failed to connect and hit timeout"); + print_oled("Not Connected",2); } else if(TEST_CP) { + delay(1000); + Serial.println("TEST_CP ENABLED"); // start configportal always wm.setConfigPortalTimeout(60); wm.startConfigPortal(); @@ -132,6 +199,7 @@ void setup() { else { //if you get here you have connected to the WiFi Serial.println("connected...yeey :)"); + print_oled("Connected\nIP: " + WiFi.localIP().toString() + "\nSSID: " + WiFi.SSID(),1); } pinMode(TRIGGER_PIN, INPUT); } @@ -139,25 +207,33 @@ void setup() { void loop() { // is configuration portal requested? if ( digitalRead(TRIGGER_PIN) == LOW ) { - Serial.println("BUTTON PRESSED"); - wm.setConfigPortalTimeout(120); + delay(100); + if ( digitalRead(TRIGGER_PIN) == LOW ){ + Serial.println("BUTTON PRESSED"); + wm.setConfigPortalTimeout(140); - // disable captive portal redirection - // wm.setCaptivePortalEnable(false); - - if (!wm.startConfigPortal("OnDemandAP")) { - Serial.println("failed to connect and hit timeout"); - delay(3000); - } else { + // disable captive portal redirection + // wm.setCaptivePortalEnable(false); + + if (!wm.startConfigPortal("OnDemandAP","12345678")) { + Serial.println("failed to connect and hit timeout"); + delay(3000); + } + } + else { //if you get here you have connected to the WiFi Serial.println("connected...yeey :)"); + print_oled("Connected\nIP: " + WiFi.localIP().toString() + "\nSSID: " + WiFi.SSID(),1); getTime(); } } - if(WiFi.status() == WL_CONNECTED) getTime(); + if(WiFi.status() == WL_CONNECTED && millis()-mtime > 10000 ){ + getTime(); + mtime = millis(); + } // put your main code here, to run repeatedly: - delay(5000); + delay(100); } void getTime() { @@ -175,7 +251,7 @@ void getTime() { if((millis() - start) > timeout){ Serial.println("[ERROR] Failed to get NTP time."); return; - } + } } Serial.println(""); struct tm timeinfo; diff --git a/examples/NonBlocking/AutoConnectNonBlocking/AutoConnectNonBlocking.ino b/examples/NonBlocking/AutoConnectNonBlocking/AutoConnectNonBlocking.ino index 3187bec..fa04d91 100644 --- a/examples/NonBlocking/AutoConnectNonBlocking/AutoConnectNonBlocking.ino +++ b/examples/NonBlocking/AutoConnectNonBlocking/AutoConnectNonBlocking.ino @@ -2,6 +2,7 @@ WiFiManager wm; void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); diff --git a/examples/NonBlocking/AutoConnectNonBlockingwParams/AutoConnectNonBlockingwParams.ino b/examples/NonBlocking/AutoConnectNonBlockingwParams/AutoConnectNonBlockingwParams.ino index f5d4881..3af79f0 100644 --- a/examples/NonBlocking/AutoConnectNonBlockingwParams/AutoConnectNonBlockingwParams.ino +++ b/examples/NonBlocking/AutoConnectNonBlockingwParams/AutoConnectNonBlockingwParams.ino @@ -3,6 +3,7 @@ WiFiManager wm; WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "", 40); void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); diff --git a/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino b/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino index ef8e1eb..7ebd8d5 100644 --- a/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino +++ b/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino @@ -14,9 +14,10 @@ WiFiManager wm; unsigned int timeout = 120; // seconds to run for unsigned int startTime = millis(); bool portalRunning = false; -bool startCP = false; // start AP and webserver if true, else start only webserver +bool startAP = false; // start AP and webserver if true, else start only webserver void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once Serial.begin(115200); Serial.println("\n Starting"); @@ -35,7 +36,7 @@ void doWiFiManager(){ if((millis()-startTime) > (timeout*1000)){ Serial.println("portaltimeout"); portalRunning = false; - if(startCP){ + if(startAP){ wm.stopConfigPortal(); } else{ @@ -46,7 +47,7 @@ void doWiFiManager(){ // is configuration portal requested? if(digitalRead(TRIGGER_PIN) == LOW && (!portalRunning)) { - if(startCP){ + if(startAP){ Serial.println("Button Pressed, Starting Config Portal"); wm.setConfigPortalBlocking(false); wm.startConfigPortal(); diff --git a/examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino b/examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino index e9252c3..a352b38 100644 --- a/examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino +++ b/examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino @@ -12,6 +12,7 @@ int timeout = 120; // seconds to run for void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once: Serial.begin(115200); Serial.println("\n Starting"); diff --git a/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino b/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino index d3cbe3f..7b6676a 100644 --- a/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino +++ b/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino @@ -12,6 +12,7 @@ WiFiManager wm; bool portalRunning = false; void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP // put your setup code here, to run once Serial.begin(115200); Serial.println("\n Starting"); diff --git a/examples/ParamsChildClass/ParamsChildClass.ino b/examples/ParamsChildClass/ParamsChildClass.ino index c5d991a..0117d77 100644 --- a/examples/ParamsChildClass/ParamsChildClass.ino +++ b/examples/ParamsChildClass/ParamsChildClass.ino @@ -52,8 +52,9 @@ struct Settings { void setup() { + WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP pinMode(SETUP_PIN, INPUT_PULLUP); - Serial.begin(9600); + Serial.begin(115200); //Delay to push SETUP button Serial.println("Press setup button"); diff --git a/extras/WiFiManager.template.html b/extras/WiFiManager.template.html index fffb888..07ba834 100644 --- a/extras/WiFiManager.template.html +++ b/extras/WiFiManager.template.html @@ -166,11 +166,18 @@ button.D{ background-color:#dc3630; } +input:disabled { + opacity: 0.5; +} + @@ -253,7 +260,7 @@ button.D{
AP not found - +
Could not Connect diff --git a/extras/test.html b/extras/test.html index 1a77214..0789e49 100644 --- a/extras/test.html +++ b/extras/test.html @@ -11,11 +11,12 @@ // preventDefault(); document.getElementById('s').value = l.innerText || l.textContent; // document.location.href = document.location +"#wmform"; - document.getElementById('p').focus(); + p = l.nextElementSibling.classList.contains("l"); + document.getElementById('p').disabled = !p; + if(p)document.getElementById('p').focus(); return false; } - diff --git a/strings_en.h b/strings_en.h index e0715bf..2936b2c 100644 --- a/strings_en.h +++ b/strings_en.h @@ -10,11 +10,20 @@ * @license MIT */ +#ifndef _WM_STRINGS_H_ +#define _WM_STRINGS_H_ + #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_SCRIPT[] PROGMEM = ""; +const char HTTP_HEAD_START[] PROGMEM = "{v}"; +const char HTTP_SCRIPT[] PROGMEM = ""; + const char HTTP_HEAD_END[] PROGMEM = "
"; const char HTTP_ROOT_MAIN[] PROGMEM = "

{v}

WiFiManager

"; @@ -87,6 +96,7 @@ const char HTTP_STYLE[] PROGMEM = ""; const char HTTP_HELP[] PROGMEM = @@ -333,8 +343,29 @@ const char * const AUTH_MODE_NAMES[] PROGMEM const char* const WIFI_MODES[] PROGMEM = { "NULL", "STA", "AP", "STA+AP" }; + #ifdef ESP32 -const wifi_country_t WM_COUNTRY_US{"US",1,11,WIFI_COUNTRY_POLICY_AUTO}; -const wifi_country_t WM_COUNTRY_CN{"CN",1,13,WIFI_COUNTRY_POLICY_AUTO}; -const wifi_country_t WM_COUNTRY_JP{"JP",1,14,WIFI_COUNTRY_POLICY_AUTO}; +// as 2.5.2 +// typedef struct { +// char cc[3]; /**< country code string */ +// uint8_t schan; /**< start channel */ +// uint8_t nchan; /**< total channel number */ +// int8_t max_tx_power; /**< This field is used for getting WiFi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. */ +// wifi_country_policy_t policy; /**< country policy */ +// } wifi_country_t; +const wifi_country_t WM_COUNTRY_US{"US",1,11,CONFIG_ESP32_PHY_MAX_TX_POWER,WIFI_COUNTRY_POLICY_AUTO}; +const wifi_country_t WM_COUNTRY_CN{"CN",1,13,CONFIG_ESP32_PHY_MAX_TX_POWER,WIFI_COUNTRY_POLICY_AUTO}; +const wifi_country_t WM_COUNTRY_JP{"JP",1,14,CONFIG_ESP32_PHY_MAX_TX_POWER,WIFI_COUNTRY_POLICY_AUTO}; +#elif defined(ESP8266) +// typedef struct { +// char cc[3]; /**< country code string */ +// uint8_t schan; /**< start channel */ +// uint8_t nchan; /**< total channel number */ +// uint8_t policy; /**< country policy */ +// } wifi_country_t; +static wifi_country_t WM_COUNTRY_US{"US",1,11,WIFI_COUNTRY_POLICY_AUTO}; +static wifi_country_t WM_COUNTRY_CN{"CN",1,13,WIFI_COUNTRY_POLICY_AUTO}; +static wifi_country_t WM_COUNTRY_JP{"JP",1,14,WIFI_COUNTRY_POLICY_AUTO}; #endif + +#endif \ No newline at end of file