# ═══════════════════════════════════════════════════════════ # Klubhaus Doorbell — Multi-Target Build Harness # ═══════════════════════════════════════════════════════════ # Required tools [tools] hk = "latest" pkl = "latest" # zellij = "latest" # Install manually if needed (brew install zellij) # Usage: # BOARD=esp32-32e-4 mise run compile # compile # BOARD=esp32-32e-4 mise run upload # upload # BOARD=esp32-32e-4 mise run monitor # monitor # BOARD=esp32-32e-4 mise run monitor-screen # shows tio command to run manually # # Valid BOARD: esp32-32e, esp32-32e-4, esp32-s3-lcd-43 # Board config lives in: boards/{BOARD}/board-config.sh [tasks.compile] description = "Compile (uses BOARD env var)" run = """ source ./boards/$BOARD/board-config.sh arduino-cli compile --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --warnings default ./boards/$BOARD """ [tasks.upload] description = "Upload (uses BOARD env var)" run = """ source ./boards/$BOARD/board-config.sh source ./scripts/lockfile.sh FORCE=1 TASK_NAME=upload acquire_lock || exit 1 PORT="${PORT:-$PORT}" arduino-cli compile --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --warnings default ./boards/$BOARD && \ arduino-cli upload --fqbn "$FQBN" --port "$PORT" ./boards/$BOARD """ [tasks.monitor] description = "Monitor (uses BOARD env var)" run = """ source ./boards/$BOARD/board-config.sh source ./scripts/lockfile.sh acquire_lock || exit 1 PORT="${PORT:-$PORT}" TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")" arduino-cli monitor -p "$TARGET" --config baudrate=115200 """ [tasks.monitor-tio] description = "Show tio command to run in separate terminal" run = """ source ./boards/$BOARD/board-config.sh source ./scripts/lockfile.sh acquire_lock || exit 1 PORT="${PORT:-$PORT}" TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")" tio --map INLCRNL "$TARGET" -e """ [tasks.kill] description = "Kill running monitor/upload for BOARD" run = """ source ./scripts/lockfile.sh kill_locked """ [tasks.install-libs-shared] description = "Install shared (platform-independent) libraries" run = """ arduino-cli lib install "ArduinoJson@7.4.1" arduino-cli lib install "NTPClient@3.2.1" echo "[OK] Shared libraries installed" """ [tasks.install-libs-32e] description = "Vendor TFT_eSPI into vendor/esp32-32e" run = """ #!/usr/bin/env bash set -euo pipefail if [ ! -d "vendor/esp32-32e/TFT_eSPI" ]; then echo "Cloning TFT_eSPI..." git clone --depth 1 --branch V2.5.43 \ https://github.com/Bodmer/TFT_eSPI.git \ vendor/esp32-32e/TFT_eSPI fi echo "Copying board-specific User_Setup.h..." cp boards/esp32-32e/tft_user_setup.h vendor/esp32-32e/TFT_eSPI/User_Setup.h echo "[OK] TFT_eSPI 2.5.43 vendored + configured" """ [tasks.install-libs-32e-4] description = "Vendor TFT_eSPI into vendor/esp32-32e-4 (ST7796 320x480)" run = """ #!/usr/bin/env bash set -euo pipefail if [ ! -d "vendor/esp32-32e-4/TFT_eSPI" ]; then echo "Cloning TFT_eSPI..." git clone --depth 1 --branch V2.5.43 \ https://github.com/Bodmer/TFT_eSPI.git \ vendor/esp32-32e-4/TFT_eSPI fi echo "Copying board-specific User_Setup.h..." cp boards/esp32-32e-4/tft_user_setup.h vendor/esp32-32e-4/TFT_eSPI/User_Setup.h echo "[OK] TFT_eSPI 2.5.43 vendored + configured for 4 inch" """ [tasks.install-libs-s3-43] description = "Vendor LovyanGFX into vendor/esp32-s3-lcd-43" run = """ #!/usr/bin/env bash set -euo pipefail LOVyanGFX_DIR="vendor/esp32-s3-lcd-43/LovyanGFX" # Clone LovyanGFX (latest) if [ ! -d "$LOVyanGFX_DIR" ]; then echo "Cloning LovyanGFX..." git clone --depth 1 \ https://github.com/lovyan03/LovyanGFX.git \ "$LOVyanGFX_DIR" else echo "LovyanGFX already exists, skipping" fi # Create library.properties that correctly points to source cat > "$LOVyanGFX_DIR/library.properties" << 'EOF' name=LovyanGFX version=1.2.0 author=lovyan03 maintainer=lovyan03 sentence=Display and touch driver library for ESP32 paragraph=Universal graphics library for ESP32 with support for various displays and touch controllers category=Display url=https://github.com/lovyan03/LovyanGFX architectures=esp32 includes=LovyanGFX.hpp # This tells Arduino to build from src/ # Arduino will look in src/ for .cpp files EOF # Create a empty src to ensure sources are found mkdir -p "$LOVyanGFX_DIR/src" echo "[OK] LovyanGFX vendored" """ [tasks.install-libs] description = "Install all libraries (shared + vendored)" depends = [ "install-libs-shared", "install-libs-32e", "install-libs-32e-4", "install-libs-s3-43", ] # Convenience [tasks.clean] description = "Remove build artifacts" run = """ rm -rf vendor/ rm -rf boards/esp32-32e/build rm -rf boards/esp32-32e-4/build rm -rf boards/esp32-s3-lcd-43/build echo "[OK] Build artifacts cleaned" """ [tasks.arduino-clean] description = "Clean Arduino CLI cache (staging + packages)" run = """ echo "Checking ~/.arduino15..." du -sh ~/.arduino15/staging 2>/dev/null || echo "No staging folder" du -sh ~/.arduino15/packages 2>/dev/null || echo "No packages folder" read -p "Delete staging + packages folders? [y/N] " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then rm -rf ~/.arduino15/staging rm -rf ~/.arduino15/packages echo "[OK] Arduino staging + packages cleared" else echo "Aborted" fi """ [tasks.format] run = """ clang-format -i --style=file \ boards/esp32-32e/*.cpp \ boards/esp32-32e/*.h \ boards/esp32-32e/*.ino \ boards/esp32-32e-4/*.cpp \ boards/esp32-32e-4/*.h \ boards/esp32-32e-4/*.ino \ boards/esp32-s3-lcd-43/*.cpp \ boards/esp32-s3-lcd-43/*.h \ boards/esp32-s3-lcd-43/*.ino \ libraries/KlubhausCore/src/*.cpp \ libraries/KlubhausCore/src/*.h \ libraries/KlubhausCore/*.properties """ [env] BOARD = "esp32-32e-4"