Files
Device-Framework/README.md
T

176 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ESP32 Device Framework
A reusable ESP32 firmware base with Wi-Fi, web configuration UI, authentication, MQTT / Home Assistant integration, and factory reset. Add device-specific logic on top without re-implementing the boilerplate.
## Table of contents
- [Features](#features)
- [Building and flashing](#building-and-flashing)
- [First-time Wi-Fi setup](#first-time-wi-fi-setup)
- [Web UI](#web-ui)
- [MQTT / Home Assistant](#mqtt--home-assistant)
- [HTTP API](#http-api)
- [Configuration reference](#configuration-reference)
- [Extending the framework](#extending-the-framework)
---
## Features
- **Wi-Fi** via WiFiManager — captive-portal setup on first boot, credentials stored in flash
- **mDNS** — device reachable as `<hostname>.local`
- **Web UI** — responsive configuration page served from the device
- **Authentication** — optional HTTP Basic Auth to protect the web UI
- **MQTT** — connects to any broker, publishes an availability topic, reconnects automatically without blocking the web server
- **Home Assistant discovery** — stub ready for your entities
- **Factory reset** — rapid 5× power-cycle clears all settings and restarts
- **Config persistence** — all settings stored as JSON in LittleFS (`/config.json`)
---
## Building and flashing
The project uses [PlatformIO](https://platformio.org/).
```bash
# Build
pio run
# Flash
pio run --target upload
# Open serial monitor (115200 baud)
pio device monitor
```
Board target: `esp32-s3-devkitc-1`
---
## First-time Wi-Fi setup
On first boot (or when stored Wi-Fi credentials are missing), the device starts an access point named **ESP32-Device**. Connect to it with any phone or laptop — a captive portal will appear automatically.
1. Enter your Wi-Fi SSID and password.
2. Optionally change the **Device hostname** (default: `esp32-device`).
3. Click **Save**. The device connects to your network and restarts.
After connecting, the device is reachable at:
- `http://<hostname>.local` (default `http://esp32-device.local`) — mDNS, works on most local networks
- `http://<IP address>` — shown in the serial monitor on boot
### Factory reset
If you lose the web UI password or need to clear all settings, **reset the device 5 times in quick succession** (press EN or cycle power 5× within a few seconds, before boot completes). All settings are wiped and the device restarts into the Wi-Fi captive portal.
Serial output shows the progress:
```
[BOOT] reset count 1/5
[BOOT] reset count 2/5
...
[BOOT] reset count 5/5, triggering factory reset
[BOOT] factory reset triggered!
[BOOT] factory reset complete, restarting...
```
---
## Web UI
Browse to the device address to open the configuration page.
### Info panel
Shows the current hostname and IP address.
### Hostname
Sets the mDNS name (`<hostname>.local`) and the MQTT client ID. Saved across reboots.
### Security
| Field | Description |
|-------|-------------|
| Require password | Enables HTTP Basic Auth on the web UI |
| Password | Password for the `admin` account. Leave blank to keep the existing password |
### MQTT
| Field | Description |
|-------|-------------|
| Enable | Toggle MQTT on/off |
| Broker | Hostname or IP of your MQTT broker |
| Port | Default `1883` |
| User / Pass | Broker credentials (leave Pass blank to keep the existing value) |
| Prefix | Topic prefix (default `device`) |
Click **Save** to persist all settings.
---
## MQTT / Home Assistant
### Connection behaviour
On connect the device publishes `online` to `<prefix>/status` (retained) and sets `offline` as the LWT. If the broker is unreachable, the firmware probes the TCP port before attempting a full MQTT connect and retries every 30 seconds without blocking the web server.
### Extending with discovery and topics
Three stubs in `main.cpp` are the intended extension points:
| Function | Purpose |
|----------|---------|
| `mqttSubscribe()` | Subscribe to command topics after connecting |
| `mqttCallback()` | Handle incoming messages |
| `mqttPublishDiscovery()` | Publish Home Assistant discovery payloads |
---
## HTTP API
### `GET /`
Returns the HTML configuration page.
### `POST /config`
Saves all configuration submitted by the HTML form. Redirects back to `/`.
---
## Configuration reference
Config is stored as JSON in LittleFS at `/config.json`.
```json
{
"hostname": "esp32-device",
"mqtt": {
"en": true,
"host": "192.168.1.10",
"port": 1883,
"user": "ha",
"pass": "secret",
"prefix": "device"
},
"auth": {
"en": true,
"pass": "secret"
}
}
```
The file is written by the web UI. To erase everything including flash, use `pio run --target erase`.
---
## Extending the framework
1. Add your hardware setup in `setup()` after the framework initialises.
2. Add your per-loop logic in `loop()` alongside `server.handleClient()` and `mqttLoop()`.
3. Fill in the three MQTT stubs to subscribe, receive, and publish discovery payloads.
4. Add extra web routes with `server.on(...)` in `startServer()` if you need device-specific endpoints.
5. Persist extra config fields by adding keys to `loadConfig()` and `saveConfig()`.