From a42415e64e845d0442dcda6f1919c2c1a6a43efe Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 17 Feb 2026 21:35:10 -0800 Subject: [PATCH] chore(doorbell-touch): add clangd config and project documentation --- .clangd | 29 ++++++++++ AGENTS.md | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 .clangd create mode 100644 AGENTS.md diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..d6661da --- /dev/null +++ b/.clangd @@ -0,0 +1,29 @@ +CompileFlags: + Add: + - "-std=c++17" + - "-DARDUINO=200" + - "-DESP32" + - "-DCORE_DEBUG_LEVEL=0" + - "-DBOARD_HAS_PSRAM" + - "-DLGFX_USE_V1" + - "-DDEBUG_MODE" + - "-I/home/david/.arduino15/packages/esp32/hardware/esp32/3.3.6/cores/esp32" + - "-I/home/david/.arduino15/packages/esp32/hardware/esp32/3.3.6/tools" + - "-I/home/david/.arduino15/packages/esp32/hardware/esp32/3.3.6/libraries" + - "-I/home/david/.arduino15/packages/esp32/tools/esp32-libs/3.3.6/include" + - "-I/home/david/.arduino15/packages/esp32/tools/esp32-libs/3.3.6/include/freertos/FreeRTOS-Kernel/include" + - "-I/home/david/.arduino15/packages/esp32/tools/esp32-libs/3.3.6/include/freertos/config/include" + - "-I/home/david/.arduino15/packages/arduino/hardware/arduino/1.8.6/cores/arduino" + - "-I/home/david/.arduino15/packages/arduino/hardware/arduino/1.8.6/libraries/WiFi/src" + - "-I/home/david/Arduino/sketchbook/libraries/ArduinoJson/src" + - "-I/home/david/Arduino/sketchbook/libraries/NTPClient" + - "-I/home/david/Arduino/sketches/doorbell-touch/libraries/KlubhausCore/src" + - "-I/home/david/Arduino/sketches/doorbell-touch/boards/esp32-s3-lcd-43" + - "-I/home/david/Arduino/sketches/doorbell-touch/vendor/esp32-s3-lcd-43/LovyanGFX/src/lgfx" + - "-I/home/david/Arduino/sketches/doorbell-touch/vendor/esp32-s3-lcd-43/LovyanGFX/src/lgfx/v0" + - "-I/home/david/Arduino/sketches/doorbell-touch/vendor/esp32-s3-lcd-43/LovyanGFX/src/lgfx/v0/platforms/esp32" + +Diagnostics: + ClangTidy: + Remove: [readability-*, modernize-*, performance-*, bugprone-*] + Add: [clang-diagnostic-*, modernize-use-trailing-return-type] diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1bc2204 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,158 @@ +# AGENTS.md — Klubhaus Doorbell + +Multi-target Arduino/ESP32 doorbell alert system using ntfy.sh. + +## Project Overview + +Three board targets share business logic via a common library: + +| Board | Display | Library | Build Target | +|-------|---------|---------|--------------| +| 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` | + +## Essential Commands + +All commands run via **mise**: + +```bash +# Install all dependencies (shared libs + vendored display libs) +mise run install-libs + +# Build ESP32-32E +mise run compile-32e +mise run upload-32e +mise run monitor-32e + +# Build ESP32-S3-LCD-4.3 +mise run compile-s3-43 +mise run upload-s3-43 +mise run monitor-s3-43 + +# Format code +mise run format + +# Clean build artifacts +mise run clean +``` + +**Upload port override**: `PORT=/dev/ttyXXX mise run upload-32e` + +**Prerequisites**: arduino-cli with `esp32:esp32` platform installed, mise. + +## Project Structure + +``` +libraries/KlubhausCore/src/ Shared Arduino library +├── KlubhausCore.h Umbrella include (board sketches use this) +├── Config.h Constants, timing, WiFiCred struct +├── ScreenState.h State enums/structs +├── IDisplayDriver.h Pure virtual display interface +├── DisplayManager.h Thin wrapper delegating to IDisplayDriver +├── NetManager.* WiFi, HTTP, NTP +└── DoorbellLogic.* State machine, ntfy polling + +boards/ +├── esp32-32e/ +│ ├── esp32-32e.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 + ├── secrets.h WiFi creds (gitignored, copy from .example) + ├── LovyanPins.h Pin definitions + └── DisplayDriverGFX.* Concrete IDisplayDriver for LovyanGFX + +vendor/ Vendored display libs (recreated by install-libs) +├── esp32-32e/TFT_eSPI/ +└── esp32-s3-lcd-43/LovyanGFX/ +``` + +## Code Patterns + +### Header Guards +Use `#pragma once` (not `#ifndef` guards). + +### Formatting +- 4-space indentation, no tabs +- WebKit-based style (see `.clang-format`) +- Column limit: 100 +- Opening brace stays on same line (`BreakBeforeBraces: Attach`) + +### Class Design +- Pure virtual `IDisplayDriver` interface in shared library +- Each board implements a concrete driver (e.g., `DisplayDriverTFT`, `DisplayDriverGFX`) +- `DisplayManager` delegates to `IDisplayDriver` — no display-lib coupling in shared code + +### Arduino Patterns +- `setup()` runs once at boot — call `begin()` on managers +- `loop()` runs continuously — call `update()` on managers +- Use `millis()` for timing (not `delay()`) +- Serial console at 115200 baud for debug commands + +## Testing/Debugging + +**Serial commands** (type into serial monitor at 115200 baud): + +| Command | Action | +|---------|--------| +| `alert` | Trigger a test alert | +| `silence` | Silence current alert | +| `dashboard` | Show dashboard screen | +| `off` | Turn off display | +| `status` | Print state + memory info | +| `reboot` | Restart device | + +## 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-s3-lcd-43/secrets.h.example boards/esp32-s3-lcd-43/secrets.h + ``` + +2. **Display libs are vendored**: Each board uses a different display library. The build system uses `--libraries` to link only the board's vendored lib — never link both TFT_eSPI and LovyanGFX in the same build. + +3. **No unit tests**: This is an embedded Arduino sketch — no test suite exists. Verify changes by building and deploying to hardware. + +4. **LSP errors are expected**: The LSP cannot find `Arduino.h` because it requires arduino-cli to resolve. Ignore clangd/IntelliSense errors about missing Arduino types; builds work correctly via arduino-cli. + +5. **Build artifacts in board dirs**: Build output goes to `boards/[board]/build/` — cleaned by `mise run clean`. + +6. **WiFi credentials are per-board**: Each board directory has its own `secrets.h` because boards may be on different networks. + +## Hardware Research Log + +### Hosyond ESP32-32E 4" (320x480) - Planned + +**Source**: https://www.lcdwiki.com/4.0inch_ESP32-32E_Display + +| Spec | Value | +|------|-------| +| Display Controller | ST7796S | +| Resolution | 320x480 | +| Touch | XPT2046 (resistive) | +| Library | TFT_eSPI V2.5.43 (same as 32E) | + +**GPIO Pinout**: + +| Function | GPIO | +|----------|------| +| LCD CS | 15 | +| LCD DC | 2 | +| LCD MOSI | 13 | +| LCD SCLK | 14 | +| LCD RST | EN | +| LCD BL | 27 | +| Touch CS | 33 | +| Touch IRQ | 36 | + +**Quirks**: +- SPI pins shared between LCD and touch +- Touch IRQ on IO36 (input-only) triggers LOW on touch +- Backlight on IO27 (HIGH = on) +- Common anode RGB LEDs on IO16, IO17, IO22 (LOW = on)