#!/usr/local/bin/bash
#####
# This script gathers and outputs the CPU and drive
# temperatures in a format rrdtool can consume.
# Author: Seren Thompson
# Date: 2016-04-02
#####

# quit on errors
set -o errexit
# error on unset variables
set -o nounset

if [ "$(id -u)" != "0" ]; then
  echo "Error: this script needs to be run as root (for smartctl). Try 'sudo $0'" 1>&2
  exit 1
fi

sep=':'

# Return temperature for specified device, or 'N' (RRD code for no data).
function one-temp {
    local dev="$1"
    local devpath="/dev/$1"
    local temp=$( smartctl --nocheck=standby -A "$devpath" | \
		  grep -Ei '^194[[:space:]]+Temperature_Celsius' | \
		  cut -w -f 10 )
    # If no temp, indicate "no data" to RRD
    if [ -z "$temp" ]; then
	temp="U"
    fi
    echo $temp
}

# Get CPU ids from system (that's pretty stable)
numcpus=$(/sbin/sysctl -n hw.ncpu)
# Get drive device names out of rrd file
drivedevs=
# for i in $(/sbin/sysctl -n kern.disks | awk '{for (i=NF; i!=0 ; i--) if(match($i, '/da/')) print $i }' ); do
#   drivedevs="${drivedevs} ${i}"
# done
for dbase in $( rrdinfo temps-5min.rrd ); do
    if [[ "$dbase" =~ ^ds\[(ada[[:digit:]]+)\]\.index ]] ; then
	drivedevs="${drivedevs} ${BASH_REMATCH[1]}"
    fi
done

# Get CPU temperatures
data=
for (( i=0; i < ${numcpus}; i++ )); do
  t=`/sbin/sysctl -n dev.cpu.$i.temperature`
  data=${data}${sep}${t%.*}  # Append the temperature to the data string, removing anything after the decimal
done
# Get drive temperatures
for i in ${drivedevs}; do
  DevTemp=` one-temp "$i" `;
  if ! [[ "$DevTemp" == "" ]]; then
    data="${data}${sep}${DevTemp}"
  fi
done

# Strip any leading, trailing, or duplicate colons
echo "${data}" | sed 's/:::*/:/;s/^://;s/:$//'

