Merge pull request #197 from Hieromon/pr/181

Pr/181
pull/201/head
Hieromon Ikasamo 5 years ago committed by GitHub
commit 4ac83431c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      README.md
  2. 25
      examples/MyLabels/mylabels.h
  3. 13
      keywords.txt
  4. 2
      library.json
  5. 2
      library.properties
  6. 2
      mkdocs.yml
  7. 2
      mkdocs/achandling.md
  8. 2
      mkdocs/acupload.md
  9. 84
      mkdocs/advancedusage.md
  10. 53
      mkdocs/api.md
  11. 2
      mkdocs/apiaux.md
  12. 41
      mkdocs/apiconfig.md
  13. 8
      mkdocs/apiupdate.md
  14. 12
      mkdocs/changelabel.md
  15. 5
      mkdocs/changelog.md
  16. 4
      mkdocs/credit.md
  17. 1
      mkdocs/css/paragraph.css
  18. 10
      mkdocs/datatips.md
  19. 14
      mkdocs/faq.md
  20. BIN
      mkdocs/images/applymenu.png
  21. BIN
      mkdocs/images/castmenu.png
  22. BIN
      mkdocs/images/menu.png
  23. BIN
      mkdocs/images/webupdate.gif
  24. BIN
      mkdocs/images/webupdate.png
  25. 87
      mkdocs/images/webupdate.svg
  26. 4
      mkdocs/index.md
  27. 46
      mkdocs/menu.md
  28. 184
      mkdocs/otabrowser.md
  29. 8
      mkdocs/otaserver.md
  30. 2
      mkdocs/otaupdate.md
  31. 2
      mkdocs/wojson.md
  32. 47
      src/AutoConnect.cpp
  33. 45
      src/AutoConnect.h
  34. 12
      src/AutoConnectAux.cpp
  35. 4
      src/AutoConnectDefs.h
  36. 2
      src/AutoConnectElementBasisImpl.h
  37. 2
      src/AutoConnectElementJson.h
  38. 34
      src/AutoConnectLabels.h
  39. 229
      src/AutoConnectOTA.cpp
  40. 87
      src/AutoConnectOTA.h
  41. 39
      src/AutoConnectOTAPage.h
  42. 99
      src/AutoConnectPage.cpp
  43. 4
      src/AutoConnectUpdate.h
  44. 12
      src/AutoConnectUpdatePage.h
  45. 2
      src/AutoConnectUpload.h
  46. 12
      src/AutoConnectUploadImpl.h

@ -101,6 +101,10 @@ Full documentation is available on https://Hieromon.github.io/AutoConnect, some
## Change log ## Change log
### [1.1.5] Apr. 1, 2020
- Supports AutoConnect menu configuration.
- Changed the bootUri behavior to be an automatic pop-up at the captive portal. (PR #181)
### [1.1.4] Feb. 14, 2020 ### [1.1.4] Feb. 14, 2020
- Supports for overriding text of the menu items with user-defined labels. - Supports for overriding text of the menu items with user-defined labels.
- Fixed the compiler warning with experimental WiFi mode of ESP8266. - Fixed the compiler warning with experimental WiFi mode of ESP8266.

@ -62,6 +62,11 @@
//#define AUTOCONNECT_BUTTONLABEL_RESET "NEW_STRING_YOU_WISH" //#define AUTOCONNECT_BUTTONLABEL_RESET "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_BUTTONLABEL_RESET //#endif // !AUTOCONNECT_BUTTONLABEL_RESET
// Button label: UPDATE
//#ifndef AUTOCONNECT_BUTTONLABEL_UPDATE
//#define AUTOCONNECT_BUTTONLABEL_UPDATE "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_BUTTONLABEL_UPDATE
// Page title: Page not found // Page title: Page not found
//#ifdef AUTOCONNECT_PAGETITLE_NOTFOUND //#ifdef AUTOCONNECT_PAGETITLE_NOTFOUND
//#undef AUTOCONNECT_PAGETITLE_NOTFOUND //#undef AUTOCONNECT_PAGETITLE_NOTFOUND
@ -212,6 +217,26 @@
//#define AUTOCONNECT_PAGETITLE_CREDENTIALS "NEW_STRING_YOU_WISH" //#define AUTOCONNECT_PAGETITLE_CREDENTIALS "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_PAGETITLE_CREDENTIALS //#endif // !AUTOCONNECT_PAGETITLE_CREDENTIALS
// Text: The update page caption
//#ifndef AUTOCONNECT_TEXT_UPDATINGFIRMWARE
//#define AUTOCONNECT_TEXT_UPDATINGFIRMWARE "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_TEXT_UPDATINGFIRMWARE
// Text: The update page's file selection button label
//#ifndef AUTOCONNECT_TEXT_SELECTFIRMWARE
//#define AUTOCONNECT_TEXT_SELECTFIRMWARE "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_TEXT_SELECTFIRMWARE
// Text: OTA success
//#ifndef AUTOCONNECT_TEXT_OTASUCCESS
//#define AUTOCONNECT_TEXT_OTASUCCESS "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_TEXT_OTASUCCESS
// Text: OTA failure
//#ifndef AUTOCONNECT_TEXT_OTAFAILURE
//#define AUTOCONNECT_TEXT_OTAFAILURE "NEW_STRING_YOU_WISH"
//#endif // !AUTOCONNECT_TEXT_OTAFAILURE
// Page title: AutoConnect connecting // Page title: AutoConnect connecting
//#ifdef AUTOCONNECT_PAGETITLE_CONNECTING //#ifdef AUTOCONNECT_PAGETITLE_CONNECTING
//#undef AUTOCONNECT_PAGETITLE_CONNECTING //#undef AUTOCONNECT_PAGETITLE_CONNECTING

@ -10,6 +10,7 @@ AutoConnectCheckbox KEYWORD1
AutoConnectElement KEYWORD1 AutoConnectElement KEYWORD1
AutoConnectFile KEYWORD1 AutoConnectFile KEYWORD1
AutoConnectInput KEYWORD1 AutoConnectInput KEYWORD1
AutoConnectOTA KEYWORD1
AutoConnectRadio KEYWORD1 AutoConnectRadio KEYWORD1
AutoConnectSelect KEYWORD1 AutoConnectSelect KEYWORD1
AutoConnectStyle KEYWORD1 AutoConnectStyle KEYWORD1
@ -27,9 +28,11 @@ aux KEYWORD2
config KEYWORD2 config KEYWORD2
begin KEYWORD2 begin KEYWORD2
disable KEYWORD2 disable KEYWORD2
disableMenu KEYWORD2
del KEYWORD2 del KEYWORD2
end KEYWORD2 end KEYWORD2
enable KEYWORD2 enable KEYWORD2
enableMenu KEYWORD2
entries KEYWORD2 entries KEYWORD2
fetchElement KEYWORD2 fetchElement KEYWORD2
getElement KEYWORD2 getElement KEYWORD2
@ -68,8 +71,18 @@ AC_Behind LITERAL1
AC_EXIT_AHEAD LITERAL1 AC_EXIT_AHEAD LITERAL1
AC_EXIT_LATER LITERAL1 AC_EXIT_LATER LITERAL1
AC_EXIT_BOTH LITERAL1 AC_EXIT_BOTH LITERAL1
AC_MENUITEM_NONE LITERAL1
AC_MENUITEM_CONFIGNEW LITERAL1
AC_MENUITEM_OPENSSIDS LITERAL1
AC_MENUITEM_DISCONNECT LITERAL1
AC_MENUITEM_RESET LITERAL1
AC_MENUITEM_HOME LITERAL1
AC_MENUITEM_UPDATE LITERAL1
AC_MENUITEM_DEVINFO LITERAL1
AC_ONBOOTURI_ROOT LITERAL1 AC_ONBOOTURI_ROOT LITERAL1
AC_ONBOOTURI_HOME LITERAL1 AC_ONBOOTURI_HOME LITERAL1
AC_OTA_BUILTIN LITERAL1
AC_OTA_EXTRA LITERAL1
AC_SAVECREDENTIAL_NEVER LITERAL1 AC_SAVECREDENTIAL_NEVER LITERAL1
AC_SAVECREDENTIAL_AUTO LITERAL1 AC_SAVECREDENTIAL_AUTO LITERAL1
AC_Button LITERAL1 AC_Button LITERAL1

@ -25,6 +25,6 @@
"espressif8266", "espressif8266",
"espressif32" "espressif32"
], ],
"version": "1.1.4", "version": "1.1.5",
"license": "MIT" "license": "MIT"
} }

@ -1,5 +1,5 @@
name=AutoConnect name=AutoConnect
version=1.1.4 version=1.1.5
author=Hieromon Ikasamo <hieromon@gmail.com> author=Hieromon Ikasamo <hieromon@gmail.com>
maintainer=Hieromon Ikasamo <hieromon@gmail.com> maintainer=Hieromon Ikasamo <hieromon@gmail.com>
sentence=ESP8266/ESP32 WLAN configuration at runtime with web interface. sentence=ESP8266/ESP32 WLAN configuration at runtime with web interface.

@ -72,7 +72,7 @@ theme:
extra_css: extra_css:
- 'css/paragraph.css' - 'css/paragraph.css'
- 'css/extra.css' - 'css/extra.css'
- 'https://use.fontawesome.com/releases/v5.6.1/css/all.css' - 'https://use.fontawesome.com/releases/v5.6.3/css/all.css'
extra_javascript: extra_javascript:
- 'js/gifffer.min.js' - 'js/gifffer.min.js'
extra: extra:

@ -543,7 +543,7 @@ String append(AutoConnectAux& aux, PageArgument& args) {
### <i class="fa fa-wrench"></i> How you can reach the values ### <i class="fa fa-wrench"></i> How you can reach the values
AutoConnectSubmit uses the POST method to send HTTP requests. A value of AutoConnectInput sent to the ESP8266 or ESP32 with POST is stored in the request body of the HTTP request: AutoConnectSubmit uses the POST method to send HTTP requests. A value of AutoConnectInput sent to the ESP8266 or ESP32 with POST is stored in the request body of the HTTP request:
``` ```powershell
POST /feels HTTP/1.1 POST /feels HTTP/1.1
Host: ESP8266_IP_ADDRESS Host: ESP8266_IP_ADDRESS
name1=value1&name2=value2&name3=value3 name1=value1&name2=value2&name3=value3

@ -209,7 +209,7 @@ typedef struct {
</span></dd> </span></dd>
</dl> </dl>
The upload handler needs to implement processing based on the enumeration value of HTTPUpload.status as **HTTPUploadStatus** enum type. HTTPUploadStatus enumeration is as follows: An upload handler needs to implement a procedure corresponding with **HTTPUploadStatus** enum value indicated by the uploading process of ESP8266WebServer class, which contained in HTTPUpload.status as following values:
- **`UPLOAD_FILE_START`** : Invokes to the \_open. - **`UPLOAD_FILE_START`** : Invokes to the \_open.
- **`UPLOAD_FILE_WRITE`** : Invokes to the \_write. - **`UPLOAD_FILE_WRITE`** : Invokes to the \_write.

@ -199,7 +199,50 @@ To implement embedding your legacy web pages to the AutoConnect menu, you can us
5. [Begin](api.md#begin) the portal. 5. [Begin](api.md#begin) the portal.
6. Performs [*AutoConnect::handleClient*](api.md#handleClient) in the **loop** function. 6. Performs [*AutoConnect::handleClient*](api.md#handleClient) in the **loop** function.
For details, see section [Constructing the menu](menuize.md) of Examples page. ```cpp hl_lines="10 28 32"
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <AutoConnect.h>
ESP8266WebServer server;
// Declaration for casting legacy page to AutoConnect menu.
// Specifies an uri and the menu label.
AutoConnect portal(server);
AutoConnectAux hello("/hello", "Hello"); // Step #1 as the above procedure
// Step #2 as the above procedure
// A conventional web page driven by the ESP8266WebServer::on handler.
// This is a legacy.
void handleHello() {
server.send(200, "text/html", String(F(
"<html>"
"<head><meta name='viewport' content='width=device-width,initial-scale=1.0'></head>"
"<body>Hello, world</body>"
"</html>"
)));
}
void setup() {
// Step #3 as the above procedure
// Register the "on" handler as usual to ESP8266WebServer.
// Match this URI with the URI of AutoConnectAux to cast.
server.on("/hello", handleHello);
// Step #4 as the above procedure
// Joins AutoConnectAux to cast the page via the handleRoot to AutoConnect.
portal.join({ hello });
portal.begin(); // Step #5 as the above procedure
}
void loop() {
portal.handleClient(); // Step #6 as the above procedure
}
```
<img width="232px" src="images/castmenu.png">
For more details, see section [Constructing the menu](menuize.md) of Examples page.
### <i class="fa fa-caret-right"></i> Change menu title ### <i class="fa fa-caret-right"></i> Change menu title
@ -224,7 +267,7 @@ Executing the above sketch will rewrite the menu title for the **FSBrowser** as
### <i class="fa fa-caret-right"></i> Change the menu labels ### <i class="fa fa-caret-right"></i> Change the menu labels
You can change the label of the AutoConnect menu item by rewriting the default label letter in [AutoConnectLabels.h](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectLabels.h) macros. However, changing menu items letter influences all the sketch's build scenes. You can change the label of the AutoConnect menu item by rewriting the default label letter in [AutoConnectLabels.h](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectLabels.h) macros. However, changing menu items letter influences all build scenes for the Sketch.
```cpp ```cpp
#define AUTOCONNECT_MENULABEL_CONFIGNEW "Configure new AP" #define AUTOCONNECT_MENULABEL_CONFIGNEW "Configure new AP"
@ -234,6 +277,7 @@ You can change the label of the AutoConnect menu item by rewriting the default l
#define AUTOCONNECT_MENULABEL_HOME "HOME" #define AUTOCONNECT_MENULABEL_HOME "HOME"
#define AUTOCONNECT_BUTTONLABEL_RESET "RESET" #define AUTOCONNECT_BUTTONLABEL_RESET "RESET"
``` ```
See also: [*Change label text*](changelabel.md)
### <i class="fa fa-caret-right"></i> Combination with mDNS ### <i class="fa fa-caret-right"></i> Combination with mDNS
@ -307,7 +351,7 @@ By default, the credentials saving area is occupied from the beginning of EEPROM
> The following diagram illustrates flash layout used in Arduino environment: > The following diagram illustrates flash layout used in Arduino environment:
> ``` > ```powershell
> |--------------|-------|---------------|--|--|--|--|--| > |--------------|-------|---------------|--|--|--|--|--|
> ^ ^ ^ ^ ^ > ^ ^ ^ ^ ^
> Sketch OTA update File system EEPROM WiFi config (SDK) > Sketch OTA update File system EEPROM WiFi config (SDK)
@ -443,6 +487,7 @@ AutoConnect will activate SoftAP at failed the first *WiFi.begin*. It SoftAP set
- Home URL of the user sketch application. - Home URL of the user sketch application.
- Menu title. - Menu title.
- Ticker signal output. - Ticker signal output.
- Built-in OTA update.
!!! note "AutoConnect::config before AutoConnect::begin" !!! note "AutoConnect::config before AutoConnect::begin"
*AutoConnect::config* must be executed before *AutoConnect::begin*. *AutoConnect::config* must be executed before *AutoConnect::begin*.
@ -453,6 +498,22 @@ AutoConnect will activate SoftAP at failed the first *WiFi.begin*. It SoftAP set
<img src="images/menu_home.png" /> <img src="images/menu_home.png" />
The sketch HOME path is closely related to the [bootUri](apiconfig.md#booturi) that specifies the access path on module restart. AutoConnect has the following three parameters concerning control the URIs:
- **AUTOCONNECT_URI**
The **ROOT** of AutoConnect. It is defined in `AutoConnectDefs.h` and is assigned an [AutoConnect statistics screen](menu.md#where-the-from) by default.
- [**AutoConnectConfig::homeUri**](apiconfig.md#homeuri)
It is the hyperlink of listed on the AutoConnect menu list as **HOME**.
- [**AutoConnectConfig::bootUri**](apiconfig.md#booturi)
Which page appears at the captive portal, AUTOCONNECT_URI or the homeUri. Its page will pop up automatically when you visit the captive portal.
| The definition of **HOME** | Behavior | Specified by | Default value | Possible value |
|---|---|---|---|---|
| **ROOT** of AutoConnect | Default for AC_ONBOOTURI_ROOT | `#define AUTOCONNECT_URI` in `AutoConnectDefs.h` | `/_ac` | URI string |
| **HOME** for Application-specific | Listed on the **menu list** as **HOME**<br>Also, It may be linked from the **menu title** and is **redundant** with the HOME menu item.<br>eg. Case of bootURI = AC_ONBOOTURI_HOME | AutoConnectConfig::homeURI | `/` | URI string |
| Which page **loads** at the boot time, ROOT or HOME | Appears after module reboot by **RESET** button with AutoConnect menu | AutoConnectConfig::bootURI | AC_ONBOOTURI_ROOT | AC_ONBOOTURI_HOME |
| Which page **appears** at the captive portal, ROOT or HOME | Auto pop-up | AutoConnectConfig::bootURI | AC_ONBOOTURI_ROOT | AC_ONBOOTURI_HOME |
### <i class="fa fa-caret-right"></i> Change SSID and Password for SoftAP ### <i class="fa fa-caret-right"></i> Change SSID and Password for SoftAP
An **esp8266ap** is default SSID name for SoftAP of captive portal and password is **12345678** for ESP8266. Similarly, **esp32ap** and **12345678** for ESP32. You can change both by setting [apid](apiconfig.md#apid) and [psk](apiconfig.md#psk). An **esp8266ap** is default SSID name for SoftAP of captive portal and password is **12345678** for ESP8266. Similarly, **esp32ap** and **12345678** for ESP32. You can change both by setting [apid](apiconfig.md#apid) and [psk](apiconfig.md#psk).
@ -486,7 +547,7 @@ But this method is not recommended. The broadcast radio of SSID emitted from Sof
### <i class="fa fa-caret-right"></i> Relocate the AutoConnect home path ### <i class="fa fa-caret-right"></i> Relocate the AutoConnect home path
A home path of AutoConnect is **/\_ac** by default. You can access from the browser with http://IPADDRESS/\_ac. You can change the home path by revising [**AUTOCONNECT_URI**](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDefs.h#L62) macro in the include header file as [AutoConnectDef.h](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDef.h). A home path of AutoConnect is **/\_ac** by default. You can access from the browser with http://IPADDRESS/\_ac. You can change the home path by revising [**AUTOCONNECT_URI**](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDefs.h#L69) macro in the include header file as [AutoConnectDef.h](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDef.h).
```cpp ```cpp
#define AUTOCONNECT_URI "/_ac" #define AUTOCONNECT_URI "/_ac"
@ -581,3 +642,18 @@ NodeMCU 32s | Active-high | 2 | T2
LOLIN32 Pro | Active-low | 5 | SS LOLIN32 Pro | Active-low | 5 | SS
SparkFun ESP32 Thing | Active-high | 5 SparkFun ESP32 Thing | Active-high | 5
Adafruit Feather HUZZAH32 | Active-high | 13 | A12 Adafruit Feather HUZZAH32 | Active-high | 13 | A12
### <i class="fa fa-caret-right"></i> Built-in OTA update feature
AutoConnect features a built-in OTA function to update ESP module firmware. You can easily make the Sketch that equips OTA and able to operate with the AutoConnect menu.
<span style="display:block;margin-left:auto;margin-right:auto;width:292px;height:482px;border:1px solid lightgrey;"><img data-gifffer="images/webupdate.gif" data-gifffer-height="480" data-gifffer-width="290" /></span>
[AutoConnectConfig::ota](apiconfig.md#ota) specifies to import the [built-in OTA update class](otabrowser.md) into the Sketch.
See the [Updates with the Web Browser](otabrowser.md) chapter for details.
<script>
window.onload = function() {
Gifffer();
};
</script>

@ -13,17 +13,22 @@ They contain in ```AutoConnectDefs.h```.
```cpp ```cpp
#define AC_DEBUG // Monitor message output activation #define AC_DEBUG // Monitor message output activation
#define AC_DEBUG_PORT Serial // Default message output device #define AC_DEBUG_PORT Serial // Default message output device
#define AUTOCONNECT_AP_IP 0x01F4A8C0 // Default SoftAP IP #define AUTOCONNECT_AP_IP 0x011CD9AC // Default SoftAP IP
#define AUTOCONNECT_AP_GW 0x01F4A8C0 // Default SoftAP Gateway IP #define AUTOCONNECT_AP_GW 0x011CD9AC // Default SoftAP Gateway IP
#define AUTOCONNECT_AP_NM 0x00FFFFFF // Default subnet mask #define AUTOCONNECT_AP_NM 0x00FFFFFF // Default subnet mask
#define AUTOCONNECT_DNSPORT 53 // Default DNS port at captive portal #define AUTOCONNECT_DNSPORT 53 // Default DNS port at captive portal
#define AUTOCONNECT_HTTPPORT 80 // Default HTTP #define AUTOCONNECT_HTTPPORT 80 // Default HTTP
#define AUTOCONNECT_MENU_TITLE "AutoConnect" // Default AutoConnect menu title #define AUTOCONNECT_MENU_TITLE "AutoConnect" // Default AutoConnect menu title
#define AUTOCONNECT_STARTUPTIME 10 // Default waiting time[s] for after reset
#define AUTOCONNECT_URI "/_ac" // Default AutoConnect root path #define AUTOCONNECT_URI "/_ac" // Default AutoConnect root path
#define AUTOCONNECT_TIMEOUT 30000 // Default connection timeout[ms] #define AUTOCONNECT_TIMEOUT 30000 // Default connection timeout[ms]
#define AUTOCONNECT_CAPTIVEPORTAL_TIMEOUT 0 // Captive portal timeout value #define AUTOCONNECT_CAPTIVEPORTAL_TIMEOUT 0 // Captive portal timeout value
#define AUTOCONNECT_STARTUPTIME 30 // Default waiting time[s] for after reset
#define AUTOCONNECT_USE_JSON // Allow AutoConnect elements to be handled by JSON format #define AUTOCONNECT_USE_JSON // Allow AutoConnect elements to be handled by JSON format
#define AUTOCONNECT_USE_UPDATE // Indicator of whether to use the AutoConnectUpdate feature.
#define AUTOCONNECT_UPDATE_PORT 8000 // Available HTTP port number for the update
#define AUTOCONNECT_UPDATE_TIMEOUT 8000 // HTTP client timeout limitation for the update [ms]
#define AUTOCONNECT_TICKER_PORT LED_BUILTIN // Ticker port
#endif
``` ```
!!! note "Macros placement moved" !!! note "Macros placement moved"
@ -121,6 +126,35 @@ Set SoftAP's WiFi configuration and static IP configuration.
<dd><span class="apidef">false</span><span class="aidesc">Configuration parameter is invalid, some values out of range.</span></dd> <dd><span class="apidef">false</span><span class="aidesc">Configuration parameter is invalid, some values out of range.</span></dd>
</dl> </dl>
### <i class="fa fa-caret-right"></i> enableMenu
```cpp
void enableMenu(const uint16_t items)
```
Enable the [AutoConnect menu](menu.md) items specified by the items parameter with logical OR value using **AC_MENUITEM_t** constant.
<dl class="apidl">
<dt>**Parameter**</dt>
<dd><span class="apidef">items</span><span class="apidesc">Specify the combined value of **AC_MENUITEM_t** of the items applying to the AutoConnect menu. It provides the value calculated from the **logical OR** by the AC_MENUITEM_t value of each item applied as a menu. AC_MENUITEM_t is enumeration type to identify each menu item and it has the below values.</span></dd>
: - **AC_MENUITEM_CONFIGNEW** :
[Configure new AP](menu.md#configure-new-ap)
: - **AC_MENUITEM_OPENSSIDS** :
[Open SSIDs](menu.md#open-ssids)
: - **AC_MENUITEM_DISCONNECT** :
[Disconnect](menu.md#disconnect)
: - **AC_MENUITEM_RESET** :
[Reset...](menu.md#reset)
: - **AC_MENUITEM_HOME** :
[HOME](menu.md#home)
: - **AC_MENUITEM_DEVINFO** :
[Device statistics](menu.md#where-the-from) as AutoConnect root page
</dl>
!!! note "It is added, not replaced."
The initial configuration of the AutoConnect menu items:
`AC_MENUITEM_CONFIGNEW | AC_MENUITEM_OPENSSIDS | AC_MENUITEM_DISCONNECT | AC_MENUITEM_RESET | AC_MENUITEM_HOME`
The enableMenu function adds an indication of the specified items to the current. Therefore, use the [disableMenu](#disableMenu) to remove the specified item from the initial menu.
### <i class="fa fa-caret-right"></i> end ### <i class="fa fa-caret-right"></i> end
```cpp ```cpp
@ -132,6 +166,19 @@ Stops AutoConnect captive portal service. Release ESP8266WebServer/WebServer and
!!! warning "Attention to end" !!! warning "Attention to end"
The end function releases the instance of ESP8266WebServer/WebServer and DNSServer. It can not process them after the end function. The end function releases the instance of ESP8266WebServer/WebServer and DNSServer. It can not process them after the end function.
### <i class="fa fa-caret-right"></i> disableMenu
```cpp
void disableMenu(const uint16_t items)
```
Disable the [AutoConnect menu](menu.md) items specified by the items parameter with logical OR value using **AC_MENUITEM_t** constant.
<dl class="apidl">
<dt>**Parameter**</dt>
<dd><span class="apidef">items</span><span class="apidesc">Specify the combined value of **AC_MENUITEM_t** of the items deleting from the AutoConnect menu. It provides the value calculated from the **logical OR** by the AC_MENUITEM_t value of each item. Refer to the [enableMenu](#enablemenu) about AC_MENUITEM_t.</span></dd>
</dl>
### <i class="fa fa-caret-right"></i> handleClient ### <i class="fa fa-caret-right"></i> handleClient
```cpp ```cpp

@ -188,7 +188,7 @@ Load specified element from JSON document into AutoConnectAux. The JSON document
!!! caution "Maybe it is an array" !!! caution "Maybe it is an array"
Please note that the JSON document that is the input for loadElement is an array syntax of AutoConnectElements when there are multiple elements. For example, the following JSON document has a syntax error: Please note that the JSON document that is the input for loadElement is an array syntax of AutoConnectElements when there are multiple elements. For example, the following JSON document has a syntax error:
```json ```js
{ {
"name": "Caption", "name": "Caption",
"type": "ACText", "type": "ACText",

@ -97,7 +97,7 @@ Specify the location to be redirected after module reset in the AutoConnect menu
<dt>**Type**</dt> <dt>**Type**</dt>
<dd>AC_ONBOOTURI_t</dd> <dd>AC_ONBOOTURI_t</dd>
<dt>**Value**</dt> <dt>**Value**</dt>
<dd><span class="apidef">AC_ONBOOTURI_ROOT</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Resetting the module redirects it to the AutoConnect root path. The root path is assumed to be AUTOCONNECT_URI defined in AutoConnectDefs.h.</span></dd> <dd><span class="apidef">AC_ONBOOTURI_ROOT</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Resetting the module redirects it to the AutoConnect root path. The root path is assumed to be AUTOCONNECT_URI defined in [`AutoConnectDefs.h`](api.md#defined-macros).</span></dd>
<dd><span class="apidef">AC_ONBOOTURI_HOME</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">It is redirected to the URI specified by [**AutoConnectConfig::homeUri**](apiconfig.md#homeuri).</span></dd> <dd><span class="apidef">AC_ONBOOTURI_HOME</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">It is redirected to the URI specified by [**AutoConnectConfig::homeUri**](apiconfig.md#homeuri).</span></dd>
</dl> </dl>
@ -189,6 +189,31 @@ Disable the first WiFi.begin() and start the captive portal. If this option is e
<dd><span class="apidef">false</span><span class="apidesc">Enable the first WiFi.begin() and it will start captive portal when connection failed. This is default.</span></dd> <dd><span class="apidef">false</span><span class="apidesc">Enable the first WiFi.begin() and it will start captive portal when connection failed. This is default.</span></dd>
</dl> </dl>
### <i class="fa fa-caret-right"></i> menuItems
Configure applying items of the [AutoConnect menu](menu.md). You can arbitrarily combine valid menus by coordinating the menuItems value.
<dl class="apidl">
<dt>**Type**</dt>
<dd><span class="apidef">uint16_t</span><span class="apidesc">It provides the combined **AC_MENUITEM_t** value of the item to apply to the AutoConnect menu.<br>Specify the value calculated from the **logical OR** by the AC_MENUITEM_t value of each item applied as a menu. It affects not only disappear the items from the menu also invalidates the URI they have. As a consequence, even if it accesses the URL directly will occur a 404 error.<br>The default value is logical OR of AC_MENUITEM_CONFIGNEW, AC_MENUITEM_OPENSSIDS, AC_MENUITEM_DISCONNECT, AC_MENUITEM_RESET, AC_MENUITEM_UPDATE and AC_MENUITEM_HOME.</span></dd>
<dt>**Value**</dt>
<dd><span class="apidef">AC_MENUITEM_NONE</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">No assign items except for the AutoConnectAux page item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_CONFIGNEW</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends [Configure new AP](menu.md#config-new-ap) item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_OPENSSIDS</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends [Open SSIDs](menu.md#open-ssids) item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_DISCONNECT</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends [Disconnect](menu.md#disconnect) item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_RESET</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends [Reset...](menu.md#reset) item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_UPDATE</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends [Update](menu.md#update) item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_HOME</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends [HOME](menu.md#home) item.</span></dd>
<dd><span class="apidef">AC_MENUITEM_DEVINFO</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Appends the **Device info** item which links to [AutoConnect statistics page](menu.md##where-the-from).</span></dd>
</dl>
!!! 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
AutoConnectConfig config;
config.menuItems = AC_MENUITEM_OPENSSIDS | AC_MENUITEM_HOME;
```
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.
### <i class="fa fa-caret-right"></i> netmask ### <i class="fa fa-caret-right"></i> netmask
Sets subnet mask for Soft AP in captive portal. When AutoConnect fails the initial WiFi.begin, it starts the captive portal with the IP address specified this. Sets subnet mask for Soft AP in captive portal. When AutoConnect fails the initial WiFi.begin, it starts the captive portal with the IP address specified this.
@ -197,6 +222,18 @@ Sets subnet mask for Soft AP in captive portal. When AutoConnect fails the initi
<dd><span class="apidef">IPAddress</span><span class="apidesc">The default value is **255.255.255.0**</span></dd> <dd><span class="apidef">IPAddress</span><span class="apidesc">The default value is **255.255.255.0**</span></dd>
</dl> </dl>
### <i class="fa fa-caret-right"></i> ota
Specifies to import the built-in OTA update class into the sketch. When this option is enabled, an **Update** item will appear in the AutoConnect menu, and the OTA update via Web browser will be automatically embedded to the Sketch.
<dl class="apidl">
<dt>**Type**</dt>
<dd>AC_OTA_t</dd>
<dt>**Value**</dt>
<dd><span class="apidef">AC_OTA_EXTRA</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">AutoConnect does not import AutoConnectOTA. This is the default.</span></dd>
<dd><span class="apidef">AC_OTA_BUILTIN</span><span class="apidesc"></span><span class="apidef">&nbsp;</span><span class="apidesc">Specifies to include AutoConnectOTA in the Sketch.</span></dd>
</dl>
### <i class="fa fa-caret-right"></i> portalTimeout ### <i class="fa fa-caret-right"></i> portalTimeout
Specify the timeout value of the captive portal in [ms] units. It is valid when the station is not connected and does not time out if the station is connected to the ESP module in SoftAP mode (i.e. Attempting WiFi connection with the portal function). If 0, the captive portal will not be timed-out. Specify the timeout value of the captive portal in [ms] units. It is valid when the station is not connected and does not time out if the station is connected to the ESP module in SoftAP mode (i.e. Attempting WiFi connection with the portal function). If 0, the captive portal will not be timed-out.
@ -267,7 +304,7 @@ Set flicker signal output according to WiFi connection status during AutoConnect
### <i class="fa fa-caret-right"></i> tickerPort ### <i class="fa fa-caret-right"></i> tickerPort
Specifies the GPIO port number to output the flicker signal of the ticker. The default assumes on the board dependent definition LED_BUILTIN macro redefined by **AUTOCONNECT_TICKER_PORT** in `AutoConnectDefs.h`. Specifies the GPIO port number to output the flicker signal of the ticker. The default assumes on the board dependent definition LED_BUILTIN macro redefined by **AUTOCONNECT_TICKER_PORT** in [`AutoConnectDefs.h`](api.md#defined-macros).
<dl class="apidl"> <dl class="apidl">
<dt>**Type**</dt> <dt>**Type**</dt>
<dd>uint8_t</dd> <dd>uint8_t</dd>

@ -8,9 +8,9 @@ AutoConnectUpdate(const String& host, const uint16_t port, const String& uri, co
<dl class="apidl"> <dl class="apidl">
<dt>**Parameters**</dt> <dt>**Parameters**</dt>
<dd><span class="apidef">host</span><span class="apidesc">Update server address. Specifies IP address or FQDN.</span></dd> <dd><span class="apidef">host</span><span class="apidesc">Update server address. Specifies IP address or FQDN.</span></dd>
<dd><span class="apidef">port</span><span class="apidesc">Specifies HTTP port for the updating process. The default is defined as the **AUTOCONNECT_UPDATE_PORT** macro in the `AutoConnectDefs.h` header file.</span></dd> <dd><span class="apidef">port</span><span class="apidesc">Specifies HTTP port for the updating process. The default is defined as the **AUTOCONNECT_UPDATE_PORT** macro in the [`AutoConnectDefs.h`](api.md#defined-macros) header file.</span></dd>
<dd><span class="apidef">uri</span><span class="apidesc">Specifies a URI on the update server that has deployed available binary sketch files.</span></dd> <dd><span class="apidef">uri</span><span class="apidesc">Specifies a URI on the update server that has deployed available binary sketch files.</span></dd>
<dd><span class="apidef">timeout</span><span class="apidesc">Specifies the maximum response time for the update server. The default is defined as the **AUTOCONNECT_UPDATE_TIMEOUT** macro in the `AutoConnectDefs.h` header file.</span></dt> <dd><span class="apidef">timeout</span><span class="apidesc">Specifies the maximum response time for the update server. The default is defined as the **AUTOCONNECT_UPDATE_TIMEOUT** macro in the [`AutoConnectDefs.h`](api.md#defined-macros) header file.</span></dt>
<dd><span class="apidef">ledOn</span><span class="apidesc">Active signal to light the LED ticker during the update. Specifies **HIGH** or **LOW**</span></dt> <dd><span class="apidef">ledOn</span><span class="apidesc">Active signal to light the LED ticker during the update. Specifies **HIGH** or **LOW**</span></dt>
</dl> </dl>
@ -82,7 +82,7 @@ void AutoConnectUpdate::setLedPin(int ledPin, uint8_t ledOn)
Sets the port and the ON signal level of the externally connected LED that should act as a ticker during the update process. Sets the port and the ON signal level of the externally connected LED that should act as a ticker during the update process.
<dl class="apidl"> <dl class="apidl">
<dt>**Parameter**</dt> <dt>**Parameter**</dt>
<dd><span class="apidef">ledPin</span><span class="apidesc">Specifies the PIN connected external LED for the ticker. The default is defined as the **AUTOCONNECT_TICKER_PORT** macro in the `AutoConnectDefs.h` header file and it is derived from the board-specific **LED_BUILTIN**. By default, the AutoConnectUpdate class does not use the ticker for boards without the LED_BUILTIN definition. If you connect the ticker LED externally, you need to specify the PIN using the [setLedPin](#setledpin) function.</span></dd> <dd><span class="apidef">ledPin</span><span class="apidesc">Specifies the PIN connected external LED for the ticker. The default is defined as the **AUTOCONNECT_TICKER_PORT** macro in the [`AutoConnectDefs.h`](api.md#defined-macros) header file and it is derived from the board-specific **LED_BUILTIN**. By default, the AutoConnectUpdate class does not use the ticker for boards without the LED_BUILTIN definition. If you connect the ticker LED externally, you need to specify the PIN using the [setLedPin](#setledpin) function.</span></dd>
<dd><span class="apidef">ledOn</span><span class="apidesc">Specifies the the ON signal level of the LED PIN port. It is **HIGH** or **LOW**.</span></dd> <dd><span class="apidef">ledOn</span><span class="apidesc">Specifies the the ON signal level of the LED PIN port. It is **HIGH** or **LOW**.</span></dd>
</dl> </dl>
@ -123,7 +123,7 @@ Update server address. Specifies IP address or FQDN.
HTTP port for the updating process. HTTP port for the updating process.
<dl class="apidl"> <dl class="apidl">
<dt>**Type**</dt> <dt>**Type**</dt>
<dd><span class="apidef">String</span><span class="apidesc">The default is defined as the **AUTOCONNECT_UPDATE_PORT** macro in the `AutoConnectDefs.h` header file.</span></dd> <dd><span class="apidef">String</span><span class="apidesc">The default is defined as the **AUTOCONNECT_UPDATE_PORT** macro in the [`AutoConnectDefs.h`](api.md#defined-macros) header file.</span></dd>
</dl> </dl>
### <i class="fa fa-caret-right"></i> uri ### <i class="fa fa-caret-right"></i> uri

@ -29,13 +29,15 @@ AutoConnect label texts are pre-assigned with a fixed string so that it can be d
<table> <table>
<tr><th>Label placed</th><th>Pre-defined text</th><th>ID (#define macro)</th></tr> <tr><th>Label placed</th><th>Pre-defined text</th><th>ID (#define macro)</th></tr>
<tr><td rowspan="6">Menu item</td><td>Configure new AP</td><td>AUTOCONNECT_MENULABEL_CONFIGNEW</td></tr> <tr><td rowspan="7">Menu item</td><td>Configure new AP</td><td>AUTOCONNECT_MENULABEL_CONFIGNEW</td></tr>
<tr><td>Open SSIDs</td><td>AUTOCONNECT_MENULABEL_OPENSSIDS</td></tr> <tr><td>Open SSIDs</td><td>AUTOCONNECT_MENULABEL_OPENSSIDS</td></tr>
<tr><td>Disconnect</td><td>AUTOCONNECT_MENULABEL_DISCONNECT</td></tr> <tr><td>Disconnect</td><td>AUTOCONNECT_MENULABEL_DISCONNECT</td></tr>
<tr><td>Reset...</td><td>AUTOCONNECT_MENULABEL_RESET</td></tr> <tr><td>Reset...</td><td>AUTOCONNECT_MENULABEL_RESET</td></tr>
<tr><td>HOME</td><td>AUTOCONNECT_MENULABEL_HOME</td></tr> <tr><td>HOME</td><td>AUTOCONNECT_MENULABEL_HOME</td></tr>
<tr><td>Update</td><td>AUTOCONNECT_MENULABEL_UPDATE</td></tr> <tr><td>Update</td><td>AUTOCONNECT_MENULABEL_UPDATE</td></tr>
<tr><td>Button label</td><td>RESET</td><td>AUTOCONNECT_BUTTONLABEL_RESET</td></tr> <tr><td>Device info</td><td>AUTOCONNECT_MENULABEL_DEVINFO</td></tr>
<tr><td rowspan="2">Button label</td><td>RESET</td><td>AUTOCONNECT_BUTTONLABEL_RESET</td></tr>
<tr><td>UPDATE</td><td>AUTOCONNECT_BUTTONLABEL_UPDATE</td></tr>
<tr><td rowspan="8">Page title</td><td>Page not found</td><td>AUTOCONNECT_PAGETITLE_NOTFOUND</td></tr> <tr><td rowspan="8">Page title</td><td>Page not found</td><td>AUTOCONNECT_PAGETITLE_NOTFOUND</td></tr>
<tr><td>AutoConnect config</td><td>AUTOCONNECT_PAGETITLE_CONFIG</td></tr> <tr><td>AutoConnect config</td><td>AUTOCONNECT_PAGETITLE_CONFIG</td></tr>
<tr><td>AutoConnect connecting</td><td>AUTOCONNECT_PAGETITLE_CONNECTING</td></tr> <tr><td>AutoConnect connecting</td><td>AUTOCONNECT_PAGETITLE_CONNECTING</td></tr>
@ -64,6 +66,10 @@ AutoConnect label texts are pre-assigned with a fixed string so that it can be d
<tr><td>Passphrase</td><td>AUTOCONNECT_PAGECONFIG_PASSPHRASE</td></tr> <tr><td>Passphrase</td><td>AUTOCONNECT_PAGECONFIG_PASSPHRASE</td></tr>
<tr><td>Enable DHCP</td><td>AUTOCONNECT_PAGECONFIG_ENABLEDHCP</td></tr> <tr><td>Enable DHCP</td><td>AUTOCONNECT_PAGECONFIG_ENABLEDHCP</td></tr>
<tr><td>Apply</td><td>AUTOCONNECT_PAGECONFIG_APPLY</td></tr> <tr><td>Apply</td><td>AUTOCONNECT_PAGECONFIG_APPLY</td></tr>
<tr><td rowspan="4">Page:[update] text</td><td>Updating firmware</td><td>AUTOCONNECT_TEXT_UPDATINGFIRMWARE</td></tr>
<tr><td>Select firmware:</td><td>AUTOCONNECT_TEXT_SELECTFIRMWARE</td></tr>
<tr><td>Successfully updated, rebooting...</td><td>AUTOCONNECT_TEXT_OTASUCCESS</td></tr>
<tr><td>Failed to update:</td><td>AUTOCONNECT_TEXT_OTAFAILURE</td></tr>
<tr><td>Page:[connection failed]</td><td>Connection Failed</td><td>AUTOCONNECT_PAGECONNECTIONFAILED_CONNECTIONFAILED</td></tr> <tr><td>Page:[connection failed]</td><td>Connection Failed</td><td>AUTOCONNECT_PAGECONNECTIONFAILED_CONNECTIONFAILED</td></tr>
<tr><td>Text</td><td>No saved credentials.</td><td>AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS</td></tr> <tr><td>Text</td><td>No saved credentials.</td><td>AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS</td></tr>
<tr><td rowspan="3">Menu Text</td><td>Connecting</td><td>AUTOCONNECT_MENUTEXT_CONNECTING</td></tr> <tr><td rowspan="3">Menu Text</td><td>Connecting</td><td>AUTOCONNECT_MENUTEXT_CONNECTING</td></tr>
@ -88,7 +94,7 @@ You prepare its header file and place it in the `src` folder of the project fold
When you store `mylabels.h` containing the new label text definition in the `src` folder, your Arduino project folder structure should look like this: When you store `mylabels.h` containing the new label text definition in the `src` folder, your Arduino project folder structure should look like this:
``` ```javascript
<Project folder> <Project folder>
|-- <pio> |-- <pio>
|-- <.vscode> |-- <.vscode>

@ -1,3 +1,8 @@
#### [1.1.5] Apr. 15, 2020
- Changed the [bootUri behavior](advancedusage.md#assign-user-sketchs-home-path) to be an automatic pop-up at the captive portal.
- Supports AutoConnect [menu configuration](menu.md#applying-the-active-menu-items).
- Supports the built-in OTA feature as [AutoConnectOTA](otabrowser.md#updates-with-the-web-browserupdated-wv115).
#### [1.1.4] Feb. 14, 2020 #### [1.1.4] Feb. 14, 2020
- Supports for overriding text of the menu items with user-defined labels. - Supports for overriding text of the menu items with user-defined labels.
- Fixed the compiler warning with experimental WiFi mode of ESP8266. - Fixed the compiler warning with experimental WiFi mode of ESP8266.

@ -207,6 +207,6 @@ There may be 0xff as an invalid data in the credential saving area. The 0xff are
!!! note "AutoConnectCredential has changed" !!! note "AutoConnectCredential has changed"
It was lost AutoConnectCredential backward compatibility. Credentials saved by AutoConnect v1.0.3 (or earlier) will not work properly with AutoConnect v1.1.0. You need to erase the flash of the ESP module using the esptool before the sketch uploading. It was lost AutoConnectCredential backward compatibility. Credentials saved by AutoConnect v1.0.3 (or earlier) will not work properly with AutoConnect v1.1.0. You need to erase the flash of the ESP module using the esptool before the sketch uploading.
``` ```powershell
esptool -c esp8266 (or esp32) - p [COM_PORT] erase_flash esptool -c esp8266 (or esp32) -p [COM_PORT] erase_flash
``` ```

@ -9,6 +9,7 @@
} }
.md-typeset pre { .md-typeset pre {
background-color: #272822 !important;
font-size: 12px; font-size: 12px;
} }

@ -149,31 +149,31 @@ Here, represent examples the typical regular expression for the input validation
### <img src="images/regexp.png" align="top"> URL ### <img src="images/regexp.png" align="top"> URL
``` ```powershell
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
``` ```
### <img src="images/regexp.png" align="top"> DNS hostname ### <img src="images/regexp.png" align="top"> DNS hostname
``` ```powershell
^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$ ^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$
``` ```
### <img src="images/regexp.png" align="top"> email address [^2] ### <img src="images/regexp.png" align="top"> email address [^2]
``` ```powershell
^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$ ^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$
``` ```
### <img src="images/regexp.png" align="top"> IP Address ### <img src="images/regexp.png" align="top"> IP Address
``` ```powershell
^(([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])$ ^(([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])$
``` ```
### <img src="images/regexp.png" align="top"> Date as MM/DD/YYYY [^3] ### <img src="images/regexp.png" align="top"> Date as MM/DD/YYYY [^3]
``` ```powershell
^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d$ ^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d$
``` ```

@ -32,7 +32,7 @@ You can avoid a compile error in one of two ways:
1. Disable an AutoConnectUpdate feature if you don't need. 1. Disable an AutoConnectUpdate feature if you don't need.
You can disable the AutoConnectUpdate feature by commenting out the **AUTOCONNECT_USE_UPDATE** macro in the `AutoConnectDefs.h` header file. You can disable the AutoConnectUpdate feature by commenting out the [**AUTOCONNECT_USE_UPDATE**](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDefs.h#L34) macro in the [`AutoConnectDefs.h`](api.md#defined-macros) header file.
```cpp ```cpp
#define AUTOCONNECT_USE_UPDATE #define AUTOCONNECT_USE_UPDATE
``` ```
@ -115,7 +115,7 @@ If ESP8266 hang up after reset by AutoConnect menu, perhaps manual reset is not
If you received the following message, the boot mode is still sketch uploaded. It needs to the manual reset once. If you received the following message, the boot mode is still sketch uploaded. It needs to the manual reset once.
``` ```powershell
ets Jan 8 2013,rst cause:2, boot mode:(1,6) or (1,7) ets Jan 8 2013,rst cause:2, boot mode:(1,6) or (1,7)
ets Jan 8 2013,rst cause:4, boot mode:(1,6) or (1,7) ets Jan 8 2013,rst cause:4, boot mode:(1,6) or (1,7)
wdt reset wdt reset
@ -124,7 +124,7 @@ wdt reset
The correct boot mode for starting the sketch is **(3, x)**. The correct boot mode for starting the sketch is **(3, x)**.
!!! info "ESP8266 Boot Messages" !!! info "ESP8266 Boot Messages"
It is described by [ESP8266 Non-OS SDK API Reference](view-source:https://www.espressif.com/en/products/hardware/esp8266ex/resources), section A.5. It is described by [ESP8266 Non-OS SDK API Reference](https://www.espressif.com/en/products/hardware/esp8266ex/resources), section A.5.
| Messages | Description | | Messages | Description |
|----------|-------------| |----------|-------------|
@ -137,7 +137,7 @@ You can use the [AutoConnect::onDetect](api.md#ondetect) exit routine. For more
## <i class="fa fa-question-circle"></i> How change HTTP port? ## <i class="fa fa-question-circle"></i> How change HTTP port?
HTTP port number is defined as a macro in [AutoConnectDefs.h](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDefs.h#L112) header file. You can change it directly with several editors and must re-compile. HTTP port number is defined as a macro in [AutoConnectDefs.h](https://github.com/Hieromon/AutoConnect/blob/master/src/AutoConnectDefs.h#L123) header file. You can change it directly with several editors and must re-compile.
```cpp ```cpp
#define AUTOCONNECT_HTTPPORT 80 #define AUTOCONNECT_HTTPPORT 80
@ -154,7 +154,7 @@ To completely remove ArduinoJson at compile-time from the binary, you need to de
To exclude ArduinoJson at compile-time, give the following `#define` directive as a compiler option such as the [arduino-cli](https://github.com/arduino/arduino-cli) or [PlatformIO](https://platformio.org/). To exclude ArduinoJson at compile-time, give the following `#define` directive as a compiler option such as the [arduino-cli](https://github.com/arduino/arduino-cli) or [PlatformIO](https://platformio.org/).
``` ```cpp
#define AUTOCONNECT_NOUSE_JSON #define AUTOCONNECT_NOUSE_JSON
``` ```
@ -200,7 +200,7 @@ If the sketch is correct, a JSON syntax error may have occurred. In this case, a
## <i class="fa fa-question-circle"></i> Saved credentials are wrong or lost. ## <i class="fa fa-question-circle"></i> Saved credentials are wrong or lost.
A structure of AutoConnect saved credentials has changed two times throughout enhancement with v1.0.3 and v1.1.0. In particular, due to enhancements in v1.1.0, AutoConnectCredential data structure has lost the backward compatibility with previous versions. You must erase the flash of the ESP module using the esptool completely to save the credentials correctly with v1.1.0. A structure of AutoConnect saved credentials has changed two times throughout enhancement with v1.0.3 and v1.1.0. In particular, due to enhancements in v1.1.0, AutoConnectCredential data structure has lost the backward compatibility with previous versions. You must erase the flash of the ESP module using the esptool completely to save the credentials correctly with v1.1.0.
``` ```powershell
esptool -c esp8266 (or esp32) -p [COM_PORT] erase_flash esptool -c esp8266 (or esp32) -p [COM_PORT] erase_flash
``` ```
@ -216,7 +216,7 @@ Also, you can check the memory running out status by rebuilding the sketch with
If the heap memory is insufficient, the following message is displayed on the serial console. If the heap memory is insufficient, the following message is displayed on the serial console.
``` ```powershell
[PB] Failed building, free heap:<Size of free heap> [PB] Failed building, free heap:<Size of free heap>
``` ```

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 111 KiB

@ -30,8 +30,8 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="1" inkscape:zoom="1"
inkscape:cx="651.92637" inkscape:cx="296.75158"
inkscape:cy="34.265665" inkscape:cy="216.8199"
inkscape:document-units="mm" inkscape:document-units="mm"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
showgrid="false" showgrid="false"
@ -41,8 +41,8 @@
fit-margin-bottom="0" fit-margin-bottom="0"
inkscape:window-width="1728" inkscape:window-width="1728"
inkscape:window-height="951" inkscape:window-height="951"
inkscape:window-x="1256" inkscape:window-x="1435"
inkscape:window-y="402" inkscape:window-y="57"
inkscape:window-maximized="0" inkscape:window-maximized="0"
inkscape:snap-global="false" inkscape:snap-global="false"
units="px" /> units="px" />
@ -54,7 +54,7 @@
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title> <dc:title />
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
@ -63,6 +63,17 @@
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer1" id="layer1"
transform="translate(-12.547598,-15.546577)"> transform="translate(-12.547598,-15.546577)">
<rect
style="opacity:0.36199999;vector-effect:none;fill:#3366cc;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
id="rect948"
width="45.150471"
height="115.4073"
x="145.46172"
y="24.934029"
rx="0.60422629"
ry="0.60422629"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2" />
<image <image
y="75.296074" y="75.296074"
x="12.547598" x="12.547598"
@ -344,7 +355,7 @@
id="rect1235" id="rect1235"
width="14.40583" width="14.40583"
height="44.609631" height="44.609631"
x="118.32714" x="114.62297"
y="25.193104" y="25.193104"
rx="0.60422671" rx="0.60422671"
ry="0.60422671" ry="0.60422671"
@ -356,24 +367,21 @@
width="14.40583" width="14.40583"
height="108.9034" height="108.9034"
x="149.43047" x="149.43047"
y="31.543108" y="28.368105"
rx="0.60422671" rx="0.60422671"
ry="0.60422671" ry="0.60422671"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2" /> inkscape:export-ydpi="115.2" />
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:tb-rl;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333333px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332;"
x="156.66739" x="156.66739"
y="85.779831" y="82.604828"
id="text1239-6" id="text1239-6"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><tspan inkscape:export-ydpi="115.2"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan1237-5" id="tspan926">AutoConnectOTA</tspan></text>
x="85.779831"
y="156.66739"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:tb-rl;text-anchor:middle;stroke-width:0.26458332">ESP8266HTTPUpdateServer</tspan></text>
<path <path
id="path1371" id="path1371"
d="M 110.00865,33.59853 H 97.95942 c -0.26445,0 -0.47887,0.21442 -0.47887,0.47887 v 2.23473 c 0,0.26446 0.21442,0.47887 0.47887,0.47887 h 12.04923 v 1.83803 c 0,0.85327 1.03161,1.28058 1.63499,0.67724 l 3.43426,-3.43426 c 0.37404,-0.37404 0.37404,-0.98045 0,-1.35444 l -3.43426,-3.43427 c -0.60334,-0.60333 -1.63499,-0.17602 -1.63499,0.67725 z" d="M 110.00865,33.59853 H 97.95942 c -0.26445,0 -0.47887,0.21442 -0.47887,0.47887 v 2.23473 c 0,0.26446 0.21442,0.47887 0.47887,0.47887 h 12.04923 v 1.83803 c 0,0.85327 1.03161,1.28058 1.63499,0.67724 l 3.43426,-3.43426 c 0.37404,-0.37404 0.37404,-0.98045 0,-1.35444 l -3.43426,-3.43427 c -0.60334,-0.60333 -1.63499,-0.17602 -1.63499,0.67725 z"
@ -463,7 +471,7 @@
width="14.40583" width="14.40583"
height="75.036728" height="75.036728"
x="171.50305" x="171.50305"
y="31.543108" y="28.368105"
rx="0.60422671" rx="0.60422671"
ry="0.60422671" ry="0.60422671"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
@ -472,31 +480,17 @@
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:tb-rl;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:tb-rl;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="178.73997" x="178.73997"
y="68.958122" y="65.783119"
id="text1239-6-0" id="text1239-6-0"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><tspan inkscape:export-ydpi="115.2"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan1237-5-6" id="tspan924"
x="68.958122" x="66.312286"
y="178.73997" y="178.21082">Update class of Arduino core</tspan></text>
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:tb-rl;text-anchor:middle;stroke-width:0.26458332">ESP8266HTTPUpdate</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="167.95082"
y="29.151556"
id="text1493-91-9"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><tspan
sodipodi:role="line"
id="tspan1491-3-7"
x="167.95082"
y="29.151556"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52777767px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;stroke-width:0.26458332">ESP8266 Arduino Core</tspan></text>
<path <path
id="path1371-5-3-0-2-8" id="path1371-5-3-0-2-8"
d="m 165.10961,86.653036 c 0,0.85326 1.03161,1.28057 1.63499,0.67723 l 3.43425,-3.43425 c 0.37404,-0.37405 0.37404,-0.98046 0,-1.35445 l -3.43425,-3.43427 c -0.60334,-0.60333 -1.63499,-0.17602 -1.63499,0.67725 -0.0135,2.99825 0,4.18637 0,6.86849 z" d="m 165.10961,83.478034 c 0,0.85326 1.03161,1.28057 1.63499,0.67723 l 3.43425,-3.43425 c 0.37404,-0.37405 0.37404,-0.98046 0,-1.35445 l -3.43425,-3.43427 c -0.60334,-0.60333 -1.63499,-0.17602 -1.63499,0.67725 -0.0135,2.99825 0,4.18637 0,6.86849 z"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
style="fill:#3366cc;stroke-width:0.26458332" style="fill:#3366cc;stroke-width:0.26458332"
sodipodi:nodetypes="ccccccc" sodipodi:nodetypes="ccccccc"
@ -504,7 +498,7 @@
inkscape:export-ydpi="115.2" /> inkscape:export-ydpi="115.2" />
<path <path
id="path1371-5-3-0-2-84" id="path1371-5-3-0-2-84"
d="m 180.30222,126.23079 v -17.38126 c 0,-0.26445 -0.21445,-0.56964 -0.47888,-0.57241 l -2.23472,-0.0234 c -0.26445,-0.003 -0.47888,0.34281 -0.47888,0.60751 v 17.36954 h -1.83803 c -0.85326,0 -1.28057,1.03161 -0.67723,1.63499 l 3.43425,3.43425 c 0.37405,0.37404 0.98046,0.37404 1.35445,0 l 3.43427,-3.43425 c 0.60333,-0.60334 0.17602,-1.63499 -0.67725,-1.63499 z" d="m 180.30222,123.05577 v -17.38126 c 0,-0.26445 -0.21445,-0.56964 -0.47888,-0.57241 l -2.23472,-0.0234 c -0.26445,-0.003 -0.47888,0.34281 -0.47888,0.60751 v 17.36954 h -1.83803 c -0.85326,0 -1.28057,1.03161 -0.67723,1.63499 l 3.43425,3.43425 c 0.37405,0.37404 0.98046,0.37404 1.35445,0 l 3.43427,-3.43425 c 0.60333,-0.60334 0.17602,-1.63499 -0.67725,-1.63499 z"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
style="fill:#3366cc;stroke-width:0.26458332" style="fill:#3366cc;stroke-width:0.26458332"
sodipodi:nodetypes="csssscsccccsc" sodipodi:nodetypes="csssscsccccsc"
@ -525,43 +519,32 @@
sodipodi:nodetypes="csssscsccccsc" sodipodi:nodetypes="csssscsccccsc"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2" /> inkscape:export-ydpi="115.2" />
<rect
style="opacity:0.36199999;vector-effect:none;fill:#3366cc;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill"
id="rect948"
width="45.150471"
height="118.58781"
x="145.46172"
y="24.928524"
rx="0.60422629"
ry="0.60422629"
inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2" />
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.15875;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.15875;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="178.23099" x="178.23099"
y="121.06407" y="117.88908"
id="text1493-91-8" id="text1493-91-8"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><tspan inkscape:export-ydpi="115.2"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan1491-3-2" id="tspan1491-3-2"
x="178.23099" x="178.23099"
y="121.06407" y="117.88908"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;stroke:#ffffff;stroke-width:0.15875;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">UPDATE</tspan></text> style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;stroke:#ffffff;stroke-width:0.15875;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">UPDATE</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:tb-rl;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333333px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332;"
x="125.21369" x="121.50953"
y="47.255043" y="47.255043"
id="text1239" id="text1239"
inkscape:export-xdpi="115.2" inkscape:export-xdpi="115.2"
inkscape:export-ydpi="115.2"><tspan inkscape:export-ydpi="115.2"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan1237" id="tspan1237"
x="47.255043" x="47.78421"
y="125.21369" y="120.98036"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:tb-rl;text-anchor:middle;stroke-width:0.26458332">AutoConnectAux</tspan></text> style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333333px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:tb;text-anchor:middle;stroke-width:0.26458332;">AutoConnectAux</tspan></text>
<image <image
y="133.65536" y="133.65536"
x="173.49591" x="173.49591"

Before

Width:  |  Height:  |  Size: 252 KiB

After

Width:  |  Height:  |  Size: 251 KiB

@ -39,11 +39,11 @@ Easy implementing the Web interface constituting the WLAN for ESP8266/ESP32 WiFi
<span style="float:left;width:242px;height:425px;border:1px solid lightgrey;"><img data-gifffer="images/aux_ov.gif" data-gifffer-width="240" data-gifffer-height="423" /></span> <span style="float:left;width:242px;height:425px;border:1px solid lightgrey;"><img data-gifffer="images/aux_ov.gif" data-gifffer-width="240" data-gifffer-height="423" /></span>
</div> </div>
### <i class="fa fa-arrow-circle-right" aria-hidden="true"></i> Quick and easy to equip the [OTA update feature](otaupdate.md) <sup><sub>ENHANCED w/v1.0.0</sub></sup> ### <i class="fa fa-arrow-circle-right" aria-hidden="true"></i> Quick and easy to equip the [OTA update feature](otaupdate.md) <sup><sub>UPDATED w/v1.1.5</sub></sup>
<span class="lead">You can quickly and easily equip the OTA update feature to your sketch and also you can operate the firmware update process via OTA from AutoConnect menu.</span> <span class="lead">You can quickly and easily equip the OTA update feature to your sketch and also you can operate the firmware update process via OTA from AutoConnect menu.</span>
<span style="display:block;margin-left:auto;margin-right:auto;width:282px;height:362px;border:1px solid lightgrey;"><img data-gifffer="images/webupdate.gif" data-gifffer-height="360" data-gifffer-width="280" /></span> <span style="display:block;margin-left:auto;margin-right:auto;width:294px;height:482px;border:1px solid lightgrey;"><img data-gifffer="images/webupdate.gif" data-gifffer-height="480" data-gifffer-width="292" /></span>
## Installation ## Installation

@ -12,12 +12,13 @@ The following screen will appear as the AutoConnect menu when you access to **Au
## <i class="fa fa-bars"></i> Right on top ## <i class="fa fa-bars"></i> Right on top
Currently, AutoConnect supports four menus. Undermost menu as "HOME" returns to the home path of its sketch. Currently, AutoConnect supports six menus. Undermost menu as "HOME" returns to the home path of its sketch.
- **Configure new AP**: Configure SSID and Password for new access point. - **Configure new AP**: Configure SSID and Password for new access point.
- **Open SSIDs**: Opens the past SSID which has been established connection from the flash. - **Open SSIDs**: Opens the past SSID which has been established connection from the flash.
- **Disconnect**: Disconnects current connection. - **Disconnect**: Disconnects current connection.
- **Reset...**: Rest the ESP8266/ESP32 module. - **Reset...**: Rest the ESP8266/ESP32 module.
- **Update**: OTA updates. (Optional)
- **HOME**: Return to user home page. - **HOME**: Return to user home page.
<img src="images/menu.png" style="width:280px;" /> <img src="images/menu.png" style="width:280px;" />
@ -43,8 +44,8 @@ After WiFi connected, AutoConnect will automatically save the established SSID a
!!! note "Saved credentials data structure has changed" !!! 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. 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.
``` ```powershell
esptool -c esp8266 (or esp32) - p [COM_PORT] erase_flash esptool -c esp8266 (or esp32) -p [COM_PORT] erase_flash
``` ```
## <i class="fa fa-bars"></i> Disconnect ## <i class="fa fa-bars"></i> Disconnect
@ -66,6 +67,13 @@ Resetting the ESP8266/ESP32 module will initiate a reboot. When the module resta
If the sketch has custom Web pages, the AutoConnect menu lines them up with the AutoConnect's items. Details for [Custom Web pages in AutoConnect menu](acintro.md#custom-web-pages-in-autoconnectmenu). If the sketch has custom Web pages, the AutoConnect menu lines them up with the AutoConnect's items. Details for [Custom Web pages in AutoConnect menu](acintro.md#custom-web-pages-in-autoconnectmenu).
## <i class="fa fa-bars"></i> Update
If you specify [AutoConnectConfig::ota](apiconfig.md#ota) to import the OTA update feature into Sketch, an item will appear in the menu list as **Update**.
!!! note "The Update menu item will appear only AutoConnectOTA enabled"
The Update item is displayed automatically in the menu only when [AutoConnectConfig::ota](apiconfig.md#ota) is specified with **AC_OTA_BUILTIN** or [AutoConnectUpdate](otaserver.md#how-to-embed-autoconnectupdate-to-your-sketch) is attached.
## <i class="fa fa-bars"></i> HOME ## <i class="fa fa-bars"></i> HOME
A **HOME** item at the bottom of the menu list is a link to the home path, and the default URI is `/` which is defined by `AUTOCONNECT_HOMEURI` in **AutoConnectDefs.h** header file. A **HOME** item at the bottom of the menu list is a link to the home path, and the default URI is `/` which is defined by `AUTOCONNECT_HOMEURI` in **AutoConnectDefs.h** header file.
@ -76,6 +84,38 @@ A **HOME** item at the bottom of the menu list is a link to the home path, and t
Also, you can change the HOME path using the AutoConnect API. The [**AutoConnect::home**](api.md#home) function sets the URI as a link of the HOME item in the AutoConnect menu. Also, you can change the HOME path using the AutoConnect API. The [**AutoConnect::home**](api.md#home) function sets the URI as a link of the HOME item in the AutoConnect menu.
## <i class="fa fa-bars"></i> Applying the active menu items
Each of the above menu items can be configured with a Sketch. [AutoConnectConfig::menuItems](apiconfig.md#menuitems) specifies the menu items that will be enabled at runtime. You can also adjust available menu items using [AutoConnect::enableMenu](api.md#enablemenu) and [AutoConnect::disableMenu](api.md#disablemenu) function. It is an alternative to [AutoConnectConfig::menuItems](apiconfig.md#menuitems) and provides a shortcut to avoid using AutoConnectConfig.
For example, by disabling the [Configure new AP](#configure-new-ap) and [Disconnect](#disconnect) item, you can prevent the configuration for unknown access points.
```cpp
AutoConnect portal;
AutoConnectConfig config;
void setup() {
config.menuItems = AC_MENUITEM_OPENSSIDS | AC_MENUITEM_RESET | AC_MENUITEM_HOME;
portal.config(config);
}
```
The next is another way to achieve the same effect.
```cpp
AutoConnect portal;
void setup() {
portal.disableMenu(AC_MENUITEM_CONFIGNEW | AC_MENUITEM_DISCONNECT);
portal.config(config);
}
```
The result of executing the above Sketch is as below:
<img src="images/applymenu.png" style="border-style:solid;border-width:1px;border-color:lightgrey;width:280px;" />
Details for [AutoConnectConfig::menuItems](apiconfig.md#menuitems).
## <i class="fa fa-bars"></i> Attaching to AutoConnect menu ## <i class="fa fa-bars"></i> Attaching to AutoConnect menu
The AutoConnect menu can contain your sketch's web pages as extra items as a custom. It works for HTML pages implemented by the **ESP8266WebServer::on** handler or the **WebServer::on** handler for ESP32. That is, you can make them invoke the legacy web pages from the AutoConnect menu. The below screen-shot is the result of adding an example sketch for the ESP8266WebServer library known as [FSBrowser](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer/examples/FSBrowser) to the AutoConnect menu item. It can add Edit and List items with little modification to the legacy sketch code. The AutoConnect menu can contain your sketch's web pages as extra items as a custom. It works for HTML pages implemented by the **ESP8266WebServer::on** handler or the **WebServer::on** handler for ESP32. That is, you can make them invoke the legacy web pages from the AutoConnect menu. The below screen-shot is the result of adding an example sketch for the ESP8266WebServer library known as [FSBrowser](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer/examples/FSBrowser) to the AutoConnect menu item. It can add Edit and List items with little modification to the legacy sketch code.

@ -1,21 +1,141 @@
## Updates with the Web Browser ## Updates with the Web Browser&nbsp;<sup><sub>UPDATED w/v1.1.5</sub></sup>
You can implement the user sketch as described in the [ESP8266 Arduino Core documentation](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#implementation-overview) to realize using the web browser as an update client. By incorporating the ESP8266HTTPUpdateServer class into AutoConnect, you can operate the dialog page for selecting the updating binary sketch file owned by ESP8266HTTPUpdateServer from the AutoConnect menu. AutoConnect features a built-in OTA function to update ESP module firmware. You can easily make the Sketch that equips OTA and able to operate with the AutoConnect menu. As the **AutoConnectOTA** class, which is compliant with OTA updates using a web browser as described in the [ESP8266 Arduino Core documentation](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#implementation-overview).
Update feature with a web browser is implemented using ESP8266HTTPUpdateServer class and ESP8266mDNS class. However, **ESP32 Arduino core does not provide a class implementation equivalent to ESP8266HTTPUpdateServer**. Therefore, it is necessary to implement an HTTPUpdateServer class for ESP32 to realize the update using a Web browser. **The AutoConnect library includes an implementation of the HTTPUpdateServer class for ESP32 to make it easy for you to experience**. [^1] You will be able to import the AutoConnectOTA class into your sketch just by specifying [AutoConnectConfig::ota](apiconfig.md#ota). By incorporating the AutoConnectOTA class into your Sketch, you can have an OTA updating feature which able to updating binary sketch from the AutoConnect menu.
[^1]: You can find the implementation of the **HTTPUpdateServer** class in the **WebUpdate** folder included in the **AutoConnect library examples folder**. <span style="display:block;margin-left:auto;margin-right:auto;width:292px;height:482px;border:1px solid lightgrey;"><img data-gifffer="images/webupdate.gif" data-gifffer-height="480" data-gifffer-width="290" /></span>
The AutoConnectOTA feature is implemented based on the [Updater class](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#updater-class) of the ESP8266 arduino core library. Its Updater class is also supported by the ESP32 Arduino core, so you can commonly import AutoConnectOTA into the Sketch without being aware of the differences between ESP8266 and ESP32 modules.
<img src="images/webupdate.png" width="480" /> <img src="images/webupdate.png" width="480" />
!!! warning "For the client devices equipped with Android OS" !!! info "Limitation of AutoConnectOTA with authentication"
Depending on the state of Android OS configuration, Bonjour service may not be incorporated. This method does not work with some Android devices as the client. AutoConnectOTA does not support authentication in v1.1.5 yet. It is planned for inclusion in AutoConnect v1.2.0, which will support HTTP authentication.
### <i class="fa fa-edit"></i> How to embed AutoConnectOTA in your sketch
To embed the AutoConnectOTA class into your sketch, basically follow these steps:
1. Include `ESP8266WiFi.h`, `ESP8266WebServer.h` and `AutoConnect.h` as usual.[^1]
2. Declare an ESP8266WebServer object. It's optional. (as WebServer for ESP32)
3. Declare an AutoConnect object, with an argument as ESP8266WebServer if separate the declarations.
4. Declare an AutoConnectConfig object.
5. Declare an AutoConnectAux object for your sketch own if needed.
6. Perform the following procedure steps in the `setup()` function:
1. Set [AutoConnectConfig::ota](apiconfig.md#ota) to **AC_OTA_BUILTIN** and configure AutoConnect.
2. Load the AutoConnectAux pages declared in step #4 for your application.
3. Join these pages to AutoConnect.
4. Invokes [AutoConnect::begin](api.md#begin) function.
7. Invokes [AutoConnect::handleClient](api.md#handleclient) function in the `loop()`.
```cpp
#include <ESP8266WiFi.h> // Step #1
#include <ESP8266WebServer.h> // Step #1
#include <AutoConnect.h> // Step #1
ESP8266WebServer server; // Step #2
AutoConnect portal(server); // Step #3
AutoConnectConfig config; // Step #4
AutoConnectAux hello; // Step #5
static const char HELLO_PAGE[] PROGMEM = R"(
{ "title": "Hello world", "uri": "/", "menu": true, "element": [
{ "name": "caption", "type": "ACText", "value": "<h2>Hello, world</h2>", "style": "text-align:center;color:#2f4f4f;padding:10px;" },
{ "name": "content", "type": "ACText", "value": "In this page, place the custom web page handled by the sketch application." } ]
}
)"; // Step #5
void setup() {
config.ota = AC_OTA_BUILTIN; // Step #6.a
portal.config(config); // Step #6.a
hello.load(HELLO_PAGE); // Step #6.b
portal.join({ hello }); // Step #6.c
portal.begin(); // Step #6.d
}
void loop() {
portal.handleClient(); // Step #7
}
```
[^1]:For ESP32, change the following items:
- Change the include directives appropriately for the ESP32 environment.
- Change ESP8266WebServer to Web.
!!! faq "How LED ticking during updates"
AutoConnectOTA applies LED ticking during updates automatically. The destination LED port and ticker drive depends on [AutoConnectConfig::tickerPort](apiconfig.md#tickerport) and [AutoConnectConfig::tickerOn](apiconfig.md#tickeron) specifying.
**IMPORTANT**
The AutoConnectOTA activates the ticker constantly regardless of the [AutoConnectConfig::ticker](apiconfig.md#ticker) value. If you want to stop the ticker output to GPIO during updates, give `0xff` to [AutoConnectConfig::tickerPort](apiconfig.md#tickerport).
### <i class="fa fa-wrench"></i> AutoConnectOTA allocation URI
AutoConnectOTA has implemented using AutoConnectAUX. So it occupies two URIs by default. An update operation page is assigned to **AUTOCONNECT_URI_UPDATE** and the binary file uploader for the update is assigned to **AUTOCONNECT_URI_UPDATE_ACT**. These symbols are defined in the `AutoConnectDefs.h` header file as follows:
```cpp
#define AUTOCONNECT_URI "/_ac"
#define AUTOCONNECT_URI_UPDATE AUTOCONNECT_URI "/update"
#define AUTOCONNECT_URI_UPDATE_ACT AUTOCONNECT_URI "/update_act"
```
Therefore, the normal Sketch that imports AutoConnectOTA while keeping the default, you cannot use the two URIs `/_ac/update` and `/_ac/update_act` for your specific. If you want to use the URIs for any purpose other than AutoConnectOTA, you need to override the `AutoConnectDefs.h` definition at compile time. It can be overwritten by giving the build flags for platformio.ini as follows with the PlatformIO environment for example.
```ini
build_flags =
-DAUTOCONNECT_URI_UPDATE='"/YOURURI"'
-DAUTOCONNECT_URI_UPDATE_ACT='"/YOURURIACT"'
```
### <i class="fa fa-wrench"></i> Timing of AutoConnectOTA instantiation
It will be born during [AutoConnect::handleClient](api.md#handleclient) process. AutoConnect will evaluate the enabled state of [AutoConnectConfig::ota](apiconfig.md#ota) each time the handleClient is executed, and if OTA is enabled then it creates an AutoConnectAux internally and assigns it to the update page. At this time, AutoConnectOTA is also instantiated together. The generated AUX page containing AutoConnectOTA is bound to AutoConnect inside the AutoConnect::handleClient process.
If you want to attach AutoConnectOTA dynamically with an external trigger, you can sketch like this:
_This sketch imports the OTA update feature with an external switch assigned to the GPIO pin. While the trigger not occurs, AutoConnect OTA will not be imported into Sketch and will not appear on the menu list._
```cpp
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <AutoConnect.h>
#define TRIGGER 4 // pin assigned to external trigger switch
AutoConnect portal;
AutoConnectConfig config;
void setup() {
pinMode(TRIGGER, INPUT);
portal.begin();
}
void loop() {
if (digitalRead(TRIGGER) == HIGH) {
config.ota = AC_OTA_BUILTIN;
portal.config(config);
}
portal.handleClient();
}
```
!!! note "AutoConnectOTA **cannot** detach dynamically"
Once imported, AutoConnectOTA cannot be removed from the Sketch. It can be only excluded from the menu by overriding [AutoConnectConfig::menuItems](apiconfig.md#menuitems). In this case, the AutoConnectOTA instance remains as a residue.
### <i class="fa fa-wrench"></i> How to make the binary sketch
Binary sketch files for updating can be retrieved using the Arduino IDE. Open the **Sketch** menu and select the **Export compiled Binary**, then starts compilation.
<img src="images/export_binary.png" width="450" />
When the compilation is complete, a binary sketch will save with the extension `.bin` in the same folder as the sketch.
### <i class="fa fa-edit"></i> How to embed ESP8266HTTPUpdateServer in AutoConnect ### <i class="fa fa-edit"></i> 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: To embed the ESP8266HTTPUpdateServer class with AutoConnect into your sketch, basically follow these steps:
1. Include `ESP8266mDNS.h` and `ESP8266HTTPUpdateServer.h`, also `WiFiClient.h`, in addition to the usual directives as `ESP8266WebServer.h` and `AutoConnect.h`. 1. Include `ESP8266HTTPUpdateServer.h`, also `WiFiClient.h`, in addition to the usual directives as `ESP8266WebServer.h` and `AutoConnect.h`.
2. Declare an ESP8266WebServer object. (In ESP32, as WebServer) 2. Declare an ESP8266WebServer object. (In ESP32, as WebServer)
3. Declare an ESP8266HTTPUpdateServer object. 3. Declare an ESP8266HTTPUpdateServer object.
4. Declare an AutoConnect object with an ESP8266WebServer object as an argument. 4. Declare an AutoConnect object with an ESP8266WebServer object as an argument.
@ -28,16 +148,12 @@ To embed the ESP8266HTTPUpdateServer class with AutoConnect into your sketch, ba
2. Load the AutoConnectAux pages declared in step #8 for your application. (Except the update dialog page) 2. Load the AutoConnectAux pages declared in step #8 for your application. (Except the update dialog page)
3. Join these pages to AutoConnect along with the update dialog page declared in step #5. 3. Join these pages to AutoConnect along with the update dialog page declared in step #5.
4. Invokes [AutoConnect::begin](api.md#begin) function. 4. Invokes [AutoConnect::begin](api.md#begin) function.
5. Call the `MDNS.begin` and `MDNS.addServer` functions to start the multi cast DNS service. 10. Invokes [AutoConnect::handleClient](api.md#handleclient) function in the `loop()`.
10. Perform the following procedure steps in the `loop()` function:
1. Call the `MDNS.update` function to parse requests for mDNS. (No needed as ESP32)
2. Invokes [AutoConnect::handleClient](api.md#handleclient) function.
```cpp ```cpp
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h> // Step #1 #include <ESP8266HTTPUpdateServer.h> // Step #1
#include <ESP8266mDNS.h> // Step #1
#include <WiFiClient.h> // Step #1 #include <WiFiClient.h> // Step #1
#include <AutoConnect.h> #include <AutoConnect.h>
@ -58,52 +174,14 @@ void setup() {
httpUpdate.setup(&httpServer, "USERNAME", "PASSWORD"); // Step #9.a httpUpdate.setup(&httpServer, "USERNAME", "PASSWORD"); // Step #9.a
hello.load(HELLO_PAGE); // Step #9.b hello.load(HELLO_PAGE); // Step #9.b
portal.join({ hello, update }); // Step #9.c portal.join({ hello, update }); // Step #9.c
if (portal.begin()) { // Step #9.d portal.begin(); // Step #9.d
if (MDNS.begin("esp-webupdate")) // Step #9.e
MDNS.addService("http", "tcp", 80); // Step #9.e
}
} }
void loop() { void loop() {
MDNS.update(); // Step #10.a portal.handleClient(); // Step #10
portal.handleClient(); // Step #10.b
} }
``` ```
!!! hint "For ESP32"
This procedure is equally applicable to ESP32. If the target module is ESP32, change the following items:
- Change the include directives appropriately for the ESP32 environment.
- Change ESP8266HTTPUpdaetServer to HTTPUpdateServer using an implementation provided from AutoConnect library example code.
- Remove `MDNS.update` line from the sketch code.
!!! example "Share an ESP8266WebServer"
AutoConnect shares the ESP8266WebServer instance with the ESP8266HTTPUpdateServer class. You can give the same instance as ESP8266WebServer instance given to AutoConnect to ESP8266HTTPUpdateServer class.
```cpp
ESP8266WebServer httpServer;
ESP8266HTTPUpdateServer updateServer;
AutoConnect portal(httpServer);
updateServer(&httpServer);
```
This sharing specification is the same for ESP32.
The result of the above sketch should be as follows. [^2]
[^2]: The authentication dialog is displayed first.
<span style="display:block;margin-left:auto;margin-right:auto;width:282px;height:362px;border:1px solid lightgrey;"><img data-gifffer="images/webupdate.gif" data-gifffer-height="360" data-gifffer-width="280" /></span>
!!! faq "How LED ticking during updates"
You **cannot** get the ticker with LED during updates by using this way. It is since the current implementation of the ESP8266HTTPUpdateServer class of the Arduino core **library does not assign an LED PIN** to the ESP8266HTTPUpdate class.
### <i class="fa fa-wrench"></i> How to make the binary sketch
Binary sketch files for updating can be retrieved using the Arduino IDE. Open the **Sketch** menu and select the **Export compiled Binary**, then starts compilation.
<img src="images/export_binary.png" width="450" />
When the compilation is complete, a binary sketch will save with the extension `.bin` in the same folder as the sketch.
<script> <script>
window.onload = function() { window.onload = function() {
Gifffer(); Gifffer();

@ -70,7 +70,7 @@ In the OTA platform, you can place the update server operated by the script in a
For Python2: *AUTOCONNECT\_LIBRARY\_PATH*/src/updateserver/python2 For Python2: *AUTOCONNECT\_LIBRARY\_PATH*/src/updateserver/python2
For Python3: *AUTOCONNECT\_LIBRARY\_PATH*/src/updateserver/python3 For Python3: *AUTOCONNECT\_LIBRARY\_PATH*/src/updateserver/python3
```bash ```powershell
updateserver.py [-h] [--port PORT] [--bind IP_ADDRESS] [--catalog CATALOG] [--log LOG_LEVEL] updateserver.py [-h] [--port PORT] [--bind IP_ADDRESS] [--catalog CATALOG] [--log LOG_LEVEL]
``` ```
<dl class="apidl"> <dl class="apidl">
@ -91,7 +91,7 @@ updateserver.py [-h] [--port PORT] [--bind IP_ADDRESS] [--catalog CATALOG] [--lo
3. Start updateserver.py 3. Start updateserver.py
For example, to start the update server on the host with IP address 172.16.1.10 using 8080 port[^4], execute the following command: For example, to start the update server on the host with IP address 172.16.1.10 using 8080 port[^4], execute the following command:
```bash ```powershell
python updateserver.py --port 8080 --bind 172.16.1.10 --catalog bin --log debug python updateserver.py --port 8080 --bind 172.16.1.10 --catalog bin --log debug
``` ```
In this example assumes that the binary sketch files are deployed under the path `bin` from the current directory. In this example assumes that the binary sketch files are deployed under the path `bin` from the current directory.
@ -118,7 +118,7 @@ Above requirements will be implemented on along the HTTP protocol. The AutoConne
#### 1. HTTP URL query for the catalog list of the updatable #### 1. HTTP URL query for the catalog list of the updatable
``` ```powershell
[address]/_catalog?op=list&path=[path] [address]/_catalog?op=list&path=[path]
``` ```
<dl class="apidl"> <dl class="apidl">
@ -159,7 +159,7 @@ The above JSON object is one entry. The actual catalog list is an array of this
The AutoConnectUpdate class issues a HTTP GET request with the specified host address and URI. The update server responds by sending back a binary sketch file with the following header: The AutoConnectUpdate class issues a HTTP GET request with the specified host address and URI. The update server responds by sending back a binary sketch file with the following header:
``` ```powershell
Content-Type: application/octet-stream Content-Type: application/octet-stream
Content-Disposition: attachment; filename="BINARY_SKETCH_FILE_NAME" Content-Disposition: attachment; filename="BINARY_SKETCH_FILE_NAME"
Content-Length: LENGTH_OF_CONTENT Content-Length: LENGTH_OF_CONTENT

@ -2,7 +2,7 @@
AutoConnect provides **two type platforms** for updating the binary sketch in the ESP8266 or ESP32 module via OTA. They correspond to the [Web Browser Update](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#web-browser) and [HTTP Server Update](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#http-server) whiches mentioned in the [ESP8266 Arduino Core documentation](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#ota-updates). AutoConnect provides **two type platforms** for updating the binary sketch in the ESP8266 or ESP32 module via OTA. They correspond to the [Web Browser Update](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#web-browser) and [HTTP Server Update](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#http-server) whiches mentioned in the [ESP8266 Arduino Core documentation](https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#ota-updates).
[**The update behavior using a web browser**](otabrowser.md) as the client that supplies the binary sketch file for update follows the scenario assumed by the ESP8266 Arduino core. Therefore, the user sketch must meet the requirements described in the ESP8266 Arduino Core documentation, but you can easily embed the update feature that able to handle with the web browser by AutoConnect. All you need to do is that [join](api.md#join) the [AutoConnectAux](apiaux.md) with embedded **ESP8266HTTPUpdateServer**[^1] of the core library to AutoConnect. [**The update behavior using a web browser**](otabrowser.md) as the client that supplies the binary sketch file for update follows the scenario assumed by the ESP8266 Arduino core. Therefore, the user sketch must meet the requirements described in the ESP8266 Arduino Core documentation, but you can easily embed the OTA update feature that able to operate via the web browser by AutoConnect menu. All you need to do is that specify [AutoConnectConfig](apiconfig.md#ota).
[^1]: The AutoConnect library provides an implementation of the **HTTPUpdateServer** class that ported from ESP8266HTTPUpdateServer class for ESP32 intention. It is contained the **WebUpdate** under the examples folder. [^1]: The AutoConnect library provides an implementation of the **HTTPUpdateServer** class that ported from ESP8266HTTPUpdateServer class for ESP32 intention. It is contained the **WebUpdate** under the examples folder.

@ -35,7 +35,7 @@ In addition to the above procedure, to completely cut off for binding with the A
The code excluding JSON processing from the mqttRSSI sketch attached to the library is as follows. <small>(It is a part of code. Refer to mqttRSSI_NA.ino for the whole sketch.)</small> The code excluding JSON processing from the mqttRSSI sketch attached to the library is as follows. <small>(It is a part of code. Refer to mqttRSSI_NA.ino for the whole sketch.)</small>
<i class="fa fa-code"></i> The JSON document for mqttRSSI <i class="fab fa-js-square"></i> The JSON document for mqttRSSI
```json ```json
[ [

@ -2,8 +2,8 @@
* AutoConnect class implementation. * AutoConnect class implementation.
* @file AutoConnect.cpp * @file AutoConnect.cpp
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 1.1.1 * @version 1.1.5
* @date 2019-10-17 * @date 2020-03-30
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -311,6 +311,21 @@ bool AutoConnect::_configSTA(const IPAddress& ip, const IPAddress& gateway, cons
return rc; return rc;
} }
/**
* Get URI to redirect at boot. It uses the URI according to the
* AutoConnectConfig::bootUti setting with the AutoConnectConfig::homeUri
* as the boot path.
* @return the boot uri.
*/
String AutoConnect::_getBootUri(void) {
if (_apConfig.bootUri == AC_ONBOOTURI_ROOT)
return String(AUTOCONNECT_URI);
else if (_apConfig.bootUri == AC_ONBOOTURI_HOME)
return _apConfig.homeUri.length() > 0 ? _apConfig.homeUri : String("/");
else
return _emptyString;
}
/** /**
* Obtains the currently established AP connection to determine if the * Obtains the currently established AP connection to determine if the
* station configuration needs to run before the first WiFi.begin. * station configuration needs to run before the first WiFi.begin.
@ -362,6 +377,9 @@ void AutoConnect::home(const String& uri) {
void AutoConnect::end(void) { void AutoConnect::end(void) {
_responsePage.reset(); _responsePage.reset();
_currentPageElement.reset(); _currentPageElement.reset();
_ticker.reset();
_update.reset();
_ota.reset();
_stopPortal(); _stopPortal();
_dnsServer.reset(); _dnsServer.reset();
@ -568,6 +586,27 @@ void AutoConnect::handleRequest(void) {
// Handle the update behaviors for attached AutoConnectUpdate. // Handle the update behaviors for attached AutoConnectUpdate.
if (_update) if (_update)
_update->handleUpdate(); _update->handleUpdate();
// Attach AutoConnectOTA if OTA is available.
if (_apConfig.ota == AC_OTA_BUILTIN) {
if (!_ota) {
_ota.reset(new AutoConnectOTA());
_ota->attach(*this);
_ota->setTicker(_apConfig.tickerPort, _apConfig.tickerOn);
}
}
// Post-process for AutoConnectOTA
if (_ota) {
if (_ota->status() == AutoConnectOTA::OTA_RIP) {
// Indicate the reboot at the next handleClient turn
// with on completion of the update via OTA.
_webServer->client().setNoDelay(true);
_rfReset = true;
}
// Reflect the menu display specifier from AutoConnectConfig to AutoConnectOTA page
_ota->menu(_apConfig.menuItems & AC_MENUITEM_UPDATE);
}
} }
/** /**
@ -675,7 +714,7 @@ bool AutoConnect::_captivePortal(void) {
String hostHeader = _webServer->hostHeader(); String hostHeader = _webServer->hostHeader();
if (!_isIP(hostHeader) && (hostHeader != WiFi.localIP().toString()) && (!hostHeader.endsWith(F(".local")))) { if (!_isIP(hostHeader) && (hostHeader != WiFi.localIP().toString()) && (!hostHeader.endsWith(F(".local")))) {
AC_DBG("Detected application, %s, %s\n", hostHeader.c_str(), WiFi.localIP().toString().c_str()); AC_DBG("Detected application, %s, %s\n", hostHeader.c_str(), WiFi.localIP().toString().c_str());
String location = String(F("http://")) + _webServer->client().localIP().toString() + String(AUTOCONNECT_URI); String location = String(F("http://")) + _webServer->client().localIP().toString() + _getBootUri();
_webServer->sendHeader(String(F("Location")), location, true); _webServer->sendHeader(String(F("Location")), location, true);
_webServer->send(302, String(F("text/plain")), _emptyString); _webServer->send(302, String(F("text/plain")), _emptyString);
_webServer->client().flush(); _webServer->client().flush();
@ -835,7 +874,7 @@ String AutoConnect::_induceConnect(PageArgument& args) {
// that occurs at connection establishment. // that occurs at connection establishment.
// [WiFiClient.cpp:463] connected(): Disconnected: RES: 0, ERR: 128 // [WiFiClient.cpp:463] connected(): Disconnected: RES: 0, ERR: 128
// When connecting as a station, TCP reset caused by switching of the // When connecting as a station, TCP reset caused by switching of the
// radio channel occurs. Although the Espressif's view is true. However, // radio channel occurs. Although the Espressif view is true. However,
// the actual TCP reset occurs not at the time of switching the channel. // the actual TCP reset occurs not at the time of switching the channel.
// It occurs at the connection from the ESP32 to the AP is established // It occurs at the connection from the ESP32 to the AP is established
// and it is possible that TCP reset is occurring in other situations. // and it is possible that TCP reset is occurring in other situations.

@ -2,8 +2,8 @@
* Declaration of AutoConnect class and accompanying AutoConnectConfig class. * Declaration of AutoConnect class and accompanying AutoConnectConfig class.
* @file AutoConnect.h * @file AutoConnect.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 1.1.1 * @version 1.1.5
* @date 2019-10-17 * @date 2020-04-01
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -31,8 +31,12 @@ using WebServerClass = WebServer;
#include "AutoConnectDefs.h" #include "AutoConnectDefs.h"
#include "AutoConnectPage.h" #include "AutoConnectPage.h"
#include "AutoConnectCredential.h" #include "AutoConnectCredential.h"
#include "AutoConnectAux.h"
#include "AutoConnectTicker.h" #include "AutoConnectTicker.h"
#include "AutoConnectAux.h"
// The realization of AutoConnectOTA is effective only by the explicit
#include "AutoConnectOTA.h"
class AutoConnectOTA; // Reference to avoid circular
// The realization of AutoConnectUpdate is effective only by the explicit // The realization of AutoConnectUpdate is effective only by the explicit
// definition of AUTOCONNECT_USE_UPDATE // definition of AUTOCONNECT_USE_UPDATE
@ -45,11 +49,30 @@ typedef enum AC_SAVECREDENTIAL {
AC_SAVECREDENTIAL_AUTO AC_SAVECREDENTIAL_AUTO
} AC_SAVECREDENTIAL_t; } AC_SAVECREDENTIAL_t;
/**< URI that can be specified to AutoConnectConfig::bootUri. */
typedef enum AC_ONBOOTURI { typedef enum AC_ONBOOTURI {
AC_ONBOOTURI_ROOT, AC_ONBOOTURI_ROOT,
AC_ONBOOTURI_HOME AC_ONBOOTURI_HOME
} AC_ONBOOTURI_t; } AC_ONBOOTURI_t;
/**< Specifier for using built-in OTA */
typedef enum AC_OTA {
AC_OTA_EXTRA,
AC_OTA_BUILTIN
} AC_OTA_t;
/**< An enumerated type of the designated menu items. */
typedef enum AC_MENUITEM {
AC_MENUITEM_NONE = 0x0000,
AC_MENUITEM_CONFIGNEW = 0x0001,
AC_MENUITEM_OPENSSIDS = 0x0002,
AC_MENUITEM_DISCONNECT = 0x0004,
AC_MENUITEM_RESET = 0x0008,
AC_MENUITEM_HOME = 0x0010,
AC_MENUITEM_UPDATE = 0x0020,
AC_MENUITEM_DEVINFO = 0x0040
} AC_MENUITEM_t;
class AutoConnectConfig { class AutoConnectConfig {
public: public:
/** /**
@ -75,9 +98,11 @@ class AutoConnectConfig {
immediateStart(false), immediateStart(false),
retainPortal(false), retainPortal(false),
portalTimeout(AUTOCONNECT_CAPTIVEPORTAL_TIMEOUT), portalTimeout(AUTOCONNECT_CAPTIVEPORTAL_TIMEOUT),
menuItems(AC_MENUITEM_CONFIGNEW | AC_MENUITEM_OPENSSIDS | AC_MENUITEM_DISCONNECT | AC_MENUITEM_RESET | AC_MENUITEM_UPDATE | AC_MENUITEM_HOME),
ticker(false), ticker(false),
tickerPort(AUTOCONNECT_TICKER_PORT), tickerPort(AUTOCONNECT_TICKER_PORT),
tickerOn(LOW), tickerOn(LOW),
ota(AC_OTA_EXTRA),
hostName(String("")), hostName(String("")),
homeUri(AUTOCONNECT_HOMEURI), homeUri(AUTOCONNECT_HOMEURI),
title(AUTOCONNECT_MENU_TITLE), title(AUTOCONNECT_MENU_TITLE),
@ -107,9 +132,11 @@ class AutoConnectConfig {
immediateStart(false), immediateStart(false),
retainPortal(false), retainPortal(false),
portalTimeout(portalTimeout), portalTimeout(portalTimeout),
menuItems(AC_MENUITEM_CONFIGNEW | AC_MENUITEM_OPENSSIDS | AC_MENUITEM_DISCONNECT | AC_MENUITEM_RESET | AC_MENUITEM_UPDATE | AC_MENUITEM_HOME),
ticker(false), ticker(false),
tickerPort(AUTOCONNECT_TICKER_PORT), tickerPort(AUTOCONNECT_TICKER_PORT),
tickerOn(LOW), tickerOn(LOW),
ota(AC_OTA_EXTRA),
hostName(String("")), hostName(String("")),
homeUri(AUTOCONNECT_HOMEURI), homeUri(AUTOCONNECT_HOMEURI),
title(AUTOCONNECT_MENU_TITLE), title(AUTOCONNECT_MENU_TITLE),
@ -139,9 +166,11 @@ class AutoConnectConfig {
immediateStart = o.immediateStart; immediateStart = o.immediateStart;
retainPortal = o.retainPortal; retainPortal = o.retainPortal;
portalTimeout = o.portalTimeout; portalTimeout = o.portalTimeout;
menuItems = o.menuItems;
ticker = o.ticker; ticker = o.ticker;
tickerPort = o.tickerPort; tickerPort = o.tickerPort;
tickerOn = o.tickerOn; tickerOn = o.tickerOn;
ota = o.ota;
hostName = o.hostName; hostName = o.hostName;
homeUri = o.homeUri; homeUri = o.homeUri;
title = o.title; title = o.title;
@ -170,9 +199,11 @@ class AutoConnectConfig {
bool immediateStart; /**< Skips WiFi.begin(), start portal immediately */ bool immediateStart; /**< Skips WiFi.begin(), start portal immediately */
bool retainPortal; /**< Even if the captive portal times out, it maintains the portal state. */ bool retainPortal; /**< Even if the captive portal times out, it maintains the portal state. */
unsigned long portalTimeout; /**< Timeout value for stay in the captive portal */ unsigned long portalTimeout; /**< Timeout value for stay in the captive portal */
uint16_t menuItems; /**< A compound value of the menu items to be attached */
bool ticker; /**< Drives LED flicker according to WiFi connection status. */ bool ticker; /**< Drives LED flicker according to WiFi connection status. */
uint8_t tickerPort; /**< GPIO for flicker */ uint8_t tickerPort; /**< GPIO for flicker */
uint8_t tickerOn; /**< A signal for flicker turn on */ uint8_t tickerOn; /**< A signal for flicker turn on */
AC_OTA_t ota; /**< Attach built-in OTA */
String hostName; /**< host name */ String hostName; /**< host name */
String homeUri; /**< A URI of user site */ String homeUri; /**< A URI of user site */
String title; /**< Menu title */ String title; /**< Menu title */
@ -204,6 +235,8 @@ class AutoConnect {
void join(AutoConnectAuxVT auxVector); void join(AutoConnectAuxVT auxVector);
bool on(const String& uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order = AC_EXIT_AHEAD); bool on(const String& uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order = AC_EXIT_AHEAD);
String where(void) const { return _auxUri; } String where(void) const { return _auxUri; }
inline void enableMenu(const uint16_t items) { _apConfig.menuItems |= items; }
inline void disableMenu(const uint16_t items) { _apConfig.menuItems &= (0xffff ^ items); }
/** For AutoConnectAux described in JSON */ /** For AutoConnectAux described in JSON */
#ifdef AUTOCONNECT_USE_JSON #ifdef AUTOCONNECT_USE_JSON
@ -224,6 +257,7 @@ class AutoConnect {
} AC_STARECONNECT_t; } AC_STARECONNECT_t;
bool _config(void); bool _config(void);
bool _configSTA(const IPAddress& ip, const IPAddress& gateway, const IPAddress& netmask, const IPAddress& dns1, const IPAddress& dns2); bool _configSTA(const IPAddress& ip, const IPAddress& gateway, const IPAddress& netmask, const IPAddress& dns1, const IPAddress& dns2);
String _getBootUri(void);
bool _getConfigSTA(station_config_t* config); bool _getConfigSTA(station_config_t* config);
void _startWebServer(void); void _startWebServer(void);
void _startDNSServer(void); void _startDNSServer(void);
@ -233,7 +267,7 @@ class AutoConnect {
bool _classifyHandle(HTTPMethod mothod, String uri); bool _classifyHandle(HTTPMethod mothod, String uri);
void _handleUpload(const String& requestUri, const HTTPUpload& upload); void _handleUpload(const String& requestUri, const HTTPUpload& upload);
void _purgePages(void); void _purgePages(void);
virtual PageElement* _setupPage(String uri); virtual PageElement* _setupPage(String& uri);
#ifdef AUTOCONNECT_USE_JSON #ifdef AUTOCONNECT_USE_JSON
template<typename T> template<typename T>
bool _parseJson(T in); bool _parseJson(T in);
@ -256,6 +290,7 @@ class AutoConnect {
void _setReconnect(const AC_STARECONNECT_t order); void _setReconnect(const AC_STARECONNECT_t order);
/** Utilities */ /** Utilities */
String _attachMenuItem(const AC_MENUITEM_t item);
static uint32_t _getChipId(void); static uint32_t _getChipId(void);
static uint32_t _getFlashChipRealSize(void); static uint32_t _getFlashChipRealSize(void);
static String _toMACAddressString(const uint8_t mac[]); static String _toMACAddressString(const uint8_t mac[]);
@ -283,6 +318,8 @@ class AutoConnect {
String _prevUri; /**< Previous generated page uri */ String _prevUri; /**< Previous generated page uri */
/** Available updater, only reset by AutoConnectUpdate::attach is valid */ /** Available updater, only reset by AutoConnectUpdate::attach is valid */
std::unique_ptr<AutoConnectUpdate> _update; std::unique_ptr<AutoConnectUpdate> _update;
/** OTA updater */
std::unique_ptr<AutoConnectOTA> _ota;
/** Saved configurations */ /** Saved configurations */
AutoConnectConfig _apConfig; AutoConnectConfig _apConfig;

@ -53,14 +53,18 @@ const char AutoConnectAux::_PAGE_AUX[] PROGMEM = {
"</div></div>" "</div></div>"
"</div>" "</div>"
"<script>" "<script>"
"function _sa(url) {" "function _bu(url) {"
"var uri=document.createElement('input');" "var uri=document.createElement('input');"
"uri.setAttribute('type','hidden');" "uri.setAttribute('type','hidden');"
"uri.setAttribute('name','" AUTOCONNECT_AUXURI_PARAM "');" "uri.setAttribute('name','" AUTOCONNECT_AUXURI_PARAM "');"
"uri.setAttribute('value','{{AUX_URI}}');" "uri.setAttribute('value','{{AUX_URI}}');"
"document.getElementById('_aux').appendChild(uri);" "var fm=document.getElementById('_aux');"
"document.getElementById('_aux').action=url;" "fm.appendChild(uri);"
"document.getElementById('_aux').submit();" "fm.action=url;"
"return fm;"
"}"
"function _sa(url) {"
"_bu(url).submit();"
"}" "}"
"</script>" "</script>"
"</body>" "</body>"

@ -185,7 +185,7 @@
#define AUTOCONNECT_JSONPSRAM_SIZE (16* 1024) #define AUTOCONNECT_JSONPSRAM_SIZE (16* 1024)
#endif // !AUTOCONNECT_JSONPSRAM_SIZE #endif // !AUTOCONNECT_JSONPSRAM_SIZE
// Available HTTP port number for the update [ms] // Available HTTP port number for the update
#ifndef AUTOCONNECT_UPDATE_PORT #ifndef AUTOCONNECT_UPDATE_PORT
#define AUTOCONNECT_UPDATE_PORT 8000 #define AUTOCONNECT_UPDATE_PORT 8000
#endif // !AUTOCONNECT_UPDATE_PORT #endif // !AUTOCONNECT_UPDATE_PORT
@ -207,7 +207,7 @@
// Wait timer for rebooting after updated // Wait timer for rebooting after updated
#ifndef AUTOCONNECT_UPDATE_WAITFORREBOOT #ifndef AUTOCONNECT_UPDATE_WAITFORREBOOT
#define AUTOCONNECT_UPDATE_WAITFORREBOOT 9000 #define AUTOCONNECT_UPDATE_WAITFORREBOOT 15000
#endif // !AUTOCONNECT_UPDATE_WAITFORREBOOT #endif // !AUTOCONNECT_UPDATE_WAITFORREBOOT
// A signal value that the board dependent LED turns on. // A signal value that the board dependent LED turns on.

@ -100,7 +100,7 @@ const String AutoConnectFileBasis::toHTML(void) const {
/** /**
* Instantiate the upload handler with the specified store type. * Instantiate the upload handler with the specified store type.
* @param store An enumuration value of ACFile_t * @param store An enumeration value of ACFile_t
*/ */
bool AutoConnectFileBasis::attach(const ACFile_t store) { bool AutoConnectFileBasis::attach(const ACFile_t store) {
AutoConnectUploadFS* handlerFS; AutoConnectUploadFS* handlerFS;

@ -139,7 +139,7 @@ class AutoConnectCheckboxJson : public AutoConnectElementJson, public AutoConnec
* @param value A string value entered by the selected file name. * @param value A string value entered by the selected file name.
* @param label A label string that follows file-select box, optionally. * @param label A label string that follows file-select box, optionally.
* The label is placed in front of file-select box. * The label is placed in front of file-select box.
* @param store An enumuration value of store type. * @param store An enumeration value of store type.
*/ */
class AutoConnectFileJson : public AutoConnectElementJson, public AutoConnectFileBasis { class AutoConnectFileJson : public AutoConnectElementJson, public AutoConnectFileBasis {
public: public:

@ -2,8 +2,8 @@
* AutoConnect proper menu label constant definition. * AutoConnect proper menu label constant definition.
* @file AutoConnectLabels.h * @file AutoConnectLabels.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 1.1.4 * @version 1.1.5
* @date 2020-02-13 * @date 2020-04-09
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -61,12 +61,22 @@
#define AUTOCONNECT_MENULABEL_UPDATE "Update" #define AUTOCONNECT_MENULABEL_UPDATE "Update"
#endif // !AUTOCONNECT_MENULABEL_UPDATE #endif // !AUTOCONNECT_MENULABEL_UPDATE
// Menu item: Device Info
#ifndef AUTOCONNECT_MENULABEL_DEVINFO
#define AUTOCONNECT_MENULABEL_DEVINFO "Device info"
#endif // !AUTOCONNECT_MENULABEL_DEVINFO
// Button label: RESET // Button label: RESET
#ifndef AUTOCONNECT_BUTTONLABEL_RESET #ifndef AUTOCONNECT_BUTTONLABEL_RESET
#define AUTOCONNECT_BUTTONLABEL_RESET "RESET" #define AUTOCONNECT_BUTTONLABEL_RESET "RESET"
//#define AUTOCONNECT_BUTTONLABEL_RESET "Reboot" //#define AUTOCONNECT_BUTTONLABEL_RESET "Reboot"
#endif // !AUTOCONNECT_BUTTONLABEL_RESET #endif // !AUTOCONNECT_BUTTONLABEL_RESET
// Button label: UPDATE
#ifndef AUTOCONNECT_BUTTONLABEL_UPDATE
#define AUTOCONNECT_BUTTONLABEL_UPDATE "UPDATE"
#endif // !AUTOCONNECT_BUTTONLABEL_UPDATE
// Page title: Page not found // Page title: Page not found
#ifndef AUTOCONNECT_PAGETITLE_NOTFOUND #ifndef AUTOCONNECT_PAGETITLE_NOTFOUND
#define AUTOCONNECT_PAGETITLE_NOTFOUND "Page not found" #define AUTOCONNECT_PAGETITLE_NOTFOUND "Page not found"
@ -217,6 +227,26 @@
#define AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS "No saved credentials." #define AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS "No saved credentials."
#endif // !AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS #endif // !AUTOCONNECT_TEXT_NOSAVEDCREDENTIALS
// Text: The update page caption
#ifndef AUTOCONNECT_TEXT_UPDATINGFIRMWARE
#define AUTOCONNECT_TEXT_UPDATINGFIRMWARE "Updating firmware"
#endif // !AUTOCONNECT_TEXT_UPDATINGFIRMWARE
// Text: The update page's file selection button label
#ifndef AUTOCONNECT_TEXT_SELECTFIRMWARE
#define AUTOCONNECT_TEXT_SELECTFIRMWARE "Select firmware: "
#endif // !AUTOCONNECT_TEXT_SELECTFIRMWARE
// Text: OTA success
#ifndef AUTOCONNECT_TEXT_OTASUCCESS
#define AUTOCONNECT_TEXT_OTASUCCESS "Successfully updated, rebooting..."
#endif // !AUTOCONNECT_TEXT_OTASUCCESS
// Text: OTA failure
#ifndef AUTOCONNECT_TEXT_OTAFAILURE
#define AUTOCONNECT_TEXT_OTAFAILURE "Failed to update: "
#endif // !AUTOCONNECT_TEXT_OTAFAILURE
// Menu Text: Connecting // Menu Text: Connecting
#ifndef AUTOCONNECT_MENUTEXT_CONNECTING #ifndef AUTOCONNECT_MENUTEXT_CONNECTING
#define AUTOCONNECT_MENUTEXT_CONNECTING "Connecting" #define AUTOCONNECT_MENUTEXT_CONNECTING "Connecting"

@ -0,0 +1,229 @@
/**
* AutoConnectOTA class implementation.
* @file AutoConnectOTA.cpp
* @author hieromon@gmail.com
* @version 1.1.5
* @date 2020-04-09
* @copyright MIT license.
*/
#include <functional>
#if defined(ARDUINO_ARCH_ESP8266)
#include <WiFiUdp.h>
#include <Updater.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <Update.h>
#endif
#include <StreamString.h>
#include "AutoConnectOTA.h"
#include "AutoConnectOTAPage.h"
/**
* A destructor. Release the OTA operation pages.
*/
AutoConnectOTA::~AutoConnectOTA() {
_auxUpdate.reset(nullptr);
_auxResult.reset(nullptr);
}
/**
* Attach the AutoConnectOTA to hosted AutoConnect which constitutes
* the update process. This function creates an OTA operation page as
* AutoConnectAux instance and allows it to receive binary updates.
* @param portal A reference of AutoConnect
*/
void AutoConnectOTA::attach(AutoConnect& portal) {
AutoConnectAux* updatePage;
updatePage = new AutoConnectAux(String(FPSTR(_pageUpdate.uri)), String(FPSTR(_pageUpdate.title)), _pageUpdate.menu);
_buildAux(updatePage, &_pageUpdate, lengthOf(_elmUpdate));
_auxUpdate.reset(updatePage);
updatePage = new AutoConnectAux(String(FPSTR(_pageResult.uri)), String(FPSTR(_pageResult.title)), _pageResult.menu);
_buildAux(updatePage, &_pageResult, lengthOf(_elmResult));
_auxResult.reset(updatePage);
_auxResult->on(std::bind(&AutoConnectOTA::_updated, this, std::placeholders::_1, std::placeholders::_2));
_auxResult->onUpload<AutoConnectOTA>(*this);
portal.join(*_auxUpdate.get());
portal.join(*_auxResult.get());
}
/**
* Create the update operation pages using a predefined page structure
* with two structures as ACPage_t and ACElementProp_t which describe
* for AutoConnectAux configuration.
* This function receives instantiated AutoConnectAux, instantiates
* defined AutoConnectElements by ACPage_t, and configures it into
* received AutoConnectAux.
* @param aux An instantiated AutoConnectAux that will configure according to ACPage_t.
* @param page Pre-defined ACPage_t
* @param elementNum Number of AutoConnectElements to configure.
*/
void AutoConnectOTA::_buildAux(AutoConnectAux* aux, const AutoConnectOTA::ACPage_t* page, const size_t elementNum) {
for (size_t n = 0; n < elementNum; n++) {
if (page->element[n].type == AC_Button) {
AutoConnectButton* element = new AutoConnectButton;
element->name = String(FPSTR(page->element[n].name));
if (page->element[n].value)
element->value = String(FPSTR(page->element[n].value));
if (page->element[n].peculiar)
element->action = String(FPSTR(page->element[n].peculiar));
aux->add(reinterpret_cast<AutoConnectElement&>(*element));
}
else if (page->element[n].type == AC_Element) {
AutoConnectElement* element = new AutoConnectElement;
element->name = String(FPSTR(page->element[n].name));
if (page->element[n].value)
element->value = String(FPSTR(page->element[n].value));
aux->add(reinterpret_cast<AutoConnectElement&>(*element));
}
else if (page->element[n].type == AC_File) {
AutoConnectFile* element = new AutoConnectFile;
element->name = String(FPSTR(page->element[n].name));
element->label = String(FPSTR(page->element[n].peculiar));
element->store = ACFile_t::AC_File_Extern;
aux->add(reinterpret_cast<AutoConnectElement&>(*element));
}
else if (page->element[n].type == AC_Style) {
AutoConnectStyle* element = new AutoConnectStyle;
element->name = String(FPSTR(page->element[n].name));
if (page->element[n].value)
element->value = String(FPSTR(page->element[n].value));
aux->add(reinterpret_cast<AutoConnectElement&>(*element));
}
else if (page->element[n].type == AC_Text) {
AutoConnectText* element = new AutoConnectText;
element->name = String(FPSTR(page->element[n].name));
if (page->element[n].value)
element->value = String(FPSTR(page->element[n].value));
if (page->element[n].peculiar)
element->style = String(FPSTR(page->element[n].peculiar));
aux->add(reinterpret_cast<AutoConnectText&>(*element));
}
}
}
/**
* Check the space needed for the update
* This function overrides AutoConnectUploadHandler::_open.
* @param filename An updater bin file name
* @param mode File access mode, but it is not be used.
* @return true Ready for update
* @return false Not enough FLASH space to update.
*/
bool AutoConnectOTA::_open(const char* filename, const char* mode) {
AC_UNUSED(mode);
_binName = String(strchr(filename, '/') + sizeof(char));
#ifdef ARDUINO_ARCH_ESP8266
WiFiUDP::stopAll();
#endif
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
// It only supports FLASH as a sketch area for updating.
if (Update.begin(maxSketchSpace, U_FLASH)) {
if (_tickerPort != -1)
pinMode(static_cast<uint8_t>(_tickerPort), OUTPUT);
_status = OTA_START;
AC_DBG("%s updating start\n", filename);
return true;
}
_setError();
return false;
}
/**
* Writes received updater to the flash.
* This function overrides AutoConnectUploadHandler::_write.
* @param buf Buffer address where received update file was stored.
* @param size Size to be written.
* @return the amount written
*/
size_t AutoConnectOTA::_write(const uint8_t *buf, const size_t size) {
size_t wsz = 0;
if (_tickerPort != -1)
digitalWrite(_tickerPort, digitalRead(_tickerPort) ^ 0x01);
if (!_err.length()) {
_status = OTA_PROGRESS;
wsz = Update.write(const_cast<uint8_t*>(buf), size);
if (wsz != size)
_setError();
}
return wsz;
}
/**
* All bytes are written, this call writes the config to reboot.
* If there is an error this will clear everything.
* This function overrides AutoConnectUploadHandler::_close.
* @param status Updater binary upload completion status.
*/
void AutoConnectOTA::_close(const HTTPUploadStatus status) {
AC_DBG("OTA update");
if (!_err.length()) {
if (status == UPLOAD_FILE_END) {
if (Update.end(true)) {
_status = OTA_SUCCESS;
AC_DBG_DUMB(" succeeds, turn to reboot");
}
else {
_setError();
AC_DBG_DUMB(" flash failed");
}
}
else {
AC_DBG_DUMB(" aborted");
}
}
AC_DBG_DUMB(". %s\n", _err.c_str());
if (_err.length())
Update.end(false);
if (_tickerPort != -1)
digitalWrite(_tickerPort, !_tickerOn);
}
/**
* Callback of the update operation page as AutoConnectAux.
* Reflect the flash result of Update class to the page.
* @param result Upload post-process page
* @param args Unused
* @return Empty string
*/
String AutoConnectOTA::_updated(AutoConnectAux& result, PageArgument& args) {
AC_UNUSED(args);
PGM_P stColor;
String st;
// Build an updating result caption.
// Change the color of the bin name depending on the result of the update.
if (_status == OTA_SUCCESS) {
st = String(F(AUTOCONNECT_TEXT_OTASUCCESS));
stColor = PSTR("3d7e9a");
// Notify to the handleClient of loop() thread that it can reboot.
_status = OTA_RIP;
}
else {
st = String(F(AUTOCONNECT_TEXT_OTAFAILURE)) + _err;
stColor = PSTR("e66157");
}
result["bin"].as<AutoConnectText>().value = _binName;
result["bin"].as<AutoConnectText>().style += String(stColor);
result["result"].as<AutoConnectText>().value = st;
// AutoConnectOTA result page generates a transition after reboot
// according to the error code from the Update class. By setting the
// error code of the Update class into the rc element, this page will
// automatically GET the homepage of the updated sketch.
result["rc"].value.replace("%d", String(Update.getError()));
return String("");
}
/**
* Save the last error
*/
void AutoConnectOTA::_setError(void) {
StreamString eStr;
Update.printError(eStr);
_err = String(eStr.c_str());
_status = OTA_FAIL;
}

@ -0,0 +1,87 @@
/**
* Declaration of AutoConnectOTA class.
* The AutoConnecOTA class is a class for web updating a Sketch binary
* via OTA and implements with an AutoConnectAux page handler that
* inherits from AutoConnectUploadHandler.
* By overriding the _write function of AutoConnectUploadHandler to
* write the executable binary using the Update class, it can update
* the module firmware in synchronization with the upload of the sketch
* binary file.
* @file AutoConnectOTA.h
* @author hieromon@gmail.com
* @version 1.1.5
* @date 2020-04-09
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTOTA_H_
#define _AUTOCONNECTOTA_H_
#include <memory>
#include "AutoConnect.h"
#include "AutoConnectUpload.h"
class AutoConnectOTA : public AutoConnectUploadHandler {
public:
// Updating process status
typedef enum {
OTA_IDLE, /**< Update process has not started */
OTA_START, /**< Update process has started */
OTA_PROGRESS, /**< Update process in progress */
OTA_SUCCESS, /**< A binary updater has uploaded fine */
OTA_RIP, /**< Ready for module restart */
OTA_FAIL /**< Failed to save binary updater by Update class */
} AC_OTAStatus_t;
AutoConnectOTA() : _status(OTA_IDLE), _tickerPort(-1), _tickerOn(LOW) {}
~AutoConnectOTA();
void attach(AutoConnect& portal);
String error(void) const { return _err; } /**< Returns current error string */
void menu(const bool post) { _auxUpdate->menu(post); }; /**< Enabel or disable arranging a created AutoConnectOTA page in the menu. */
AC_OTAStatus_t status(void) const { return _status; } /**< Return current error status of the Update class */
void setTicker(int8_t pin, uint8_t on) { _tickerPort = pin, _tickerOn = on; } /**< Set ticker LED port */
protected:
// Attribute definition of the element to be placed on the update page.
typedef struct {
const ACElement_t type;
const char* name; /**< Name to assign to AutoConnectElement */
const char* value; /**< Value owned by an element */
const char* peculiar; /**< Specific ornamentation for the element */
} ACElementProp_t;
// Attributes to treat included update pages as AutoConnectAux.
typedef struct {
const char* uri; /**< URI for the page */
const char* title; /**< Menu title of update page */
const bool menu; /**< Whether to display in menu */
const ACElementProp_t* element;
} ACPage_t;
template<typename T, size_t N> constexpr
size_t lengthOf(T(&)[N]) noexcept { return N; }
void _buildAux(AutoConnectAux* aux, const AutoConnectOTA::ACPage_t* page, const size_t elementNum);
bool _open(const char* filename, const char* mode) override;
size_t _write(const uint8_t *buf, const size_t size) override;
void _close(const HTTPUploadStatus status) override;
String _updated(AutoConnectAux& result, PageArgument& args);
std::unique_ptr<AutoConnectAux> _auxUpdate; /**< An update operation page */
std::unique_ptr<AutoConnectAux> _auxResult; /**< An update result page */
private:
void _setError(void);
AC_OTAStatus_t _status; /**< Status for update progress */
int8_t _tickerPort; /**< GPIO for flicker */
uint8_t _tickerOn; /**< A signal for flicker turn on */
String _binName; /**< An updater file name */
String _err; /**< Occurred error stamp */
static const ACPage_t _pageUpdate PROGMEM;
static const ACElementProp_t _elmUpdate[] PROGMEM;
static const ACPage_t _pageResult PROGMEM;
static const ACElementProp_t _elmResult[] PROGMEM;
};
#endif // !_AUTOCONNECTOTA_H_

@ -0,0 +1,39 @@
/**
* Define pages to operate updates using the AutoConnectUpdate class.
* @file AutoConnectOTAPage.h
* @author hieromon@gmail.com
* @version 1.1.5
* @date 2020-04-09
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTOTAPAGE_H_
#define _AUTOCONNECTOTAPAGE_H_
const AutoConnectOTA::ACElementProp_t AutoConnectOTA::_elmUpdate[] PROGMEM = {
{ AC_Style, "s_rc", ".s_rc{display:none}", nullptr },
{ AC_Text, "cap", "<h3>" AUTOCONNECT_TEXT_UPDATINGFIRMWARE "<h3>", nullptr },
{ AC_File, "bin", nullptr, AUTOCONNECT_TEXT_SELECTFIRMWARE },
{ AC_Button, "update", AUTOCONNECT_BUTTONLABEL_UPDATE, "_upd(this,'bin','" AUTOCONNECT_URI_UPDATE_ACT "')" },
{ AC_Element, "js", "<script type=\"text/javascript\">function _upd(e,t,n){var r=document.getElementById(t);if(r.files.length>0){par=e.parentNode,par.removeChild(e),pb=document.createElement(\"progress\"),pb.setAttribute(\"id\",\"pb\"),pb.setAttribute(\"style\",\"margin-top:1.0em\"),pb.setAttribute(\"value\",\"0\"),pb.setAttribute(\"max\",r.files[0].size),par.appendChild(pb);var p=new FormData(_bu(n)),o=new XMLHttpRequest;o.upload.addEventListener(\"progress\",function(e){pb.setAttribute(\"value\",e.loaded)},!1),o.addEventListener(\"load\",function(){document.body.innerHTML=o.response.body.innerHTML,\"0\"==document.getElementById(\"rc\").innerText&&setTimeout(function(){location.href=\"" AUTOCONNECT_HOMEURI "\"}," AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_WAITFORREBOOT) ")},!1),o.open(\"POST\",n),o.responseType=\"document\",o.send(p)}}var par,pb;</script>", nullptr }
};
// The definition of the OTA update operation page, which will be located to AUTOCONNECT_URI_UPDATE.
const AutoConnectOTA::ACPage_t AutoConnectOTA::_pageUpdate PROGMEM = {
AUTOCONNECT_URI_UPDATE, AUTOCONNECT_MENULABEL_UPDATE, true, AutoConnectOTA::_elmUpdate
};
const AutoConnectOTA::ACElementProp_t AutoConnectOTA::_elmResult[] PROGMEM = {
{ AC_Text, "bin", nullptr, "margin-bottom:0.5em;font-size:1.2em;font-weight:bold;color:#" },
{ AC_Text, "result", nullptr, nullptr },
{ AC_Element, "rc", "<div class=\"s_rc\" id=\"rc\">%d</div>", nullptr }
};
// The definition of the OTA update result display page.
// This page is assigned to AUTOCONNECT_URI_UPDATE_ACT, but the actual
// HTML document is dynamically rewritten on AUTOCONNECT_URI_UPDATE page
// by the JavaScript function included in the _pageUpdate AutoConnectAux.
const AutoConnectOTA::ACPage_t AutoConnectOTA::_pageResult PROGMEM = {
AUTOCONNECT_URI_UPDATE_ACT, AUTOCONNECT_MENULABEL_UPDATE, false, AutoConnectOTA::_elmResult
};
#endif // !_AUTOCONNECTOTAPAGE_H_

@ -2,8 +2,8 @@
* AutoConnect portal site web page implementation. * AutoConnect portal site web page implementation.
* @file AutoConnectPage.h * @file AutoConnectPage.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 1.1.4 * @version 1.1.5
* @date 2020-02-13 * @date 2020-04-01
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -550,13 +550,10 @@ const char AutoConnect::_ELM_MENU_PRE[] PROGMEM = {
"<div class=\"lb-menu lb-menu-right lb-menu-material\">" "<div class=\"lb-menu lb-menu-right lb-menu-material\">"
"<ul class=\"lb-navigation\">" "<ul class=\"lb-navigation\">"
"<li class=\"lb-header\">" "<li class=\"lb-header\">"
"<a href=\"" AUTOCONNECT_URI "\" class=\"lb-brand\">MENU_TITLE</a>" "<a href=\"BOOT_URI\" class=\"lb-brand\">MENU_TITLE</a>"
"<label class=\"lb-burger lb-burger-dblspin\" id=\"lb-burger\" for=\"lb-cb\"><span></span></label>" "<label class=\"lb-burger lb-burger-dblspin\" id=\"lb-burger\" for=\"lb-cb\"><span></span></label>"
"</li>" "</li>"
"<li class=\"lb-item\"><a href=\"" AUTOCONNECT_URI_CONFIG "\">" AUTOCONNECT_MENULABEL_CONFIGNEW "</a></li>" "MENU_LIST"
"<li class=\"lb-item\"><a href=\"" AUTOCONNECT_URI_OPEN "\">" AUTOCONNECT_MENULABEL_OPENSSIDS "</a></li>"
"<li class=\"lb-item\"><a href=\"" AUTOCONNECT_URI_DISCON "\">" AUTOCONNECT_MENULABEL_DISCONNECT "</a></li>"
"<li class=\"lb-item\" id=\"reset\"><a href=\"#rdlg\">" AUTOCONNECT_MENULABEL_RESET "</a></li>"
}; };
const char AutoConnect::_ELM_MENU_AUX[] PROGMEM = { const char AutoConnect::_ELM_MENU_AUX[] PROGMEM = {
@ -564,7 +561,8 @@ const char AutoConnect::_ELM_MENU_AUX[] PROGMEM = {
}; };
const char AutoConnect::_ELM_MENU_POST[] PROGMEM = { const char AutoConnect::_ELM_MENU_POST[] PROGMEM = {
"<li class=\"lb-item\"><a href=\"HOME_URI\">" AUTOCONNECT_MENULABEL_HOME "</a></li>" "MENU_HOME"
"MENU_DEVINFO"
"</ul>" "</ul>"
"</div>" "</div>"
"<div class=\"lap\" id=\"rdlg\"><a href=\"#reset\" class=\"overlap\"></a>" "<div class=\"lap\" id=\"rdlg\"><a href=\"#reset\" class=\"overlap\"></a>"
@ -972,6 +970,12 @@ String AutoConnect::_token_HEAD(PageArgument& args) {
String AutoConnect::_token_MENU_PRE(PageArgument& args) { String AutoConnect::_token_MENU_PRE(PageArgument& args) {
String currentMenu = FPSTR(_ELM_MENU_PRE); String currentMenu = FPSTR(_ELM_MENU_PRE);
String menuItem = _attachMenuItem(AC_MENUITEM_CONFIGNEW) +
_attachMenuItem(AC_MENUITEM_OPENSSIDS) +
_attachMenuItem(AC_MENUITEM_DISCONNECT) +
_attachMenuItem(AC_MENUITEM_RESET);
currentMenu.replace(String(F("MENU_LIST")), menuItem);
currentMenu.replace(String(F("BOOT_URI")), _getBootUri());
currentMenu.replace(String(F("MENU_TITLE")), _menuTitle); currentMenu.replace(String(F("MENU_TITLE")), _menuTitle);
currentMenu.replace(String(F("{{CUR_SSID}}")), _token_ESTAB_SSID(args)); currentMenu.replace(String(F("{{CUR_SSID}}")), _token_ESTAB_SSID(args));
return currentMenu; return currentMenu;
@ -987,7 +991,9 @@ String AutoConnect::_token_MENU_AUX(PageArgument& args) {
String AutoConnect::_token_MENU_POST(PageArgument& args) { String AutoConnect::_token_MENU_POST(PageArgument& args) {
AC_UNUSED(args); AC_UNUSED(args);
String postMenu = FPSTR(_ELM_MENU_POST); String postMenu = FPSTR(_ELM_MENU_POST);
postMenu.replace(String(F("MENU_HOME")), _attachMenuItem(AC_MENUITEM_HOME));
postMenu.replace(String(F("HOME_URI")), _apConfig.homeUri); postMenu.replace(String(F("HOME_URI")), _apConfig.homeUri);
postMenu.replace(String(F("MENU_DEVINFO")), _attachMenuItem(AC_MENUITEM_DEVINFO));
return postMenu; return postMenu;
} }
@ -1272,7 +1278,7 @@ String AutoConnect::_token_CONFIG_STAIP(PageArgument& args) {
char* liBuf = liCont; char* liBuf = liCont;
for (uint8_t i = 0; i < 5; i++) { for (uint8_t i = 0; i < 5; i++) {
IPAddress* ip; IPAddress* ip = nullptr;
if (i == 0) if (i == 0)
ip = &_apConfig.staip; ip = &_apConfig.staip;
else if (i == 1) else if (i == 1)
@ -1283,7 +1289,7 @@ String AutoConnect::_token_CONFIG_STAIP(PageArgument& args) {
ip = &_apConfig.dns1; ip = &_apConfig.dns1;
else if (i == 4) else if (i == 4)
ip = &_apConfig.dns2; ip = &_apConfig.dns2;
String ipStr = *ip ? ip->toString() : String(F("0.0.0.0")); String ipStr = ip != nullptr ? ip->toString() : String(F("0.0.0.0"));
snprintf_P(liBuf, sizeof(liCont) - (liBuf - liCont), (PGM_P)_configIPList, reps[i].lid, reps[i].lbl, reps[i].lid, reps[i].lid, ipStr.c_str()); snprintf_P(liBuf, sizeof(liCont) - (liBuf - liCont), (PGM_P)_configIPList, reps[i].lid, reps[i].lbl, reps[i].lid, reps[i].lid, ipStr.c_str());
liBuf += strlen(liBuf); liBuf += strlen(liBuf);
} }
@ -1340,12 +1346,7 @@ String AutoConnect::_token_UPTIME(PageArgument& args) {
String AutoConnect::_token_BOOTURI(PageArgument& args) { String AutoConnect::_token_BOOTURI(PageArgument& args) {
AC_UNUSED(args); AC_UNUSED(args);
if (_apConfig.bootUri == AC_ONBOOTURI_ROOT) return _getBootUri();
return String(AUTOCONNECT_URI);
else if (_apConfig.bootUri == AC_ONBOOTURI_HOME)
return _apConfig.homeUri.length() > 0 ? _apConfig.homeUri : String("/");
else
return _emptyString;
} }
String AutoConnect::_token_CURRENT_SSID(PageArgument& args) { String AutoConnect::_token_CURRENT_SSID(PageArgument& args) {
@ -1357,6 +1358,60 @@ String AutoConnect::_token_CURRENT_SSID(PageArgument& args) {
return ssid; return ssid;
} }
/**
* Generate AutoConnect menu item configured by AutoConnectConfig::attachMenu.
* @param item An enumerated value for the generating item configured in AutoConnectConfig.
* @return HTML string of a li tag with the menu item.
*/
String AutoConnect::_attachMenuItem(const AC_MENUITEM_t item) {
static const char _liTempl[] PROGMEM = "<li class=\"lb-item\"%s><a href=\"%s\">%s</a></li>";
PGM_P id;
PGM_P link;
PGM_P label;
switch (static_cast<AC_MENUITEM_t>(_apConfig.menuItems & static_cast<uint16_t>(item))) {
case AC_MENUITEM_CONFIGNEW:
id = PSTR("");
link = PSTR(AUTOCONNECT_URI_CONFIG);
label = PSTR(AUTOCONNECT_MENULABEL_CONFIGNEW);
break;
case AC_MENUITEM_OPENSSIDS:
id = PSTR("");
link = PSTR(AUTOCONNECT_URI_OPEN);
label = PSTR(AUTOCONNECT_MENULABEL_OPENSSIDS);
break;
case AC_MENUITEM_DISCONNECT:
id = PSTR("");
link = PSTR(AUTOCONNECT_URI_DISCON);
label = PSTR(AUTOCONNECT_MENULABEL_DISCONNECT);
break;
case AC_MENUITEM_RESET:
id = PSTR(" id=\"reset\"");
link = PSTR("#rdlg");
label = PSTR(AUTOCONNECT_MENULABEL_RESET);
break;
case AC_MENUITEM_HOME:
id = PSTR("");
link = PSTR("HOME_URI");
label = PSTR(AUTOCONNECT_MENULABEL_HOME);
break;
case AC_MENUITEM_DEVINFO:
id = PSTR("");
link = PSTR(AUTOCONNECT_URI);
label = PSTR(AUTOCONNECT_MENULABEL_DEVINFO);
break;
default:
id = nullptr;
link = nullptr;
label = nullptr;
break;
}
char li[128] = { '\0' };
if (!!id && !!link && !!label)
snprintf(li, sizeof(li), (PGM_P)_liTempl, id, link, label);
return String(li);
}
/** /**
* This function dynamically build up the response pages that conform to * This function dynamically build up the response pages that conform to
* the requested URI. A PageBuilder instance is stored in _responsePage * the requested URI. A PageBuilder instance is stored in _responsePage
@ -1365,7 +1420,7 @@ String AutoConnect::_token_CURRENT_SSID(PageArgument& args) {
* @retval true A response page generated. * @retval true A response page generated.
* @retval false Requested uri is not defined. * @retval false Requested uri is not defined.
*/ */
PageElement* AutoConnect::_setupPage(String uri) { PageElement* AutoConnect::_setupPage(String& uri) {
PageElement *elm = new PageElement(); PageElement *elm = new PageElement();
// Restore menu title // Restore menu title
@ -1400,7 +1455,7 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(String(FPSTR("CHIP_ID")), std::bind(&AutoConnect::_token_CHIP_ID, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CHIP_ID")), std::bind(&AutoConnect::_token_CHIP_ID, this, std::placeholders::_1));
elm->addToken(String(FPSTR("FREE_HEAP")), std::bind(&AutoConnect::_token_FREE_HEAP, this, std::placeholders::_1)); elm->addToken(String(FPSTR("FREE_HEAP")), std::bind(&AutoConnect::_token_FREE_HEAP, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_CONFIG)) { else if (uri == String(AUTOCONNECT_URI_CONFIG) && (_apConfig.menuItems & AC_MENUITEM_CONFIGNEW)) {
// Setup /auto/config // Setup /auto/config
elm->setMold(_PAGE_CONFIGNEW); elm->setMold(_PAGE_CONFIGNEW);
@ -1419,7 +1474,7 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(String(FPSTR("HIDDEN_COUNT")), std::bind(&AutoConnect::_token_HIDDEN_COUNT, this, std::placeholders::_1)); elm->addToken(String(FPSTR("HIDDEN_COUNT")), std::bind(&AutoConnect::_token_HIDDEN_COUNT, this, std::placeholders::_1));
elm->addToken(String(FPSTR("CONFIG_IP")), std::bind(&AutoConnect::_token_CONFIG_STAIP, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CONFIG_IP")), std::bind(&AutoConnect::_token_CONFIG_STAIP, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_CONNECT)) { else if (uri == String(AUTOCONNECT_URI_CONNECT) && (_apConfig.menuItems & AC_MENUITEM_CONFIGNEW || _apConfig.menuItems & AC_MENUITEM_OPENSSIDS)) {
// Setup /auto/connect // Setup /auto/connect
_menuTitle = FPSTR(AUTOCONNECT_MENUTEXT_CONNECTING); _menuTitle = FPSTR(AUTOCONNECT_MENUTEXT_CONNECTING);
@ -1433,7 +1488,7 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(String(FPSTR("CUR_SSID")), std::bind(&AutoConnect::_token_CURRENT_SSID, this, std::placeholders::_1)); elm->addToken(String(FPSTR("CUR_SSID")), std::bind(&AutoConnect::_token_CURRENT_SSID, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_OPEN)) { else if (uri == String(AUTOCONNECT_URI_OPEN) && (_apConfig.menuItems & AC_MENUITEM_OPENSSIDS)) {
// Setup /auto/open // Setup /auto/open
elm->setMold(_PAGE_OPENCREDT); elm->setMold(_PAGE_OPENCREDT);
@ -1447,7 +1502,7 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
elm->addToken(String(FPSTR("OPEN_SSID")), std::bind(&AutoConnect::_token_OPEN_SSID, this, std::placeholders::_1)); elm->addToken(String(FPSTR("OPEN_SSID")), std::bind(&AutoConnect::_token_OPEN_SSID, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_DISCON)) { else if (uri == String(AUTOCONNECT_URI_DISCON) && (_apConfig.menuItems & AC_MENUITEM_DISCONNECT)) {
// Setup /auto/disc // Setup /auto/disc
_menuTitle = FPSTR(AUTOCONNECT_MENUTEXT_DISCONNECT); _menuTitle = FPSTR(AUTOCONNECT_MENUTEXT_DISCONNECT);
@ -1459,7 +1514,7 @@ PageElement* AutoConnect::_setupPage(String uri) {
elm->addToken(String(FPSTR("MENU_PRE")), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1)); elm->addToken(String(FPSTR("MENU_PRE")), std::bind(&AutoConnect::_token_MENU_PRE, this, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1)); elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, this, std::placeholders::_1));
} }
else if (uri == String(AUTOCONNECT_URI_RESET)) { else if (uri == String(AUTOCONNECT_URI_RESET) && (_apConfig.menuItems & AC_MENUITEM_RESET)) {
// Setup /auto/reset // Setup /auto/reset
elm->setMold(_PAGE_RESETTING); elm->setMold(_PAGE_RESETTING);

@ -11,7 +11,7 @@
* The dialog pages are all AutoConnectAux, and they select available * The dialog pages are all AutoConnectAux, and they select available
* sketch binary, display during update processing, and display * sketch binary, display during update processing, and display
* update results. * update results.
* 2. Daialog pages handler * 2. Dialog pages handler
* In the dialog page, AUTOCONNECT_URI_UPDATE, AUTOCONNECT_URI_UPDATE_ACT, * In the dialog page, AUTOCONNECT_URI_UPDATE, AUTOCONNECT_URI_UPDATE_ACT,
* AUTOCONNECT_URI_UPDATE_RESULT are assigned and there is a page * AUTOCONNECT_URI_UPDATE_RESULT are assigned and there is a page
* handler for each. * handler for each.
@ -65,7 +65,7 @@ typedef enum AC_UPDATESTATUS {
UPDATE_RESET, /**< Update process ended, need to reset */ UPDATE_RESET, /**< Update process ended, need to reset */
UPDATE_IDLE, /**< Update process has not started */ UPDATE_IDLE, /**< Update process has not started */
UPDATE_START, /**< Update process has been started */ UPDATE_START, /**< Update process has been started */
UPDATE_PROGRESS, /**< Update process has been started */ UPDATE_PROGRESS, /**< Update process in progress */
UPDATE_SUCCESS, /**< Update successfully completed */ UPDATE_SUCCESS, /**< Update successfully completed */
UPDATE_NOAVAIL, /**< No available update */ UPDATE_NOAVAIL, /**< No available update */
UPDATE_FAIL /**< Update fails */ UPDATE_FAIL /**< Update fails */

@ -8,8 +8,8 @@
* @copyright MIT license. * @copyright MIT license.
*/ */
#ifndef _AUTOCONNECTUPDATEPAGE_H #ifndef _AUTOCONNECTUPDATEPAGE_H_
#define _AUTOCONNECTUPDATEPAGE_H #define _AUTOCONNECTUPDATEPAGE_H_
// Define the AUTOCONNECT_URI_UPDATE page to select the sketch binary // Define the AUTOCONNECT_URI_UPDATE page to select the sketch binary
// for update and order update execution. // for update and order update execution.
@ -19,10 +19,10 @@ const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmCatalog[]
{ AC_Element, "c1", "<div class=\"bins\">", nullptr }, { AC_Element, "c1", "<div class=\"bins\">", nullptr },
{ AC_Radio, "firmwares", nullptr, nullptr }, { AC_Radio, "firmwares", nullptr, nullptr },
{ AC_Element, "c1", "</div>", nullptr }, { AC_Element, "c1", "</div>", nullptr },
{ AC_Submit, "update", "UPDATE", AUTOCONNECT_URI_UPDATE_ACT } { AC_Submit, "update", AUTOCONNECT_BUTTONLABEL_UPDATE, AUTOCONNECT_URI_UPDATE_ACT }
}; };
const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_pageCatalog PROGMEM = { const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_pageCatalog PROGMEM = {
AUTOCONNECT_URI_UPDATE, "Update", false, AutoConnectUpdateAct::_elmCatalog AUTOCONNECT_URI_UPDATE, AUTOCONNECT_MENULABEL_UPDATE, false, AutoConnectUpdateAct::_elmCatalog
}; };
// Define the AUTOCONNECT_URI_UPDATE_ACT page to display during the // Define the AUTOCONNECT_URI_UPDATE_ACT page to display during the
@ -45,7 +45,7 @@ const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmProgress[]
{ AC_Element, "c7", "}window.onload=bar;</script>", nullptr } { AC_Element, "c7", "}window.onload=bar;</script>", nullptr }
}; };
const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_pageProgress PROGMEM = { const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_pageProgress PROGMEM = {
AUTOCONNECT_URI_UPDATE_ACT, "Update", false, AutoConnectUpdateAct::_elmProgress AUTOCONNECT_URI_UPDATE_ACT, AUTOCONNECT_MENULABEL_UPDATE, false, AutoConnectUpdateAct::_elmProgress
}; };
// Definition of the AUTOCONNECT_URI_UPDATE_RESULT page to notify update results // Definition of the AUTOCONNECT_URI_UPDATE_RESULT page to notify update results
@ -54,7 +54,7 @@ const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmResult[] P
{ AC_Element, "restart", "<script type=\"text/javascript\">window.onload=function(){var e=new FormData;e.append(\"op\",\"#r\");var o=new XMLHttpRequest;o.timeout=" AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_TIMEOUT) ",o.onloadend=function(){setTimeout(\"location.href='" AUTOCONNECT_HOMEURI "'\"," AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_WAITFORREBOOT) ")},o.open(\"POST\",\"" AUTOCONNECT_URI_UPDATE_PROGRESS "\",!0),o.send(e)};</script>", nullptr } { AC_Element, "restart", "<script type=\"text/javascript\">window.onload=function(){var e=new FormData;e.append(\"op\",\"#r\");var o=new XMLHttpRequest;o.timeout=" AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_TIMEOUT) ",o.onloadend=function(){setTimeout(\"location.href='" AUTOCONNECT_HOMEURI "'\"," AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_WAITFORREBOOT) ")},o.open(\"POST\",\"" AUTOCONNECT_URI_UPDATE_PROGRESS "\",!0),o.send(e)};</script>", nullptr }
}; };
const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_pageResult PROGMEM = { const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_pageResult PROGMEM = {
AUTOCONNECT_URI_UPDATE_RESULT, "Update", false, AutoConnectUpdateAct::_elmResult AUTOCONNECT_URI_UPDATE_RESULT, AUTOCONNECT_MENULABEL_UPDATE, false, AutoConnectUpdateAct::_elmResult
}; };
#endif // _AUTOCONNECTUPDATEPAGE_H #endif // _AUTOCONNECTUPDATEPAGE_H

@ -32,7 +32,7 @@ class AutoConnectUploadHandler {
protected: protected:
virtual bool _open(const char* filename, const char* mode) = 0; virtual bool _open(const char* filename, const char* mode) = 0;
virtual size_t _write(const uint8_t *buf, const size_t size) = 0; virtual size_t _write(const uint8_t *buf, const size_t size) = 0;
virtual void _close(void) = 0; virtual void _close(const HTTPUploadStatus status) = 0;
}; };
#endif // !_AUTOCONNECTUPLOAD_H_ #endif // !_AUTOCONNECTUPLOAD_H_

@ -74,7 +74,7 @@ void AutoConnectUploadHandler::upload(const String& requestUri, const HTTPUpload
break; break;
case UPLOAD_FILE_ABORTED: case UPLOAD_FILE_ABORTED:
case UPLOAD_FILE_END: case UPLOAD_FILE_END:
_close(); _close(upload.status);
break; break;
} }
} }
@ -83,7 +83,7 @@ void AutoConnectUploadHandler::upload(const String& requestUri, const HTTPUpload
class AutoConnectUploadFS : public AutoConnectUploadHandler { class AutoConnectUploadFS : public AutoConnectUploadHandler {
public: public:
explicit AutoConnectUploadFS(SPIFFST& media) : _media(&media) {} explicit AutoConnectUploadFS(SPIFFST& media) : _media(&media) {}
~AutoConnectUploadFS() { _close(); } ~AutoConnectUploadFS() { _close(HTTPUploadStatus::UPLOAD_FILE_END); }
protected: protected:
bool _open(const char* filename, const char* mode) override { bool _open(const char* filename, const char* mode) override {
@ -106,7 +106,8 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler {
return -1; return -1;
} }
void _close(void) override { void _close(const HTTPUploadStatus status) override {
AC_UNUSED(status);
if (_file) if (_file)
_file.close(); _file.close();
_media->end(); _media->end();
@ -142,7 +143,7 @@ class AutoConnectUploadFS : public AutoConnectUploadHandler {
class AutoConnectUploadSD : public AutoConnectUploadHandler { class AutoConnectUploadSD : public AutoConnectUploadHandler {
public: public:
explicit AutoConnectUploadSD(SDClassT& media, const uint8_t cs = AUTOCONNECT_SD_CS, const uint32_t speed = AUTOCONNECT_SD_SPEED) : _media(&media), _cs(cs), _speed(speed) {} explicit AutoConnectUploadSD(SDClassT& media, const uint8_t cs = AUTOCONNECT_SD_CS, const uint32_t speed = AUTOCONNECT_SD_SPEED) : _media(&media), _cs(cs), _speed(speed) {}
~AutoConnectUploadSD() { _close(); } ~AutoConnectUploadSD() { _close(HTTPUploadStatus::UPLOAD_FILE_END); }
protected: protected:
bool _open(const char* filename, const char* mode) override { bool _open(const char* filename, const char* mode) override {
@ -205,7 +206,8 @@ class AutoConnectUploadSD : public AutoConnectUploadHandler {
return -1; return -1;
} }
void _close(void) override { void _close(const HTTPUploadStatus status) override {
AC_UNUSED(status);
if (_file) if (_file)
_file.close(); _file.close();
AutoConnectUtil::end<SDClassT>(_media); AutoConnectUtil::end<SDClassT>(_media);

Loading…
Cancel
Save