mirror of
https://github.com/sweidac/kidsbox.git
synced 2026-10-27 22:52:57 +01:00
install.sh: - Add SCRIPT_DIR so .env is written to the repo root regardless of cwd - Detect OS (macOS/Linux) and show platform-appropriate missing-tool hints - Check for Xcode Command Line Tools on macOS (required by IDF install.sh) - Handle pip3 absence by falling back to python3 -m pip - Remove ninja from hard prerequisite list (IDF bundles its own) setup.sh: - Show macOS serial port hint (/dev/cu.usbserial-*) vs Linux (/dev/ttyUSB0) - Show macOS SD card mount hint (/Volumes/) vs Linux (/media/$USER/) https://claude.ai/code/session_01MhAnh68DPNnTjcKqjNYDmk
141 lines
4.9 KiB
Bash
Executable File
141 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# setup.sh — configure, build, and optionally flash/deploy Kidsbox
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
DEVICE_DIR="$SCRIPT_DIR/device"
|
|
WWW_DIR="$SCRIPT_DIR/www"
|
|
|
|
BOLD='\033[1m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; RED='\033[0;31m'; NC='\033[0m'
|
|
info() { echo -e "${GREEN}[setup]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[warn]${NC} $*"; }
|
|
die() { echo -e "${RED}[error]${NC} $*" >&2; exit 1; }
|
|
heading() { echo -e "\n${BOLD}$*${NC}"; }
|
|
prompt() { echo -e "${YELLOW}$*${NC}"; }
|
|
|
|
# ── check environment ──────────────────────────────────────────────────────────
|
|
|
|
heading "Checking environment"
|
|
|
|
[[ -f "$SCRIPT_DIR/.env" ]] && source "$SCRIPT_DIR/.env"
|
|
|
|
[[ -n "${IDF_PATH:-}" ]] || die "IDF_PATH not set. Run: source .env && source \$IDF_PATH/export.sh"
|
|
[[ -n "${ADF_PATH:-}" ]] || die "ADF_PATH not set. Run: source .env && source \$IDF_PATH/export.sh"
|
|
command -v idf.py &>/dev/null || die "idf.py not found. Run: source \$IDF_PATH/export.sh"
|
|
|
|
info "IDF_PATH: $IDF_PATH"
|
|
info "ADF_PATH: $ADF_PATH"
|
|
|
|
# ── WiFi credentials ───────────────────────────────────────────────────────────
|
|
|
|
heading "WiFi configuration"
|
|
|
|
SDKCONFIG_DEFAULTS="$DEVICE_DIR/sdkconfig.defaults"
|
|
|
|
if [[ -f "$SDKCONFIG_DEFAULTS" ]] \
|
|
&& grep -q "CONFIG_ESP_WIFI_SSID" "$SDKCONFIG_DEFAULTS" 2>/dev/null; then
|
|
CURRENT_SSID=$(grep 'CONFIG_ESP_WIFI_SSID' "$SDKCONFIG_DEFAULTS" | cut -d'"' -f2)
|
|
info "WiFi already configured (SSID: $CURRENT_SSID)"
|
|
prompt "Re-enter credentials? [y/N] "
|
|
read -r RECONFIGURE
|
|
[[ "$RECONFIGURE" =~ ^[Yy]$ ]] || SKIP_WIFI=1
|
|
fi
|
|
|
|
if [[ -z "${SKIP_WIFI:-}" ]]; then
|
|
prompt "WiFi SSID: "
|
|
read -r WIFI_SSID
|
|
prompt "WiFi Password: "
|
|
read -rs WIFI_PASSWORD
|
|
echo ""
|
|
|
|
[[ -n "$WIFI_SSID" ]] || die "SSID cannot be empty"
|
|
[[ -n "$WIFI_PASSWORD" ]] || die "Password cannot be empty"
|
|
|
|
cat > "$SDKCONFIG_DEFAULTS" <<EOF
|
|
CONFIG_ESP_WIFI_SSID="${WIFI_SSID}"
|
|
CONFIG_ESP_WIFI_PASSWORD="${WIFI_PASSWORD}"
|
|
CONFIG_ESP_MAXIMUM_RETRY=5
|
|
CONFIG_ESP_ADF_BOARD_LYRAT_V4_3=y
|
|
CONFIG_IDF_TARGET="esp32"
|
|
EOF
|
|
info "Wrote $SDKCONFIG_DEFAULTS"
|
|
fi
|
|
|
|
# ── set target & build ─────────────────────────────────────────────────────────
|
|
|
|
heading "Building firmware"
|
|
|
|
cd "$DEVICE_DIR"
|
|
|
|
idf.py set-target esp32
|
|
|
|
info "Running idf.py build (this takes a few minutes on first run)"
|
|
idf.py build
|
|
|
|
info "Build complete."
|
|
|
|
# ── flash ──────────────────────────────────────────────────────────────────────
|
|
|
|
heading "Flash to device"
|
|
|
|
prompt "Flash firmware to device now? [y/N] "
|
|
read -r DO_FLASH
|
|
|
|
if [[ "$DO_FLASH" =~ ^[Yy]$ ]]; then
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
PORT_HINT="/dev/cu.usbserial-* or /dev/cu.SLAB_USBtoUART"
|
|
else
|
|
PORT_HINT="/dev/ttyUSB0 or /dev/ttyACM0"
|
|
fi
|
|
prompt "Serial port (e.g. $PORT_HINT, leave blank to auto-detect): "
|
|
read -r SERIAL_PORT
|
|
|
|
if [[ -n "$SERIAL_PORT" ]]; then
|
|
idf.py -p "$SERIAL_PORT" flash monitor
|
|
else
|
|
idf.py flash monitor
|
|
fi
|
|
fi
|
|
|
|
# ── SD card setup ──────────────────────────────────────────────────────────────
|
|
|
|
heading "SD card setup"
|
|
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
SD_HINT="/Volumes/KIDSBOX"
|
|
else
|
|
SD_HINT="/media/\$USER/KIDSBOX"
|
|
fi
|
|
prompt "Mount path of SD card (e.g. $SD_HINT, leave blank to skip): "
|
|
read -r SD_MOUNT
|
|
|
|
if [[ -n "$SD_MOUNT" ]]; then
|
|
[[ -d "$SD_MOUNT" ]] || die "Mount path not found: $SD_MOUNT"
|
|
|
|
info "Creating directory structure on SD card"
|
|
mkdir -p "$SD_MOUNT/www"
|
|
mkdir -p "$SD_MOUNT/internal"
|
|
mkdir -p "$SD_MOUNT/cache"
|
|
|
|
info "Copying web interface"
|
|
cp -r "$WWW_DIR/." "$SD_MOUNT/www/"
|
|
|
|
info "SD card contents:"
|
|
ls "$SD_MOUNT/"
|
|
|
|
echo ""
|
|
echo " SD card is ready."
|
|
echo " To configure a tag: create a file at $SD_MOUNT/internal/<tag-id>"
|
|
echo " containing either:"
|
|
echo " - An http:// URL (will be streamed and cached)"
|
|
echo " - A local path (e.g. /sdcard/music/song.mp3)"
|
|
echo " Tag IDs are shown in the serial monitor when a tag is scanned."
|
|
fi
|
|
|
|
# ── done ───────────────────────────────────────────────────────────────────────
|
|
|
|
heading "Done!"
|
|
echo ""
|
|
echo " Once running, open http://<device-ip> in your browser."
|
|
echo ""
|