Complete configuration Web UI with tabbed SPA (fw 0.8.2).
Add now-playing view with metadata polling, six-band EQ controls, full REST coverage, companion-chip badges, and gzip-www helper for the embedded setup page. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
**Open-source digital radio — Si4684 tuner · ADAU1701 SigmaDSP · Bluetooth aptX Adaptive · ESP32-S3**
|
**Open-source digital radio — Si4684 tuner · ADAU1701 SigmaDSP · Bluetooth aptX Adaptive · ESP32-S3**
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
@@ -57,7 +57,7 @@ no analogue conversions are introduced between the tuner and the wireless link.
|
|||||||
- **6-layer impedance-controlled PCB**, 50 × 90 mm, two ground planes
|
- **6-layer impedance-controlled PCB**, 50 × 90 mm, two ground planes
|
||||||
- Three antennas (ESP32 2.4 GHz, BT1035 2.4 GHz, FM/DAB SMA) with proper keep-outs
|
- Three antennas (ESP32 2.4 GHz, BT1035 2.4 GHz, FM/DAB SMA) with proper keep-outs
|
||||||
|
|
||||||
### Firmware (ESP-IDF, C++23 — fw **0.8.1**)
|
### Firmware (ESP-IDF, C++23 — fw **0.8.2**)
|
||||||
|
|
||||||
| Area | Capability |
|
| Area | Capability |
|
||||||
|------|------------|
|
|------|------------|
|
||||||
@@ -67,7 +67,7 @@ no analogue conversions are introduced between the tuner and the wireless link.
|
|||||||
| **Audio** | 5-band EQ, input mixer, stereo/bass enhancement overlays, profile persist in NVS |
|
| **Audio** | 5-band EQ, input mixer, stereo/bass enhancement overlays, profile persist in NVS |
|
||||||
| **Presets** | Station list CRUD, reorder, recall with audio profile re-apply, last-preset restore at boot |
|
| **Presets** | Station list CRUD, reorder, recall with audio profile re-apply, last-preset restore at boot |
|
||||||
| **Bluetooth** | Discoverable pairing, A2DP status, disconnect |
|
| **Bluetooth** | Discoverable pairing, A2DP status, disconnect |
|
||||||
| **Network** | SoftAP setup mode, STA provisioning, gzipped SPA (`/`), typed JSON REST API |
|
| **Network** | SoftAP setup mode, STA provisioning, tabbed gzipped SPA (`/`), typed JSON REST API |
|
||||||
| **Security** | NVS-backed credential and preset storage (flash encryption planned — see roadmap) |
|
| **Security** | NVS-backed credential and preset storage (flash encryption planned — see roadmap) |
|
||||||
| **Quality** | **13** host unit tests, Doxygen gate, LaTeX manual sync check, GitHub Actions CI on `main` |
|
| **Quality** | **13** host unit tests, Doxygen gate, LaTeX manual sync check, GitHub Actions CI on `main` |
|
||||||
|
|
||||||
@@ -83,6 +83,7 @@ Vertical slices landed on `main` (newest first):
|
|||||||
|
|
||||||
| Version | Highlights |
|
| Version | Highlights |
|
||||||
|---------|------------|
|
|---------|------------|
|
||||||
|
| **0.8.2** | Tabbed configuration Web UI — now-playing, 6-band EQ, full API coverage |
|
||||||
| **0.8.1** | `IntegrationService` — boot preset recall, tune orchestration (tuner + audio + NVS `last_preset`); services stub removed |
|
| **0.8.1** | `IntegrationService` — boot preset recall, tune orchestration (tuner + audio + NVS `last_preset`); services stub removed |
|
||||||
| **0.8.0** | Preset reorder API/UI; broadcast metadata (RDS + DAB DLS); `readDabServiceData` driver path |
|
| **0.8.0** | Preset reorder API/UI; broadcast metadata (RDS + DAB DLS); `readDabServiceData` driver path |
|
||||||
| **0.7.1** | CI workflow (host tests, Doxygen, manual sync); Doxygen warnings cleared |
|
| **0.7.1** | CI workflow (host tests, Doxygen, manual sync); Doxygen warnings cleared |
|
||||||
@@ -90,8 +91,7 @@ Vertical slices landed on `main` (newest first):
|
|||||||
| **0.5–0.6** | ADAU1701 runtime EQ/mixer, Si4684 tuning & DAB service list, BT1035 driver |
|
| **0.5–0.6** | ADAU1701 runtime EQ/mixer, Si4684 tuning & DAB service list, BT1035 driver |
|
||||||
| **0.3–0.4** | Secure store, Wi-Fi provisioning, companion-chip boot, walking skeleton |
|
| **0.3–0.4** | Secure store, Wi-Fi provisioning, companion-chip boot, walking skeleton |
|
||||||
|
|
||||||
**Next up** ([`Software/docs/TODO.md`](Software/docs/TODO.md)): polished configuration Web UI (T6),
|
**Next up** ([`Software/docs/TODO.md`](Software/docs/TODO.md)): Si4684 blob procurement docs (T7), NVS/flash encryption (T8).
|
||||||
Si4684 blob procurement docs (T7), NVS/flash encryption (T8).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -221,8 +221,8 @@ Generated C++ API reference: run `doxygen Doxyfile` → `Software/docs/api/html/
|
|||||||
| **PCB layout** | 6-layer, DRC clean, plane continuity verified |
|
| **PCB layout** | 6-layer, DRC clean, plane continuity verified |
|
||||||
| **BOM** | Finalised (manufacturable / sourced) |
|
| **BOM** | Finalised (manufacturable / sourced) |
|
||||||
| **Prototype** | In fabrication (PCBWay) |
|
| **Prototype** | In fabrication (PCBWay) |
|
||||||
| **Firmware** | **0.8.1** on `main` — CI green; tuner, DSP, BT, presets, RDS/DLS, integration service |
|
| **Firmware** | **0.8.2** on `main` — CI green; full Web UI, integration, RDS/DLS |
|
||||||
| **Web UI** | Functional SPA; full polish tracked as T6 |
|
| **Web UI** | Tabbed SPA covering every REST endpoint |
|
||||||
| **Production hardening** | Si4684 blob policy (T7), NVS encryption (T8) — open |
|
| **Production hardening** | Si4684 blob policy (T7), NVS encryption (T8) — open |
|
||||||
|
|
||||||
Agent task list: [`Software/docs/TODO.md`](Software/docs/TODO.md).
|
Agent task list: [`Software/docs/TODO.md`](Software/docs/TODO.md).
|
||||||
|
|||||||
+4
-3
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
Open-source Hi-Fi DAB+/FM receiver firmware for the ESP32-S3.
|
Open-source Hi-Fi DAB+/FM receiver firmware for the ESP32-S3.
|
||||||
|
|
||||||
**Status:** fw **0.8.1** — `IntegrationService` (boot preset recall, tune +
|
**Status:** fw **0.8.2** — tabbed Web UI (now-playing, 6-band EQ, all APIs);
|
||||||
audio profile); RDS/DLS now-playing metadata; **13** host tests; CI on `main`.
|
`IntegrationService`; **13** host tests; CI on `main`.
|
||||||
See [`docs/TODO.md`](docs/TODO.md) for the agent task list.
|
See [`docs/TODO.md`](docs/TODO.md) for the agent task list.
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
@@ -31,6 +31,7 @@ Documentation gates (must exit 0 before merging; also enforced in CI):
|
|||||||
```bash
|
```bash
|
||||||
doxygen Doxyfile
|
doxygen Doxyfile
|
||||||
python3 tools/check-manual-sync.py
|
python3 tools/check-manual-sync.py
|
||||||
|
python3 tools/gzip-www.sh # after editing components/net/www/index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
Manual PDF (design + HTTP API + class reference):
|
Manual PDF (design + HTTP API + class reference):
|
||||||
@@ -39,7 +40,7 @@ Manual PDF (design + HTTP API + class reference):
|
|||||||
cd docs/manual && latexmk -lualatex manual.tex
|
cd docs/manual && latexmk -lualatex manual.tex
|
||||||
```
|
```
|
||||||
|
|
||||||
## HTTP API (fw 0.8.1)
|
## HTTP API (fw 0.8.2)
|
||||||
|
|
||||||
| Method | Path | Purpose |
|
| Method | Path | Purpose |
|
||||||
|--------|------|---------|
|
|--------|------|---------|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace net {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr char kTag[] = "SetupWebServer";
|
constexpr char kTag[] = "SetupWebServer";
|
||||||
constexpr char kFirmwareVersion[] = "0.8.1";
|
constexpr char kFirmwareVersion[] = "0.8.2";
|
||||||
constexpr unsigned kRebootDelaySec = 3;
|
constexpr unsigned kRebootDelaySec = 3;
|
||||||
|
|
||||||
extern const uint8_t www_index_html_gz_start[] asm(
|
extern const uint8_t www_index_html_gz_start[] asm(
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+7
-14
@@ -12,8 +12,8 @@ errors, no plaintext secrets.
|
|||||||
|
|
||||||
Working directory for all commands is `Software/`.
|
Working directory for all commands is `Software/`.
|
||||||
|
|
||||||
**Current firmware:** `0.8.1` — integration service (preset recall +
|
**Current firmware:** `0.8.2` — tabbed configuration Web UI (full API
|
||||||
audio profile), RDS/DLS metadata, CI gate.
|
coverage), integration service, RDS/DLS metadata, CI gate.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -59,18 +59,11 @@ audio profile re-apply, and last-preset NVS. Stub removed; `app_main` and
|
|||||||
|
|
||||||
## P2 — User interface
|
## P2 — User interface
|
||||||
|
|
||||||
### T6. Complete the configuration Web UI
|
### T6. Complete the configuration Web UI — **DONE (fw 0.8.2)**
|
||||||
**Why:** `components/net/www/index.html` is functional but the
|
Tabbed SPA (`Now` / `Radio` / `Presets` / `Audio` / `BT` / `Wi‑Fi`):
|
||||||
requirement is an *elegant, essential* SPA. It should cover:
|
now-playing hero with 5 s metadata poll, six-band EQ sliders, all REST
|
||||||
Wi-Fi provisioning, station list management, tuner control (FM/DAB,
|
endpoints wired, companion-chip badges, `tools/gzip-www.sh` for the
|
||||||
seek, play), live EQ/volume/enhancement control, Bluetooth pairing, and
|
embedded gzip blob. No debug routes in `SetupWebServer`.
|
||||||
now-playing metadata.
|
|
||||||
**What:** a minimal single-page app served gzipped from flash, design
|
|
||||||
tokens defined once (spacing, type scale, one accent), thin client over
|
|
||||||
the existing typed JSON API. No heavy frameworks. No business logic in
|
|
||||||
the UI.
|
|
||||||
**Done when:** every API capability has a UI control; the page is served
|
|
||||||
gzipped; no debug endpoint is exposed in a shipping build.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -369,10 +369,13 @@ delegate to \texttt{AudioService}:
|
|||||||
\item \texttt{POST /api/audio/bass-enhance} --- same schema.
|
\item \texttt{POST /api/audio/bass-enhance} --- same schema.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
The gzipped setup page (\texttt{components/net/www/index.html}) exposes master
|
The gzipped setup page (\texttt{components/net/www/index.html}) is a tabbed
|
||||||
volume, Si4684/ESP32 path levels, and enhancement sliders; saving sends
|
SPA: a \emph{Now playing} view (RDS/DLS metadata), tuner and preset panels,
|
||||||
\texttt{PUT /api/audio/profile}, while slider release on enhancements sends
|
master/path levels, six PEQ band gain sliders, enhancement overlays, Bluetooth
|
||||||
the dedicated POST routes for immediate safeload + persist.
|
controls, and Wi-Fi provisioning. Saving sends \texttt{PUT /api/audio/profile};
|
||||||
|
enhancement sliders call the dedicated POST routes for immediate safeload +
|
||||||
|
persist. Regenerate \texttt{index.html.gz} with \texttt{tools/gzip-www.sh}
|
||||||
|
after editing the HTML source.
|
||||||
|
|
||||||
\section{Typical usage patterns}
|
\section{Typical usage patterns}
|
||||||
\label{sec:adau1701-patterns}
|
\label{sec:adau1701-patterns}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ Returns a health-check DTO serialised by
|
|||||||
|
|
||||||
\begin{drnote}[Response schema]
|
\begin{drnote}[Response schema]
|
||||||
\begin{drcode}[JSON]
|
\begin{drcode}[JSON]
|
||||||
{"status":"ok","fw":"0.8.1",
|
{"status":"ok","fw":"0.8.2",
|
||||||
"chips":{"si4684":true,"adau1701":true,"bt1035":true}}
|
"chips":{"si4684":true,"adau1701":true,"bt1035":true}}
|
||||||
\end{drcode}
|
\end{drcode}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
|||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Regenerate the gzipped setup UI embedded by components/net/CMakeLists.txt.
|
||||||
|
set -euo pipefail
|
||||||
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
SRC="${ROOT}/components/net/www/index.html"
|
||||||
|
OUT="${ROOT}/components/net/www/index.html.gz"
|
||||||
|
gzip -c -9 "$SRC" > "$OUT"
|
||||||
|
echo "Wrote $(wc -c < "$OUT" | tr -d ' ') bytes -> ${OUT#"$ROOT"/}"
|
||||||
Reference in New Issue
Block a user