From 64d6c9f209e926d94f192df0b1a546e2a85dab27 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Tue, 8 Feb 2022 20:57:03 +0900 Subject: [PATCH 01/20] Describes how to select the correct partition to enable OTA. --- mkdocs/otabrowser.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mkdocs/otabrowser.md b/mkdocs/otabrowser.md index 6daef2ab..61dd0a7e 100644 --- a/mkdocs/otabrowser.md +++ b/mkdocs/otabrowser.md @@ -161,6 +161,20 @@ Binary sketch files for updating can be retrieved using the Arduino IDE. Open th When the compilation is complete, a binary sketch will save with the extension `.bin` in the same folder as the Sketch. +### Select a partition scheme to enable OTA w/ESP32 + +To enable OTA on the ESP32, you need to build a sketch with a partition scheme that has reserved a binary sketch space for OTA. The ESP32 Arduino core comes with a variety of [pre-configured partition schemes](https://github.com/espressif/arduino-esp32/tree/master/tools/partitions) that can be selected from the **Tools** menu in the Arduino IDE. + +![partition](images/partition.png) + +In most cases, this is simply a matter of selecting a built-in partition scheme with a reserved OTA area from the **Tools** menu in the Arduino IDE. However, Of the various ESP32-based modules, only a few have many partition schemes pre-configured. If you cannot find a partition scheme with reserved OTA space for your ESP32 module, you will need to modify [`boards.txt`](https://github.com/espressif/arduino-esp32/blob/master/boards.txt) as the board configuration file included in the ESP32Arduino core distribution. The [WebCamServer.ino](https://github.com/Hieromon/AutoConnect/tree/master/examples/WebCamServer) example in the AutoConnect library shows the changes to boards.txt for esp32cam. But this modification is not recommended as it can inadvertently destroy the board configuration and will be overwritten and restored by the Arduino core version upstreams. + +Another way to choose a partition scheme is to use [PlatformIO](https://platformio.org/platformio-ide) for your build system. You can easily select the reserved partition scheme for the OTA area using PlatformIO. When using PlatformIO, you can select a partition scheme with OTA reserved space by simply writing the following line in the [`platformio.ini`](https://docs.platformio.org/en/latest/platforms/espressif32.html?highlight=partition#partition-tables) file. + +```ini +board_build.partitions = min_spiffs.csv +``` + ### OTA updates w/browser without using AutoConnectOTA The legacy OTA method based on ESP8266HTTPUpdateServer without AutoConnectOTA is still valid. To embed the ESP8266HTTPUpdateServer class with AutoConnect into your sketch, basically follow these steps: From d4e3f434f5000472fd51f373b81e1299b3ab20a9 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 10 Feb 2022 01:07:45 +0900 Subject: [PATCH 02/20] Add the ability to delete a credential --- src/AutoConnect.cpp | 41 +++++++++++++++++++++++-- src/AutoConnect.h | 8 +++-- src/AutoConnectDefs.h | 5 +-- src/AutoConnectLabels.h | 9 ++++-- src/AutoConnectPage.cpp | 67 +++++++++++++++++++++++++++++++++-------- src/AutoConnectTypes.h | 7 +++-- 6 files changed, 113 insertions(+), 24 deletions(-) diff --git a/src/AutoConnect.cpp b/src/AutoConnect.cpp index 42367009..820cfde9 100644 --- a/src/AutoConnect.cpp +++ b/src/AutoConnect.cpp @@ -2,8 +2,8 @@ * AutoConnect class implementation. * @file AutoConnect.cpp * @author hieromon@gmail.com - * @version 1.3.2 - * @date 2021-11-19 + * @version 1.3.4 + * @date 2022-02-09 * @copyright MIT license. */ @@ -1400,6 +1400,43 @@ String AutoConnect::_invokeResult(PageArgument& args) { return _emptyString; } +/** + * Perform interactive deletion of stored credentials available in the + * OPEN SSIDs menu, in the handler of the page request. + * Having performed the credential deletion, this handler will eventually + * respond as the deletion result by redirecting to the URL of the SSIDs list. + * + */ +String AutoConnect::_promptDeleteCredential(PageArgument& args) { + AutoConnectCredential credt; + + _indelibleSSID = args.arg("del"); + if (_indelibleSSID.length()) { + if (credt.del(_indelibleSSID.c_str())) { + AC_DBG("%s has been deleted\n", _indelibleSSID.c_str()); + _indelibleSSID.clear(); + } + } + String redirect = String(F("http://")); +#if defined(ARDUINO_ARCH_ESP32) + // In ESP32, the station IP address just established could not be reached. + redirect += _webServer->client().localIP().toString(); +#elif defined(ARDUINO_ARCH_ESP8266) + // In ESP8266, the host address that responds for the connection + // successful is the IP address of ESP8266 as a station. + // This is the specification as before. + redirect += _currentHostIP.toString(); +#endif + // Redirect to + redirect += String(F(AUTOCONNECT_URI_OPEN)); + _webServer->sendHeader(String(F("Location")), redirect, true); + _webServer->send(302, String(F("text/plain")), _emptyString); + _webServer->client().stop(); + _waitForEndTransmission(); + _responsePage->cancel(); + return _emptyString; +} + /** * Classify the requested URI to responsive page builder. * There is always only one PageBuilder instance that can exist in diff --git a/src/AutoConnect.h b/src/AutoConnect.h index 731a6a40..7e9f383d 100644 --- a/src/AutoConnect.h +++ b/src/AutoConnect.h @@ -2,8 +2,8 @@ * Declaration of AutoConnect class and accompanying AutoConnectConfig class. * @file AutoConnect.h * @author hieromon@gmail.com - * @version 1.3.1 - * @date 2021-10-07 + * @version 1.3.4 + * @date 2022-02-09 * @copyright MIT license. */ @@ -320,6 +320,7 @@ class AutoConnect { String _induceDisconnect(PageArgument& args); String _induceReset(PageArgument& args); String _invokeResult(PageArgument& args); + String _promptDeleteCredential(PageArgument& args); /** For portal control */ bool _captivePortal(void); @@ -378,6 +379,7 @@ class AutoConnect { uint8_t _connectCh; unsigned long _portalAccessPeriod; unsigned long _attemptPeriod; + String _indelibleSSID; /** The control indicators */ bool _rfAdHocBegin = false; /**< Specified with AutoConnect::begin */ @@ -402,6 +404,7 @@ class AutoConnect { static const char _CSS_LUXBAR[] PROGMEM; static const char _CSS_UL[] PROGMEM; static const char _CSS_ICON_LOCK[] PROGMEM; + static const char _CSS_ICON_TRASH[] PROGMEM; static const char _CSS_INPUT_BUTTON[] PROGMEM; static const char _CSS_INPUT_TEXT[] PROGMEM; static const char _CSS_TABLE[] PROGMEM; @@ -423,6 +426,7 @@ class AutoConnect { /** Token handlers for PageBuilder */ String _token_CSS_BASE(PageArgument& args); String _token_CSS_ICON_LOCK(PageArgument& args); + String _token_CSS_ICON_TRASH(PageArgument& args); String _token_CSS_INPUT_BUTTON(PageArgument& args); String _token_CSS_INPUT_TEXT(PageArgument& args); String _token_CSS_LUXBAR(PageArgument& args); diff --git a/src/AutoConnectDefs.h b/src/AutoConnectDefs.h index a129c06c..1053e99c 100644 --- a/src/AutoConnectDefs.h +++ b/src/AutoConnectDefs.h @@ -2,8 +2,8 @@ * Predefined AutoConnect configuration parameters. * @file AutoConnectDefs.h * @author hieromon@gmail.com - * @version 1.3.0 - * @date 2021-05-27 + * @version 1.3.4 + * @date 2022-02-09 * @copyright MIT license. */ @@ -133,6 +133,7 @@ #define AUTOCONNECT_URI_CONNECT AUTOCONNECT_URI "/connect" #define AUTOCONNECT_URI_RESULT AUTOCONNECT_URI "/result" #define AUTOCONNECT_URI_OPEN AUTOCONNECT_URI "/open" +#define AUTOCONNECT_URI_DELETE AUTOCONNECT_URI "/del" #define AUTOCONNECT_URI_DISCON AUTOCONNECT_URI "/disc" #define AUTOCONNECT_URI_RESET AUTOCONNECT_URI "/reset" #define AUTOCONNECT_URI_SUCCESS AUTOCONNECT_URI "/success" diff --git a/src/AutoConnectLabels.h b/src/AutoConnectLabels.h index 8ee45607..5395a3d9 100644 --- a/src/AutoConnectLabels.h +++ b/src/AutoConnectLabels.h @@ -2,8 +2,8 @@ * AutoConnect proper menu label constant definition. * @file AutoConnectLabels.h * @author hieromon@gmail.com - * @version 1.2.3 - * @date 2021-01-23 + * @version 1.3.4 + * @date 2022-02-09 * @copyright MIT license. */ @@ -432,6 +432,11 @@ #define AUTOCONNECT_PAGETITLE_DISCONNECTED "AutoConnect disconnected" #endif // !AUTOCONNECT_PAGETITLE_DISCONNECTED +// Text: Delete a credential. +#ifndef AUTOCONNECT_TEXT_DELETECREDENTIAL +#define AUTOCONNECT_TEXT_DELETECREDENTIAL "Delete a credential?" +#endif // !AUTOCONNECT_TEXT_DELETECREDENTIAL + // Text: No saved credentials. #ifndef AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS #define AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS "No saved credentials." diff --git a/src/AutoConnectPage.cpp b/src/AutoConnectPage.cpp index d26fe1dc..dc948926 100644 --- a/src/AutoConnectPage.cpp +++ b/src/AutoConnectPage.cpp @@ -2,8 +2,8 @@ * AutoConnect portal site web page implementation. * @file AutoConnectPage.cpp * @author hieromon@gmail.com - * @version 1.3.2 - * @date 2021-11-24 + * @version 1.3.4 + * @date 2022-02-09 * @copyright MIT license. */ @@ -150,6 +150,18 @@ const char AutoConnect::_CSS_ICON_LOCK[] PROGMEM = { "}" }; +/**< Image icon for inline expansion, the trash mark. */ +const char AutoConnect::_CSS_ICON_TRASH[] PROGMEM = { + ".img-trash{" + "width:22px;" + "height:22px;" + "margin-top:14px;" + "float:right;" + "cursor:pointer;" + "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV/TSkUqDnYQcQhSnSyIijpKFYtgobQVWnUwufQLmjQkKS6OgmvBwY/FqoOLs64OroIg+AHi6OSk6CIl/i8ptIjx4Lgf7+497t4BQqPCVDMwDqiaZaTiMTGbWxWDrxAQRAAzGJaYqSfSixl4jq97+Ph6F+VZ3uf+HL1K3mSATySeY7phEW8QT29aOud94jArSQrxOfGYQRckfuS67PIb56LDAs8MG5nUPHGYWCx2sNzBrGSoxFPEEUXVKF/Iuqxw3uKsVmqsdU/+wlBeW0lzneYQ4lhCAkmIkFFDGRVYiNKqkWIiRfsxD/+g40+SSyZXGYwcC6hCheT4wf/gd7dmYXLCTQrFgK4X2/4YAYK7QLNu29/Htt08AfzPwJXW9lcbwOwn6fW2FjkC+raBi+u2Ju8BlzvAwJMuGZIj+WkKhQLwfkbflAP6b4GeNbe31j5OH4AMdbV8AxwcAqNFyl73eHd3Z2//nmn19wONxHKyvZQ4mgAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAN1wAADdcBQiibeAAAALdJREFUOMvt1KEKAkEQBuBPMWkzWsRosWg2WEw2wTfQ6LNYfROLwSxWo81o02LQMsJxcJ4KguD9MOzMv8M/u8PsUqDAf2CMM25h5+CeopSzX8MBa6yCG2KAVhR5S3iDKuohsMcl9qpoR8FT8P20QCVDeIc5ljhm5DQwxeKdvnajn91ELOWnc146cbrIFr2Ik34myt8apUL4N4T3mMWa9J8ib9xG6OCKSXAPv/nJTUrxrG85tsn6Fu6nuijCLc4LEwAAAABJRU5ErkJggg==) no-repeat" + "}" +}; + /**< INPUT button and submit style */ const char AutoConnect::_CSS_INPUT_BUTTON[] PROGMEM = { "input[type=\"button\"],input[type=\"submit\"],button[type=\"submit\"],button[type=\"button\"]{" @@ -159,7 +171,8 @@ const char AutoConnect::_CSS_INPUT_BUTTON[] PROGMEM = { "color:#fff;" "border:1px solid;" "border-radius:2px;" - "margin-top:12px" + "margin-top:12px;" + "cursor:pointer" "}" "input[type=\"button\"],button[type=\"button\"]{" "background-color:#1b5e20;" @@ -174,7 +187,7 @@ const char AutoConnect::_CSS_INPUT_BUTTON[] PROGMEM = { "width:auto" "}" "#sb[type=\"submit\"]{" - "width:15em" + "width:13em" "}" "input[type=\"submit\"],button[type=\"submit\"]{" "padding:8px 30px;" @@ -728,6 +741,7 @@ const char AutoConnect::_PAGE_OPENCREDT[] PROGMEM = { "" @@ -738,11 +752,14 @@ const char AutoConnect::_PAGE_OPENCREDT[] PROGMEM = { "{{MENU_AUX}}" "{{MENU_POST}}" "
" - "
" + "" "{{OPEN_SSID}}" "
" "
" "" + "" "" "" }; @@ -906,6 +923,11 @@ String AutoConnect::_token_CSS_ICON_LOCK(PageArgument& args) { return String(FPSTR(_CSS_ICON_LOCK)); } +String AutoConnect::_token_CSS_ICON_TRASH(PageArgument& args) { + AC_UNUSED(args); + return (_apConfig.menuItems & AC_MENUITEM_DELETESSID) ? String(FPSTR(_CSS_ICON_TRASH)) : String(""); +} + String AutoConnect::_token_CSS_INPUT_BUTTON(PageArgument& args) { AC_UNUSED(args); return String(FPSTR(_CSS_INPUT_BUTTON)); @@ -1158,24 +1180,33 @@ String AutoConnect::_token_NETMASK(PageArgument& args) { String AutoConnect::_token_OPEN_SSID(PageArgument& args) { AC_UNUSED(args); - static const char _ssidList[] PROGMEM = "%s
"; + static const char _ssidUndeleted[] PROGMEM = "
%s could not deleted
"; + static const char _ssidList[] PROGMEM = "%s%s
"; static const char _ssidRssi[] PROGMEM = "%d% Ch.%d"; static const char _ssidNA[] PROGMEM = "N/A"; + static const char _ssidTrsh[] PROGMEM = ""; static const char _ssidLock[] PROGMEM = ""; static const char _ssidNull[] PROGMEM = ""; String ssidList; station_config_t entry; - char slCont[176]; + char slCont[256]; char rssiCont[32]; + char trash[80] = {'\0'}; AutoConnectCredential credit(_apConfig.boundaryOffset); + if (_indelibleSSID.length()) { + char indelible[82]; + + snprintf_P(indelible, sizeof(indelible), _ssidUndeleted, _indelibleSSID.c_str()); + ssidList = String(indelible); + _indelibleSSID.clear(); + } + uint8_t creEntries = credit.entries(); - if (creEntries > 0) { - ssidList = String(""); + if (creEntries > 0) _scanCount = WiFi.scanNetworks(false, true); - } else - ssidList = String(F("

" AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS "

")); + ssidList += String(F("

" AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS "

")); for (uint8_t i = 0; i < creEntries; i++) { rssiCont[0] = '\0'; @@ -1196,7 +1227,9 @@ String AutoConnect::_token_OPEN_SSID(PageArgument& args) { break; } } - snprintf_P(slCont, sizeof(slCont), (PGM_P)_ssidList, AUTOCONNECT_PARAMID_CRED, reinterpret_cast(entry.ssid), rssiSym, ssidLock); + if (_apConfig.menuItems & AC_MENUITEM_DELETESSID) + snprintf_P(trash, sizeof(trash), (PGM_P)_ssidTrsh, reinterpret_cast(entry.ssid)); + snprintf_P(slCont, sizeof(slCont), (PGM_P)_ssidList, AUTOCONNECT_PARAMID_CRED, reinterpret_cast(entry.ssid), rssiSym, trash, ssidLock); ssidList += String(slCont); } return ssidList; @@ -1455,7 +1488,7 @@ PageElement* AutoConnect::_setupPage(String& uri) { elm->addToken(FPSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1)); elm->addToken(FPSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); elm->addToken(FPSTR("CUR_SSID"), std::bind(&AutoConnect::_token_CURRENT_SSID, this, std::placeholders::_1)); - } + } else if (uri == String(AUTOCONNECT_URI_OPEN) && (_apConfig.menuItems & AC_MENUITEM_OPENSSIDS)) { // Setup /_ac/open @@ -1464,6 +1497,7 @@ PageElement* AutoConnect::_setupPage(String& uri) { elm->addToken(FPSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1)); elm->addToken(FPSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, this, std::placeholders::_1)); elm->addToken(FPSTR("CSS_ICON_LOCK"), std::bind(&AutoConnect::_token_CSS_ICON_LOCK, this, std::placeholders::_1)); + elm->addToken(FPSTR("CSS_ICON_TRASH"), std::bind(&AutoConnect::_token_CSS_ICON_TRASH, this, std::placeholders::_1)); elm->addToken(FPSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, this, std::placeholders::_1)); elm->addToken(FPSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, this, std::placeholders::_1)); elm->addToken(FPSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1)); @@ -1471,6 +1505,13 @@ PageElement* AutoConnect::_setupPage(String& uri) { elm->addToken(FPSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); elm->addToken(FPSTR("OPEN_SSID"), std::bind(&AutoConnect::_token_OPEN_SSID, this, std::placeholders::_1)); } + else if (uri == String(AUTOCONNECT_URI_DELETE) && (_apConfig.menuItems & AC_MENUITEM_DELETESSID)) { + + // Setup /_ac/del + reqAuth = true; + elm->setMold(FPSTR("{{DELREQ}}")); + elm->addToken(FPSTR("DELREQ"), std::bind(&AutoConnect::_promptDeleteCredential, this, std::placeholders::_1)); + } else if (uri == String(AUTOCONNECT_URI_DISCON) && (_apConfig.menuItems & AC_MENUITEM_DISCONNECT)) { // Setup /_ac/disc diff --git a/src/AutoConnectTypes.h b/src/AutoConnectTypes.h index c0fc7ac5..06b8f4bb 100644 --- a/src/AutoConnectTypes.h +++ b/src/AutoConnectTypes.h @@ -2,8 +2,8 @@ * AutoConnect quoted type declarations. * @file AutoConnectTypes.h * @author hieromon@gmail.com - * @version 1.3.0 - * @date 2021-09-06 + * @version 1.3.4 + * @date 2022-02-09 * @copyright MIT license. */ @@ -38,7 +38,8 @@ typedef enum AC_MENUITEM { AC_MENUITEM_RESET = 0x0008, AC_MENUITEM_HOME = 0x0010, AC_MENUITEM_UPDATE = 0x0020, - AC_MENUITEM_DEVINFO = 0x0040 + AC_MENUITEM_DEVINFO = 0x0040, + AC_MENUITEM_DELETESSID = 0x0080 } AC_MENUITEM_t; /**< Specifier for using built-in OTA */ From b8d1d3bb8afd30d2c0e6054aebf187ccd953d089 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 10 Feb 2022 01:21:31 +0900 Subject: [PATCH 03/20] Adds a text of credential deletion failure --- src/AutoConnectLabels.h | 7 ++++++- src/AutoConnectPage.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/AutoConnectLabels.h b/src/AutoConnectLabels.h index 5395a3d9..35a4caca 100644 --- a/src/AutoConnectLabels.h +++ b/src/AutoConnectLabels.h @@ -432,11 +432,16 @@ #define AUTOCONNECT_PAGETITLE_DISCONNECTED "AutoConnect disconnected" #endif // !AUTOCONNECT_PAGETITLE_DISCONNECTED -// Text: Delete a credential. +// Text: Delete a credential. #ifndef AUTOCONNECT_TEXT_DELETECREDENTIAL #define AUTOCONNECT_TEXT_DELETECREDENTIAL "Delete a credential?" #endif // !AUTOCONNECT_TEXT_DELETECREDENTIAL +// Text: Could not deleted a credential. +#ifndef AUTOCONNECT_TEXT_COULDNOTDELETED +#define AUTOCONNECT_TEXT_COULDNOTDELETED "could not deleted" +#endif // !AUTOCONNECT_TEXT_COULDNOTDELETED + // Text: No saved credentials. #ifndef AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS #define AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS "No saved credentials." diff --git a/src/AutoConnectPage.cpp b/src/AutoConnectPage.cpp index dc948926..bcec1d94 100644 --- a/src/AutoConnectPage.cpp +++ b/src/AutoConnectPage.cpp @@ -1180,7 +1180,7 @@ String AutoConnect::_token_NETMASK(PageArgument& args) { String AutoConnect::_token_OPEN_SSID(PageArgument& args) { AC_UNUSED(args); - static const char _ssidUndeleted[] PROGMEM = "
%s could not deleted
"; + static const char _ssidUndeleted[] PROGMEM = "
%s " AUTOCONNECT_TEXT_COULDNOTDELETED "
"; static const char _ssidList[] PROGMEM = "%s%s
"; static const char _ssidRssi[] PROGMEM = "%d% Ch.%d"; static const char _ssidNA[] PROGMEM = "N/A"; From f2c47d4136e8bc4cb26583f375fe282f05baab0d Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 16 Feb 2022 16:48:50 +0900 Subject: [PATCH 04/20] Apply authentication to /_ac/reset --- src/AutoConnectPage.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/AutoConnectPage.cpp b/src/AutoConnectPage.cpp index d26fe1dc..4cb471b4 100644 --- a/src/AutoConnectPage.cpp +++ b/src/AutoConnectPage.cpp @@ -2,8 +2,8 @@ * AutoConnect portal site web page implementation. * @file AutoConnectPage.cpp * @author hieromon@gmail.com - * @version 1.3.2 - * @date 2021-11-24 + * @version 1.3.4 + * @date 2022-02-16 * @copyright MIT license. */ @@ -1486,6 +1486,7 @@ PageElement* AutoConnect::_setupPage(String& uri) { else if (uri == String(AUTOCONNECT_URI_RESET) && (_apConfig.menuItems & AC_MENUITEM_RESET)) { // Setup /_ac/reset + reqAuth = true; elm->setMold(FPSTR(_PAGE_RESETTING)); elm->addToken(FPSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, this, std::placeholders::_1)); elm->addToken(FPSTR("BOOTURI"), std::bind(&AutoConnect::_token_BOOTURI, this, std::placeholders::_1)); From 9b5d784cef84d6055b1bf836f833c3e07cfbc517 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 16 Feb 2022 16:52:36 +0900 Subject: [PATCH 05/20] Deactivate the delete credentials function when the OPEN SSIDs menu is disabled. --- src/AutoConnectPage.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/AutoConnectPage.cpp b/src/AutoConnectPage.cpp index bcec1d94..eecf194e 100644 --- a/src/AutoConnectPage.cpp +++ b/src/AutoConnectPage.cpp @@ -3,7 +3,7 @@ * @file AutoConnectPage.cpp * @author hieromon@gmail.com * @version 1.3.4 - * @date 2022-02-09 + * @date 2022-02-16 * @copyright MIT license. */ @@ -187,6 +187,7 @@ const char AutoConnect::_CSS_INPUT_BUTTON[] PROGMEM = { "width:auto" "}" "#sb[type=\"submit\"]{" + "padding:8px 0;" "width:13em" "}" "input[type=\"submit\"],button[type=\"submit\"]{" @@ -1505,7 +1506,7 @@ PageElement* AutoConnect::_setupPage(String& uri) { elm->addToken(FPSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); elm->addToken(FPSTR("OPEN_SSID"), std::bind(&AutoConnect::_token_OPEN_SSID, this, std::placeholders::_1)); } - else if (uri == String(AUTOCONNECT_URI_DELETE) && (_apConfig.menuItems & AC_MENUITEM_DELETESSID)) { + else if (uri == String(AUTOCONNECT_URI_DELETE) && (_apConfig.menuItems & AC_MENUITEM_OPENSSIDS) && (_apConfig.menuItems & AC_MENUITEM_DELETESSID)) { // Setup /_ac/del reqAuth = true; From 6632ab5b743ef8e757a5f3981b333cb5487365c0 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 16 Feb 2022 16:53:56 +0900 Subject: [PATCH 06/20] Documentation of the credentials removal function --- mkdocs/api.md | 4 +++- mkdocs/apiconfig.md | 14 +++++++++++++- mkdocs/changelabel.md | 2 ++ mkdocs/images/open.png | Bin 22982 -> 0 bytes mkdocs/images/openssid.png | Bin 25950 -> 11166 bytes mkdocs/images/openssid_trash.png | Bin 0 -> 14915 bytes mkdocs/menu.md | 6 +++++- 7 files changed, 23 insertions(+), 3 deletions(-) delete mode 100644 mkdocs/images/open.png create mode 100644 mkdocs/images/openssid_trash.png diff --git a/mkdocs/api.md b/mkdocs/api.md index 6a635bd7..71c339ac 100644 --- a/mkdocs/api.md +++ b/mkdocs/api.md @@ -212,7 +212,9 @@ This function only works for AutoConnect primary menu items. It has no effect on : - **AC_MENUITEM_HOME** : [HOME](menu.md#home) : - **AC_MENUITEM_DEVINFO** : - [Device statistics](menu.md#where-the-from) as AutoConnect root page + [Device statistics](menu.md#where-the-from) as AutoConnect root page +: - **AC_MENUITEM_DELETESSID** : + Enable to delete credentials on [Open SSIDs](http://localhost:8000/AutoConnect/menu.html#open-ssids). !!! note "It is added, not replaced." The initial configuration of the AutoConnect menu items: diff --git a/mkdocs/apiconfig.md b/mkdocs/apiconfig.md index 3691197d..13e46526 100644 --- a/mkdocs/apiconfig.md +++ b/mkdocs/apiconfig.md @@ -220,13 +220,25 @@ Configure applying items of the [AutoConnect menu](menu.md). You can arbitrarily
AC_MENUITEM_RESET Appends [Reset...](menu.md#reset) item.
AC_MENUITEM_UPDATE Appends [Update](menu.md#update) item.
AC_MENUITEM_HOME Appends [HOME](menu.md#home) item.
-
AC_MENUITEM_DEVINFO Appends the **Device info** item which links to [AutoConnect statistics page](menu.md##where-the-from).
+
AC_MENUITEM_DEVINFO Appends the **Device info** item which links to [AutoConnect statistics page](menu.md##where-the-from).
+
AC_MENUITEM_DELETESSID Enables the ability to interactively delete credentials on the [Open SSIDs](menu.md#open-ssids) menu screen.
!!! info "How to specify the value of the menu items" An menuItems accepts the logical OR of AC_MENUITEM_t type value. For example, to enable only Open SSIDs and HOME items, specify: ```cpp + AutoConnect portal; AutoConnectConfig config; + config.menuItems = AC_MENUITEM_OPENSSIDS | AC_MENUITEM_HOME; + portal.config(config); + ``` + Also, to enable the credentials removal feature, follow these settings procedures. + ```cpp + AutoConnect portal; + AutoConnectConfig config; + + config.menuItems = config.menuItems | AC_MENUITEM_DELETESSID; + portal.config(config); ``` However, even if you specify like the above, the AutoConnectAux page items still display on the menu. To remove the AutoConnectAux items, use the [AutoConnectAux::menu](apiaux.md#menu) function. diff --git a/mkdocs/changelabel.md b/mkdocs/changelabel.md index 951a866d..49db9883 100644 --- a/mkdocs/changelabel.md +++ b/mkdocs/changelabel.md @@ -66,6 +66,8 @@ AutoConnect label texts are pre-assigned with a fixed string so that it can be d PassphraseAUTOCONNECT_PAGECONFIG_PASSPHRASE Enable DHCPAUTOCONNECT_PAGECONFIG_ENABLEDHCP ApplyAUTOCONNECT_PAGECONFIG_APPLY + Page:[open SSIDs] textDelete a credential?AUTOCONNECT_TEXT_DELETECREDENTIAL + could not deletedAUTOCONNECT_TEXT_COULDNOTDELETED Page:[update] textUpdating firmwareAUTOCONNECT_TEXT_UPDATINGFIRMWARE Select firmware:AUTOCONNECT_TEXT_SELECTFIRMWARE Successfully updated, rebooting...AUTOCONNECT_TEXT_OTASUCCESS diff --git a/mkdocs/images/open.png b/mkdocs/images/open.png deleted file mode 100644 index ddc22f3effc801907d027f4ed439d9245c1d0d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22982 zcmd43WmH_<(ly#ikl?``f=hxETtd)5a1V5_;O;Jgpg}?i9^BpCJ-E9=2-3Jack!Ha zew_Eu9ryjl_{Qx(cK2#}v)9^HHLK>VMX-XLBpNaiG6VuadoLxX1c5x=hd|&IpCf<~ zS4Bhxa6r(PkrabGJpM~<%83FaNH$WM_7Dgj&Exlz_e#`<5Xei&dod9em$}_VXB8av zXYhv&GLmokLS}GrP;%+@+kBh!)C)Ta41#IcstLjpW}4$n(iJn_@0MLG@pE+sz?Z&i zx)}2ECQvsr{sJGnbC*=H$!cx9JkT6(creiHN|mQFE{8z*_+T96?2qQwd-VbnJfdxs zxSl*d!Sv(*=fGBr{doNM;eRvw-zWOd8UFX9|937$ks+s-Hg)W+j10=(>}*yJ4*&RI zBqb$fOnmadnHiq10g^8{IHJPDzyo#PFw*ww*kq!#Irr95f%R#!;AXPo04FEsNM#w- z!d!j(VAUH&P4xlWrOeFF3v~~WnuDc|$f%s7oik#tmtb|Hd9miZ2Mtr!h*K^%Og!HF zwO72N681hNWdGqVVGHk+heP)4T7NAzLr=Teqgf{i;ehaP|z0D zBgLl4CO$Ee9X{H<#D0MMYH}fT zCcgyMi4{3IN^kx7YhN^DTegz8N`VrgV7-HHWLnx*m6av5?DNt^9G9`sXLds2qt0Qn zM@x;x+c-TNoh`B~K2fPGe>dJ8X47%Qb@Bb(RE{L~z=Ku5*rwHTQ=osp+RExWUHay` zj`r1u(|8ZJs~zE^uHSkDLM|^)9US3L&Ufbshjp5}cUtcC{D2#5h?*W?f12{J^IT|f zu)q)$6cm~D3tam~u-M?dx}^9U+~dw)gv#O@nwpv#r4EDv9ztrSChD}z%w#Qv+J42J zh*Z>^A5L#CN0W0^Gx&&;f`Wnw7GzMmtk{u)gX4}mo{oAXEzXIkO9r}2QAA2nYut8N z{2ZUg|7raB^Gf2uU;X*wCir}A9!?yCmV3P3-d-0EuK34}!06QQCxo|+)MH2NFI zzz5kEgt$p1hN?wMgd62&8NfQe>pvMxT*{;V`Kd28Q0UA z`b*b~NtS75eipg!Q==Evj>He_S28G-&X(}gc+9268c&RjvROx_B^^Gzrp!pU9loGo zc87LUB`!(H$|zqo@lKQkBAo4n^x@x^YZp;n?ef|@AJ6%K^OKj$e*gYGs5I!gfcyQ^9{Ch;1u2u@PexX+ znFdy;vfu2?&9=7>pwiNI2ZenT1@r#Y?By3_JVZtP`h(?-coEU$Xql&0EvMzvS12fP ziHQ_!Y)B=`2y3#sFP9q8+T&61?e7Ng&W$62f~4Z*{|@Cb5B@5(9h4TCo%80>yCOH= z7*Bk-eKsT)=C5Zri)^vf%%Rh-R7l51i!iuY|F<9<(+^SqoKr7l7rp5k>FLz>CwGS( z1J)<12P=vOHk(U+0)9J{@3BWRWay%;baC*=zP$0a?%aPC2#1KrtI2u6e`@lubKR<4DEHDMS+5)!mhG<3quSc;0S-2+^pv5pr|drcM!ZK4S0oQ{PmfFrc zY1gi)uH2=$O)|!T*z%FfI%czxJsy>AIJu`!_@RA#lSOP8f9i2P=($rqs1q6*)Q}6f zX|sCnPMD4gGzpiD8oD{{g+|>tr5jHVF)lk!jJ1;p58UE4aNWVfLU50NwZyl#VM2C! zT{QL%XxJHvEbHqsR5z241M}0G=;tW7!$^o$eh*m^u({|a5P>$# z(Rjtr&3(Ky9eVv39}~Eo1}Z$Wlo+%Vcvpv)z1m8?;k8b5@+==%Znb*xl$$3?r`_G% zz{b)9(GM0vtm(oxx#1s!5k9V;-Ns07QBvw|TSrg2&40{lt6#H2Tam`4*xV?yLi4_zMY9<{b z>E(54KCX71qlyt6Mf9drR)105LsLj=!BmOz$+9h+}_kW!+g;#q3~aRcg_$LcwdoUqo0Vme62+hH$b!{KLLQ)=y8`VR%xnO zB`TM%Uf|oJ#vIsuALtj5`u&A=tq1OxHj3wHXrj@5TqbKRQ@M~G3427KU?9D1%~u+hhih z;LU|lW@}r=Jl^Dv|ACNOLWPVNKZ4Z#Vl`$M+K7hwuFh^lp~(yv1RDLV)ccXqDZBw; zrwJ(#!0?_7Cl}mRNQ#Mdt|W))bH|5;BNe8guTr3%5$aEJP;!a4(sB78jqe(sN)O+($0p5vr&oE1|93n0h-2<9@v0A!uW$ zn))?A`Y@hwj`p|KE=go)sD?zNNA8;GZ5oGI!M^Q6X z4=-cxI5E!lgm3lJ)6%~5u6M5#SR3b`Jub;la>M3=4^@n+BQs@bsk`OVj$%EX^hpl` z{xVWB*q<~^pk+^i7rm~qJl)GgO84q;-WT-QtPM^t&EEnrOdw!}s&C+LER@K@7liHu zN%e50Qk;d=d`Z#f|3d@TFC{GTEA$3~5p4u=xHf6-!F#1OD#dlSGldx@rLxdp2(3V% z_2T`g5cBJYZ(ByU?p-%i9a$~3VLOZ>qgl-3oo{NR`(}9E5}I@Obd;`%?o0Xxw>#Qy z`6LSDy^sUNSpmzB)h{N&L{xtE-4b3133eIO90=P9^jxiDW7+ifqma&3WBzP#hJ_^7 z9Q>?1XXAK-8OnOxj3)G8CSANr+b~jUGoVwC+QN*r^u=j6H?nru5vpKhL5;qTgcSTZ z3&SgN@Al25JAuuHn^ycy=1&sS;a11&AWxgCGW+BHysKUNZ|9 z>JcDvQoOsyuIz<>IewQunpMCUxVMco@dDWAU_p0_nv<2a9w;uON_0fW`I@Aq1R9~a z{2?aR)ZDzSDhnk%Szyo_o$~tgf2D_p*P#t6jN%9T?Ro_3YwNc6#~a!@IfcZso9KID zcc1!wzj!XBWo6OO^ShjW?bADJTF)7#6rg;k@OR=jCP;^U*{NvSphq8eaz@Zy{U^X} z$rpII>Q@&tr0u>UcFkgqHMKHhS!HM3RX%JpM`)p{q`ezm;-Hy(mS)#8PTT1G~?H>>;y$c`sdx{zR;1K+S z`fzSi@i*D|EA4Sfaqb$-S=dipp`ySi&`J3z=nHfW^G@rL3>Ty1Qd+*3Y=}#UciapK zQq$7(l5<5DUKNQvruhD85o2ZZ@_(-C|NQy4l(voSSz<`dv!T#Zk z$Dhz!K4-;SnSix3c($^#bk{y&LNB|$@5Ct$7bjJXxmzYQ6m#@CjyQkWlZb*bK9UI? zy;7KGgncwnZ-_B*XG|uPm-_JaBFX*g(^4r*cbcs^_mx54z`;Kk(Um=LZp+Qi`L^f0 zU8val=`+=x4wOb>Xtq`kx^MXu^AIZ=*U(Y>)L3_Oc+%E~Ed$|)r_=a2ltL&4E^X;+ zU5OA~1IxSKDp9Mae!eGF0$nKLUz`^^k26?fXJq0?!2#7p(%2H+uePS2TT^*{x$^Zot>YeHhmrB|3|n*sd3nJAZ**Zpf`;i~KmB`G zzL$buONdLus4Rd&obh>KZ*AX8fn@Ky*2|&SYiVpK_VG%2IJmDgkorEe>z>T1!WYPk zdf4b1>M{RPD;E^y3E=xDi`VX}?{zSlm*D*P!K=>s;G>amLpd{JTUr`?F$=TMlkM$o z--;xOfOf;q&Y*@qoD0H>HIu+!nVFe*S2rvJhD1aJK|`J9=H?p(FojQ*RgT9C$%Y&1 z?39%HHZ1mLY9$DuR6)tw4>;RZERx0rC{(Yo>=&c9YE5KF)%evzOgCCOEB!kjJ_`xk z->z4-4e{{_ZvoDNtlP{xLdOMNvZ6Z-&ahwoAy{(uS_5B_{}1)6R~5g7S^Vn;ZqKV& zG;HvlzOixQL{yQH4z9>O8WD|B3fUrZmDj~S^l(1GQJgHF2J8Lm!HWd=WttDNAH+lt zo6vBUw72g&B&FWV`WJ^EzBa{8ls-gp$)CEQjFe&>GkE!WK-eMc_ds9!#H{_dCQ>2X zzWSBS%dKP(+7Fc=z`8wS#&QMI|M~xHl4tfM((}$$!?A1Fbjw&it%f;vtVs&L52@<9i+aSi~V4KVHS1RO@X&dxll0yj{Sy~8{OC$?i4xAmy~Na;JRzXj9QVum3d?VyGPMHqxBf!i;uy~_+_ zdn>$F`d@Z9*g1Wsw+(#n`+!@Gc8)$-a^AgQVRktO% zq7C^>52^Qk1tBIf_skVRU-x2*(}`NJX`sBwJAF#_it^ORBA5b53%*NH`#Y@^6!NQy zBRB&(<5}MV&%S4L_@Y;1>seP9-O5f_V!9nza+TtYmr!k@nQ5leYPT~952Is)Ax>^v zhZl%bHESG$_$4mEeGZNehgXLbX71LYhGer)@TO^7Z0M})$azZ}wOaM=W@l#$$LzZo zHUafcx^kHhqP~G-Sm&DSaz8m00>+;jgvY5D_(evhnM}m}oKX42=e(M+Bj~gfnp-Fn zc%J@kZAqDgrM@u|vu_(#&?t~7JtZ9|rE)Rv^^1EiU$=vW!s=$!G*rHp} z?J&QP3Q{5X8jt;;z5p~Lh17blI9@d1Rk6YnXym>#mpoaBfxezH>iC}SXTPV*=jy7l zNE@N`ZehzrkLg!2x~F?^LoW%R(^>{hR_a5iA5bikFN~wgn5U&FPd43KjAxz5G|B&(?$?0uUr^dnT0sE z+)-ZpuY-K>w!vK|*gR0aZTkct6Q89qJk{~r-(2+?x#peinPN1eHx@7X=#_4(;2>%b zRU(}Ap^_~^jO4dwrlxwQ&sW=Yq)Z5IQ-s$4Wf$Isb8pO3^#t8TG(W3w7HhYp#au@u z;W@{ej_3Q2eUplI{I)e&#Q~Pg4jK@k65?8s-7%4=yC{z17s9w`AD+S+SZcF6;^DYw z!M6HMk&&e)IOEwh!>_?cyE}yaE1`ii$CFrQWxk!?m!m1GIlL7LOZ46bKK!8Ywe&6# zr-6m|9{>4?Gw`XDb-GxhYZl!Qs-(nTeSk^MDVri7!ui@n4#3sweDJ#X28`QMm9OPt z+?XfVX5>?m8LkJvsjqZ@;^oF>X#rG5!3iY$RbJ-+u8#`_LK(-kdS~_|<&z|gvfZqh z?f1uUM=#eC5)uGjJiA|PQfEB?3&>{NtGN6%kyAp)UO!h5At}@GXQhlRo{xV&sjFr_^1WqpB z*C;r2qzO-Lc*b0T96IiB57k2Bt|3>Z-Djz3B(3Pxl=Xsd)FyM#^=o7Go@%b^x{KD4 zFL&^k_e&v@-fNSIHFd=@w$&Xux*b!bTk{nSx-LV1Ws?pMguT}a@;F}L{5U}?N#M5h zePFs2;ruvU4Rv3!Kky1Kxv@OsbAU}e;hQ7B&Wa#o!vWEvOm~|-YrVJ%#DvpY<=yH)+3ktWFP|I42&y9wLmX*;+BH;GUvR_JCy4$~BeKbqdU8K(a zf;oMK43jVz#@#ep?#dzJin5u_LrHKE6 zo)njcTcnL5y&PC>NTQI?V=)1+6*jb(&enB7Cg6KsTqK5nj=sAdKKI6Kr9Haf(DN3q zIU@Nb7c)9-_lBN&1D>1nK|nH;KiG=PVHW0A{DrYWOURkc{QlkR8`I=1UJ!OZq_AUx zI$o@`V)Kz%0wl`|Qfw3|Dp8Gu#Exn;*@;}WH$B(R`}{tG^Uisd%>P)J!w1yni=e;sK#4=|ezb$@K`y8UvkOlVdWF0nj<%CwW=K3rxai*>V{j1T zEw*UD_)#+rR0vzi{r(aB=VYxhqzxye3-T!~LBTrVct5uR8Dv=ybG(ghJj{TGu{@{) z_XRlNC^)W71eY@h>*uEoX&7URLL25Mm;t*b~ye^la*b?Yd!BV z0yqs4F-|i?^&Z0Vs~$_(=BX^6`Lx1@4SRfhFYQqBmJ|k_-)wK#x(S9c8K<%F$s-sz zj9%SsNRJ**dZz=r#Ks)PNMB-ZTyPA(uI0S1$XEWeUdSDgcKM9ho(nhhqz!jp=VI-T zLhye?b>X)&Eal-slABzD359RJ{+yWbU|OHa<9H+}IXRD8Ou<5~0gHflvj$}`0h`m) zMyrLsJ1LgfQn&t1W+7r>!XxCGRQ0ajip|x1ws%ZWlw=|AFKkgcfB7q8zdF&w&dKf=vI&u_crlV#jjXVUcr{vRGsxUXcZFXwoj3-Nf@sv;AKs)57jYSl-r40na4EH|EHjGHXONoj2yt9QHY$ zD|bhTw0sg&nVWtzMEhlt!sS|VhZH!~_M1?0yp@qM?6^0McF8RZk5x$P==!DSpc`CZ z0A4S!zuZj5Jfa)xUbwOity6K;Qh66GJ6`EEeog&)wsByvCAq9jC=^-r=Ldz zwGPe;)&6lL{UXw4rW5#M1l>>*UPh+2$}((s1;T-5@V0RMPkLY#*?gIbMlcL*%YjctIt&+?r5w(~EN1SGwn zo(_3G3-|a0B*6b1IvGDGd<y3Y~-6YPThJP?JvRolK!^8u5VYJBh#*tiJ_ z6X{&})VTIzRy+Xk*arvwpShm?M+5yIO6Gq{qW|N~f4}@c82#_l|LYo}g*c1`e7=17 za(i^K>|Jm>hfOE zDaDnQoYb_medOag@{$@FandD&0|P%>nBTln&6?hwtw0P84mKH0hks0Je_790TLy)N zMNfNQ9UER=UD^66Mvi~RR(Nk{p#PNnrao6sFPta_k9BOaEw-=#I`U9O zIHOVa$oSZhWAg8>aAMTde>7vO%GgjH9pMc{*x0~rP~>ZQ&+Dl{M1<7$PTv4Cv0pRk zg7GIy#4)lCB?}eh_k_qJMaz#GXIPlH0lB&KACmZRwW=)?-50^scwCREA*u2yLUlt8 zw(Am#vr|P{N9z&7c2r=IJm*4B9oQ<|)jw>{V7kqHl-}(9(OY`b%`_nFLf}O~!8=vu zxl2%)tI9EK*iB2f{@&)fm!Kq@FA_wB2}CIfd%=ZdsQ?C`*DmW#r1tbku00 z5n3Djju*FN){2+YHFs%EHQrCpGChv_dWWlwIW_3nM*^aB`#U$2pckpX{?iNasRAKk zy6_1w%}f8UE4B)(Q_#k*#(Jx+Q+lZxe(y;aS5%6K%(OJ$=|~dGi*_7R^T53t{?(z3 zJ5(M|Ot1nQB3)IOMW`x#P4NZpNm^R%!#R_euqQf2S=p6UMio_HnqkpLh!3=;@n}7b z>Z&*+z#ra=m`_8YdS`(5*QuulHEeWz^a=LDTw7W>+5jr*AtNQ$lQg|c*qGsN!(N9s zyGp*rVm)qhaB#Z;jqyhTdG^ZK5W{JQ*qenVj2al zqfN)f4Z3bu9>?^ zy2tErHH&6B9B|;b3JNbiHG2fVQZG(*giS4IsC=I3Ns|7FOXe3Ha2|_^=|YG}!N@%_ z+LqR<)7CzsUR?L)I~`Ku@LW&7!7 zt1h|UD#q;8`L$Ho*_aP+lq8#`y1RL}J@e@+jdL>cg6sAL#aEA-=G0HFinhZxoXhv*9 z8~)7fA5@i9bm?SB9H*c~yDWR0pyjKVphKQNf8Lrd{%u0d`H{3G7rNc2e#^Z0`7yIT zXnA-FK}ACwt+CcYCE-!H_t0}#r2zJ%)HXLmU@+%Zt0YYI3MHy$@9mi>hoa})Yn2o( z6g=#f?#sb>IAgnlgm^t)E&k}3qv4HLhZ+rX_XI7j#ORj`m}ko5^Pt3^QNe1uSN%-w zHRG*-^VN-y?{`ki{sg9KMN-rI{@<-}VTlw`y~p=&rKt~XoQ5{)jNorl3-Xo>{SZ=P zqO(#3@11wyvTqxn_3R737~ltigtI^q`kwR|@L8%9FC3h&ru@zZm-Q{Sx6LKGOUnUn zZ?%+fJ5~aQ1>qfU-R}^tAIcEy&q-TPZ1lL39FwVj-v2COh}MsjvH!5Y70@C?jMUO4 z+&0*}FS*xoJvW!m%x{Rehv`;y@#BAwoJVb^CcL{Cpo zRI=Muj%N1@t7w+5G)jn0(P>y2@2m2Cx2rZ;RxUV<;SDj7kTmS?pE^`>mMs{3Z`6+V z+J&s#t>HQ?)Y8yvfp-c+LsxFbJ>rOoo=O)Q;3i$!hi+=`f%mEMQ6iv zwB}Po`20z;;&4S82ux^b z5TClVCuSctg02T(FcX9RxZ%lqjN$!RsMm_e0Y}1N8wiO3BD{%#<0}-rrtD?5p25Cx%8v zVOv;O*!^O0=Z?pul7K*dB_$~qeSFjCafQXk#>V4u$$EWpFdQZ>?rXe|*O{wa=Bs;c zsp1fRvVV5|#ak-(Hc~4VN%d=Y*XpGoA~H-_al4UFQ}fbp9q+Rtzu%|ndP*VdMP%Xg zJthLzzW`A1NO`l5-RPZ+4W}M4+&cD=+Vz-07uy%G0VU`1uu26K`vf zSov-TMEmOm@g*d%al3lA-0_q}msIxPyw47JFUq}@pmm?`_ zK*gm=w#~s3wWa*u@7e7@f`~TmCwvZetPj>WVoz6g#_p2xn!=f2#e7K`vcIv+Q9cXpEZW~n2u+s z84oA34sU!+Tv%vy#TF3}aYeW&(yF0cZ+Tem2tdRBwLvc6!WzR2MTYQr-SU8P#J;ID z8sz4EBwZuw{e4(ZWbjx2Jk$Ag?D_RXKDm{fRVu4_4L)rq=g!n*zXQ{&#+dw?(~7#~ zH~UTeXNZRL5mqr=t`LzFMqq$1+Z4;y6&3Kx8_)gcPpc(QjINOPck(YX4@4(^-6whQ z-4Nbf5UCcuj#G0IIU04p*l1fE`~BkNrq%!eXpoGY1c2mP?rR&i?K^JkBd(8^{rw%S zF9lFh`)mcFdlsudieM9u1L$~&Q=t#&x+;Pi{e!JWa$BI~1X9`s1 zCMLxt-(=;wf9~;@+AqYWZ~7YOvl&b;c@zceJI4qv9Sl*YxL!U#VqiFC<^grdic$q_ zv7ozJ=2>@6<{y^|hLuGr){_Nyq`pR6^lr#XkErB|k&e2TY=^U8z23*^At`AYY!Y3# zu1?)fw@EAKr8+M`2g?~qwVIkuMF~|)>KjHjOdX4v&;bkM)5*cNl87znUKbUv@5~sD z_Gh*Jq$GtPF9y5u^6Bex(76hGLu`r_Np-3%{rsGN9d!i^N@FwzNtaidPp9j31W3Jq z-v6c!7ANd|-|+05 zNsC}1PpUM6KboFu>LH968K1+*SV@jtkd*YWpy#c?%`&CSU~+Iwm3f}_gF5NlYUc#Q zaZecUGKEPO`)k4xd7Qoy!9jk4gZk~T{`)8C$A)xr`3@Oby9WhY9SFzUuj5f~td^e~ z7P|+p1u^lW?P;i-F^-K+bWX9QWO!BUFkvYxAHjOZ(_OKZlvnR>7~4t{J`xe7^Vb6_ z7v9g~5%RvNcVw;0Ag<>sWFhc3I$yeDBwxXqXk2RggMZH~;GvRLc0D;LC9hsdS`m1@ zyFkpV-&4zWYb=^2w>MYCW;{f4bqZqqiC}s^up-PChx^`6R*RpxEM{IlXdPL&pRe36 zox!Fz&al{O$LXkenMjN9n7?f55Zjzwp|ruL_SH`02lrQGqqLh^?G_b{f_r$Cp&7RG zoslp}_qdw$dDyr9ie_orZX1=YYzRcB(pHr(R8J0phZpH@3(=v9&FJ6zhxT*#XNkN> z*PQr{O|z<8Z@R7sm-XK&(}`Ra3f}x&s+$0b6J2vWW$lP+ykm05=sH!mD5B3BssKH? z5;FhlmZ=gIq^Jkt!3|9fo|sp>3Jl0|L~EW*FFA4SFUZAORLz0oC2YMl1}VyYN1BrH zT%~EQPKywvb$A#RoYrJ_Pv5CI{^9dotXV&%s zWur$kh*NgY6w?gU2^nqK%gal*^YH;B_||=S!Z%eTNzAWRJ5d;X%@r*sqD2|03yT{y zVckT8lj!l7DDPNXE4$oci$huGvq`J zoxxU9`qk}=Sio%*nXPC4{h9r1XZM<+81=2_yE0e|HS zs*Q!3dfF{NER(lNn6#9l56zc*=z5#be-fy5xDw=8@}BNd}hk)M_`**v1%sN*6HbD`1;<3 zD+H@gVAtPbH`4B!x+KGqKm!3k4t6xcU?O)9h}LChlZ=3Y(_g5y<#9i^NG@?d11f>X z67+eo8F&1x%l$2H@u#Mc7$&WMn1E*X(-(Zqb;1%=D_cm)i@F!X++S5pF_
  • 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 diff --git a/mkdocs/images/openssid.png b/mkdocs/images/openssid.png index fcf0798c73dec4ec9cb4bdca70e118c6c1b1a1da..ba3e6a199ce6896b0dcd11804ca3060f7643fcae 100644 GIT binary patch literal 11166 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 literal 25950 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 literal 0 HcmV?d00001 diff --git a/mkdocs/menu.md b/mkdocs/menu.md index 5e86bb0b..3d96b0f2 100644 --- a/mkdocs/menu.md +++ b/mkdocs/menu.md @@ -40,7 +40,11 @@ If you want to configure with static IP, uncheck "**Enable DHCP**". Once the WiF After WiFi connected, AutoConnect will automatically save the established SSID and password to the flash on the ESP module. **Open SSIDs** menu reads the saved SSID credentials and lists them as below. Listed items are clickable buttons and can initiate a connection to its access point. - + + +Also, this menu allows you to interactively delete the stored credentials. icon will appear next to each SSID in the Open SSIDs menu when the credential removal feature is enabled with [AutoConnectConfig::menuItems](apiconfig.md#menuitems). Clicking the on this screen will delete the SSID. This feature is disabled by default. + + !!! note "Saved credentials data structure has changed" A structure of AutoConnect saved credentials has changed in v1.1.0 and was lost backward compatibility. Credentials saved by AutoConnect v1.0.3 (or earlier) will not display properly with AutoConnect v1.1.0. You need to erase the flash of the ESP module using the esptool before the Sketch uploading. From 597562ed1f609921fddd5faddeb5876f8bac08b3 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Tue, 22 Feb 2022 00:56:53 +0900 Subject: [PATCH 07/20] Migrate Build CI to GitHub Actions --- .github/workflows/build.yml | 120 ++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..339191c6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,120 @@ +# AutoConnect library examples build CI + +name: build + +on: + pull_request: + branches: + - 'master' + types: + - opened + release: + types: + - published + repository_dispatch: + workflow_dispatch: + +jobs: + biuld: + name: ${{ matrix.board.fqbn }} + runs-on: ubuntu-latest + + env: + LIBRARIES: | + - source-path: ./ + - name: PageBuilder + - name: PubSubClient + SKETCHES_PATH: examples + SKETCHES_REPORTS_PATH: sketches-reports + + strategy: + matrix: + board: + - fqbn: "esp8266:esp8266:generic" + platform-name: esp8266:esp8266 + - fqbn: "esp32:esp32:esp32" + platform-name: esp32:esp32 + + library-dependency: + - name: ArduinoJson + version: 5.13.5 + - name: ArduinoJson + + include: + - board: + platform-name: esp8266:esp8266 + platforms: | + - name: esp8266:esp8266 + source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json + - board: + platform-name: esp32:esp32 + platforms: | + - name: esp32:esp32 + source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + + fail-fast: false + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install ESP32 platform dependencies + if: matrix.board.platform-name == 'esp32:esp32' + run: pip3 install pyserial + + - name: Combines Platform-compliant sketches for ESP8266 + if: matrix.board.platform-name == 'esp8266:esp8266' + env: + BUILD_SKETCHES: | + - ${{ env.SKETCHES_PATH }}/EEPROM + - ${{ env.SKETCHES_PATH }}/FSBrowser + + - name: Combines Platform-compliant sketches for ESP32 + if: matrix.board.platform-name == 'esp32:esp32' + env: + BUILD_SKETCHES: | + - ${{ env.SKETCHES_PATH }}/CreditMigrate + - ${{ env.SKETCHES_PATH }}/FSBrowser32 + - ${{ env.SKETCHES_PATH }}/WebCamServer + + - name: Compile example sketches that require ArduinoJson + uses: arduino/compile-sketches@v1 + with: + fqbn: ${{ matrix.board.fqbn }} + platforms: ${{ matrix.platforms }} + libraries: | + - ${{ env.LIBRARIES }} + - ${{ matrix.library-dependency.name }} + enable-deltas-report: true + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + sketch-paths: | + - ${{ env.BUILD_SKETCHES }} + - ${{ env.SKETCHES_PATH }}/ConfigIP + - ${{ env.SKETCHES_PATH }}/Credential + - ${{ env.SKETCHES_PATH }}/Elements + - ${{ env.SKETCHES_PATH }}/FileUpload + - ${{ env.SKETCHES_PATH }}/HandleClient + - ${{ env.SKETCHES_PATH }}/HandlePortal + - ${{ env.SKETCHES_PATH }}/HandlePortalEX + - ${{ env.SKETCHES_PATH }}/HelloWorld + - ${{ env.SKETCHES_PATH }}/mqttRSSI + - ${{ env.SKETCHES_PATH }}/mqttRSSI_FS + - ${{ env.SKETCHES_PATH }}/Simple + - ${{ env.SKETCHES_PATH }}/Update + - ${{ env.SKETCHES_PATH }}/OTAUpdate + - ${{ env.SKETCHES_PATH }}/WebUpdate + + - name: Compile example sketches without JSON + uses: arduino/compile-sketches@v1 + with: + fqbn: ${{ matrix.board.fqbn }} + platforms: ${{ matrix.platforms }} + libraries: | + - ${{ env.LIBRARIES }} + cli-compile-flags: | + - --build-property + - compiler.cpp.extra_flags="-DAUTOCONNECT_NOUSE_JSON" + enable-deltas-report: true + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + sketch-paths: | + - ${{ env.SKETCHES_PATH }}/mqttRSSI_NA From d842785a5246cb67b719b6f6ae3577ac3c8000a5 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 12:53:27 +0900 Subject: [PATCH 08/20] Separate a job excluded ArduinoJson --- .github/workflows/build.yml | 164 ++++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 54 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 339191c6..219fc092 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,20 +14,52 @@ on: repository_dispatch: workflow_dispatch: +env: + LIBRARIES: | + - source-path: ./ + - name: AutoConnect + - name: PageBuilder + - name: PubSubClient + + SKETCHES_PATH: examples + + SKETCHES: | + ConfigIP + Credential + Elements + FileUpload + HandleClient + HandlePortal + HandlePortalEX + HelloWorld + mqttRSSI + mqttRSSI_FS + OTAUpdate + Simple + Update + WebUpdate + + SKETCHES_ESP8266: | + EEPROM + FSBrowser + + SKETCHES_ESP32: | + CreditMigrate + FSBrowser32 + WebCamServer + + SKETCHES_WO_JSON: | + mqttRSSI_NA + + SKETCHES_REPORTS_PATH: sketches-reports + jobs: - biuld: - name: ${{ matrix.board.fqbn }} + build_with_ArduinoJson: + name: ${{ matrix.board.fqbn }} ${{ matrix.library.dependency }} runs-on: ubuntu-latest - env: - LIBRARIES: | - - source-path: ./ - - name: PageBuilder - - name: PubSubClient - SKETCHES_PATH: examples - SKETCHES_REPORTS_PATH: sketches-reports - strategy: + fail-fast: false matrix: board: - fqbn: "esp8266:esp8266:generic" @@ -35,10 +67,14 @@ jobs: - fqbn: "esp32:esp32:esp32" platform-name: esp32:esp32 - library-dependency: - - name: ArduinoJson - version: 5.13.5 - - name: ArduinoJson + library: + - name: ArduinoJsonV6 + dependency: | + - name: ArduinoJson + - name: ArduinoJsonV5 + dependency: | + - name: ArduinoJson + version: 5.13.5 include: - board: @@ -52,30 +88,29 @@ jobs: - name: esp32:esp32 source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - fail-fast: false - steps: - name: Checkout repository uses: actions/checkout@v2 - - name: Install ESP32 platform dependencies - if: matrix.board.platform-name == 'esp32:esp32' - run: pip3 install pyserial - - - name: Combines Platform-compliant sketches for ESP8266 + - name: Append sketches depending on ESP8266 if: matrix.board.platform-name == 'esp8266:esp8266' - env: - BUILD_SKETCHES: | - - ${{ env.SKETCHES_PATH }}/EEPROM - - ${{ env.SKETCHES_PATH }}/FSBrowser + run: | + echo "BUILD_SKETCHES<> $GITHUB_ENV + echo "${{ env.SKETCHES }}${{ env.SKETCHES_ESP8266 }}" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV - - name: Combines Platform-compliant sketches for ESP32 + - name: Append sketches depending on ESP32 if: matrix.board.platform-name == 'esp32:esp32' - env: - BUILD_SKETCHES: | - - ${{ env.SKETCHES_PATH }}/CreditMigrate - - ${{ env.SKETCHES_PATH }}/FSBrowser32 - - ${{ env.SKETCHES_PATH }}/WebCamServer + run: | + echo "BUILD_SKETCHES<> $GITHUB_ENV + echo "${{ env.SKETCHES }}${{ env.SKETCHES_ESP32 }}" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Create sketches list + run: | + echo "BUILD_SKETCHES_LIST<> $GITHUB_ENV + echo -n "${{ env.BUILD_SKETCHES }}" | sed -e 's/^/- ${{ env.SKETCHES_PATH }}\//' >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV - name: Compile example sketches that require ArduinoJson uses: arduino/compile-sketches@v1 @@ -83,38 +118,59 @@ jobs: fqbn: ${{ matrix.board.fqbn }} platforms: ${{ matrix.platforms }} libraries: | - - ${{ env.LIBRARIES }} - - ${{ matrix.library-dependency.name }} + ${{ env.LIBRARIES }} + ${{ matrix.library.dependency }} enable-deltas-report: true sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} sketch-paths: | - - ${{ env.BUILD_SKETCHES }} - - ${{ env.SKETCHES_PATH }}/ConfigIP - - ${{ env.SKETCHES_PATH }}/Credential - - ${{ env.SKETCHES_PATH }}/Elements - - ${{ env.SKETCHES_PATH }}/FileUpload - - ${{ env.SKETCHES_PATH }}/HandleClient - - ${{ env.SKETCHES_PATH }}/HandlePortal - - ${{ env.SKETCHES_PATH }}/HandlePortalEX - - ${{ env.SKETCHES_PATH }}/HelloWorld - - ${{ env.SKETCHES_PATH }}/mqttRSSI - - ${{ env.SKETCHES_PATH }}/mqttRSSI_FS - - ${{ env.SKETCHES_PATH }}/Simple - - ${{ env.SKETCHES_PATH }}/Update - - ${{ env.SKETCHES_PATH }}/OTAUpdate - - ${{ env.SKETCHES_PATH }}/WebUpdate - - - name: Compile example sketches without JSON + ${{ env.BUILD_SKETCHES_LIST }} + + build_wo_ArduinoJson: + name: ${{ matrix.board.fqbn }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + board: + - fqbn: "esp8266:esp8266:generic" + platform-name: esp8266:esp8266 + - fqbn: "esp32:esp32:esp32" + platform-name: esp32:esp32 + + include: + - board: + platform-name: esp8266:esp8266 + platforms: | + - name: esp8266:esp8266 + source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json + - board: + platform-name: esp32:esp32 + platforms: | + - name: esp32:esp32 + source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Create sketches list with precluded ArduinoJson + run: | + echo "BUILD_SKETCHES_LIST_WO_JSON<> $GITHUB_ENV + echo -n "${{ env.SKETCHES_WO_JSON }}" | sed -e 's/^/- ${{ env.SKETCHES_PATH }}\//' >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Compile example sketches w/o ArduinoJson uses: arduino/compile-sketches@v1 with: fqbn: ${{ matrix.board.fqbn }} platforms: ${{ matrix.platforms }} - libraries: | - - ${{ env.LIBRARIES }} cli-compile-flags: | - --build-property - - compiler.cpp.extra_flags="-DAUTOCONNECT_NOUSE_JSON" + - build.extra_flags=-DAUTOCONNECT_NOUSE_JSON + libraries: | + ${{ env.LIBRARIES }} enable-deltas-report: true sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} sketch-paths: | - - ${{ env.SKETCHES_PATH }}/mqttRSSI_NA + ${{ env.BUILD_SKETCHES_LIST_WO_JSON }} From d4180a81901cccd25a6a80506f803b05a9697ada Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 12:58:07 +0900 Subject: [PATCH 09/20] Exclude AutoConnect itself from the dependency --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 219fc092..b9b27cbe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,6 @@ on: env: LIBRARIES: | - source-path: ./ - - name: AutoConnect - name: PageBuilder - name: PubSubClient From d8ee5b9d7fe25a4d818fb37bf8d833ffd044cbb6 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 13:25:01 +0900 Subject: [PATCH 10/20] Changes the build status badge to the actions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b4beb86..d44d5006 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![GitHub release](https://img.shields.io/github/v/release/Hieromon/AutoConnect)](https://github.com/Hieromon/AutoConnect/releases) [![arduino-library-badge](https://www.ardu-badge.com/badge/AutoConnect.svg?)](https://www.ardu-badge.com/AutoConnect) -[![Build Status](https://app.travis-ci.com/Hieromon/AutoConnect.svg?branch=master)](https://app.travis-ci.com/Hieromon/AutoConnect) +[![Build Status](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml/badge.svg)](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml) [![License](https://img.shields.io/github/license/Hieromon/AutoConnect)](https://github.com/Hieromon/AutoConnect/blob/master/LICENSE) An Arduino library for ESP8266/ESP32 WLAN configuration at run time with web interface. From 60169e6ce79be03b181a564f64e734a7f68ddbbe Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 13:27:14 +0900 Subject: [PATCH 11/20] Drop Travis CI --- .travis.yml | 51 --------------------------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a13ab479..00000000 --- a/.travis.yml +++ /dev/null @@ -1,51 +0,0 @@ -os: linux -language: generic -env: - global: - - IDE_VERSION=1.8.19 - jobs: - - BOARD="esp8266:esp8266:generic:xtal=80,eesz=4M3M,ip=lm2f,exception=disabled,FlashMode=qio,FlashFreq=80" PB="1.5.2" ARDJSON="5.13.5" - - BOARD="esp32:esp32:esp32:FlashFreq=80,FlashSize=4M,PartitionScheme=min_spiffs" PB="1.5.2" ARDJSON="5.13.5" - - BOARD="esp8266:esp8266:generic:xtal=80,eesz=4M3M,ip=lm2f,exception=disabled,FlashMode=qio,FlashFreq=80" PB="1.5.2" ARDJSON="6.18.5" - - BOARD="esp32:esp32:esp32:FlashFreq=80,FlashSize=4M,PartitionScheme=min_spiffs" PB="1.5.2" ARDJSON="6.18.5" -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-$IDE_VERSION-linux64.tar.xz - - tar xf arduino-$IDE_VERSION-linux64.tar.xz - - sudo mv arduino-$IDE_VERSION ~/arduino-ide - - export PATH=$PATH:~/arduino-ide - - arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json,https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json" --save-prefs - - if [[ "$BOARD" =~ "esp8266:esp8266:" ]]; then - arduino --install-boards esp8266:esp8266; - fi - - if [[ "$BOARD" =~ "esp32:esp32:" ]]; then - arduino --install-boards esp32:esp32; - fi - - arduino --install-library PageBuilder:$PB,ArduinoJson:$ARDJSON,PubSubClient - - buildExampleSketch() { arduino --verify --board $BOARD $PWD/examples/$1/$1.ino; } -install: - - mkdir -p ~/Arduino/libraries - - ln -s $PWD ~/Arduino/libraries/. -script: - - buildExampleSketch ConfigIP - - buildExampleSketch Credential - - if [[ "$BOARD" =~ "esp32:esp32:" ]]; then buildExampleSketch CreditMigrate; fi - - if [[ "$BOARD" =~ "esp8266:esp8266:" ]]; then buildExampleSketch EEPROM; fi - - buildExampleSketch Elements - - buildExampleSketch FileUpload - - if [[ "$BOARD" =~ "esp8266:esp8266:" ]]; then buildExampleSketch FSBrowser; fi - - if [[ "$BOARD" =~ "esp32:esp32:" ]]; then buildExampleSketch FSBrowser32; fi - - buildExampleSketch HandleClient - - buildExampleSketch HandlePortal - - buildExampleSketch HandlePortalEX - - buildExampleSketch HelloWorld - - buildExampleSketch mqttRSSI - - buildExampleSketch mqttRSSI_FS - - buildExampleSketch mqttRSSI_NA - - buildExampleSketch Simple - - buildExampleSketch Update - - buildExampleSketch OTAUpdate - - if [[ "$BOARD" =~ "esp32:esp32:" ]]; then buildExampleSketch WebCamServer; fi - - buildExampleSketch WebUpdate From de6d3aaff80f27857c3d1dd6062e6b4e2bf1fc76 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 13:29:17 +0900 Subject: [PATCH 12/20] Fix an unused warning --- src/AutoConnectAux.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/AutoConnectAux.h b/src/AutoConnectAux.h index e23fbac9..58eecbba 100644 --- a/src/AutoConnectAux.h +++ b/src/AutoConnectAux.h @@ -2,8 +2,8 @@ * Declaration of AutoConnectAux basic class. * @file AutoConnectAux.h * @author hieromon@gmail.com - * @version 1.3.2 - * @date 2021-11-24 + * @version 1.3.4 + * @date 2022-02-24 * @copyright MIT license. */ @@ -235,6 +235,7 @@ class AutoConnectAux : public PageBuilder { */ template<> inline bool AutoConnectAux::_isCompatible(const AutoConnectElement* element) const { + AC_UNUSED(element); return true; } From cbf80cbc5e2dc45ad5a4c7257413acf0363818d8 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 13:44:06 +0900 Subject: [PATCH 13/20] Change a text of the build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d44d5006..fdd65dbe 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![GitHub release](https://img.shields.io/github/v/release/Hieromon/AutoConnect)](https://github.com/Hieromon/AutoConnect/releases) [![arduino-library-badge](https://www.ardu-badge.com/badge/AutoConnect.svg?)](https://www.ardu-badge.com/AutoConnect) -[![Build Status](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml/badge.svg)](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml) +[![Build status](https://github.com/Hieromon/AutoConnect/actions/workflows/build/badge.svg)](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml) [![License](https://img.shields.io/github/license/Hieromon/AutoConnect)](https://github.com/Hieromon/AutoConnect/blob/master/LICENSE) An Arduino library for ESP8266/ESP32 WLAN configuration at run time with web interface. From b87f82c2f615e220b8e18d310c3237f2edaf670c Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 13:51:00 +0900 Subject: [PATCH 14/20] Revert "Change a text of the build status badge" This reverts commit cbf80cbc5e2dc45ad5a4c7257413acf0363818d8. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fdd65dbe..d44d5006 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![GitHub release](https://img.shields.io/github/v/release/Hieromon/AutoConnect)](https://github.com/Hieromon/AutoConnect/releases) [![arduino-library-badge](https://www.ardu-badge.com/badge/AutoConnect.svg?)](https://www.ardu-badge.com/AutoConnect) -[![Build status](https://github.com/Hieromon/AutoConnect/actions/workflows/build/badge.svg)](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml) +[![Build Status](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml/badge.svg)](https://github.com/Hieromon/AutoConnect/actions/workflows/build.yml) [![License](https://img.shields.io/github/license/Hieromon/AutoConnect)](https://github.com/Hieromon/AutoConnect/blob/master/LICENSE) An Arduino library for ESP8266/ESP32 WLAN configuration at run time with web interface. From aef7620ce24267e86cf7d908ad77795e76f22162 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Thu, 24 Feb 2022 17:53:24 +0900 Subject: [PATCH 15/20] Change log for v1.3.4 --- README.md | 9 +++++++++ mkdocs/changelog.md | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/README.md b/README.md index d44d5006..7853e8a0 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,15 @@ Full documentation is available on https://Hieromon.github.io/AutoConnect, some ## Change log +### [1.3.4] Feb. 25, 2022 +- Added enablement of credentials removal function with Open SSIDs menu. (Discussions #433) +- Fixed AutoConnectOTA crashing if there is no OTA partition. +- Fixed AutoConnectUpdate crashing if there is no OTA partition. +- Migrate the CI platform to GitHub actions. + +##### Breaking changes: +- Authentication has been applied to **RESET** menu. This avoids resetting modules in an unauthenticated state by direct access to `/_ac/reset`. + ### [1.3.3] Jan. 25, 2022 - Fixed the missing initialization of MQTT parameter settings of mqttRSSI.ino example sketch. - Reverted the MQTT API endpoint of Thingspeak.com in the mqttRSSI example sketches. diff --git a/mkdocs/changelog.md b/mkdocs/changelog.md index 5b8db4e5..37ce786e 100644 --- a/mkdocs/changelog.md +++ b/mkdocs/changelog.md @@ -1,3 +1,16 @@ +### [1.3.4] Feb. 25, 2022 + +#### Enhancements + +- Added enablement of credentials removal function with Open SSIDs menu. +- Migrate the CI platform to GitHub actions. + +#### Fix + +- Fixed AutoConnectOTA crashing if there is no OTA partition. +- Fixed AutoConnectUpdate crashing if there is no OTA partition. + +--- ### [1.3.3] Jan. 25, 2022 #### Fix From 5fda87dfd4f03f817ed44bf818da28a28ab680a9 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Sun, 27 Feb 2022 23:30:15 +0900 Subject: [PATCH 16/20] Bump Version --- library.json | 4 ++-- library.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library.json b/library.json index a6c0f267..509640ea 100644 --- a/library.json +++ b/library.json @@ -12,7 +12,7 @@ [ { "name": "PageBuilder", - "version": ">=1.5.1" + "version": ">=1.5.2" }, { "name": "ArduinoJson", @@ -25,7 +25,7 @@ "espressif8266", "espressif32" ], - "version": "1.3.3", + "version": "1.3.4", "license": "MIT", "headers": "AutoConnect.h" } diff --git a/library.properties b/library.properties index 66f7a218..81178a3d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AutoConnect -version=1.3.3 +version=1.3.4 author=Hieromon Ikasamo maintainer=Hieromon Ikasamo sentence=ESP8266/ESP32 WLAN configuration at runtime with web interface. From ae41971cf3a8fe092b1b523cd77dc54e8506f6c2 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Mon, 28 Feb 2022 14:49:32 +0900 Subject: [PATCH 17/20] Add mqttRSSI_NA to jobs for ArduinoJson dependency --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b9b27cbe..cfca1036 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,6 +38,9 @@ env: Update WebUpdate + SKETCHES_WO_JSON: | + mqttRSSI_NA + SKETCHES_ESP8266: | EEPROM FSBrowser @@ -47,9 +50,6 @@ env: FSBrowser32 WebCamServer - SKETCHES_WO_JSON: | - mqttRSSI_NA - SKETCHES_REPORTS_PATH: sketches-reports jobs: @@ -95,14 +95,14 @@ jobs: if: matrix.board.platform-name == 'esp8266:esp8266' run: | echo "BUILD_SKETCHES<> $GITHUB_ENV - echo "${{ env.SKETCHES }}${{ env.SKETCHES_ESP8266 }}" >> $GITHUB_ENV + echo "${{ env.SKETCHES }}${{ env.SKETCHES_WO_JSON }}${{ env.SKETCHES_ESP8266 }}" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - name: Append sketches depending on ESP32 if: matrix.board.platform-name == 'esp32:esp32' run: | echo "BUILD_SKETCHES<> $GITHUB_ENV - echo "${{ env.SKETCHES }}${{ env.SKETCHES_ESP32 }}" >> $GITHUB_ENV + echo "${{ env.SKETCHES }}${{ env.SKETCHES_WO_JSON }}${{ env.SKETCHES_ESP32 }}" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - name: Create sketches list From 8724380aa174f4e8841774db11c501ade2ccbfd8 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 2 Mar 2022 22:35:41 +0900 Subject: [PATCH 18/20] Supports LittleFS_esp32 legacy library --- README.md | 3 ++- mkdocs/changelog.md | 3 ++- src/AutoConnectFS.h | 13 +++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7853e8a0..afdd499c 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,8 @@ Full documentation is available on https://Hieromon.github.io/AutoConnect, some ## Change log -### [1.3.4] Feb. 25, 2022 +### [1.3.4] Mar. 02, 2022 +- Supports [LittleFS_esp32](https://github.com/lorol/LITTLEFS) legacy library with ESP32 Arduino core 1.0.6 or less. - Added enablement of credentials removal function with Open SSIDs menu. (Discussions #433) - Fixed AutoConnectOTA crashing if there is no OTA partition. - Fixed AutoConnectUpdate crashing if there is no OTA partition. diff --git a/mkdocs/changelog.md b/mkdocs/changelog.md index 37ce786e..f5400b54 100644 --- a/mkdocs/changelog.md +++ b/mkdocs/changelog.md @@ -1,7 +1,8 @@ -### [1.3.4] Feb. 25, 2022 +### [1.3.4] Mar. 02, 2022 #### Enhancements +- Supports [LittleFS_esp32](https://github.com/lorol/LITTLEFS) legacy library with ESP32 Arduino core 1.0.6 or less. - Added enablement of credentials removal function with Open SSIDs menu. - Migrate the CI platform to GitHub actions. diff --git a/src/AutoConnectFS.h b/src/AutoConnectFS.h index 3c1d7b94..cdeb4660 100644 --- a/src/AutoConnectFS.h +++ b/src/AutoConnectFS.h @@ -2,8 +2,8 @@ * Predefined file system applied for AutoConnect usage. * @file AutoConnectFS.h * @author hieromon@gmail.com - * @version 1.3.1 - * @date 2021-10-03 + * @version 1.3.4 + * @date 2022-03-02 * @copyright MIT license. */ @@ -58,6 +58,15 @@ extern "C" { #include } #define AUTOCONNECT_APPLIED_FILECLASS fs::LittleFSFS + +// With ESP32 platform core version less 2.0, reverts the LittleFS class and +// the exported instance to the ordinary LittleFS_esp32 library owns. +#if !defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR<2 +#undef AUTOCONNECT_APPLIED_FILESYSTEM +#define AUTOCONNECT_APPLIED_FILESYSTEM LITTLEFS +#undef AUTOCONNECT_APPLIED_FILECLASS +#define AUTOCONNECT_APPLIED_FILECLASS fs::LITTLEFSFS +#endif #endif #endif From df5d49800013edae52f3dea9a2ffe7cbcb4b0444 Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 2 Mar 2022 22:41:03 +0900 Subject: [PATCH 19/20] Match compatible version to PageBuilder upstream --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index 509640ea..e47509fc 100644 --- a/library.json +++ b/library.json @@ -12,7 +12,7 @@ [ { "name": "PageBuilder", - "version": ">=1.5.2" + "version": ">=1.5.3" }, { "name": "ArduinoJson", From 48906d2de6a35f00b942ae01899643336199df9d Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Sat, 5 Mar 2022 14:09:16 +0900 Subject: [PATCH 20/20] Deploy for v1.3.4 --- docs/404.html | 19 +- docs/acelements.html | 24 +- docs/achandling.html | 44 ++-- docs/acintro.html | 20 +- docs/acjson.html | 74 +++--- docs/acupload.html | 20 +- docs/adauthentication.html | 20 +- docs/adconnection.html | 20 +- docs/adcpcontrol.html | 20 +- docs/adcredential.html | 20 +- docs/adexterior.html | 20 +- docs/adnetwork.html | 20 +- docs/adothers.html | 20 +- docs/advancedusage.html | 20 +- docs/api.html | 28 ++- docs/apiaux.html | 22 +- docs/apiconfig.html | 35 ++- docs/apielements.html | 20 +- docs/apiextra.html | 20 +- docs/apiupdate.html | 20 +- .../assets/javascripts/bundle.5413a266.min.js | 29 +++ .../javascripts/bundle.5413a266.min.js.map | 8 + .../assets/javascripts/bundle.e1a181d9.min.js | 29 --- .../javascripts/bundle.e1a181d9.min.js.map | 8 - ...0bbba5b5.min.js => search.bd0b6b67.min.js} | 14 +- ....min.js.map => search.bd0b6b67.min.js.map} | 6 +- docs/assets/stylesheets/main.2d9f7617.min.css | 1 + .../stylesheets/main.2d9f7617.min.css.map | 1 + docs/assets/stylesheets/main.edf004c2.min.css | 9 - .../stylesheets/main.edf004c2.min.css.map | 1 - docs/basicusage.html | 32 +-- docs/changelabel.html | 22 +- docs/changelog.html | 221 ++++++++++++------ docs/colorized.html | 20 +- docs/credit.html | 20 +- docs/datatips.html | 20 +- docs/esp32cam.html | 20 +- docs/faq.html | 36 +-- docs/filesystem.html | 20 +- docs/gettingstarted.html | 20 +- docs/howtoembed.html | 20 +- docs/images/open.png | Bin 22982 -> 0 bytes docs/images/openssid.png | Bin 25950 -> 11166 bytes docs/images/openssid_trash.png | Bin 0 -> 14915 bytes docs/index.html | 20 +- docs/license.html | 20 +- docs/lsbegin.html | 20 +- docs/menu.html | 24 +- docs/menuize.html | 20 +- docs/otabrowser.html | 41 +++- docs/otaserver.html | 20 +- docs/otaupdate.html | 20 +- docs/search/search_index.json | 2 +- docs/sitemap.xml | 78 +++---- docs/sitemap.xml.gz | Bin 478 -> 478 bytes docs/wojson.html | 20 +- 56 files changed, 764 insertions(+), 584 deletions(-) create mode 100644 docs/assets/javascripts/bundle.5413a266.min.js create mode 100644 docs/assets/javascripts/bundle.5413a266.min.js.map delete mode 100644 docs/assets/javascripts/bundle.e1a181d9.min.js delete mode 100644 docs/assets/javascripts/bundle.e1a181d9.min.js.map rename docs/assets/javascripts/workers/{search.0bbba5b5.min.js => search.bd0b6b67.min.js} (73%) rename docs/assets/javascripts/workers/{search.0bbba5b5.min.js.map => search.bd0b6b67.min.js.map} (81%) create mode 100644 docs/assets/stylesheets/main.2d9f7617.min.css create mode 100644 docs/assets/stylesheets/main.2d9f7617.min.css.map delete mode 100644 docs/assets/stylesheets/main.edf004c2.min.css delete mode 100644 docs/assets/stylesheets/main.edf004c2.min.css.map delete mode 100644 docs/images/open.png create mode 100644 docs/images/openssid_trash.png diff --git a/docs/404.html b/docs/404.html index 60f19a0d..3d634207 100644 --- a/docs/404.html +++ b/docs/404.html @@ -13,7 +13,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -36,8 +36,9 @@ + - + @@ -156,7 +157,7 @@
    - +
    Hieromon/AutoConnect @@ -200,7 +201,7 @@
    - +
    @@ -1035,10 +1036,10 @@

    404 - Not found

    - + - + diff --git a/docs/acelements.html b/docs/acelements.html index c5dc0a4b..8c28eaa3 100644 --- a/docs/acelements.html +++ b/docs/acelements.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    @@ -2921,10 +2923,10 @@

    Variant for
    - + - + diff --git a/docs/achandling.html b/docs/achandling.html index 2dff1185..daa28385 100644 --- a/docs/achandling.html +++ b/docs/achandling.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1604,6 +1605,7 @@ +

    Handling the custom Web pages

    Page, Container, Component

    @@ -1829,10 +1831,10 @@

    {
    -  "name" : "aux",
    -  "uri" : "/aux",
    -  "menu" : true,
    -  "element" : [
    +  "name" : "aux",
    +  "uri" : "/aux",
    +  "menu" : true,
    +  "element" : [
         {
           "name": "hello",
           "type": "ACText",
    @@ -2439,8 +2441,8 @@ 

    Overwrite

    For example, the combination of the Sketch and JSON document as follows updates only the style while keeping Caption (ie. "Hello, world") as AutoConnectText value.

    External JSON document for the below sketch to modify the text style.

    {
    -  "name" : "Caption",
    -  "type" : "ACText",
    +  "name" : "Caption",
    +  "type" : "ACText",
       "style": "text-align:center;font-size:24px;font-family:'Impact','Futura',sans-serif;color:tomato;"
     }
     

    @@ -2470,13 +2472,13 @@

    Overwrite

    Check data against on submission

    By giving a pattern to AutoConnectInput, you can find errors in data styles while typing in custom Web pages. The pattern is specified with regular expression.2 If the value during input of AutoConnectInput does not match the regular expression specified in the pattern, its background color changes to pink. The following example shows the behavior when checking the IP address in the AutoConnectInput field.

    {
    -  "title" : "Page-1",
    -  "uri" : "/page1",
    -  "menu" : true,
    -  "element" : [
    +  "title" : "Page-1",
    +  "uri" : "/page1",
    +  "menu" : true,
    +  "element" : [
         {
    -      "name" : "Server",
    -      "type" : "ACInput",
    +      "name" : "Server",
    +      "type" : "ACInput",
           "label": "Server address",
           "pattern": "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
         }
    @@ -2925,7 +2927,7 @@ 

    Limitations - + @@ -2934,7 +2936,7 @@

    Limitations - +

    @@ -2947,10 +2949,10 @@

    Limitations

    - + - + diff --git a/docs/acintro.html b/docs/acintro.html index 1374a3c9..7f899c7c 100644 --- a/docs/acintro.html +++ b/docs/acintro.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1142,6 +1143,7 @@ +

    Custom Web pages with AutoConnect

    What it is

    @@ -1375,7 +1377,7 @@

    Passing parameter - + @@ -1384,7 +1386,7 @@

    Passing parameter - +

    @@ -1397,10 +1399,10 @@

    Passing parameter
    - + - + diff --git a/docs/acjson.html b/docs/acjson.html index a429f9e7..12bff97b 100644 --- a/docs/acjson.html +++ b/docs/acjson.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1566,6 +1567,7 @@ +

    Custom Web pages with JSON

    You can embed custom Web pages written in JSON into AutoConnect without AutoConnectAux & AutoConnectElements declaration. Custom Web page declaration by JSON can embed in the Sketch as a fixed string or can store in the external file such as SPIFFS for stream loading. Also, you can also load and save AutoConnectElements objects individually.1

    @@ -1637,48 +1639,48 @@

    [
       {
    -    "title" : "Page 1 title",
    -    "uri" : "/page1",
    -    "menu" : true,
    -    "element" : [
    +    "title" : "Page 1 title",
    +    "uri" : "/page1",
    +    "menu" : true,
    +    "element" : [
           {
    -        "name" : "caption",
    -        "type" : "ACText",
    -        "value" : "hello, world"
    +        "name" : "caption",
    +        "type" : "ACText",
    +        "value" : "hello, world"
           },
           {
    -        "name" : "send",
    -        "type" : "ACSubmit",
    -        "uri" : "/page2"
    +        "name" : "send",
    +        "type" : "ACSubmit",
    +        "uri" : "/page2"
           }
         ]
       },
       {
    -    "title" : "Page 1 title",
    -    "uri" : "/page2",
    -    "menu" : false,
    -    "element" : [
    +    "title" : "Page 1 title",
    +    "uri" : "/page2",
    +    "menu" : false,
    +    "element" : [
           {
    -        "name" : "responds",
    -        "type" : "ACText",
    -        "value" : "Good day"
    +        "name" : "responds",
    +        "type" : "ACText",
    +        "value" : "Good day"
           },
           {
    -        "name" : "send",
    -        "type" : "ACSubmit",
    -        "uri" : "/page3"
    +        "name" : "send",
    +        "type" : "ACSubmit",
    +        "uri" : "/page3"
           }
         ]
       },
       {
    -    "title" : "Page 3 title",
    -    "uri" : "/page3",
    -    "menu" : true,
    -    "element" : [
    +    "title" : "Page 3 title",
    +    "uri" : "/page3",
    +    "menu" : true,
    +    "element" : [
           {
    -        "name" : "responds",
    -        "type" : "ACText",
    -        "value" : "bye"
    +        "name" : "responds",
    +        "type" : "ACText",
    +        "value" : "bye"
           }
         ]
       }
    @@ -2283,7 +2285,7 @@ 

    Saving JSON document - + @@ -2292,7 +2294,7 @@

    Saving JSON document - +

    @@ -2305,10 +2307,10 @@

    Saving JSON document

    - + - + diff --git a/docs/acupload.html b/docs/acupload.html index 492655de..1a2c9af5 100644 --- a/docs/acupload.html +++ b/docs/acupload.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    @@ -1648,10 +1650,10 @@

    Register cust
    - + - + diff --git a/docs/adauthentication.html b/docs/adauthentication.html index 111e0500..f551f0b6 100644 --- a/docs/adauthentication.html +++ b/docs/adauthentication.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    @@ -1364,10 +1366,10 @@

    Authentication within th
    - + - + diff --git a/docs/adconnection.html b/docs/adconnection.html index 629fa94d..b21e73cb 100644 --- a/docs/adconnection.html +++ b/docs/adconnection.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    @@ -1475,10 +1477,10 @@

    Timeout settings for a connec
    - + - + diff --git a/docs/adcpcontrol.html b/docs/adcpcontrol.html index db5a985c..f3604b4a 100644 --- a/docs/adcpcontrol.html +++ b/docs/adcpcontrol.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1156,6 +1157,7 @@ +

    Captive portal control

    The default behavior of AutoConnect is to launch the captive portal if 1st-WiFi.begin attempting inside AutoConnect::begin fails. You can change this default behavior through the AutoConnectConfig settings join together with Sketch code that implements to control the WiFi connection attempting.

    @@ -1615,7 +1617,7 @@

    Sketch execution during - + @@ -1624,7 +1626,7 @@

    Sketch execution during - +

    @@ -1637,10 +1639,10 @@

    Sketch execution during
    - + - + diff --git a/docs/adcredential.html b/docs/adcredential.html index 961d7a6a..cfbd6ab0 100644 --- a/docs/adcredential.html +++ b/docs/adcredential.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1086,6 +1087,7 @@ +

    Credential accesses

    AutoConnect automatically saves the credentials of the established WiFi connection according to the AutoConnectConfig::autoSave settings. The save destination differs depending on the type of ESP module. In the case of ESP8266, it is the EEPROM, and in the case of ESP32, it is the NVS (Non-volatile storage) partition implemented by the Preferences class.
    @@ -1258,7 +1260,7 @@

    Move the saving area - + @@ -1267,7 +1269,7 @@

    Move the saving area - +

    @@ -1280,10 +1282,10 @@

    Move the saving area
    - + - + diff --git a/docs/adexterior.html b/docs/adexterior.html index f9095756..c11f4c07 100644 --- a/docs/adexterior.html +++ b/docs/adexterior.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    @@ -1307,10 +1309,10 @@

    Capture the legacy
    - + - + diff --git a/docs/adnetwork.html b/docs/adnetwork.html index fd400233..727c5dc4 100644 --- a/docs/adnetwork.html +++ b/docs/adnetwork.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    - + - + diff --git a/docs/adothers.html b/docs/adothers.html index f70bdb6d..869a0737 100644 --- a/docs/adothers.html +++ b/docs/adothers.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    - + - + diff --git a/docs/advancedusage.html b/docs/advancedusage.html index 5bce3713..887c299a 100644 --- a/docs/advancedusage.html +++ b/docs/advancedusage.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1058,6 +1059,7 @@ +

    Advanced usage

    Summary

    @@ -1145,7 +1147,7 @@

    Summary - + @@ -1154,7 +1156,7 @@

    Summary - +

    @@ -1167,10 +1169,10 @@

    Summary

    - + - + diff --git a/docs/api.html b/docs/api.html index 86dfbba8..aa7d8cd7 100644 --- a/docs/api.html +++ b/docs/api.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +

  • +Device statistics as AutoConnect root page + + +
    +
      +
    • AC_MENUITEM_DELETESSID : +Enable to delete credentials on Open SSIDs.
    @@ -2039,7 +2047,7 @@

    whileCaptivePortal - + @@ -2048,7 +2056,7 @@

    whileCaptivePortal - + @@ -2061,10 +2069,10 @@

    whileCaptivePortal
    - + - + diff --git a/docs/apiaux.html b/docs/apiaux.html index 97a996d9..2118c6dc 100644 --- a/docs/apiaux.html +++ b/docs/apiaux.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    @@ -1781,10 +1783,10 @@

    setTitle
    - + - + diff --git a/docs/apiconfig.html b/docs/apiconfig.html index 7c0ad173..9f9904da 100644 --- a/docs/apiconfig.html +++ b/docs/apiconfig.html @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -38,8 +38,9 @@ + - + @@ -163,7 +164,7 @@
    - +
    Hieromon/AutoConnect @@ -207,7 +208,7 @@
    - +
    Hieromon/AutoConnect @@ -1698,6 +1699,7 @@ +

    AutoConnectConfig API

    Constructor

    @@ -1873,12 +1875,23 @@