Compare commits

...
4 Commits
9 changed files with 78 additions and 66 deletions
+9
View File
@@ -1,5 +1,14 @@
# Changelog # Changelog
## 3.2.2
- Align the direct ESP8266 and ESP32 test environments with the packaged DFTE 1.2.0 dependency.
## 3.2.1
- Ensure externally supplied station profiles remain authoritative on ESP32 by clearing stale SDK-owned credentials before opening the portal for an empty or invalid external profile set.
- Pin DFTE 1.2.0, the tested template-engine release used by the maintained portal.
## 3.2.0 ## 3.2.0
- Refine the device-hosted portal with a startup Wi-Fi scan, stable loading overlays, clearer connection progress, and a resettable configuration timeout. - Refine the device-hosted portal with a startup Wi-Fi scan, stable loading overlays, clearer connection progress, and a resettable configuration timeout.
+14 -17
View File
@@ -4,11 +4,10 @@ WiFiManager gives ESP8266 and ESP32 firmware a polished, self-hosted Wi-Fi setup
## See it on real hardware ## See it on real hardware
| Branded ESP32 portal | ESP8266 portal with an application field | | Brand the built-in portal | Combine Wi-Fi and application setup |
| --- | --- | | --- | --- |
| ![Branded WiFiManager portal overview on an ESP32.](docs/assets/portal-esp32-branded-overview.png) | ![WiFiManager network picker and custom MQTT broker field on an ESP8266.](docs/assets/portal-esp8266-custom-wifi.png) | | ![Branded WiFiManager portal overview on an ESP32.](docs/assets/portal-esp32-branded-overview.png) | ![WiFiManager network picker and custom MQTT broker field on an ESP8266.](docs/assets/portal-esp8266-custom-wifi.png) |
| Give each product its own title, identity, icon, and color theme without copying portal HTML. | Show live nearby networks and collect application values, such as an MQTT broker, in the same setup flow. |
These are unmodified browser captures of [Branded Portal](examples/BrandedPortal/) and [Custom Portal Content](examples/CustomPortalContent/) running on the supported boards. The portal is served by the device itself; no cloud UI or companion app is involved.
## Start with a working portal ## Start with a working portal
@@ -38,20 +37,18 @@ const char kTitle[] PROGMEM = "Set up Temperature Monitor";
const char kBrand[] PROGMEM = "Example Devices"; const char kBrand[] PROGMEM = "Example Devices";
const char kAccent[] PROGMEM = "#347a45"; const char kAccent[] PROGMEM = "#347a45";
const WiFiManagerPortalConfig kPortalUI = {
WiFiManagerPortalText::progmem(kTitle),
WiFiManagerPortalText::progmem(kBrand),
{}, {}, {},
{
{}, {}, {}, {}, {},
WiFiManagerPortalText::progmem(kAccent),
{}, {}, {}, {}, {},
10, 0,
},
};
void setup() { void setup() {
wifi.setPortalConfig(kPortalUI); // before the portal starts WiFiManagerPortalConfig portalUI;
// Leave fields unset to keep WiFiManager's built-in portal values.
portalUI.title = WiFiManagerPortalText::progmem(kTitle);
portalUI.identityText = WiFiManagerPortalText::progmem(kBrand);
// Theme values customise the built-in styles; they do not replace the portal.
portalUI.theme.accent = WiFiManagerPortalText::progmem(kAccent);
portalUI.theme.cornerRadiusPx = 10;
wifi.setPortalConfig(portalUI); // Apply before the portal starts.
wifi.autoConnect("Device Setup"); wifi.autoConnect("Device Setup");
} }
@@ -86,7 +83,7 @@ The [Branded Portal](examples/BrandedPortal/) example includes a static SVG, acc
```ini ```ini
[common] [common]
lib_deps = lib_deps =
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.0 WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.2
``` ```
The suffix after `#` is a Git ref. PlatformIO clones the repository and checks out that release tag; GitHub Release assets are unrelated. Arduino IDE users can install this repository as a library checkout. The suffix after `#` is a Git ref. PlatformIO clones the repository and checks out that release tag; GitHub Release assets are unrelated. Arduino IDE users can install this repository as a library checkout.
+4 -5
View File
@@ -11,23 +11,22 @@ WiFiManager wifi;
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
wifi.setConfigPortalTimeout(180); wifi.setConfigPortalTimeout(180);
if (!wifi.autoConnect("Example Setup", "change-me")) { wifi.autoConnect("Example Setup", "change-me");
ESP.restart();
}
} }
void loop() { void loop() {
wifi.process(); // Keeps the portal responsive when setup is needed.
// Normal work begins after autoConnect succeeds. // Normal work begins after autoConnect succeeds.
} }
``` ```
`autoConnect()` first tries stored station credentials. If that cannot connect, it starts the AP and portal with the supplied name and password. Use a Wi-Fi-valid AP password. `autoConnect()` first tries stored station credentials. If that cannot connect, it starts the AP and portal with the supplied name and password, then returns `false`; call `process()` from `loop()` so that portal can run. Use a Wi-Fi-valid AP password.
## PlatformIO dependency ## PlatformIO dependency
```ini ```ini
lib_deps = lib_deps =
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.0 WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.2
``` ```
The package includes the asynchronous web and TCP dependencies required by the selected ESP8266 or ESP32 target. Add WiFiManager as the application’s direct dependency; do not copy its internal dependency list into your project. The package includes the asynchronous web and TCP dependencies required by the selected ESP8266 or ESP32 target. Add WiFiManager as the application’s direct dependency; do not copy its internal dependency list into your project.
+18 -19
View File
@@ -23,31 +23,30 @@ const char kSurface[] PROGMEM = "#ffffff";
const char kAccent[] PROGMEM = "#347a45"; const char kAccent[] PROGMEM = "#347a45";
const char kAccentText[] PROGMEM = "#ffffff"; const char kAccentText[] PROGMEM = "#ffffff";
const WiFiManagerPortalConfig kPortalUI = { WiFiManagerPortalConfig kPortalUI;
WiFiManagerPortalText::progmem(kTitle),
WiFiManagerPortalText::progmem(kIdentity),
WiFiManagerPortalText::progmem(kTagline),
WiFiManagerPortalAsset::svgFromProgmem(kLogo),
WiFiManagerPortalText::progmem(kLogoAlt),
{
WiFiManagerPortalText::progmem(kPage),
WiFiManagerPortalText::progmem(kSurface),
{}, {}, {},
WiFiManagerPortalText::progmem(kAccent),
{},
WiFiManagerPortalText::progmem(kAccentText),
{}, {}, {},
10, 6,
},
};
} }
void setup() { void setup() {
wifi.setPortalConfig(kPortalUI); // Set only the identity values this product needs.
kPortalUI.title = WiFiManagerPortalText::progmem(kTitle);
kPortalUI.identityText = WiFiManagerPortalText::progmem(kIdentity);
kPortalUI.tagline = WiFiManagerPortalText::progmem(kTagline);
kPortalUI.logo = WiFiManagerPortalAsset::svgFromProgmem(kLogo);
kPortalUI.logoAltText = WiFiManagerPortalText::progmem(kLogoAlt);
// Unset theme values retain the built-in style.
kPortalUI.theme.pageBackground = WiFiManagerPortalText::progmem(kPage);
kPortalUI.theme.surface = WiFiManagerPortalText::progmem(kSurface);
kPortalUI.theme.accent = WiFiManagerPortalText::progmem(kAccent);
kPortalUI.theme.accentText = WiFiManagerPortalText::progmem(kAccentText);
kPortalUI.theme.cornerRadiusPx = 10;
kPortalUI.theme.smallCornerRadiusPx = 6;
wifi.setPortalConfig(kPortalUI); // Configure before the portal starts.
wifi.autoConnect("Temperature Monitor"); wifi.autoConnect("Temperature Monitor");
} }
void loop() {} void loop() { wifi.process(); }
``` ```
The complete buildable example is [BrandedPortal](../examples/BrandedPortal/BrandedPortal.ino). The compile fixture exercises this API on ESP8266 and ESP32. The complete buildable example is [BrandedPortal](../examples/BrandedPortal/BrandedPortal.ino). The compile fixture exercises this API on ESP8266 and ESP32.
+4 -2
View File
@@ -7,9 +7,11 @@ void setup() {
Serial.begin(115200); Serial.begin(115200);
portal.setConfigPortalTimeout(180); portal.setConfigPortalTimeout(180);
portal.autoConnect("WiFiManager Basic", "example-pass"); if (portal.autoConnect("WiFiManager Basic", "example-pass")) {
Serial.println("Connected. Run your normal application here."); Serial.println("Connected. Run your normal application here.");
} else {
Serial.println("Setup portal started at http://192.168.4.1/");
}
} }
void loop() { portal.process(); } void loop() { portal.process(); }
+17 -18
View File
@@ -15,29 +15,28 @@ const char kText[] PROGMEM = "#1c251e";
const char kAccent[] PROGMEM = "#347a45"; const char kAccent[] PROGMEM = "#347a45";
const char kAccentText[] PROGMEM = "#ffffff"; const char kAccentText[] PROGMEM = "#ffffff";
const WiFiManagerPortalConfig kPortalUI = { WiFiManagerPortalConfig kPortalUI;
WiFiManagerPortalText::progmem(kPortalTitle),
WiFiManagerPortalText::progmem(kPortalIdentity),
WiFiManagerPortalText::progmem(kPortalTagline),
WiFiManagerPortalAsset::svgFromProgmem(kExampleLogo),
WiFiManagerPortalText::progmem(kPortalLogoAlt),
{
WiFiManagerPortalText::progmem(kPage),
WiFiManagerPortalText::progmem(kSurface),
WiFiManagerPortalText::progmem(kText),
{}, {},
WiFiManagerPortalText::progmem(kAccent),
{},
WiFiManagerPortalText::progmem(kAccentText),
{}, {}, {},
10, 6,
},
};
} }
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
// Brand the built-in portal; unassigned fields retain their default values.
kPortalUI.title = WiFiManagerPortalText::progmem(kPortalTitle);
kPortalUI.identityText = WiFiManagerPortalText::progmem(kPortalIdentity);
kPortalUI.tagline = WiFiManagerPortalText::progmem(kPortalTagline);
kPortalUI.logo = WiFiManagerPortalAsset::svgFromProgmem(kExampleLogo);
kPortalUI.logoAltText = WiFiManagerPortalText::progmem(kPortalLogoAlt);
// Override only the theme tokens that define this product's appearance.
kPortalUI.theme.pageBackground = WiFiManagerPortalText::progmem(kPage);
kPortalUI.theme.surface = WiFiManagerPortalText::progmem(kSurface);
kPortalUI.theme.text = WiFiManagerPortalText::progmem(kText);
kPortalUI.theme.accent = WiFiManagerPortalText::progmem(kAccent);
kPortalUI.theme.accentText = WiFiManagerPortalText::progmem(kAccentText);
kPortalUI.theme.cornerRadiusPx = 10;
kPortalUI.theme.smallCornerRadiusPx = 6;
if (!wifi.setPortalConfig(kPortalUI)) { if (!wifi.setPortalConfig(kPortalUI)) {
Serial.println("Portal UI configuration was rejected"); Serial.println("Portal UI configuration was rejected");
} }
+7
View File
@@ -349,6 +349,13 @@ bool WiFiManager::startStationConnection(char const *apName, char const *apPassw
_stationStatus.configuredProfiles = configuredStationProfileCount(_stationProfiles); _stationStatus.configuredProfiles = configuredStationProfileCount(_stationProfiles);
if (!validateStationProfiles(_stationProfiles)) { if (!validateStationProfiles(_stationProfiles)) {
// In station-profile mode the caller store is the single source of
// truth. ESP32 can reconnect from credentials retained in its own NVS
// before the portal is started, which would otherwise bypass an empty or
// invalid external profile set. Clear only that SDK-owned state here;
// the external store remains untouched and is what the portal will save.
WiFi_Disconnect();
WiFi_eraseConfig();
_stationStatus.message = _stationStatus.configuredProfiles == 0 _stationStatus.message = _stationStatus.configuredProfiles == 0
? F("No WiFi profiles configured") ? F("No WiFi profiles configured")
: F("Stored WiFi profiles are invalid"); : F("Stored WiFi profiles are invalid");
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "WiFiManager", "name": "WiFiManager",
"version": "3.2.0", "version": "3.2.2",
"keywords": [ "keywords": [
"wifi", "wifi",
"wi-fi", "wi-fi",
@@ -58,7 +58,7 @@
}, },
{ {
"name": "DeviceFrameworkTemplateEngine", "name": "DeviceFrameworkTemplateEngine",
"version": "https://github.com/alexhopeoconnor/DFTE.git#v1.1.0" "version": "https://github.com/alexhopeoconnor/DFTE.git#v1.2.0"
} }
], ],
"build": { "build": {
+2 -2
View File
@@ -16,7 +16,7 @@ build_flags =
-DUNIT_TEST -DUNIT_TEST
lib_deps = lib_deps =
ESP32Async/ESPAsyncWebServer@3.9.1 ESP32Async/ESPAsyncWebServer@3.9.1
DeviceFrameworkTemplateEngine=https://github.com/alexhopeoconnor/DFTE.git#v1.1.0 DeviceFrameworkTemplateEngine=https://github.com/alexhopeoconnor/DFTE.git#v1.2.0
ESP32Async/ESPAsyncTCP@2.0.0 ESP32Async/ESPAsyncTCP@2.0.0
[env:esp32] [env:esp32]
@@ -36,7 +36,7 @@ build_flags =
-DUNIT_TEST -DUNIT_TEST
lib_deps = lib_deps =
ESP32Async/ESPAsyncWebServer@3.9.1 ESP32Async/ESPAsyncWebServer@3.9.1
DeviceFrameworkTemplateEngine=https://github.com/alexhopeoconnor/DFTE.git#v1.1.0 DeviceFrameworkTemplateEngine=https://github.com/alexhopeoconnor/DFTE.git#v1.2.0
ESP32Async/AsyncTCP@^3.4.9 ESP32Async/AsyncTCP@^3.4.9
; Optional: compile tests with DFTE logs bridged into WiFiManager::log (see README) ; Optional: compile tests with DFTE logs bridged into WiFiManager::log (see README)