#!/usr/bin/env bash set -euo pipefail # Vigilar — NUT (Network UPS Tools) configuration helper # Detects USB UPS devices and configures NUT for standalone monitoring. info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; } ok() { printf '\033[1;32m[ OK ]\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; } fail() { printf '\033[1;31m[FAIL]\033[0m %s\n' "$*" >&2; exit 1; } detect_pkg_manager() { if command -v apt-get &>/dev/null; then echo "apt" elif command -v pacman &>/dev/null; then echo "pacman" else fail "Unsupported package manager." fi } install_nut() { if command -v upsc &>/dev/null; then ok "NUT already installed" return fi info "Installing NUT" local pkg_mgr pkg_mgr="$(detect_pkg_manager)" case "$pkg_mgr" in apt) sudo apt-get update -qq sudo apt-get install -y -qq nut nut-client nut-server ;; pacman) sudo pacman -Sy --needed --noconfirm nut ;; esac ok "NUT installed" } detect_ups() { info "Scanning for USB UPS devices..." local driver="" local port="" local desc="" # Try nut-scanner first if command -v nut-scanner &>/dev/null; then local scan_output scan_output="$(sudo nut-scanner -U 2>/dev/null)" || true if [[ -n "$scan_output" ]]; then driver="$(echo "$scan_output" | grep -oP 'driver\s*=\s*"\K[^"]+' | head -1)" || true port="$(echo "$scan_output" | grep -oP 'port\s*=\s*"\K[^"]+' | head -1)" || true desc="$(echo "$scan_output" | grep -oP 'desc\s*=\s*"\K[^"]+' | head -1)" || true fi fi # Fallback: check for common USB UPS vendor IDs if [[ -z "$driver" ]]; then if lsusb 2>/dev/null | grep -qi "051d"; then driver="usbhid-ups" port="auto" desc="APC UPS (auto-detected via lsusb)" elif lsusb 2>/dev/null | grep -qi "0764"; then driver="usbhid-ups" port="auto" desc="CyberPower UPS (auto-detected via lsusb)" elif lsusb 2>/dev/null | grep -qi "0463"; then driver="usbhid-ups" port="auto" desc="Eaton UPS (auto-detected via lsusb)" elif lsusb 2>/dev/null | grep -qi "06da"; then driver="usbhid-ups" port="auto" desc="Phoenixtec/Tripp Lite UPS (auto-detected via lsusb)" fi fi if [[ -z "$driver" ]]; then warn "No USB UPS detected. Using generic usbhid-ups driver with auto port." warn "You may need to edit /etc/nut/ups.conf manually." driver="usbhid-ups" port="auto" desc="UPS (not auto-detected)" else ok "Detected UPS: ${desc:-unknown}" fi # Export for use in config generation UPS_DRIVER="$driver" UPS_PORT="$port" UPS_DESC="${desc:-UPS}" } generate_configs() { info "Generating NUT configuration" # /etc/nut/nut.conf — standalone mode sudo tee /etc/nut/nut.conf > /dev/null <<'NUTCONF' # Vigilar NUT configuration — standalone mode MODE=standalone NUTCONF # /etc/nut/ups.conf — UPS definition sudo tee /etc/nut/ups.conf > /dev/null < /dev/null <<'UPSDCONF' # Vigilar upsd configuration LISTEN 127.0.0.1 3493 UPSDCONF # /etc/nut/upsd.users — local monitoring user sudo tee /etc/nut/upsd.users > /dev/null <<'USERSCONF' [vigilar] password = vigilar_local upsmon master USERSCONF # /etc/nut/upsmon.conf — monitoring config sudo tee /etc/nut/upsmon.conf > /dev/null <<'MONCONF' # Vigilar upsmon configuration MONITOR ups@localhost 1 vigilar vigilar_local master MINSUPPLIES 1 SHUTDOWNCMD "/sbin/shutdown -h +0" POLLFREQ 15 POLLFREQALERT 5 HOSTSYNC 15 DEADTIME 45 RBWARNTIME 43200 NOCOMMWARNTIME 600 FINALDELAY 5 MONCONF # Secure the config files sudo chmod 0640 /etc/nut/ups.conf /etc/nut/upsd.conf /etc/nut/upsd.users /etc/nut/upsmon.conf sudo chown root:nut /etc/nut/ups.conf /etc/nut/upsd.conf /etc/nut/upsd.users /etc/nut/upsmon.conf 2>/dev/null || true ok "NUT configuration files written" } enable_services() { info "Enabling and starting NUT services" # Service names vary by distro local driver_svc="nut-driver" local server_svc="nut-server" local monitor_svc="nut-monitor" # On Arch, the services may be named differently if ! systemctl list-unit-files "${server_svc}.service" &>/dev/null; then if systemctl list-unit-files "upsd.service" &>/dev/null; then server_svc="upsd" monitor_svc="upsmon" driver_svc="nut-driver-enumerator" fi fi # Enable and start for svc in "$driver_svc" "$server_svc" "$monitor_svc"; do if systemctl list-unit-files "${svc}.service" &>/dev/null; then sudo systemctl enable "${svc}.service" 2>/dev/null || true sudo systemctl restart "${svc}.service" 2>/dev/null || warn "Could not start ${svc}.service — check UPS connection" fi done ok "NUT services enabled" } main() { info "=== Vigilar NUT Setup ===" echo install_nut UPS_DRIVER="" UPS_PORT="" UPS_DESC="" detect_ups generate_configs enable_services echo ok "=== NUT setup complete ===" info "Test with: upsc ups@localhost" info "Vigilar will monitor UPS at 127.0.0.1:3493 (ups name: 'ups')" } main "$@"