feat: add PWA frontend for CYD ThermoPro dashboard

Add a Flask backend + SQLite + HTML/CSS/JS PWA that:
- Polls the CYD /api/latest endpoint
- Stores readings, sessions, and freeform notes in SQLite
- Displays probe cards with target setpoints and preset options
- Renders temperature history with Chart.js
- Serves a PWA manifest and dark-themed dashboard

Also update cyd-bridge/README.md with verified bringup instructions.
This commit is contained in:
Keith Solomon
2026-07-20 20:14:48 -05:00
parent f03cebf322
commit 9e32b1b179
10 changed files with 1077 additions and 42 deletions
+61 -42
View File
@@ -5,51 +5,37 @@ Firmware for an ESP32 "Cheap Yellow Display" (ESP32-2432S028R) that reads temper
## Hardware
- **Board:** ESP32-2432S028R
- 320×240 TFT (ILI9341 driver)
- 320×240 TFT (ILI9341 driver, detected via `LGFX_AUTODETECT`)
- Resistive touch panel (XPT2046)
- ESP32-WROOM-32 with 4 MB flash
- **Thermometer:** ThermoPro TP25 / TP25W / TP920 / TP930 / TP960
## Firmware architecture
## What it does
```
┌─────────────────────────────────────────┐
│ CYD (ESP32-2432S028R) │
│ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ ThermoPro │ │ HTTP API │ │
│ │ BLE client │─────▶│ Web server │ │
│ └─────────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ SettingsManager (NVS/Preferences)│ │
│ └──────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────┐ │
│ │ Touch UI: status + setup screens │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
```
- Connects the CYD to your WiFi network.
- Scans for a ThermoPro thermometer by its advertised service UUID (`1086FFF0-3343-4817-8BB2-B32206336CE8`) and connects over BLE.
- Decodes battery level, connection status, and up to four probe temperatures.
- Runs a small HTTP API that any frontend (web app, mobile app, Home Assistant, etc.) can consume.
- Shows a simple touch dashboard with probe temperatures and connection status.
## API endpoints
- `GET /api/health` — device health and connectivity status.
- `GET /api/latest` — latest ThermoPro reading.
- `GET /api/settings` — current settings (excluding WiFi password).
- `POST /api/settings` — update settings (JSON body).
- `GET /` — setup page when in AP mode; status page when in STA mode.
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/health` | Device health and connectivity status. |
| `GET` | `/api/latest` | Latest ThermoPro reading. |
| `GET` | `/api/settings` | Current settings (WiFi password omitted). |
| `POST` | `/api/settings` | Update settings (JSON body). |
| `GET` | `/` | Setup page in AP mode; status page in STA mode. |
## Endpoints response examples
### `GET /api/latest`
### `GET /api/latest` example
```json
{
"ok": true,
"deviceId": "cyd-smoker",
"device": "ThermoPro TP930",
"mac": "C9:48:1D:B1:E1:E7",
"mac": "c9:48:1d:b1:e1:e7",
"connected": true,
"battery": 90,
"unit": "F",
@@ -60,8 +46,9 @@ Firmware for an ESP32 "Cheap Yellow Display" (ESP32-2432S028R) that reads temper
{ "id": 3, "name": "Probe 3", "temperature": null, "connected": false },
{ "id": 4, "name": "Probe 4", "temperature": null, "connected": false }
],
"readingTime": "2026-07-19T12:00:00+00:00",
"bridgeTime": "2026-07-19T12:00:01+00:00"
"readingTime": "12345",
"bridgeTime": "12346",
"source": "cyd-bridge"
}
```
@@ -70,9 +57,10 @@ Firmware for an ESP32 "Cheap Yellow Display" (ESP32-2432S028R) that reads temper
1. **First boot:** the CYD starts a captive portal AP named `CYD-ThermoPro-Setup`.
2. Connect to the AP with a phone or laptop and open `http://192.168.4.1`.
3. Enter your home WiFi SSID and password, plus the ThermoPro MAC address.
4. The device connects to WiFi, stores the credentials, and reboots into normal mode.
4. The device saves the credentials and reboots into normal mode.
5. Find the CYD's local IP from your router or the serial monitor, then open `http://<cyd-ip>/api/latest`.
Runtime settings (endpoint, token, probe names, units, polling interval) can be changed through the same web UI at the device's local IP or via the JSON API.
**Note on MAC addresses:** If you previously paired the thermometer with the official ThermoPro app, the app may show a *resolved* public-looking MAC while the device actually advertises with a *random* BLE address. The CYD scans by the ThermoPro service UUID, so it will find the device regardless. Enter whatever address the app displays; the UUID match takes priority.
## Building and flashing
@@ -94,26 +82,57 @@ If you have not installed PlatformIO yet:
pip install platformio
```
## First-time hardware check
### First-time upload
Before relying on the dashboard, verify the pinout matches your exact board revision:
If the CYD is not detected:
1. Open `src/display/DisplayConfig.hpp`.
2. Confirm `TFT_CS`, `TFT_DC`, `TFT_RST`, `TFT_BL`, `TOUCH_CS`, and the SPI pins match the silkscreen or schematic of your ESP32-2432S028R.
3. If the screen stays white or touch is inverted, adjust `cfg.offset_rotation` in `DisplayConfig.hpp` or `setRotation()` in `Dashboard::begin()`.
1. Try both USB ports; only one is wired to the UART chip.
2. Install the USB-to-serial driver if Windows shows an unknown device:
- CH340/CH343: [WCH driver](https://www.wch-ic.com/downloads/CH343SER_ZIP.html)
- CP2102: [Silicon Labs driver](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers)
3. If the upload still fails, hold the **BOOT** button, press and release **RST**, then release **BOOT**, and retry.
## Memory usage
With the default partition table the firmware uses approximately:
- **RAM:** ~18 % (~58 kB of 320 kB)
- **Flash:** ~92 % (~1.2 MB of 1.3 MB)
- **Flash:** ~96 % (~1.2 MB of 1.3 MB)
There is enough headroom to run, but large future features (e.g. local graphing, OTA) may require switching to a larger app partition or dropping unused NimBLE options.
## Runtime settings
Change settings by POSTing JSON to `/api/settings`:
```bash
curl -X POST http://192.168.2.55/api/settings \
-H "Content-Type: application/json" \
-d '{
"probeNames": ["Brisket", "Ambient", "Probe 3", "Probe 4"],
"unit": "F",
"deviceId": "cyd-smoker"
}'
```
Available fields:
- `wifiSsid`, `wifiPass`
- `thermoproMac`
- `deviceId`
- `probeNames` (array of 4 strings)
- `unit` (`"F"` or `"C"`)
## Development notes
- LovyanGFX driver/pin configuration lives in `src/display/DisplayConfig.hpp` and is tuned for the ESP32-2432S028R variant.
- Display pinout is handled by `LGFX_AUTODETECT`, which detects the common `Sunton_2432S028` (ILI9341) layout.
- BLE uses `NimBLE-Arduino` to leave enough RAM for the web server and UI.
- The CYD connects to the ThermoPro by scanning for the advertised service UUID. This is more reliable than MAC matching when the thermometer uses BLE privacy/random addresses.
- All user settings are stored in ESP32 NVS via `Preferences`.
- The firmware compiles successfully in PlatformIO; the remaining work is on-device testing and pinout verification.
- Serial log runs at 115200 baud for diagnostics.
## Known issues / next steps
- `/api/latest` timestamps are device-relative millis; wall-clock time would require NTP.
- Touch dashboard is minimal; a nicer layout, settings menu, and local alerts are planned.
- Flash usage is tight due to `LGFX_AUTODETECT`; a hardcoded board config would free space.