#!/bin/sh # OpenWrt HA Presence Tracker Installer # Usage: sh <(wget --no-check-certificate -O - https://your-gitea-url/raw/branch/main/install.sh) set -e # UPDATE THIS URL to the raw files directory of your Gitea repository GITEA_RAW_URL="https://raw.githubusercontent.com/your-user/your-repo/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}$" } read_with_default() { local prompt="$1" local default="$2" local result if [ -n "$default" ]; then printf "%s [%s]: " "$prompt" "$default" else printf "%s: " "$prompt" fi read -r result if [ -z "$result" ] && [ -n "$default" ]; then echo "$default" else echo "$result" fi } if [ "$(id -u)" -ne 0 ]; then error "This script must be run as root." exit 1 fi info "Updating opkg and installing dependencies..." if ! opkg update 2>/dev/null; then warn "Failed to update opkg lists." printf "Continue anyway? [y/N]: " read -r answer [ "$answer" != "y" ] && [ "$answer" != "Y" ] && exit 1 fi PACKAGES_OK=true opkg install mosquitto-client-nossl 2>/dev/null || PACKAGES_OK=false opkg install hostapd-utils 2>/dev/null || PACKAGES_OK=false if [ "$PACKAGES_OK" = "false" ]; then warn "Some packages failed to install." printf "Continue anyway? [y/N]: " read -r answer [ "$answer" != "y" ] && [ "$answer" != "Y" ] && exit 1 fi SKIP_CONFIG=false ADD_DEVICE_ONLY=false if [ -f "$CONFIG_FILE" ]; then echo "" echo "Existing configuration detected." echo "1) Update scripts (keep MQTT and device settings)" echo "2) Add a new device" echo "3) Uninstall completely" echo "4) Exit" printf "Choose [1-4]: " read -r choice case "$choice" in 1) SKIP_CONFIG=true ;; 2) SKIP_CONFIG=true; ADD_DEVICE_ONLY=true ;; 3) info "Uninstalling..." 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 rm -f /etc/hostapd.user rm -f /usr/bin/mqtt_ha_discovery.sh rm -f "$CONFIG_FILE" rm -rf "$STATES_DIR" info "Uninstallation complete. Remove entities in Home Assistant manually." exit 0 ;; *) exit 1 ;; esac fi if [ "$SKIP_CONFIG" = "false" ]; then echo "" info "MQTT Broker Configuration:" MQTT_HOST=$(read_with_default "MQTT Broker IP or Domain" "192.168.1.100") MQTT_PORT=$(read_with_default "MQTT Port" "1883") MQTT_USER=$(read_with_default "MQTT Username" "mqtt_user") MQTT_PASS=$(read_with_default "MQTT Password" "mqtt_password") BASE_TOPIC=$(read_with_default "Base MQTT Topic" "openwrt") info "Testing MQTT connection..." 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 connection successful." else warn "Failed to connect to MQTT broker." printf "Continue anyway? [y/N]: " read -r answer [ "$answer" != "y" ] && [ "$answer" != "Y" ] && exit 1 fi fi if [ "$SKIP_CONFIG" = "false" ] || [ "$ADD_DEVICE_ONLY" = "true" ]; then echo "" printf "Add a device now? [Y/n]: " read -r answer if [ "$answer" != "n" ] && [ "$answer" != "N" ]; then DEVICE_COUNT=1 if [ "$ADD_DEVICE_ONLY" = "true" ]; then DEVICE_COUNT=$(uci show openwrt_ha 2>/dev/null | grep -c "device[0-9]" || echo 0) DEVICE_COUNT=$((DEVICE_COUNT + 1)) fi while true; do echo "" echo "Device #$DEVICE_COUNT:" DEVICE_NAME=$(read_with_default "Device Name" "Device $DEVICE_COUNT") while true; do echo "Enter MAC address(es) separated by space (e.g., 14:e0:1d:c7:05:76 aa:bb:cc:dd:ee:ff)" read -r -p "MAC(s): " DEVICE_MACS if [ -z "$DEVICE_MACS" ]; then warn "At least one MAC address is required." continue fi ALL_VALID=true for mac in $DEVICE_MACS; do if ! validate_mac "$mac"; then warn "Invalid MAC format: $mac" ALL_VALID=false break fi done [ "$ALL_VALID" = "true" ] && break done echo "Device Type:" echo "1) Tracker (people, home/not_home)" echo "2) Alarm/IoT (devices, online/offline)" DEVICE_TYPE_NUM=$(read_with_default "Choose [1-2]" "1") if [ "$DEVICE_TYPE_NUM" = "2" ]; then DEVICE_TYPE="alarm" DEFAULT_DELAY="0" else DEVICE_TYPE="tracker" DEFAULT_DELAY="30" fi DEVICE_DELAY=$(read_with_default "Delay before 'disconnected' (seconds)" "$DEFAULT_DELAY") DEVICE_ID="device${DEVICE_COUNT}" uci set openwrt_ha.${DEVICE_ID}='device' uci set openwrt_ha.${DEVICE_ID}.name="$DEVICE_NAME" uci set openwrt_ha.${DEVICE_ID}.macs="$DEVICE_MACS" uci set openwrt_ha.${DEVICE_ID}.type="$DEVICE_TYPE" uci set openwrt_ha.${DEVICE_ID}.delay="$DEVICE_DELAY" info "Device '$DEVICE_NAME' added." printf "Add another device? [Y/n]: " read -r answer [ "$answer" = "n" ] || [ "$answer" = "N" ] && break DEVICE_COUNT=$((DEVICE_COUNT + 1)) done uci commit openwrt_ha fi fi if [ "$SKIP_CONFIG" = "false" ]; then 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 fi info "Downloading files from repository..." if ! wget --spider --no-check-certificate "$GITEA_RAW_URL/hostapd.user" 2>/dev/null; then error "Cannot reach repository at: $GITEA_RAW_URL" exit 1 fi wget --no-check-certificate -O /etc/hostapd.user "$GITEA_RAW_URL/hostapd.user" 2>/dev/null || exit 1 wget --no-check-certificate -O /usr/bin/mqtt_ha_discovery.sh "$GITEA_RAW_URL/mqtt_ha_discovery.sh" 2>/dev/null || exit 1 wget --no-check-certificate -O /etc/init.d/openwrt_presence "$GITEA_RAW_URL/openwrt_presence" 2>/dev/null || exit 1 for file in /etc/hostapd.user /usr/bin/mqtt_ha_discovery.sh /etc/init.d/openwrt_presence; do if [ ! -s "$file" ] || grep -q "" "$file"; then error "File $file downloaded incorrectly (possibly 404)." exit 1 fi done chmod +x /etc/hostapd.user chmod +x /usr/bin/mqtt_ha_discovery.sh chmod +x /etc/init.d/openwrt_presence info "Configuring autostart..." /etc/init.d/openwrt_presence enable 2>/dev/null || exit 1 /etc/init.d/openwrt_presence restart 2>/dev/null || exit 1 sleep 2 if ! ps | grep -q "[h]ostapd_cli"; then warn "Service started, but hostapd_cli process not found." echo "Check logs: logread | grep hostapd" echo "Verify Wi-Fi interfaces with: iw dev" fi info "Configuring 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 is not installed. Run: opkg install cron" fi info "Running initial discovery..." /usr/bin/mqtt_ha_discovery.sh 2>/dev/null || warn "Initial discovery failed. Run manually later." echo "" echo "==================================================" info "Installation completed successfully!" echo "==================================================" echo "To edit settings: vi /etc/config/openwrt_ha" echo "To view logs: logread | grep wifi_tracker" echo "To test: Turn off Wi-Fi on the added device and check logs after the delay."