feat: update ESP32 board version and add LSP configs

This commit is contained in:
2026-02-18 16:07:31 -08:00
parent 9f7a383b38
commit 34ca86d771
6 changed files with 3669 additions and 24 deletions

142
AGENTS.md
View File

@@ -2,15 +2,33 @@
Multi-target Arduino/ESP32 doorbell alert system using ntfy.sh.
## Quick Reference
```bash
# Compile, upload, monitor
BOARD=esp32-32e-4 mise run compile # compile
BOARD=esp32-32e-4 mise run upload # upload (auto-kills monitor)
BOARD=esp32-32e-4 mise run monitor # start JSON monitor daemon
BOARD=esp32-32e-4 mise run log-tail # watch colored logs
BOARD=esp32-32e-4 mise run cmd COMMAND=dashboard # send command
BOARD=esp32-32e-4 mise run state # show device state
# Install libs (run after cloning)
mise run install-libs-shared # shared libs (ArduinoJson, NTPClient)
BOARD=esp32-32e-4 mise run install # shared + board-specific libs
```
**Default BOARD**: `esp32-32e-4` (set in mise.toml)
## Project Overview
Three board targets share business logic via a common library:
| Board | Display | Library | Build Target |
| Board | Display | Library | Build Command |
|-------|---------|---------|--------------|
| ESP32-32E | SPI TFT 320x240 (ILI9341) | TFT_eSPI | `compile-32e` |
| ESP32-32E-4" | SPI TFT 320x480 (ST7796) | TFT_eSPI | `compile-32e-4` |
| ESP32-S3-Touch-LCD-4.3 | 800x480 RGB parallel | LovyanGFX | `compile-s3-43` |
| ESP32-32E | SPI TFT 320x240 (ILI9341) | TFT_eSPI | `BOARD=esp32-32e mise run compile` |
| ESP32-32E-4" | SPI TFT 320x480 (ST7796) | TFT_eSPI | `BOARD=esp32-32e-4 mise run compile` |
| ESP32-S3-Touch-LCD-4.3 | 800x480 RGB parallel | LovyanGFX | `BOARD=esp32-s3-lcd-43 mise run compile` |
## Essential Commands
@@ -18,26 +36,43 @@ All commands run via **mise**:
```bash
# Install all dependencies (shared libs + vendored display libs)
mise run install-libs
mise run install-libs-shared
mise run install # install shared + board-specific libs (requires BOARD env)
# Build ESP32-32E
mise run compile-32e
mise run upload-32e
mise run monitor-32e
# Generic commands (set BOARD environment variable)
BOARD=esp32-32e mise run compile # compile for ESP32-32E
BOARD=esp32-32e mise run upload # upload to ESP32-32E
BOARD=esp32-32e mise run monitor # monitor ESP32-32E
# Build ESP32-S3-LCD-4.3
mise run compile-s3-43
mise run upload-s3-43
mise run monitor-s3-43
BOARD=esp32-32e-4 mise run compile # compile for ESP32-32E-4"
BOARD=esp32-32e-4 mise run upload # upload to ESP32-32E-4"
BOARD=esp32-32e-4 mise run monitor # monitor ESP32-32E-4"
# Format code
mise run format
BOARD=esp32-s3-lcd-43 mise run compile # compile for ESP32-S3-LCD-4.3
BOARD=esp32-s3-lcd-43 mise run upload # upload to ESP32-S3-LCD-4.3
BOARD=esp32-s3-lcd-43 mise run monitor # monitor ESP32-S3-LCD-4.3
# Clean build artifacts
mise run clean
# Other useful tasks
mise run format # format code
mise run clean # clean build artifacts
mise run kill # kill running monitor/upload for BOARD
mise run log-tail # tail colored logs (requires BOARD)
mise run cmd COMMAND=dashboard # send command to device (requires BOARD)
mise run state # show device state (requires BOARD)
# LSP / IDE support
mise run gen-compile-commands # generate compile_commands.json for LSP
mise run gen-crush-config # generate .crush.json with BOARD-based FQBN
# Arduino maintenance
mise run arduino-clean # clear Arduino CLI cache (staging + packages)
# Raw serial access
mise run monitor-raw # raw serial monitor (arduino-cli)
mise run monitor-tio # show tio command for terminal UI
```
**Upload port override**: `PORT=/dev/ttyXXX mise run upload-32e`
**Upload port override**: `PORT=/dev/ttyXXX BOARD=esp32-32e mise run upload`
**Prerequisites**: arduino-cli with `esp32:esp32` platform installed, mise.
@@ -60,6 +95,12 @@ boards/
│ ├── secrets.h WiFi creds (gitignored, copy from .example)
│ ├── tft_user_setup.h TFT_eSPI config
│ └── DisplayDriverTFT.* Concrete IDisplayDriver for TFT
├── esp32-32e-4/
│ ├── esp32-32e-4.ino Main sketch
│ ├── board_config.h Board-specific config
│ ├── secrets.h WiFi creds (gitignored, copy from .example)
│ ├── tft_user_setup.h TFT_eSPI config
│ └── DisplayDriverTFT.* Concrete IDisplayDriver for TFT
└── esp32-s3-lcd-43/
├── esp32-s3-lcd-43.ino Main sketch
├── board_config.h Board-specific config
@@ -69,6 +110,7 @@ boards/
vendor/ Vendored display libs (recreated by install-libs)
├── esp32-32e/TFT_eSPI/
├── esp32-32e-4/TFT_eSPI/
└── esp32-s3-lcd-43/LovyanGFX/
```
@@ -107,11 +149,31 @@ Use `#pragma once` (not `#ifndef` guards).
| `status` | Print state + memory info |
| `reboot` | Restart device |
## Monitor Daemon and Logging
The build system includes a Python-based monitor agent that provides JSON logging and command pipes.
- **JSON log**: `/tmp/doorbell-$BOARD.jsonl` each line is `{"ts":123.456,"line":"..."}`
- **State file**: `/tmp/doorbell-$BOARD-state.json` current device state (screen, alert status, etc.)
- **Command FIFO**: `/tmp/doorbell-$BOARD-cmd.fifo` send commands via `echo 'dashboard' > /tmp/doorbell-$BOARD-cmd.fifo`
Commands to interact with the daemon:
```bash
BOARD=esp32-32e mise run monitor # Start monitor daemon (background)
BOARD=esp32-32e mise run log-tail # Tail colored logs
BOARD=esp32-32e mise run cmd COMMAND=dashboard # Send command
BOARD=esp32-32e mise run state # Show current device state
```
The monitor daemon automatically starts after upload and is killed before upload to avoid serial port conflicts.
## Gotchas
1. **secrets.h is gitignored**: Copy from `.example` before building:
```bash
cp boards/esp32-32e/secrets.h.example boards/esp32-32e/secrets.h
cp boards/esp32-32e-4/secrets.h.example boards/esp32-32e-4/secrets.h
cp boards/esp32-s3-lcd-43/secrets.h.example boards/esp32-s3-lcd-43/secrets.h
```
@@ -125,6 +187,50 @@ Use `#pragma once` (not `#ifndef` guards).
6. **WiFi credentials are per-board**: Each board directory has its own `secrets.h` because boards may be on different networks.
7. **Use BOARD environment variable**: All build commands require the `BOARD` environment variable (e.g., `BOARD=esp32-32e mise run compile`). The default BOARD is `esp32-32e-4` (set in mise.toml).
8. **Lockfile system**: The build system uses lockfiles (`/tmp/doorbell-$BOARD.lock`) to prevent concurrent upload/monitor operations. Use `mise run kill` to clean up stuck processes.
## Known Fixes
- **dashboard/off admin commands reset inactivity timer** (DoorbellLogic.cpp:234,240) — Admin commands like `dashboard` and `off` now reset the inactivity timer so the display doesn't turn off immediately after switching screens.
## Documentation Lookup Rule
When uncertain about CLI tool flags or argument syntax:
1. Run the tool with `-h` or `--help` first
2. If unclear, search for official documentation matching the tool version
3. Prefer checking the tool's own help/docs over guessing
4. For Arduino CLI, check `arduino-cli <command> --help` or official Arduino CLI docs
## LSP / IDE Configuration
The project uses clangd for C++ and arduino-language-server for Arduino. The `.crush.json` contains dynamic FQBN resolution:
```json
{
"lsp": {
"arduino": {
"command": "arduino-language-server",
"args": ["-fqbn", "$(cat boards/${BOARD:-esp32-32e-4}/board-config.sh | grep '^FQBN=' | cut -d'\"' -f2)"]
},
"cpp": {
"command": "clangd"
}
}
}
```
**Generate compile_commands.json** for accurate IDE diagnostics:
```bash
BOARD=esp32-32e-4 mise run gen-compile-commands
```
**Generate static .crush.json** for a specific board:
```bash
BOARD=esp32-32e-4 mise run gen-crush-config
```
## Hardware Research Log
### Hosyond ESP32-32E 4" (320x480) - Planned