# Klubhaus Doorbell - justfile # Run with: just # Set BOARD: just BOARD=esp32-32e-4 compile # Default recipe - show help default: @just --list # Set default BOARD BOARD := "esp32-32e-4" # Helper to source board config # just passes args as positional, so we source in each recipe # Compile firmware compile: #!/usr/bin/env bash set -e source ./boards/{{BOARD}}/board-config.sh # Only regenerate compile_commands.json if needed (board changed or first run) NEED_GEN=false if [ ! -f compile_commands.json ]; then NEED_GEN=true elif [ ! -f .board-last ] || [ "$(cat .board-last)" != "{{BOARD}}" ]; then NEED_GEN=true fi if [ "$NEED_GEN" = "true" ]; then rm -rf /tmp/arduino-build arduino-cli compile --only-compilation-database --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --build-path /tmp/arduino-build ./boards/{{BOARD}} cp /tmp/arduino-build/compile_commands.json . echo "{{BOARD}}" > .board-last echo "[OK] Generated compile_commands.json for {{BOARD}}" else echo "[SKIP] compile_commands.json already up to date for {{BOARD}}" fi arduino-cli compile --fqbn "$FQBN" --libraries ./libraries $LIBS --build-property "compiler.cpp.extra_flags=$OPTS" --warnings default ./boards/{{BOARD}} # Upload firmware upload: kill #!/usr/bin/env bash set -e source ./boards/{{BOARD}}/board-config.sh arduino-cli upload --fqbn "$FQBN" --port "$PORT" ./boards/{{BOARD}} # Kill processes using serial port kill: #!/usr/bin/env bash set +e source ./boards/{{BOARD}}/board-config.sh PORT="${PORT:-$PORT}" echo "Killing processes on $PORT..." fuser -k "$PORT" 2>/dev/null || true for pid in $(pgrep -f "monitor-agent.py.*{{BOARD}}" 2>/dev/null || true); do echo "Killing monitor-agent.py (PID: $pid)..." kill "$pid" 2>/dev/null || true done rm -f "/tmp/doorbell-{{BOARD}}.lock" 2>/dev/null || true sleep 1 echo "[OK] Killed processes for {{BOARD}}" # Monitor raw serial monitor-raw: kill #!/usr/bin/env bash source ./boards/{{BOARD}}/board-config.sh PORT="${PORT:-$PORT}" TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")" arduino-cli monitor -p "$TARGET" --config baudrate=115200 # Show tio command monitor-tio: kill #!/usr/bin/env bash source ./boards/{{BOARD}}/board-config.sh PORT="${PORT:-$PORT}" TARGET="$(readlink -f "$PORT" 2>/dev/null || echo "$PORT")" echo "Run: tio --map INLCRNL $TARGET -e" # Monitor with JSON logging monitor: kill #!/usr/bin/env bash python3 ./scripts/monitor-agent.py "{{BOARD}}" & # Tail colored logs watch: #!/usr/bin/env bash tail -f "/tmp/doorbell-{{BOARD}}.jsonl" | while read -r line; do ts=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['ts'])" 2>/dev/null) txt=$(echo "$line" | python3 -c "import sys,json; print(json.load(sys.stdin)['line'])" 2>/dev/null) if [[ "$txt" == *"[STATE]"* ]]; then echo -e "\033[1;35m[$ts]\033[0m $txt" elif [[ "$txt" == *"[ADMIN]"* ]]; then echo -e "\033[1;36m[$ts]\033[0m $txt" elif [[ "$txt" == *"[TOUCH]"* ]]; then echo -e "\033[1;33m[$ts]\033[0m $txt" elif [[ "$txt" == *"ALERT"* ]]; then echo -e "\033[1;31m[$ts]\033[0m $txt" else echo "[$ts] $txt" fi done # Send command to device cmd command: #!/usr/bin/env bash echo -n "{{command}}" > "/tmp/doorbell-{{BOARD}}-cmd.fifo" echo "[SENT] {{command}}" # Show device state state: @cat "/tmp/doorbell-{{BOARD}}-state.json" # Detect connected board detect: #!/usr/bin/env bash bash ./scripts/detect-device.sh # Install shared libraries install-libs-shared: #!/usr/bin/env bash ./scripts/install-shared.sh # Install all libraries install: install-libs-shared #!/usr/bin/env bash ./boards/{{BOARD}}/install.sh # Clean build artifacts clean: #!/usr/bin/env bash rm -rf vendor/ rm -rf boards/esp32-32e/build rm -rf boards/esp32-32e-4/build rm -rf boards/esp32-s3-lcd-43/build rm -f .board-last echo "[OK] Build artifacts cleaned" # Clean temporary files (monitor logs, FIFOs, state files) clean-temp: #!/usr/bin/env bash rm -f /tmp/doorbell-esp32-32e.jsonl /tmp/doorbell-esp32-32e-state.json /tmp/doorbell-esp32-32e-cmd.fifo rm -f /tmp/doorbell-esp32-32e-4.jsonl /tmp/doorbell-esp32-32e-4-state.json /tmp/doorbell-esp32-32e-4-cmd.fifo rm -f /tmp/doorbell-esp32-s3-lcd-43.jsonl /tmp/doorbell-esp32-s3-lcd-43-state.json /tmp/doorbell-esp32-s3-lcd-43-cmd.fifo rm -f .board-last echo "[OK] Temp files cleaned" # Clean Arduino cache arduino-clean: #!/usr/bin/env bash 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 # Format code format: #!/usr/bin/env bash 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 # Generate crush config gen-crush-config: #!/usr/bin/env bash set -e source ./boards/{{BOARD}}/board-config.sh printf '{\n "lsp": {\n "arduino": {\n "command": "arduino-language-server",\n "args": ["-fqbn", "%s"]\n },\n "cpp": {\n "command": "clangd"\n }\n }\n}\n' "$FQBN" > .crush.json echo "[OK] Generated .crush.json with FQBN: $FQBN"