6f9d2912d3
- Generate BUILD_TOKEN from 'git describe --always --dirty' - Include via -include flag in justfile compile recipe - Print BUILD_TOKEN in boot banners (DoorbellLogic + uno-r4-wifi) - Remove all [tasks] from mise.toml; keep only [tools] + [env] - Update AGENTS.md to use just commands as single source of truth - Add 'just full' recipe (compile -> upload -> monitor -> watch) - Switch BOARD var to env_var_or_default for mise set compatibility - DRY clean/clean-temp with wildcard patterns
154 lines
5.8 KiB
Markdown
154 lines
5.8 KiB
Markdown
# AGENTS.md — Klubhaus Doorbell
|
|
|
|
Multi-target Arduino/ESP32 doorbell alert system using ntfy.sh. Default BOARD: `esp32-s3-lcd-43`.
|
|
|
|
## Build Commands
|
|
|
|
```bash
|
|
# All tasks use just (see justfile). Default BOARD: esp32-s3-lcd-43
|
|
|
|
# Set target board
|
|
just BOARD=esp32-32e-4 compile # ESP32-32E 4" (320x480 ST7796)
|
|
just BOARD=esp32-32e compile # ESP32-32E 3.5" (320x240 ILI9341)
|
|
just BOARD=esp32-s3-lcd-43 compile # ESP32-S3-Touch-LCD-4.3 (800x480 RGB)
|
|
just BOARD=uno-r4-wifi compile # Arduino Uno R4 WiFi (12x8 LED matrix)
|
|
|
|
# Core commands
|
|
just compile # compile for current BOARD
|
|
just upload # upload (auto-kills monitor first)
|
|
just monitor # start JSON monitor daemon (background)
|
|
just kill # kill monitor/release serial port
|
|
just full # compile + upload + monitor + log-tail (full feedback loop)
|
|
just watch # tail colored logs
|
|
|
|
# Formatting & cleanup
|
|
just format # format code with clang-format
|
|
just clean # remove build artifacts
|
|
just clean-temp # remove monitor logs/FIFOs/state files
|
|
|
|
# Debugging
|
|
just cmd dashboard # send command to device
|
|
just state # show device state
|
|
just monitor-raw # raw serial monitor (115200 baud)
|
|
just monitor-tio # show tio command for terminal UI
|
|
|
|
# Install dependencies
|
|
just install-libs-shared # shared libs (ArduinoJson, NTPClient)
|
|
just install # shared + board-specific libs
|
|
|
|
# LSP / IDE
|
|
just gen-compile-commands # generate compile_commands.json
|
|
just gen-crush-config # generate .crush.json for BOARD
|
|
```
|
|
|
|
**Serial debug commands** (115200 baud): `alert`, `silence`, `dashboard`, `off`, `status`, `reboot`
|
|
|
|
**No unit tests exist** — verify changes by compiling and deploying to hardware.
|
|
|
|
## Code Style
|
|
|
|
### Formatting (.clang-format)
|
|
- BasedOnStyle: WebKit
|
|
- 4-space indentation, no tabs
|
|
- Column limit: 100
|
|
- Opening brace on same line (`BreakBeforeBraces: Attach`)
|
|
- Run `just format` to format code
|
|
|
|
### Header Guards
|
|
Use `#pragma once` (not `#ifndef` guards).
|
|
|
|
### Naming Conventions
|
|
| Type | Convention | Example |
|
|
|------|------------|---------|
|
|
| Classes | PascalCase | `DisplayManager`, `IDisplayDriver` |
|
|
| Constants/enums | SCREAMING_SNAKE | `POLL_INTERVAL_MS`, `ScreenState::DASHBOARD` |
|
|
| Variables/functions | camelCase | `currentState`, `updateDisplay` |
|
|
| Member variables | `_` prefix | `_screenWidth`, `_isConnected` |
|
|
|
|
### Types
|
|
- Use fixed-width types for protocol/serialization (`uint8_t`, not `byte`)
|
|
- Use `size_t` for sizes and array indices
|
|
- Avoid `bool` for pin states — use `uint8_t` or `int`
|
|
|
|
### Imports Organization (in order)
|
|
1. Arduino core (`Arduino.h`)
|
|
2. Standard C/C++ (`<cstdint>`, `<String>`, `<vector>`)
|
|
3. Third-party libs (`TFT_eSPI.h`, `ArduinoJson.h`)
|
|
4. Local project (`"Config.h"`, `"ScreenState.h"`)
|
|
|
|
### Error Handling
|
|
- Serial logging: `Serial.println("[ERROR] message")`
|
|
- Use `Serial.printf()` for formatted debug
|
|
- Return error codes, not exceptions
|
|
- Log state: `[STATE] → DASHBOARD`
|
|
|
|
## Architecture Patterns
|
|
|
|
### Display Driver Interface
|
|
- Pure virtual `IDisplayDriver` in shared `KlubhausCore`
|
|
- Each board implements concrete driver (`DisplayDriverTFT`, `DisplayDriverGFX`)
|
|
- `DisplayManager` delegates to `IDisplayDriver` — no display-lib coupling in shared code
|
|
|
|
### Arduino Patterns
|
|
- `setup()` — call `begin()` on managers
|
|
- `loop()` — call `update()` on managers
|
|
- Use `millis()` for timing (not `delay()`)
|
|
- Serial baud: 115200
|
|
|
|
### Style System
|
|
- Style constants in board's `board_config.h`: `STYLE_SPACING_X`, `STYLE_COLOR_BG`, etc.
|
|
- Font abstraction via `IDisplayDriver`: `setTitleFont()`, `setBodyFont()`, etc.
|
|
- Layout helpers in `KlubhausCore/src/Style.h`
|
|
|
|
## Key Files
|
|
|
|
```
|
|
libraries/KlubhausCore/src/
|
|
├── KlubhausCore.h # Umbrella include
|
|
├── Config.h # Timing, WiFiCred struct
|
|
├── ScreenState.h # State enums/structs
|
|
├── IDisplayDriver.h # Pure virtual interface
|
|
├── DisplayManager.h # Delegates to IDisplayDriver
|
|
├── NetManager.* # WiFi, HTTP, NTP
|
|
└── DoorbellLogic.* # State machine, ntfy polling
|
|
|
|
boards/{BOARD}/
|
|
├── {BOARD}.ino # Main sketch
|
|
├── board_config.h # Board-specific config (ESP32 boards)
|
|
├── secrets.h # WiFi credentials (optional, use env vars)
|
|
├── tft_user_setup.h # TFT_eSPI config (TFT boards)
|
|
└── DisplayDriver*.{h,cpp} # Concrete IDisplayDriver (ESP32 boards)
|
|
|
|
boards/uno-r4-wifi/ # Uno R4 WiFi (LED matrix display)
|
|
├── uno-r4-wifi.ino # Main sketch (standalone)
|
|
├── test_messages.sh # Test script to send ntfy messages
|
|
└── README.md # Quick start guide
|
|
```
|
|
|
|
## Gotchas
|
|
|
|
1. **secrets.h**: Boards with `-DLOCAL_SECRETS` use local `secrets.h`; others use `KlubhausCore/src/secrets.h`
|
|
2. **Vendored libs**: Each board links only its display lib — never TFT_eSPI + LovyanGFX together
|
|
3. **LSP errors**: Run `just gen-compile-commands` then restart LSP; build works regardless
|
|
4. **Serial port**: `upload`/`monitor` auto-depend on `kill` to release port
|
|
5. **State tags**: Use `[STATE] → DASHBOARD`, `[ADMIN]`, `[TOUCH]`, `[ALERT]` for monitor parsing
|
|
|
|
## Config Constants (Config.h)
|
|
|
|
| Constant | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `FW_VERSION` | "5.1" | Firmware version |
|
|
| `POLL_INTERVAL_MS` | 15000 | ntfy.sh poll interval |
|
|
| `ALERT_TIMEOUT_MS` | 120000 | Auto-clear alert |
|
|
| `INACTIVITY_TIMEOUT_MS` | 30000 | Display off timeout |
|
|
| `HOLD_TO_SILENCE_MS` | 3000 | Hold to silence |
|
|
| `WIFI_CONNECT_TIMEOUT_MS` | 15000 | WiFi timeout |
|
|
| `HTTP_TIMEOUT_MS` | 10000 | HTTP request timeout |
|
|
|
|
## Screen States
|
|
|
|
- **BOOT** — Initializing
|
|
- **DASHBOARD** — Normal operation
|
|
- **ALERT** — Doorbell ring detected
|
|
- **OFF** — Display backlight off (polling continues)
|