# CYD ThermoPro Bridge

Firmware for an ESP32 "Cheap Yellow Display" (ESP32-2432S028R) that reads temperature data from a ThermoPro BLE BBQ thermometer and exposes it through a local HTTP API.

## Hardware

- **Board:** ESP32-2432S028R
  - 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

## What it does

- 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

| 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. |

### `GET /api/latest` example

```json
{
  "ok": true,
  "deviceId": "cyd-smoker",
  "device": "ThermoPro TP930",
  "mac": "c9:48:1d:b1:e1:e7",
  "connected": true,
  "battery": 90,
  "unit": "F",
  "probeCount": 4,
  "probes": [
    { "id": 1, "name": "Brisket", "temperature": 266.2, "connected": true },
    { "id": 2, "name": "Ambient", "temperature": 235.5, "connected": true },
    { "id": 3, "name": "Probe 3", "temperature": null, "connected": false },
    { "id": 4, "name": "Probe 4", "temperature": null, "connected": false }
  ],
  "readingTime": "12345",
  "bridgeTime": "12346",
  "source": "cyd-bridge"
}
```

## Setup workflow

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 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`.

**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

Requires [PlatformIO](https://platformio.org/).

```bash
cd cyd-bridge
# Compile only
pio run
# Compile and upload to the CYD
pio run -t upload
# View serial output
pio device monitor
```

If you have not installed PlatformIO yet:

```bash
pip install platformio
```

### First-time upload

If the CYD is not detected:

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:** ~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

- 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`.
- 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.
