#!/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 ""