mirror of
https://github.com/alexhopeoconnor/WiFiManager.git
synced 2026-10-19 09:21:30 +10:00
feat: prepare WiFiManager 3.1.0
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Development and releases
|
||||
|
||||
Released consumers use the public Git tag. While changing WiFiManager and a sibling dependency together, point an ignored local PlatformIO override at a `symlink://` or `file://` checkout rather than changing tracked application dependencies.
|
||||
|
||||
```ini
|
||||
lib_deps =
|
||||
WiFiManager=symlink:///path/to/WiFiManager
|
||||
```
|
||||
|
||||
Before a release, update `library.json`, `CHANGELOG.md`, and the relevant public documentation, then run:
|
||||
|
||||
```bash
|
||||
./scripts/check-docs.sh
|
||||
./scripts/test.sh compile --platform esp8266
|
||||
./scripts/test.sh compile --platform esp32
|
||||
./scripts/prepare-release.sh vMAJOR.MINOR.PATCH --tag
|
||||
```
|
||||
|
||||
Push the branch and annotated tag. GitHub Actions repeats the board-free compile checks, validates the package, and creates a GitHub Release using that version’s changelog section. The workflow does not publish to the PlatformIO Registry.
|
||||
|
||||
Back to [documentation](README.md) · [project overview](../README.md).
|
||||
@@ -0,0 +1,41 @@
|
||||
# Getting started
|
||||
|
||||
WiFiManager owns station credential recovery and a temporary configuration portal. Keep one instance for the life of the application.
|
||||
|
||||
```cpp
|
||||
#include <Arduino.h>
|
||||
#include <WiFiManager.h>
|
||||
|
||||
WiFiManager wifi;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
wifi.setConfigPortalTimeout(180);
|
||||
if (!wifi.autoConnect("Example Setup", "change-me")) {
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// 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.
|
||||
|
||||
## PlatformIO dependency
|
||||
|
||||
```ini
|
||||
lib_deps =
|
||||
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.1.0
|
||||
```
|
||||
|
||||
The package manifest resolves DFTE, ESPAsyncWebServer, and the correct TCP transport for ESP8266 or ESP32. A consuming project should not duplicate those dependencies unless it is deliberately testing an unreleased stack change.
|
||||
|
||||
## DeviceFramework applications
|
||||
|
||||
DeviceFramework creates and configures WiFiManager for its normal lifecycle. Use DeviceFramework’s persistent shared device-password API instead of separately configuring an AP, OTA, HTTP, and WebSerial password.
|
||||
|
||||
Next: [portal customisation](PORTAL_CUSTOMIZATION.md) or [portal API](PORTAL_API.md).
|
||||
|
||||
Back to [documentation](README.md) · [project overview](../README.md).
|
||||
@@ -0,0 +1,34 @@
|
||||
# Portal API
|
||||
|
||||
The portal uses JSON endpoints under `/api/...` for WiFi scans and saves, parameters, information, status, restart/erase/exit actions, captive-portal closure, and station-connect status. Consumers should treat the documented response shapes as the contract; portal HTML is not an API.
|
||||
|
||||
## Profile-mode WiFi metadata
|
||||
|
||||
When an application supplies a `WiFiManagerStationProfileStore`, `GET /api/wifi/meta` reports a primary profile and optional fallback without returning passwords. `POST /api/wifi/save` verifies a submitted candidate before committing it; see [station profiles](STATION_PROFILES.md) for fields and lifecycle.
|
||||
|
||||
## WiFi connect status
|
||||
|
||||
When `portalSetBehaviorConnectOnSave(true)` is enabled, saving credentials queues a station join. The SPA polls `GET /api/wifi/connect-status`:
|
||||
|
||||
```json
|
||||
{
|
||||
"state": "waiting | success | failed",
|
||||
"message": "human readable status",
|
||||
"wifiStatus": "WL_CONNECTED",
|
||||
"stationIp": "192.168.1.42",
|
||||
"redirectUrl": "http://192.168.1.42/"
|
||||
}
|
||||
```
|
||||
|
||||
`stationIp` and `redirectUrl` are present only after a successful join. If the portal server is not on port 80, `redirectUrl` includes that port.
|
||||
|
||||
On success, WiFiManager keeps the portal alive briefly so the client can read the final status and navigate before the AP is shut down. Captive-portal helpers, DHCP timing, browser behaviour, and network isolation can still prevent an automatic redirect, so clients must handle a visible address as well.
|
||||
|
||||
## API design rules
|
||||
|
||||
- Use JSON endpoint results for state and actions.
|
||||
- Keep UI-visible capabilities in the portal bootstrap/API payloads.
|
||||
- Add a documented endpoint contract before adding a new portal workflow.
|
||||
- Do not derive state by parsing the rendered shell.
|
||||
|
||||
Back to [documentation](README.md) · [project overview](../README.md).
|
||||
@@ -0,0 +1,65 @@
|
||||
# Portal customisation
|
||||
|
||||
The stable extension surface is the `portal*` API and JSON API contract. Templates, undocumented DOM IDs, and SPA routing internals are not consumer extension points.
|
||||
|
||||
## Supported changes
|
||||
|
||||
- `portalSetBrand*` and `portalSetContextIdentityText()` for the visible identity.
|
||||
- `portalSetPage*`, `portalSetAction*`, `portalSetLayout*`, and `portalSetBehavior*` for built-in capability and layout choices.
|
||||
- `portalAddParameter()`, including raw HTML blocks inside parameter-rendering surfaces.
|
||||
- `portalAddInfoSection()` and `portalAddHomeCard()` for structured content.
|
||||
- `portalAppendCss()`, `portalOverrideCss()`, and `portalAppendJs()` for small presentation enhancements.
|
||||
|
||||
```cpp
|
||||
WiFiManager wm;
|
||||
|
||||
wm.portalSetBrandTitle("Solar Battery Monitor Setup");
|
||||
wm.portalSetContextIdentityText("Solar Battery Monitor");
|
||||
wm.portalSetBrandHomeIntro(
|
||||
"Connect the monitor to WiFi, then review its battery settings."
|
||||
);
|
||||
wm.portalSetPageUpdateVisible(false);
|
||||
wm.portalSetActionEraseVisible(false);
|
||||
wm.portalSetLayoutParamsLocation(PortalParamsLocation::SetupPage);
|
||||
|
||||
WiFiManagerParameter mqttHost(
|
||||
"mqtt_host", "MQTT host", "broker.local", 64,
|
||||
"placeholder='broker.local'"
|
||||
);
|
||||
wm.portalAddParameter(&mqttHost);
|
||||
|
||||
PortalHomeCard summary;
|
||||
summary.id = "battery";
|
||||
summary.title = "Battery";
|
||||
summary.kind = PortalHomeCardKind::KeyValue;
|
||||
summary.items.push_back({"voltage", "Voltage", "13.2V"});
|
||||
wm.portalAddHomeCard(summary);
|
||||
|
||||
wm.portalAppendJs(
|
||||
"document.addEventListener('wm:ready', function(event) {"
|
||||
" console.log('Portal ready', event.detail.boot);"
|
||||
"});"
|
||||
);
|
||||
```
|
||||
|
||||
## Enhancement events
|
||||
|
||||
Appended JavaScript may enhance the existing SPA through:
|
||||
|
||||
- `wm:ready`, with `event.detail.boot`;
|
||||
- `wm:view-changed`, with `event.detail.route`.
|
||||
|
||||
It should not replace routing or built-in action flow.
|
||||
|
||||
## Intentional boundary
|
||||
|
||||
The following are fork-level changes, not supported consumer customisation:
|
||||
|
||||
- arbitrary home, information, navigation, or shell HTML injection;
|
||||
- replacing built-in SPA routes or action flows;
|
||||
- depending on undocumented DOM IDs or private templates;
|
||||
- adding a new backend-to-frontend workflow without an API contract.
|
||||
|
||||
For data and endpoint behaviour, see [Portal API](PORTAL_API.md).
|
||||
|
||||
Back to [documentation](README.md) · [project overview](../README.md).
|
||||
@@ -0,0 +1,20 @@
|
||||
# WiFiManager documentation
|
||||
|
||||
This maintained fork intentionally has a narrower, explicit customisation boundary than upstream WiFiManager.
|
||||
|
||||
| I want to… | Read |
|
||||
| --- | --- |
|
||||
| Start a basic portal or install a released dependency | [Getting started](GETTING_STARTED.md) |
|
||||
| Brand the SPA, add parameters/cards, or use the supported hooks | [Portal customisation](PORTAL_CUSTOMIZATION.md) |
|
||||
| Configure primary/fallback station profiles or their portal workflow | [Station profiles](STATION_PROFILES.md) |
|
||||
| Consume JSON endpoints or station-connect status | [Portal API](PORTAL_API.md) |
|
||||
| Build a clean consumer | [Testing](TESTING.md) |
|
||||
| Work on this fork or make a release | [Development and releases](DEVELOPMENT.md) |
|
||||
|
||||
## Documentation rules
|
||||
|
||||
- Portal customisation owns the supported `portal*` surface.
|
||||
- Portal API owns HTTP response contracts.
|
||||
- The root README is a short onboarding page, not an API reference.
|
||||
|
||||
Back to the [project overview](../README.md).
|
||||
@@ -0,0 +1,62 @@
|
||||
# Station profiles
|
||||
|
||||
WiFiManager 3.1.0 adds an opt-in station-profile controller for applications that need a primary Wi-Fi network and one fallback. It is independent of the legacy `autoConnect()` flow: existing WiFiManager consumers do not need to change.
|
||||
|
||||
DeviceFramework enables this controller and supplies its CRC-protected storage. A direct WiFiManager consumer supplies its own durable store, or can use the controller only for the current process.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
A profile set has exactly two fixed slots:
|
||||
|
||||
- **Primary** (slot 0) is required whenever the controller is enabled.
|
||||
- **Fallback** (slot 1) is optional.
|
||||
- The last successful slot is tried first on the next connection cycle, then the remaining enabled slot.
|
||||
|
||||
The controller never treats the ESP SDK's saved single network as an additional source of truth. It begins one bounded connection attempt at a time, moves to the fallback after failure, and retries both profiles after a temporary loss of a previously working connection. If a new device has no valid profiles, it opens the normal configuration portal.
|
||||
|
||||
A candidate submitted by the portal is only committed after it connects and receives a usable IP address. A failed candidate leaves the last saved profile set intact.
|
||||
|
||||
## Direct WiFiManager use
|
||||
|
||||
Implement a small store appropriate to the application. The manager neither allocates nor owns it:
|
||||
|
||||
```cpp
|
||||
class MyProfileStore final : public WiFiManagerStationProfileStore {
|
||||
public:
|
||||
bool load(WiFiManagerStationProfiles& profiles) override;
|
||||
bool save(const WiFiManagerStationProfiles& profiles) override;
|
||||
bool clear() override;
|
||||
};
|
||||
|
||||
WiFiManager wifi;
|
||||
MyProfileStore profiles;
|
||||
|
||||
void setup() {
|
||||
wifi.setStationProfileStore(&profiles);
|
||||
wifi.setStationRecoveryInterval(30000);
|
||||
wifi.startStationConnection("Example Setup", "setup-password");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
wifi.process();
|
||||
}
|
||||
```
|
||||
|
||||
The store must return a complete `WiFiManagerStationProfiles` value. Each enabled profile has a NUL-terminated SSID of at most 32 characters and an optional NUL-terminated password of at most 64 characters. Keep slot 0 enabled; set `hasPassword = false` for an open network.
|
||||
|
||||
To stage profiles supplied by another subsystem, use `startStationCandidate(candidate)`. It connects the primary/fallback set first and calls the store only after success. Use `saveStationProfiles(profiles)` only when deliberately saving without a connection check. `clearStationProfiles()` clears the supplied store and disconnects the station.
|
||||
|
||||
## Portal contract
|
||||
|
||||
In profile mode, the existing Wi-Fi page becomes a two-profile form. It remains driven by the same JSON endpoints:
|
||||
|
||||
- `GET /api/wifi/meta` returns `profiles`, `activeSlot`, and controller `state`.
|
||||
- `POST /api/wifi/save` accepts `s0`/ `p0` for primary and `s1`/ `p1` for fallback. A blank submitted password preserves an existing password; send `clear0` or `clear1` for an intentional open network.
|
||||
- A normal save verifies the candidate by connecting. Poll `GET /api/wifi/connect-status` for its result.
|
||||
- Set `stationAction=save` only to store the submitted profiles for a later connection attempt.
|
||||
|
||||
The portal requires a non-empty primary SSID. Its API never returns a password; it only reports whether one is set.
|
||||
|
||||
See [Portal API](PORTAL_API.md) for the shared connection-status response and [DeviceFramework configuration](https://github.com/alexhopeoconnor/DeviceFramework/blob/main/docs/CONFIGURATION.md) for the local-profile JSON that supplies these slots.
|
||||
|
||||
Back to [documentation](README.md) · [project overview](../README.md).
|
||||
@@ -0,0 +1,12 @@
|
||||
# Testing
|
||||
|
||||
The clean-consumer check builds a project that declares only WiFiManager. It proves the package manifest resolves DFTE, ESPAsyncWebServer, and the correct ESP8266 or ESP32 TCP dependency without a sibling checkout or attached board.
|
||||
|
||||
```bash
|
||||
./scripts/test.sh compile --platform esp8266
|
||||
./scripts/test.sh compile --platform esp32
|
||||
```
|
||||
|
||||
CI runs both checks for pushes to the maintained branch and pull requests. They compile only; hardware portals remain a local integration concern for an application or DeviceFramework’s connected-device suite.
|
||||
|
||||
Back to [documentation](README.md) · [project overview](../README.md).
|
||||
Reference in New Issue
Block a user