#!/bin/bash
#
# check_raspberry_voltage - Nagios plugin to report Raspberry Pi voltage
# rails (core, sdram_c, sdram_i, sdram_p) as performance data, and to check
# the power supply for under-voltage via "vcgencmd get_throttled".

PROGNAME=$(basename "$0")

STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

RAILS="core sdram_c sdram_i sdram_p"

print_usage() {
    echo "Usage: $PROGNAME"
    echo ""
    echo "Reports Raspberry Pi voltage rails (${RAILS// /, }) as performance"
    echo "data, and checks the power supply for under-voltage via"
    echo "'vcgencmd get_throttled'."
    echo ""
    echo "  -h             Show this help message"
}

while getopts "h" opt; do
    case $opt in
        h) print_usage; exit $STATE_OK ;;
        *) print_usage; exit $STATE_UNKNOWN ;;
    esac
done

if ! command -v vcgencmd >/dev/null 2>&1; then
    echo "UNKNOWN: vcgencmd command not found"
    exit $STATE_UNKNOWN
fi

STATUS_MSG=""
PERFDATA=""

for rail in $RAILS; do
    OUTPUT=$(vcgencmd measure_volts "$rail" 2>/dev/null)
    if ! [[ "$OUTPUT" =~ ^volt=([0-9]+\.[0-9]+)V$ ]]; then
        echo "UNKNOWN: Unable to read voltage for rail '$rail' (got: '$OUTPUT')"
        exit $STATE_UNKNOWN
    fi
    volt="${BASH_REMATCH[1]}"
    STATUS_MSG="${STATUS_MSG}${rail}=${volt}V, "
    PERFDATA="${PERFDATA}${rail}=${volt}V;;;; "
done

THROTTLED_OUTPUT=$(vcgencmd get_throttled 2>/dev/null)
if ! [[ "$THROTTLED_OUTPUT" =~ ^throttled=(0x[0-9a-fA-F]+)$ ]]; then
    echo "UNKNOWN: Unable to read throttled state (got: '$THROTTLED_OUTPUT')"
    exit $STATE_UNKNOWN
fi
THROTTLED_HEX="${BASH_REMATCH[1]}"
THROTTLED=$((THROTTLED_HEX))

# bit 0: under-voltage detected right now
# bit 16: under-voltage has occurred since boot (sticky, may be resolved by now)
UNDERVOLTAGE_NOW=$(( (THROTTLED >> 0) & 1 ))
UNDERVOLTAGE_OCCURRED=$(( (THROTTLED >> 16) & 1 ))

if [ "$UNDERVOLTAGE_NOW" -eq 1 ]; then
    STATE=$STATE_CRITICAL
    LABEL="CRITICAL"
    PSU_MSG="power supply under-voltage detected now"
elif [ "$UNDERVOLTAGE_OCCURRED" -eq 1 ]; then
    STATE=$STATE_WARNING
    LABEL="WARNING"
    PSU_MSG="power supply under-voltage occurred since last boot (currently ok)"
else
    STATE=$STATE_OK
    LABEL="OK"
    PSU_MSG="power supply ok"
fi

PERFDATA="${PERFDATA}throttled=${THROTTLED_HEX};;;; bit0=${UNDERVOLTAGE_NOW};;;0;1 bit16=${UNDERVOLTAGE_OCCURRED};;;0;1 undervoltage_now=${UNDERVOLTAGE_NOW};;;0;1 undervoltage_occurred=${UNDERVOLTAGE_OCCURRED};;;0;1"

echo "${LABEL}: ${PSU_MSG} (${STATUS_MSG%, }) | ${PERFDATA}"
exit $STATE
