Newer
Older
smart-home-server / devices / build.sh
#!/usr/bin/env bash
set -euo pipefail

DEVICES_DIR="$(cd "$(dirname "$0")" && pwd)"
ARDUINO_CLI="arduino-cli"
LIBRARIES_DIR="${DEVICES_DIR}"

GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; NC='\033[0m'

ok()   { echo -e "${GREEN}✓${NC} $*"; }
err()  { echo -e "${RED}✗${NC} $*"; }
info() { echo -e "${YELLOW}▸${NC} $*"; }

ERRORS=()

# ─────────────────────────────────────────────
# compile <sketch_dir> <fqbn> <output_dir> [channel_num]
#   channel_num — если передан, патчит CHANNEL_NUM в .ino во временной копии
# ─────────────────────────────────────────────
compile() {
    local sketch_dir="$1"
    local fqbn="$2"
    local output_dir="$3"
    local channel_num="${4:-}"

    local sketch_name
    sketch_name="$(basename "${sketch_dir}")"
    local label="${sketch_name} [${fqbn}]"
    [ -n "${channel_num}" ] && label="${sketch_name} x${channel_num} [${fqbn}]"

    info "Building ${label}..."

    local build_src="${sketch_dir}"

    # Для варианта с нестандартным CHANNEL_NUM — временная копия скетча
    # Папка должна называться как скетч, иначе arduino-cli не найдёт .ino
    local tmp_root=""
    local tmp_dir=""
    if [ -n "${channel_num}" ]; then
        tmp_root="$(mktemp -d)"
        tmp_dir="${tmp_root}/${sketch_name}"
        mkdir "${tmp_dir}"
        find "${sketch_dir}" -maxdepth 1 -type f -exec cp {} "${tmp_dir}/" \;
        local ino_file="${tmp_dir}/${sketch_name}.ino"
        sed -i "s/extern const uint8_t CHANNEL_NUM = [0-9]*/extern const uint8_t CHANNEL_NUM = ${channel_num}/" "${ino_file}"
        build_src="${tmp_dir}"
    fi

    mkdir -p "${output_dir}"

    if ${ARDUINO_CLI} compile \
        --fqbn "${fqbn}" \
        --libraries "${LIBRARIES_DIR}" \
        --output-dir "${output_dir}" \
        "${build_src}" \
        > /tmp/arduino_build.log 2>&1; then
        ok "${label} → ${output_dir}"
    else
        err "${label} — FAILED"
        cat /tmp/arduino_build.log | tail -20
        ERRORS+=("${label}")
    fi

    if [ -n "${tmp_root}" ]; then rm -rf "${tmp_root}"; fi
}

# ─────────────────────────────────────────────
# Targets
# ─────────────────────────────────────────────

echo ""
echo "═══════════════════════════════════════════"
echo "  Smart Home Firmware Build"
echo "═══════════════════════════════════════════"
echo ""

# relay — ESP-01S (esp8266 generic)
compile "${DEVICES_DIR}/relay" \
    "esp8266:esp8266:generic" \
    "${DEVICES_DIR}/relay/build/esp8266.esp8266.generic"

# relay — ESP32-C3
compile "${DEVICES_DIR}/relay" \
    "esp32:esp32:esp32c3" \
    "${DEVICES_DIR}/relay/build/esp32.esp32.esp32c3"

# button — D1 Mini, 2 канала (дефолт)
compile "${DEVICES_DIR}/button" \
    "esp8266:esp8266:d1_mini" \
    "${DEVICES_DIR}/button/build/esp8266.esp8266.d1_mini" \
    2

# button — D1 Mini, 4 канала
compile "${DEVICES_DIR}/button" \
    "esp8266:esp8266:d1_mini" \
    "${DEVICES_DIR}/button/build/esp8266.esp8266.d1_mini_x4" \
    4

# ─────────────────────────────────────────────
# Копируем релизные бинари в builds/
# ─────────────────────────────────────────────
copy_release() {
    local src_dir="$1"
    local dst_dir="${DEVICES_DIR}/builds/$2"
    local bin_name="$3"
    mkdir -p "${dst_dir}"
    cp "${src_dir}/${bin_name}.bin" "${dst_dir}/${bin_name}.bin" 2>/dev/null || true
    cp "${src_dir}/${bin_name}.elf" "${dst_dir}/${bin_name}.elf" 2>/dev/null || true
    cp "${src_dir}/${bin_name}.map" "${dst_dir}/${bin_name}.map" 2>/dev/null || true
}

echo ""
info "Copying release binaries..."
copy_release "${DEVICES_DIR}/relay/build/esp8266.esp8266.generic"       "relay_esp8266_x1"    "relay.ino"
copy_release "${DEVICES_DIR}/button/build/esp8266.esp8266.d1_mini"      "button_esp8266_x2"   "button.ino"
copy_release "${DEVICES_DIR}/button/build/esp8266.esp8266.d1_mini_x4"   "button_esp8266_x4"   "button.ino"

# ─────────────────────────────────────────────
# Итог
# ─────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════"
if [ ${#ERRORS[@]} -eq 0 ]; then
    ok "All builds succeeded"
else
    err "Failed builds:"
    for e in "${ERRORS[@]}"; do
        echo "    - ${e}"
    done
    exit 1
fi
echo "═══════════════════════════════════════════"
echo ""