#!/bin/bash

# Variables

# Overall prefix for device
OIDprefix="1.3.6.1.4.1.318.1.1.10.3"

# Temperature Units. 1=C 2=F
tempUnits=0
tempUnitsOID="$OIDprefix.12.11.0"

# Probe prefix
probeOIDprefix="$OIDprefix.13.1.1"

# Name of probe
probeName="BLANK"
probeName_data=""
probeNameOID="$probeOIDprefix.2"

# Temperature reading
temperature=0
temperatureOID="$probeOIDprefix.3"

# High (crit) temperature thresh
tempCritHighThresh=0
tempCritHighThreshOID="$probeOIDprefix.12"

# High (warn) temperature threshold
tempHighThresh=0
tempHighThreshOID="$probeOIDprefix.4"

# Low (warn) temperature threshold
tempLowThresh=0
tempLowThreshOID="$probeOIDprefix.5"

# Low (crit) temperature thresh
tempCritLowThresh=0
tempCritLowThreshOID="$probeOIDprefix.13"

# Humidity reading
humidity=0
humidityOID="$probeOIDprefix.6"

# High (crit) humidity threshold
humidCritHighThresh=0
humidCritHighThreshOID="$probeOIDprefix.14"

# High (warn) humidity threshold
humidHighThresh=0
humidHighThreshOID="$probeOIDprefix.7"

# Low (warn) humidity threshold
humidLowThresh=0
humidLowThreshOID="$probeOIDprefix.8"

# Low (crit) humidity threshold
humidCritLowThresh=0
humidCritLowThreshOID="$probeOIDprefix.15"

# Humidity difference
# Warning will not trigger until humidity goes below $humidLowThresh-$humidDelta
# or above $humidHighThresh+$humidDelta
humidDelta=5

# Relay outlet info
relayOIDprefix="$OIDprefix.15.1.1"
relayName=""
relayNameOID="$relayOIDprefix.2.1"
relayStatus=0
relayStatusOID="$relayOIDprefix.3.1"
relayNorm=0
relayNormOID="$relayOIDprefix.4.1"

# Switched outlet info
outletOIDprefix="$OIDprefix.16.1.1"
outletName=""
outletNameOID="$outletOIDprefix.2.1"
outletStatus=0
outletStatusOID="$outletOIDprefix.3.1"
outletNorm=0
outletNormOID="$outletOIDprefix.4.1"

# Output vars
textString=""
subTemp=""
subHumid=""
subReturn=0
dataString=""
outString=""
returnStatus=0
verbose=0
sensorCount=""
HSTNAME=""
relayGet=0
outletGet=0

set -e
while getopts "H:c:vro" opt; do
    case $opt in
    H ) # Specify hostname
        HSTNAME="$OPTARG" # Hostname reserved keyword
        ;;
    v )
        verbose=1
        ;;
    c )
        sensorCount="$OPTARG"
        ;;
    r )
        relayGet=1
        ;;
    o )
        outletGet=1
        ;;
    d )
        humidDelta="$OPTARG"
        ;;
    ? )
        echo "script usage: $(basename $0) -H hostname -c sensorCount [-v] " >&2
        exit 3
        ;;
    esac
done

if ! [[ $HSTNAME ]] ; then
    echo "UNKNOWN - Please provide target hostname."
    exit 3
elif ! [[ $sensorCount ]] ; then
    echo "UNKNOWN - Please provide sensor count with -c flag."
    exit 3
fi

# Shorter function for SNMP
function snmp () {
    echo $(snmpwalk -c public -v 1 -Ovq $HSTNAME $1)
}

# Convert C to F
function ctof () {
    echo $(echo "scale=1; ($1*(9/5)) + 32" | bc -l)
}

# Verbose out
function vout () {
    if (($verbose == 1)) ; then echo $1 ; fi
}

counter=0
tempUnits=$(snmp $tempUnitsOID)
while [[ $probeName ]] && (($counter < $sensorCount)); do
    # Reset values
    subReturn=0
    subTemp=""
    subHumid=""

    # Counter keeps track of which sensor.
    counter=$(($counter + 1))
    vout "Checking probe $counter"

    # Grab the probe name, sub spaces for underscores, remove colons.
    # probeName is kept for display purposes. probeName_data is used
    # for performance counters.
    vout "- Getting probe name for probe $counter"
    probeName=$(snmp $probeNameOID.$counter | tr -d '"')
    probeName_data="${probeName// /_}"
    probeName_data="${probeName_data//:/}"

### TEMP CHECK
    vout "- Probe name $probeName. Getting temperature."
    # Grab values from probe
    temperature=$(snmp $temperatureOID.$counter)
    tempCritHighThresh=$(snmp $tempCritHighThreshOID.$counter)
    tempHighThresh=$(snmp $tempHighThreshOID.$counter)
    tempLowThresh=$(snmp $tempLowThreshOID.$counter)
    tempCritLowThresh=$(snmp $tempCritLowThreshOID.$counter)

    # If values have been returned in C, convert to F.
    if (($tempUnits == 1)) ; then
        temperatureD=$(ctof $temperature)
        tempCritHighThreshD=$(ctof $tempCritHighThresh)
        tempHighThreshD=$(ctof $tempHighThresh)
        tempLowThreshD=$(ctof $tempLowThresh)
        tempCritLowThreshD=$(ctof $tempCritLowThresh)
    else
        temperatureD=$temperature
        tempCritHighThreshD=$tempCritHighThresh
        tempHighThreshD=$tempHighThresh
        tempLowThreshD=$tempLowThresh
        tempCritLowThreshD=$tempCritLowThresh
    fi

    # Checking status
    if (($temperature >= $tempLowThresh)) && (($temperature <= $tempHighThresh)) ; then
        subTemp+="$probeName temp $temperatureD. "
    elif (($temperature < $tempCritLowThresh)) || (($temperature > $tempCritHighThresh)) ; then
        subTemp+="$probeName temp $temperatureD: CL$tempCritLowThreshD WL$tempLowThreshD WH$tempHighThreshD CH$tempHighThreshD. "
        subReturn=$(($subReturn>1 ? $subReturn : 1))
    elif (($temperature < $tempLowThresh)) || (($temperature > $tempHighThresh)) ; then
        subTemp+="$probeName temp $temperatureD: CL$tempCritLowThreshD WL$tempLowThreshD WH$tempHighThreshD CH$tempHighThreshD. "
        subReturn=$(($returnStatus>2 ? $subReturn : 2))
    else
        subTemp+="$probeName temp $temperatureD: CL$tempCritLowThreshD WL$tempLowThreshD WH$tempHighThreshD CH$tempHighThreshD. "
        subReturn=3
    fi

    # Add info to out string
    dataString+="${probeName_data}_tempF=$temperatureD;$tempLowThreshD:$tempHighThreshD;$tempCritLowThreshD:$tempCritHighThreshD; "
    
    vout "-- $probeName temperature $temperature. CL$tempCritLowThresh WL$tempLowThresh WH$tempHighThresh CH$tempHighThresh."
    vout "-- Sub return status is now $subReturn"

### HUMID CHECK
    vout "- Getting humidity."
    # Grab humidity from probe
    humidity=$(snmp $humidityOID.$counter)
    # If humidity is 0, no humidity probe
    if (($humidity != 0)) ; then
        vout "-- Humidity non-zero, pulling other humidity data"
        # Get thresholds
        humidCritHighThresh=$(snmp $humidCritHighThreshOID.$counter)
        humidHighThresh=$(snmp $humidHighThreshOID.$counter)
        humidLowThresh=$(snmp $humidLowThreshOID.$counter)
        humidCritLowThres=$(snmp $humidCritLowThreshOID.$counter)

        # Account for hysteresis
        humidLowThreshD=$humidLowThresh
        humidHighThreshD=$humidHighThresh
        humidLowThresh=$(($humidLowThresh-$humidDelta))
        humidHighThresh=$(($humidHighThresh+$humidDelta))
        
        # Checking value
        if (($humidity >= $humidLowThresh)) && (($humidity <= $humidHighThresh)) ; then
            subHumid+="$probeName humid $humidity. "
        elif (($humidity < $humidCritLowThresh)) || (($humidity > $humidCritHighThresh)) ; then
            subHumid+="$probeName humid $humidity: CL$humidCritLowThresh WL$humidLowThreshD(-$humidDelta) WH$humidHighThreshD(+$humidDelta) CH$humidHighThresh. "
            subReturn=$(($subReturn>1 ? $subReturn : 1))
        elif (($humidity < $humidLowThresh)) || (($humidity > $humidHighThresh)) ; then
            subHumid+="$probeName humid $humidity: CL$humidCritLowThresh WL$humidLowThreshD(-$humidDelta) WH$humidHighThreshD(+$humidDelta) CH$humidHighThresh. "
            subReturn=$(($subReturn>2 ? $subReturn : 2))
        else
            subHumid+="$probeName humid $humidity: CL$humidCritLowThresh WL$humidLowThreshD(-$humidDelta) WH$humidHighThreshD(+$humidDelta) CH$humidHighThresh. "
            subReturn=3
        fi

        # Add data to data string
        dataString+="${probeName_data}_humidity=$humidity;$humidLowThresh:$humidHighThresh;$humidCritLowThresh:$humidCritHighThresh; "
        vout "-- $probeName humidity $humidity. CL$humidCritLowThresh WL$humidLowThreshD(-$humidDelta) WH$humidHighThreshD(+$humidDelta) CH$humidHighThresh. "
        vout "-- Sub return status is now $subReturn"
    else
        vout "-- Humidity 0 indicates probe does not have humidity capability."
    fi

    if   (($subReturn == 0)) ; then textString+="OK - " ;
    elif (($subReturn == 1)) ; then textString+="WARN - " ;
    elif (($subReturn == 2)) ; then textString+="UNKN - " ;
    elif (($subReturn == 3)) ; then textString+="CRIT - " ; fi

    textString+=$subTemp
    textString+=$subHumid

    textString+="-- "
done
# Remove the last separator
textString=${textString% -- *}

# Grab relay info
if (($relayGet == 1)) ; then
    relayName=$(snmp $relayNameOID | tr -d '"')
    relayStatus=$(snmp $relayStatusOID)
#   relayNorm=$(snmp $relayNormOID) # Not currently used for checking
    dataString+="${relayName}_relay=$relayStatus; "
fi

# Grab switched info
if (($outletGet == 1)) ; then
    outletName=$(snmp $outletNameOID)
    outletStatus=$(snmp $outletStatusOID)
    dataString+="${outletName}_outlet=$outletStatus; "
fi

if (($returnStatus == 0)) ; then
    outString+="OK - Probe data nominal. -- "
elif (($returnStatus == 1)) ; then
    outString+="WARNING - Probe data outside normal range. -- "
elif (($returnStatus == 2)) ; then
    outString+="UNKNOWN - One or more probes provided invalid data. -- "
    returnStatus=3 # Switched due to calculations and nagios
elif (($returnStatus == 3)) ; then
    outString+="CRITICAL - Probe data for one or more probes is outside of threshold. Script probe count may be incorrect."
    returnStatus=2
else 
    # Set return status to unknown
    returnStatus=3
    outString+="UNKNOWN - Script returned invalid data. -- "
fi
outString+=$textString
outString+="|"
outString+=$dataString
echo $outString
exit $returnStatus

