feat(nut): report outage duration and battery % in ntfy
ONBATT records the epoch start time and appends current battery charge; ONLINE appends battery charge and the total outage duration (HH:mm:ss) computed from the recorded start, then clears the state. State lives in /run so it self-clears on reboot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -61,3 +61,8 @@ nut_ntfy_server: https://ntfy.jokester.fr
|
|||||||
|
|
||||||
# Path of the deployed NOTIFYCMD wrapper.
|
# Path of the deployed NOTIFYCMD wrapper.
|
||||||
nut_notify_script_path: /usr/local/bin/ups-notify
|
nut_notify_script_path: /usr/local/bin/ups-notify
|
||||||
|
|
||||||
|
# Where ups-notify records the epoch timestamp of the last ONBATT event, so the
|
||||||
|
# ONLINE notification can report total outage duration. Lives under /run so it
|
||||||
|
# is cleared on reboot (stale outage state is meaningless after a reboot).
|
||||||
|
nut_outage_state_file: /run/ups-notify-outage
|
||||||
|
|||||||
@@ -14,15 +14,34 @@ NTFY_TOKEN="{{ nut_ntfy_token }}"
|
|||||||
NTFY_TOKEN=""
|
NTFY_TOKEN=""
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
UPS_NAME="{{ nut_ups_name }}"
|
||||||
|
OUTAGE_STATE_FILE="{{ nut_outage_state_file }}"
|
||||||
|
|
||||||
MESSAGE="${1:-UPS event}"
|
MESSAGE="${1:-UPS event}"
|
||||||
EVENT="${NOTIFYTYPE:-UNKNOWN}"
|
EVENT="${NOTIFYTYPE:-UNKNOWN}"
|
||||||
HOST="$(uname -n)"
|
HOST="$(uname -n)"
|
||||||
|
|
||||||
|
# Current battery charge (%) as reported by the UPS. Empty if unavailable.
|
||||||
|
battery_charge() {
|
||||||
|
upsc "${UPS_NAME}@localhost" battery.charge 2>/dev/null | head -n1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Format a duration in whole seconds as HH:mm:ss.
|
||||||
|
format_duration() {
|
||||||
|
local total="$1"
|
||||||
|
printf '%02d:%02d:%02d' $((total / 3600)) $(((total % 3600) / 60)) $((total % 60))
|
||||||
|
}
|
||||||
|
|
||||||
case "$EVENT" in
|
case "$EVENT" in
|
||||||
ONBATT)
|
ONBATT)
|
||||||
|
# Record when line power was lost so ONLINE can report outage duration.
|
||||||
|
date +%s > "$OUTAGE_STATE_FILE" 2>/dev/null || \
|
||||||
|
logger -t ups-notify "Failed to write outage state file $OUTAGE_STATE_FILE"
|
||||||
TITLE="UPS on battery — $HOST"
|
TITLE="UPS on battery — $HOST"
|
||||||
PRIORITY="urgent"
|
PRIORITY="urgent"
|
||||||
TAGS="warning,electric_plug"
|
TAGS="warning,electric_plug"
|
||||||
|
charge="$(battery_charge)"
|
||||||
|
[[ -n "$charge" ]] && MESSAGE="$MESSAGE (battery ${charge}%)"
|
||||||
;;
|
;;
|
||||||
LOWBATT)
|
LOWBATT)
|
||||||
TITLE="UPS low battery — $HOST"
|
TITLE="UPS low battery — $HOST"
|
||||||
@@ -38,6 +57,17 @@ case "$EVENT" in
|
|||||||
TITLE="UPS back on line power — $HOST"
|
TITLE="UPS back on line power — $HOST"
|
||||||
PRIORITY="default"
|
PRIORITY="default"
|
||||||
TAGS="white_check_mark,zap"
|
TAGS="white_check_mark,zap"
|
||||||
|
charge="$(battery_charge)"
|
||||||
|
[[ -n "$charge" ]] && MESSAGE="$MESSAGE (battery ${charge}%)"
|
||||||
|
if [[ -r "$OUTAGE_STATE_FILE" ]]; then
|
||||||
|
start="$(cat "$OUTAGE_STATE_FILE" 2>/dev/null)"
|
||||||
|
if [[ "$start" =~ ^[0-9]+$ ]]; then
|
||||||
|
elapsed=$(( $(date +%s) - start ))
|
||||||
|
(( elapsed < 0 )) && elapsed=0
|
||||||
|
MESSAGE="$MESSAGE — outage lasted $(format_duration "$elapsed")"
|
||||||
|
fi
|
||||||
|
rm -f "$OUTAGE_STATE_FILE" 2>/dev/null || true
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
COMMBAD|NOCOMM)
|
COMMBAD|NOCOMM)
|
||||||
TITLE="UPS communication lost — $HOST"
|
TITLE="UPS communication lost — $HOST"
|
||||||
|
|||||||
Reference in New Issue
Block a user