#!/bin/sh # OpenWrt HA Presence Tracker Installer set -e GITEA_RAW_URL="https://git.darkmode.duckdns.org/sirmrak/openwrt-ha-presence/raw/branch/main/files" CONFIG_FILE="/etc/config/openwrt_ha" STATES_DIR="/tmp/mqtt_ha_states" info() { echo "[INFO] $1"; } warn() { echo "[WARN] $1"; } error() { echo "[ERROR] $1"; } validate_mac() { echo "$1" | grep -qE "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$" } if [ "$(id -u)" -ne 0 ]; then error "Скрипт должен выполняться от имени root." exit 1 fi # === ПРОВЕРКА ПАКЕТОВ === info "Проверка необходимых пакетов..." if opkg list-installed | grep -q "^mosquitto-client-nossl " && opkg list-installed | grep -q "^hostapd-utils "; then info "Пакеты уже установлены. Пропускаем." else info "Установка зависимостей..." opkg update >/dev/null 2>&1 || warn "Не удалось обновить списки opkg." opkg install mosquitto-client-nossl hostapd-utils >/dev/null 2>&1 || warn "Не удалось установить пакеты." if ! opkg list-installed | grep -q "^mosquitto-client-nossl " || ! opkg list-installed | grep -q "^hostapd-utils "; then warn "Не удалось установить необходимые пакеты." printf "Продолжить всё равно? [y/N]: " read answer case "$answer" in [yY]*) ;; *) exit 1 ;; esac fi fi # === ОПРЕДЕЛЕНИЕ СОСТОЯНИЯ КОНФИГА === MQTT_CONFIGURED=false if [ -f "$CONFIG_FILE" ]; then if uci -q get openwrt_ha.main.host >/dev/null 2>&1; then MQTT_CONFIGURED=true fi fi # === МЕНЮ ПРИ НАСТРОЕННОМ MQTT === ACTION="install" # install | update | add_device | change_mqtt | uninstall if [ "$MQTT_CONFIGURED" = "true" ]; then CURRENT_HOST=$(uci get openwrt_ha.main.host) echo "" echo "Обнаружена конфигурация (MQTT: $CURRENT_HOST)." echo "1) Обновить скрипты (настройки сохранятся)" echo "2) Добавить новое устройство" echo "3) Изменить настройки MQTT" echo "4) Удалить интеграцию полностью" echo "5) Выход" printf "Выберите [1-5]: " read choice case "$choice" in 1) ACTION="update" ;; 2) ACTION="add_device" ;; 3) ACTION="change_mqtt" ;; 4) ACTION="uninstall" ;; *) exit 1 ;; esac fi # === УДАЛЕНИЕ === if [ "$ACTION" = "uninstall" ]; then info "Удаление..." crontab -l 2>/dev/null | grep -v "mqtt_ha_discovery.sh" | crontab - 2>/dev/null || true /etc/init.d/cron restart 2>/dev/null || true /etc/init.d/openwrt_presence stop 2>/dev/null || true /etc/init.d/openwrt_presence disable 2>/dev/null || true rm -f /etc/init.d/openwrt_presence /etc/hostapd.user /usr/bin/mqtt_ha_discovery.sh "$CONFIG_FILE" rm -rf "$STATES_DIR" info "Удаление завершено. Удалите сущности в Home Assistant вручную." exit 0 fi # === ВВОД НАСТРОЕК MQTT === if [ "$ACTION" = "install" ] || [ "$ACTION" = "change_mqtt" ]; then echo "" echo "=== Настройка MQTT брокера ===" echo "(Нажмите Enter для значения по умолчанию)" if [ "$MQTT_CONFIGURED" = "true" ]; then DEFAULT_HOST=$(uci get openwrt_ha.main.host) DEFAULT_PORT=$(uci get openwrt_ha.main.port) DEFAULT_USER=$(uci get openwrt_ha.main.user) DEFAULT_PASS=$(uci get openwrt_ha.main.pass) DEFAULT_TOPIC=$(uci get openwrt_ha.main.base_topic) else DEFAULT_HOST="192.168.1.100" DEFAULT_PORT="1883" DEFAULT_USER="mqtt_user" DEFAULT_PASS="mqtt_password" DEFAULT_TOPIC="openwrt" fi printf "IP или домен MQTT брокера [%s]: " "$DEFAULT_HOST" read MQTT_HOST if [ -z "$MQTT_HOST" ]; then MQTT_HOST="$DEFAULT_HOST"; fi printf "Порт MQTT [%s]: " "$DEFAULT_PORT" read MQTT_PORT if [ -z "$MQTT_PORT" ]; then MQTT_PORT="$DEFAULT_PORT"; fi printf "Логин MQTT [%s]: " "$DEFAULT_USER" read MQTT_USER if [ -z "$MQTT_USER" ]; then MQTT_USER="$DEFAULT_USER"; fi printf "Пароль MQTT [%s]: " "$DEFAULT_PASS" read MQTT_PASS if [ -z "$MQTT_PASS" ]; then MQTT_PASS="$DEFAULT_PASS"; fi printf "Базовый топик MQTT [%s]: " "$DEFAULT_TOPIC" read BASE_TOPIC if [ -z "$BASE_TOPIC" ]; then BASE_TOPIC="$DEFAULT_TOPIC"; fi echo "" info "Проверка подключения к MQTT..." if mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" -u "$MQTT_USER" -P "$MQTT_PASS" \ -t "${BASE_TOPIC}/test/install" -m "ping" -I "installer_$$" -r 2>/dev/null; then info "Подключение к MQTT успешно." else warn "Не удалось подключиться к MQTT брокеру." printf "Продолжить всё равно? [y/N]: " read answer case "$answer" in [yY]*) ;; *) exit 1 ;; esac fi # === СОХРАНЕНИЕ MQTT ЧЕРЕЗ UCI === [ -f "$CONFIG_FILE" ] || touch "$CONFIG_FILE" uci set openwrt_ha.main='mqtt' uci set openwrt_ha.main.host="$MQTT_HOST" uci set openwrt_ha.main.port="$MQTT_PORT" uci set openwrt_ha.main.user="$MQTT_USER" uci set openwrt_ha.main.pass="$MQTT_PASS" uci set openwrt_ha.main.base_topic="$BASE_TOPIC" uci commit openwrt_ha info "Настройки MQTT сохранены." fi # === ДОБАВЛЕНИЕ УСТРОЙСТВ === ASK_DEVICES=false if [ "$ACTION" = "install" ] || [ "$ACTION" = "change_mqtt" ] || [ "$ACTION" = "add_device" ]; then ASK_DEVICES=true fi if [ "$ASK_DEVICES" = "true" ]; then echo "" printf "Добавить устройство прямо сейчас? [Y/n]: " read answer case "$answer" in [nN]*) ASK_DEVICES=false ;; esac fi if [ "$ASK_DEVICES" = "true" ]; then # Находим первый свободный индекс DEVICE_COUNT=1 while uci -q get "openwrt_ha.device${DEVICE_COUNT}" >/dev/null 2>&1; do DEVICE_COUNT=$((DEVICE_COUNT + 1)) done while true; do echo "" echo "--- Устройство #$DEVICE_COUNT ---" printf "Имя устройства (например, 'Телефон'): " read DEVICE_NAME if [ -z "$DEVICE_NAME" ]; then DEVICE_NAME="Устройство $DEVICE_COUNT"; fi while true; do echo "Введите MAC-адрес(а) через пробел" echo "Пример: 14:e0:1d:c7:05:76 или 14:e0:1d:c7:05:76 aa:bb:cc:dd:ee:ff" printf "MAC-адрес(а): " read DEVICE_MACS if [ -z "$DEVICE_MACS" ]; then warn "Необходимо ввести хотя бы один MAC-адрес." continue fi ALL_VALID=true for mac in $DEVICE_MACS; do if ! validate_mac "$mac"; then warn "Неверный формат MAC: $mac" ALL_VALID=false break fi done [ "$ALL_VALID" = "true" ] && break done echo "Тип устройства:" echo "1) Трекер (люди, статусы home/not_home)" echo "2) Тревога/IoT (розетки, статусы online/offline)" printf "Выберите [1-2] [1]: " read DEVICE_TYPE_NUM if [ -z "$DEVICE_TYPE_NUM" ]; then DEVICE_TYPE_NUM="1"; fi if [ "$DEVICE_TYPE_NUM" = "2" ]; then DEVICE_TYPE="alarm" DEFAULT_DELAY="0" else DEVICE_TYPE="tracker" DEFAULT_DELAY="30" fi printf "Задержка перед отправкой 'отключен' (сек) [%s]: " "$DEFAULT_DELAY" read DEVICE_DELAY if [ -z "$DEVICE_DELAY" ]; then DEVICE_DELAY="$DEFAULT_DELAY"; fi # Сохраняем через uci uci set "openwrt_ha.device${DEVICE_COUNT}"='device' uci set "openwrt_ha.device${DEVICE_COUNT}.name"="$DEVICE_NAME" uci set "openwrt_ha.device${DEVICE_COUNT}.macs"="$DEVICE_MACS" uci set "openwrt_ha.device${DEVICE_COUNT}.type"="$DEVICE_TYPE" uci set "openwrt_ha.device${DEVICE_COUNT}.delay"="$DEVICE_DELAY" uci commit openwrt_ha info "Устройство '$DEVICE_NAME' добавлено." printf "Добавить еще одно устройство? [Y/n]: " read answer case "$answer" in [nN]*) break ;; esac DEVICE_COUNT=$((DEVICE_COUNT + 1)) done fi # === СКАЧИВАНИЕ СКРИПТОВ === info "Загрузка файлов из репозитория..." if ! wget --spider --no-check-certificate "$GITEA_RAW_URL/hostapd.user" >/dev/null 2>&1; then error "Не удалось подключиться к репозиторию: $GITEA_RAW_URL" exit 1 fi wget --no-check-certificate -O /etc/hostapd.user "$GITEA_RAW_URL/hostapd.user" >/dev/null 2>&1 || exit 1 wget --no-check-certificate -O /usr/bin/mqtt_ha_discovery.sh "$GITEA_RAW_URL/mqtt_ha_discovery.sh" >/dev/null 2>&1 || exit 1 wget --no-check-certificate -O /etc/init.d/openwrt_presence "$GITEA_RAW_URL/openwrt_presence" >/dev/null 2>&1 || exit 1 chmod +x /etc/hostapd.user /usr/bin/mqtt_ha_discovery.sh /etc/init.d/openwrt_presence # === АВТОЗАПУСК === info "Настройка автозапуска..." /etc/init.d/openwrt_presence enable >/dev/null 2>&1 /etc/init.d/openwrt_presence restart >/dev/null 2>&1 sleep 2 if ! ps | grep -q "[h]ostapd_cli"; then warn "Служба запущена, но процесс hostapd_cli не найден." echo "Проверьте: logread | grep hostapd" echo "Возможно, ваши интерфейсы Wi-Fi называются не phy0-ap0/phy1-ap0 (проверьте: iw dev)" fi # === CRON === info "Настройка Cron..." if command -v crontab >/dev/null 2>&1; then if ! crontab -l 2>/dev/null | grep -q "mqtt_ha_discovery.sh"; then (crontab -l 2>/dev/null; echo "* * * * * /usr/bin/mqtt_ha_discovery.sh") | crontab - 2>/dev/null /etc/init.d/cron restart 2>/dev/null fi else warn "Cron не установлен. Установите: opkg install cron" fi # === ИНИЦИАЛИЗАЦИЯ === info "Первичная инициализация..." /usr/bin/mqtt_ha_discovery.sh >/dev/null 2>&1 || warn "Инициализация завершилась с ошибкой." echo "" echo "==================================================" info "Установка успешно завершена!" echo "==================================================" echo "Конфигурация: vi /etc/config/openwrt_ha" echo "Просмотр: uci show openwrt_ha" echo "Логи: logread | grep wifi_tracker" echo "" echo "Для проверки: выключите Wi-Fi на добавленном устройстве" echo "и проверьте лог через указанную задержку."