c4adb38576505558e068559791b726019dbaf43d
1. **Added `active` parameter to hint animation** - `updateHint()` now accepts a boolean `active` parameter across both display drivers (TFT and GFX) - When `active=true`: faster pulse animation (500ms period) during active hold - When `active=false`: slower pulse animation (2000ms period) during idle state 2. **Improved animation calculations** - Replaced modulo operator with `fmodf()` for cleaner float calculations - Standardized to `static_cast<uint8_t>()` for type conversions - Fixed GFX driver to use `color565()` method instead of manual bit shifting 3. **Updated hint display logic** - Now differentiates between "holding" state (fast pulse) and "idle" state (slow pulse) - Hint draws at both states when `holdStartX >= 0` (touch position captured) 4. **Added code formatter task** - New `mise.toml` task for running clang-format across all source files - Users get **visual feedback differentiation**: fast pulsing during active hold vs. slow pulsing when idle - More intuitive UI that clearly indicates whether a long-press is in progress or just waiting - Cleaner, more maintainable code with standardized calculations and type conversions
Klubhaus Doorbell
Multi-target doorbell alert system powered by ntfy.sh.
Targets
| Board | Display | Library | Build Task |
|---|---|---|---|
| ESP32-32E | SPI TFT (ILI9341 etc.) | TFT_eSPI | mise run compile-32e |
| ESP32-S3-Touch-LCD-4.3 | 800x480 RGB parallel | Arduino_GFX | mise run compile-s3-43 |
Quick Start
-
Install prerequisites: arduino-cli (with esp32:esp32 platform) and mise.
-
Edit WiFi credentials:
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.hThen edit both secrets.h files with your WiFi SSIDs and passwords.
-
Build and upload:
mise run compile-s3-43 mise run upload-s3-43 mise run compile-32e mise run upload-32e
Project Structure
.
├── libraries/
│ └── KlubhausCore/ Shared Arduino library
│ └── src/
│ ├── KlubhausCore.h Umbrella include
│ ├── Config.h Shared constants
│ ├── ScreenState.h State enums / structs
│ ├── IDisplayDriver.h Abstract display interface
│ ├── DisplayManager.h Thin delegation wrapper
│ ├── NetManager.* WiFi, NTP, HTTP
│ └── DoorbellLogic.* State machine, ntfy polling
├── boards/
│ ├── esp32-32e/ ESP32-32E sketch
│ │ ├── esp32-32e.ino
│ │ ├── board_config.h
│ │ ├── secrets.h (gitignored)
│ │ ├── tft_user_setup.h
│ │ └── DisplayDriverTFT.*
│ └── esp32-s3-lcd-43/ ESP32-S3-LCD-4.3 sketch
│ ├── esp32-s3-lcd-43.ino
│ ├── board_config.h
│ ├── secrets.h (gitignored)
│ └── DisplayDriverGFX.*
├── vendor/ Per-board vendored display libs
│ ├── esp32-32e/TFT_eSPI/
│ └── esp32-s3-lcd-43/GFX_Library_for_Arduino/
└── mise.toml Build harness
Serial Commands
Type into the 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 |
Architecture
Each board target gets its own sketch directory with a concrete IDisplayDriver implementation. The shared KlubhausCore library contains all business logic, networking, and the abstract interface. Arduino CLI's --libraries flag ensures each board only links its own vendored display library -- no preprocessor conflicts.
Board sketch (.ino)
|
+-- #include <KlubhausCore.h> (shared library)
| +-- DoorbellLogic (state machine + ntfy polling)
| +-- NetManager (WiFi, HTTP, NTP)
| +-- DisplayManager (delegates to IDisplayDriver)
| +-- IDisplayDriver (pure virtual interface)
|
+-- DisplayDriverXxx (board-specific, concrete driver)
+-- links against vendored display lib
(TFT_eSPI or Arduino_GFX, never both)
Description
Languages
C++
79%
C
10.1%
Shell
8.2%
Python
2.7%