Skip to content

Instantly share code, notes, and snippets.

@eljojo
Created February 25, 2025 01:35
Show Gist options
  • Save eljojo/a272cb68c766524c66808dffb67eee27 to your computer and use it in GitHub Desktop.
Save eljojo/a272cb68c766524c66808dffb67eee27 to your computer and use it in GitHub Desktop.
script to regularly test UPS using NUT
#!/bin/bash
set -euo pipefail
# Configuration
UPS_NAME="my-ups"
UPS_USER="ups-admin"
UPS_PASS="super-secret-password"
EMAIL_RECIPIENT="[email protected]"
CHECK_INTERVAL=10 # Seconds between status checks
DEBUG=0 # Default: Normal mode (no emails unless failure)
# Determine test mode
MODE="quick"
UPS_TEST_COMMAND="test.battery.start.quick"
MAX_RETRIES=60 # ~10 minutes timeout for quick mode
if [[ $# -gt 0 ]]; then
case "$1" in
full)
MODE="full"
UPS_TEST_COMMAND="test.battery.start.deep"
MAX_RETRIES=2160 # 6 hours timeout for full mode
;;
debug)
DEBUG=1
;;
full-debug)
MODE="full"
UPS_TEST_COMMAND="test.battery.start.deep"
MAX_RETRIES=2160
DEBUG=1
;;
*)
echo "Usage: $0 [full|debug|full-debug]"
exit 1
;;
esac
fi
EMAIL_SUBJECT="🔋 Testing UPS ($MODE mode)"
send_email() {
local subject="$1"
local message="$2"
echo "$message" | mail -s "$subject" "$EMAIL_RECIPIENT"
}
log() {
local message="$1"
echo "$message"
}
fail() {
local message="$1"
send_email "⚠️ UPS Test Failed ($MODE mode)" "$message"
exit 1
}
# Ensure UPS is in "OL" before beginning
UPS_STATUS=$(upsc "$UPS_NAME" | grep "ups.status" | awk '{print $2}')
if [[ "$UPS_STATUS" != "OL" ]]; then
fail "UPS is not in OL state before starting test. Current status: $UPS_STATUS"
fi
# Start UPS test
UPS_CMD_OUTPUT=$(upscmd -u "$UPS_USER" -p "$UPS_PASS" "$UPS_NAME" "$UPS_TEST_COMMAND" 2>&1) || fail "UPS test command failed: $UPS_CMD_OUTPUT"
log "UPS test ($MODE mode) command sent: $UPS_CMD_OUTPUT"
# Ensure the test actually starts before proceeding
log "Waiting for UPS test to begin..."
for ((i=1; i<=30; i++)); do
UPS_TEST_RESULT=$(upsc "$UPS_NAME" | grep "ups.test.result" | awk -F": " '{print $2}')
if [[ "$UPS_TEST_RESULT" == "In progress" ]]; then
log "UPS test is running: $UPS_TEST_RESULT"
break
fi
if [[ $i -eq 30 ]]; then
fail "UPS test did not start after waiting 30 attempts."
fi
sleep 5
done
# Wait for test result to be returned
log "Waiting for UPS test result..."
for ((i=1; i<=MAX_RETRIES; i++)); do
UPS_TEST_RESULT=$(upsc "$UPS_NAME" | grep "ups.test.result" | awk -F": " '{print $2}')
if [[ "$UPS_TEST_RESULT" != "In progress" ]]; then
log "UPS test finished: $UPS_TEST_RESULT"
break
fi
if [[ $i -eq MAX_RETRIES ]]; then
fail "UPS test never completed. Final test result: $UPS_TEST_RESULT"
fi
sleep "$CHECK_INTERVAL"
done
# Wait for UPS to return to "OL CHRG" (ensures battery discharged and is recharging)
log "Waiting for UPS to return to OL CHRG..."
for ((i=1; i<=MAX_RETRIES; i++)); do
UPS_STATUS=$(upsc "$UPS_NAME" | grep "ups.status" | awk '{print $2, $3}')
if [[ "$UPS_STATUS" == "OL CHRG" ]]; then
log "UPS is back online and recharging!"
break
fi
if [[ $i -eq MAX_RETRIES ]]; then
fail "UPS never transitioned to 'OL CHRG'. Final status: $UPS_STATUS"
fi
sleep "$CHECK_INTERVAL"
done
# Final test validation
if [[ "$UPS_TEST_RESULT" != "Done and passed" ]]; then
fail "UPS test failed. Result: $UPS_TEST_RESULT"
fi
log "✅ UPS test ($MODE mode) result: $UPS_TEST_RESULT"
# Send success email **only in debug mode**
[[ "$DEBUG" -eq 1 ]] && send_email "✅ UPS Test Completed ($MODE mode)" "UPS test successfully completed.\nResult: $UPS_TEST_RESULT"
log "✅ UPS test ($MODE mode) completed successfully."
[ups-admin]
password = super-secret-password
instcmds = test.battery.start.deep
instcmds = test.battery.start.quick
instcmds = test.battery.stop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment