docs: clarify WiFiManager integration boundary

This commit is contained in:
2026-09-08 09:54:38 +10:00
parent 9b070f45f4
commit 5592fd12e1
9 changed files with 74 additions and 30 deletions
+8 -1
View File
@@ -1,5 +1,13 @@
# Changelog
## 3.2.3
- Clarify the public integration boundary, built-in browser protocol, and
portal presentation documentation without coupling the standalone library to
DeviceFramework.
- Refresh the standalone test guidance and pin the packaged DFTE dependency to
the validated 1.2.1 release.
## 3.2.2
- Align the direct ESP8266 and ESP32 test environments with the packaged DFTE 1.2.0 dependency.
@@ -52,4 +60,3 @@
- Establish `device-framework` as the independently maintained canonical branch.
- Add safe default parameter construction and allocation-failure handling.
- Pin the DFTE dependency used by PlatformIO builds.
+1 -1
View File
@@ -91,7 +91,7 @@ The [Branded Portal](examples/BrandedPortal/) example includes a static SVG, acc
```ini
[common]
lib_deps =
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.2
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.3
```
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.
+28 -10
View File
@@ -1,17 +1,21 @@
# Architecture and boundaries
# Integrating WiFiManager
WiFiManager is a device-local provisioning component. It tries station Wi-Fi, temporarily hosts an access point and portal when the device cannot connect, and then returns control to the firmware. It is not a cloud service, a remote-management system, or a companion-app framework.
WiFiManager runs device-local Wi-Fi setup. It tries station Wi-Fi, temporarily
hosts an access point and portal when the device cannot connect, and then lets
the firmware continue its normal work. It is not a cloud service,
remote-management system, or companion-app framework.
## Ownership
## What WiFiManager handles
| WiFiManager owns | The application owns |
| WiFiManager handles | Your firmware handles |
| --- | --- |
| Temporary AP, captive DNS, portal routes, Wi-Fi connection attempts, portal session state | Durable application settings, schema migration, product services, LEDs/display, reboot policy, telemetry, and access-control decisions |
| Wi-Fi credentials in the legacy flow, or profile-selection policy in station-profile mode | The durable station-profile store when profile mode is enabled |
| Structured portal presentation and built-in Wi-Fi/settings forms | Product-specific validation and the persistence of product settings |
| The local portal JSON protocol | Any separate product HTTP API or local web server |
This separation is intentional: an application can decide how a device should be configured without having to duplicate the portal.
This lets a firmware decide what configuration it needs without copying the
portal, captive-network behavior, or Wi-Fi connection flow.
## Typical boot sequence
@@ -29,22 +33,36 @@ Firmware boot
Register portal configuration before calling autoConnect(), startConfigPortal(), startWebPortal(), or a station-profile start method. The active portal uses an immutable response model so that asynchronous requests cannot see a partially changed UI.
## Structured configuration, not a replacement web app
## Customise the built-in portal
WiFiManager supports product identity, semantic theme values, page/action visibility, field policy, parameters, information sections, and home cards. It deliberately does not provide:
WiFiManager can set product identity, named theme values, page/action
visibility, parameters, information sections, and home cards. Use its public
C++ configuration and content APIs for those tasks:
~~~cpp
WiFiManagerPortalConfig portal;
portal.title = WiFiManagerPortalText::progmem(PSTR("Set up sensor"));
wifi.setPortalConfig(portal);
~~~
The built-in portal still owns its HTML shell, routes, forms, navigation, and
captive behavior. It does not provide:
- arbitrary portal HTML-shell replacement;
- raw CSS or JavaScript injection;
- route replacement or navigation injection;
- a cloud API or a supported mobile-companion integration surface.
- a cloud API or supported mobile-companion integration surface.
Use the portal APIs where their existing semantics fit. If a product needs a new portal capability, add a narrow, documented WiFiManager contract and test it on both supported targets instead of reaching into portal internals.
The `/api/*` routes are the built-in portal's browser protocol. They are useful
for portal maintenance and tests, but are not a product firmware or
companion-app integration API. If a product needs a reusable portal capability,
add one focused public WiFiManager C++ API and test it on ESP8266 and ESP32.
## Application-service handoff
WiFiManager's portal server uses its configured HTTP port, 80 by default. A product already using that port must explicitly release it before WiFiManager starts a portal. Conversely, the application decides when its normal web service is safe to start after a successful connection.
This is a real integration boundary, not a WiFiManager callback side effect:
Release an application-owned server before starting the portal:
~~~cpp
void beginRecovery() {
+1 -1
View File
@@ -26,7 +26,7 @@ void loop() {
```ini
lib_deps =
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.2
WiFiManager=https://github.com/alexhopeoconnor/WiFiManager.git#v3.2.3
```
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.
+11 -4
View File
@@ -1,6 +1,9 @@
# Portal API
# Built-in portal browser protocol
This is the device-local protocol used by WiFiManager's built-in portal shell. It is useful for maintaining the built-in UI and for portal-focused tests, but it is not a cloud API, remote-management interface, or supported companion-app integration surface.
This device-local protocol is used by WiFiManager's built-in portal shell. It
is useful when maintaining that UI or writing portal-focused tests. It is not a
cloud API, remote-management interface, or supported companion-app integration
surface.
The portal is unauthenticated local setup infrastructure. Do not expose it as a product's general application API, and do not infer a security boundary from hiding an action in the UI.
@@ -100,8 +103,12 @@ POST /api/params/save sends registered application parameter fields and returns
| POST /api/portal/exit | 200, exit scheduled | 403 when exit is not allowed. |
| POST /u | 200, firmware update/restart scheduled | 500 with update failure detail. |
## Compatibility boundary
## Using this protocol safely
Use this document to understand and test WiFiManager's own portal behavior. Applications that need a product web API should host and secure that API themselves after WiFiManager has completed its provisioning role. Do not scrape the portal shell, depend on undocumented JSON fields, or add routes through WiFiManager's testing server accessor.
Use this document to understand and test WiFiManager's own portal behavior.
Applications that need a product web API should host and secure that API after
WiFiManager has completed its provisioning role. Do not scrape the portal shell,
depend on undocumented JSON fields, or add routes through WiFiManager's testing
server accessor.
Back to [documentation](README.md) · [project overview](../README.md).
+18 -6
View File
@@ -68,11 +68,15 @@ Leave a text or colour value empty, or a radius at 0, to retain the built-in sty
| success, danger, dangerHover | Status and destructive actions |
| cornerRadiusPx, smallCornerRadiusPx | Card and compact-control corners, limited to 64 px |
Theme values accept only simple semantic CSS value syntax and are emitted once into a small portal theme block. This is deliberately not a raw CSS or JavaScript injection API. An SVG is a trusted compiled firmware asset, never form, MQTT, or network input.
Theme values accept simple named CSS values and are emitted once into a small
portal theme block. Raw CSS and JavaScript are not supported. An SVG is a
trusted compiled firmware asset, never form, MQTT, or network input.
## Portal policy
Use the portal-prefixed methods to constrain a product's use of built-in pages and actions. Configure them during boot, before the portal starts, so a session begins with the intended policy.
Use the portal-prefixed methods to choose which built-in pages and actions a
product presents. Configure them during boot, before the portal starts, so a
session begins with the intended behavior.
~~~cpp
// An installer portal that does not expose destructive reset or OTA actions.
@@ -94,8 +98,8 @@ wifi.portalSetFieldStaticDnsVisibility(PortalFieldVisibility::Hidden);
| Pages | portalSetPageInfoVisible(), portalSetPageUpdateVisible(), portalSetPageSetupVisible() | Show only product-appropriate built-in pages. |
| Actions | portalSetActionEraseVisible(), portalSetActionRestartVisible(), portalSetActionExitVisible(), portalSetActionCloseCaptiveVisible(), portalSetActionBackVisible() | Control existing action affordances; hiding an action is not a security boundary. |
| Layout | portalSetLayoutParamsLocation() | Put registered parameters on the Wi-Fi page or separate Setup page. |
| Connection/portal behavior | portalSetBehaviorCaptivePortalEnabled(), portalSetBehaviorConnectOnSave(), portalSetBehaviorExitAllowed(), portalSetBehaviorConnectTimeoutSeconds(), portalSetBehaviorPortalTimeoutSeconds(), portalSetBehaviorAutoReconnect(), portalSetBehaviorApClientCheck(), portalSetBehaviorWebClientCheck() | Set portal behavior through the structured configuration vocabulary. |
| Field policy | portalSetFieldPasswordPlaceholderMode(), portalSetFieldStaticIpVisibility(), portalSetFieldStaticDnsVisibility() | Limit password disclosure and network-field visibility. |
| Connection/portal behavior | portalSetBehaviorCaptivePortalEnabled(), portalSetBehaviorConnectOnSave(), portalSetBehaviorExitAllowed(), portalSetBehaviorConnectTimeoutSeconds(), portalSetBehaviorPortalTimeoutSeconds(), portalSetBehaviorAutoReconnect(), portalSetBehaviorApClientCheck(), portalSetBehaviorWebClientCheck() | Set built-in portal behavior. |
| Fields | portalSetFieldPasswordPlaceholderMode(), portalSetFieldStaticIpVisibility(), portalSetFieldStaticDnsVisibility() | Limit password disclosure and network-field visibility. |
The older setConfigPortalTimeout(), setSaveConnect(), setShowStaticFields(), and related methods remain available. Prefer a single vocabulary within a product; the portal-prefixed methods make the policy visible in the portal's structured model.
@@ -105,8 +109,16 @@ Use portalAddParameter() for editable product settings, portalAddInfoSection() f
See [Portal content](PORTAL_CONTENT.md) for the full persistence, validation, callback, and lifetime rules. The buildable [Custom Portal Content](../examples/CustomPortalContent/) example shows all three content types.
## Supported boundary
## What stays built in
There is no arbitrary HTML shell, route replacement, navigation injection, raw stylesheet, or script hook. Product branding and policy configure documented built-in functionality rather than private markup. If a product needs a new portal capability, add a narrow WiFiManager contract and test it on both supported targets.
Branding, policy, and structured content configure the supplied portal. The
portal's HTML shell, routes, navigation, stylesheet, and scripts stay owned by
WiFiManager. There is no custom shell, route replacement, navigation injection,
raw stylesheet, or script hook.
For a product-specific web application, start that application's own server
after WiFiManager has completed provisioning. If the supplied portal needs a
reusable capability, add one focused public WiFiManager C++ API and test it on
ESP8266 and ESP32.
Back to the [documentation index](README.md) or [project overview](../README.md).
+2 -2
View File
@@ -2,7 +2,7 @@
| I want to… | Read |
| --- | --- |
| Understand what WiFiManager owns and what the application owns | [Architecture](ARCHITECTURE.md) |
| See what WiFiManager handles and what the firmware handles | [Integrating WiFiManager](ARCHITECTURE.md) |
| Start a basic portal or install a released dependency | [Getting started](GETTING_STARTED.md) |
| Choose and operate a provisioning flow | [Provisioning lifecycle](PROVISIONING_LIFECYCLE.md) |
| Brand or constrain the built-in portal | [Portal UI and configuration](PORTAL_UI.md) |
@@ -11,7 +11,7 @@
| Configure AP, station, scan, and reconnect settings | [Network configuration](NETWORK_CONFIGURATION.md) |
| Surface portal and station state in product firmware | [Observability](OBSERVABILITY.md) |
| Look up a supported C++ method and lifecycle rule | [API reference](API_REFERENCE.md) |
| Understand the built-in portal's local JSON protocol | [Portal API](PORTAL_API.md) |
| Maintain or test the built-in portal's browser protocol | [Portal browser protocol](PORTAL_API.md) |
| Apply an existing device-integration pattern | [Recipes](recipes/README.md) |
| Run documentation and board-free compile checks | [Testing](TESTING.md) |
| Build or flash a complete example | [Examples](../examples/README.md) |
+3 -3
View File
@@ -25,9 +25,9 @@ or Docker.
## Local hardware lifecycle tests
The Unity suite runs on a board without Wi-Fi credentials, MQTT, DeviceFramework,
or a local profile. It verifies portal start/stop recovery, scan-cache release,
and a real asynchronous Wi-Fi scan.
The Unity suite runs portal-only firmware with no Wi-Fi credentials, MQTT,
product application framework, or local profile. It verifies portal start/stop
recovery, scan-cache release, and a real asynchronous Wi-Fi scan.
Use a stable serial-by-id path rather than a changing `/dev/ttyUSB` number:
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "WiFiManager",
"version": "3.2.2",
"version": "3.2.3",
"keywords": [
"wifi",
"wi-fi",
@@ -58,7 +58,7 @@
},
{
"name": "DeviceFrameworkTemplateEngine",
"version": "https://github.com/alexhopeoconnor/DFTE.git#v1.2.0"
"version": "https://github.com/alexhopeoconnor/DFTE.git#v1.2.1"
}
],
"build": {