#!/usr/bin/bash # # ups/status.sh — query NUT UPS state + service health (read-only) # # Usage (run ON the target host via remote.sh): # PROX_HOST=pfv-tsys1 bash tests/remote.sh prox-file ups/status.sh # # shellcheck disable=SC2012 # ss/awk field extraction is intentional set -uo pipefail APC_NAME="${APC_NAME:-apc-smartups-c1500}" TRIPP_NAME="${TRIPP_NAME:-tripp-lite-ups}" echo "======================================================" echo " NUT UPS Status on $(hostname)" echo "======================================================" echo "" echo "--- Services ---" for svc in "nut-driver@${APC_NAME}" "nut-driver@${TRIPP_NAME}" nut-server nut-monitor; do if systemctl list-unit-files "$svc" >/dev/null 2>&1; then printf " %-42s " "$svc" systemctl is-active "$svc" 2>/dev/null || echo "(unknown)" fi done for ups in "$APC_NAME" "$TRIPP_NAME"; do echo "" echo "--- ${ups} ---" if upsc "${ups}@localhost" >/tmp/.nutstatus.$$ 2>&1; then awk -v u="$ups" ' BEGIN{printf " %s\n", u} /^battery\.charge:/ {printf " battery.charge: %s\n", $3} /^battery\.runtime:/ {printf " battery.runtime: %ss (%.0f min)\n", $3, $3/60} /^battery\.voltage:/ {printf " battery.voltage: %s\n", $3} /^ups\.status:/ {printf " ups.status: %s\n", $3} /^ups\.load:/ {printf " ups.load: %s%%\n", $3} /^ups\.power:/ {printf " ups.power: %s\n", $3} /^ups\.realpower:/ {printf " ups.realpower: %s W\n", $3} /^input\.voltage:/ {printf " input.voltage: %s\n", $3} /^output\.voltage:/ {printf " output.voltage: %s\n", $3} /^ups\.model:/ {printf " ups.model: %s\n", $3} /^ups\.serial:/ {printf " ups.serial: %s\n", $3} /^device\.mfr:/ {printf " device.mfr: %s\n", $3} ' /tmp/.nutstatus.$$ echo " (full dump: upsc ${ups}@localhost)" else echo " NOT RESPONDING:" sed 's/^/ /' /tmp/.nutstatus.$$ fi rm -f /tmp/.nutstatus.$$ done echo "" echo "--- upsd LISTEN sockets ---" ss -ltnp 2>/dev/null | grep -E "3493|nut" | sed 's/^/ /' || echo " (upsd not listening on 3493)" echo "" echo "======================================================"