#!/bin/bash
# Generate graphs of various data from apcupsd using gnuplot.
# This script works closely with a cron job.  Make sure that
# the cron interval and the amount of data you are keeping
# will produce the right time range for you.

# Locations
APCACCESS=/sbin/apcaccess
GNUPLOT=/usr/bin/gnuplot
DATAPATH=/var/log/ups
HTMLPATH=/var/www/htdocs/ups
GDFONTPATH=/usr/share/fonts/TTF
TEMPDIR=/tmp

# Graph display options.
FONT=LucidaGrande

TITLE_FONTSIZE=16
X_LABEL_FONTSIZE=9
Y_LABEL_FONTSIZE=10
TIC_LABEL_FONTSIZE=7

LINEV_STYLE=lines
LINEV_LINE_COLOR=#FF0000
LINEV_LINE_WEIGHT=1

LOADPCT_STYLE=impulses
LOADPCT_LINE_COLOR=#0000FF
LOADPCT_LINE_WEIGHT=1

TIMELEFT_STYLE=impulses
TIMELEFT_LINE_COLOR=#32CD32
TIMELEFT_LINE_WEIGHT=1

# HTML options.
REFRESH=300
HTMLFONT=Helvetica
APCACCESSINFO="$($APCACCESS | sed ':a;N;$!ba;s/\n/\<br\>\n/g')"

# Number of lines to keep in voltage and load data files.
# At 5 minute intervals, 20160 = 1 weeks.
LINEV_SIZE=4032
LOADPCT_SIZE=4032
TIMELEFT_SIZE=4032

# End of common user variables.

UPSMODEL="$(apcaccess | grep APCMODEL | sed s/APCMODEL\ \:\ //)"

# Graph titles and X & Y axis labels.
# X axis labels are calculated from the first and last dates
# in the data files.
LINEV_TITLE="Line Voltage"
LINEV_X_LABEL="$(head -1 $DATAPATH/voltages |    cut -c 1,2,3,4,5,6 | sed s/\-/\ /)  -  $(tail -1 $DATAPATH/voltages | cut -c 1,2,3,4,5,6 | sed s/\-/\ /)"
LINEV_Y_LABEL="Volts"

LOADPCT_TITLE="Battery Load"
LOADPCT_X_LABEL="$(head -1 $DATAPATH/loads |     cut -c 1,2,3,4,5,6 | sed s/\-/\ /)  -  $(tail -1 $DATAPATH/loads | cut -c 1,2,3,4,5,6 |    sed s/\-/\ /)"
LOADPCT_Y_LABEL="%"

TIMELEFT_TITLE="Time Remaining on Battery"
TIMELEFT_X_LABEL="$(head -1 $DATAPATH/timeleft | cut -c 1,2,3,4,5,6 | sed s/\-/\ /)  -  $(tail -1 $DATAPATH/timeleft | cut -c 1,2,3,4,5,6 | sed s/\-/\ /)"
TIMELEFT_Y_LABEL="Minutes"

# Query UPS and collect data and timestamps in trimmed files.
$APCACCESS | grep 'LINEV\|END' |    tac | awk '{printf "%s ",$0} END {print ""}' | awk '{print $5"-"$6"-"$7" "$12}' >> $DATAPATH/voltages
$APCACCESS | grep 'LOADPCT\|END' |  tac | awk '{printf "%s ",$0} END {print ""}' | awk '{print $5"-"$6"-"$7" "$12}' >> $DATAPATH/loads
$APCACCESS | grep 'TIMELEFT\|END' | tac | awk '{printf "%s ",$0} END {print ""}' | awk '{print $5"-"$6"-"$7" "$12}' >> $DATAPATH/timeleft
tail -$LINEV_SIZE $DATAPATH/voltages 	> $TEMPDIR/linev_input    && cp $TEMPDIR/linev_input 	$DATAPATH/voltages
tail -$LOADPCT_SIZE $DATAPATH/loads 	> $TEMPDIR/loadpct_input  && cp $TEMPDIR/loadpct_input 	$DATAPATH/loads
tail -$TIMELEFT_SIZE $DATAPATH/timeleft > $TEMPDIR/timeleft_input && cp $TEMPDIR/timeleft_input $DATAPATH/timeleft

# Clean up occasional bad data in files.
grep -v "\-\-" $DATAPATH/voltages	> $TEMPDIR/linev_input 	  && cp $TEMPDIR/linev_input 		$DATAPATH/voltages
grep -v "\-\-" $DATAPATH/loads 		> $TEMPDIR/loadpct_input  && cp $TEMPDIR/loadpct_input 		$DATAPATH/loads
grep -v "\-\-" $DATAPATH/timeleft	> $TEMPDIR/timeleft_input && cp $TEMPDIR/timeleft_input 	$DATAPATH/timeleft

# The graphed voltage range shall be the lowest recorded voltage minus 5,
# to the highest recorded voltage plus 5.
LINEV_Y_MIN=$(echo $(cat $DATAPATH/voltages | awk '{print $2}' | sort | uniq | head -1) - 5.0 | bc)
LINEV_Y_MAX=$(echo $(cat $DATAPATH/voltages | awk '{print $2}' | sort | uniq | tail -1) + 5.0 | bc)

# Send creation specs to gnuplot for line voltage graph.
echo "
set term png font '$FONT,$TIC_LABEL_FONTSIZE'
set title '$LINEV_TITLE' font '$FONT,$TITLE_FONTSIZE'
set nokey
set border
set mytics '1'
set grid ytics
set xdata time
set timefmt '%b-%d-%H:%M:%S'
set format x \"%b %d \n %l:%M%p\"
set yrange [115:$LINEV_Y_MAX]
set xlabel \"\n$LINEV_X_LABEL\" font '$FONT,$X_LABEL_FONTSIZE'
set ylabel '$LINEV_Y_LABEL' font '$FONT,$Y_LABEL_FONTSIZE'
set format y '%10.2f'
set ytics '1'
set mytics '1'
plot '$DATAPATH/voltages' using 1:2  with $LINEV_STYLE lw $LINEV_LINE_WEIGHT lc rgb '$LINEV_LINE_COLOR'
" | $GNUPLOT > $HTMLPATH/LineVoltage.png

# Send creation specs to gnuplot for battery load graph.
echo "
set term png font '$FONT,$TIC_LABEL_FONTSIZE' 
set title '$LOADPCT_TITLE' font '$FONT,$TITLE_FONTSIZE'
set nokey
set border
set mytics '1'
set grid ytics
set xdata time
set timefmt '%b-%d-%H:%M:%S'
set format x \"%b %d \n %l:%M%p\"
set yrange [0.0:100.0]
set xlabel \"\n$LOADPCT_X_LABEL\" font '$FONT,$X_LABEL_FONTSIZE'
set ylabel '$LOADPCT_Y_LABEL' font '$FONT,$Y_LABEL_FONTSIZE'
set format y '%10.2f'
set ytics '5'
set mytics '1'
plot '$DATAPATH/loads' using 1:2  with $LOADPCT_STYLE lw $LOADPCT_LINE_WEIGHT lc rgb '$LOADPCT_LINE_COLOR'
" | $GNUPLOT > $HTMLPATH/BatteryLoad.png

# Send creation specs to gnuplot for time remaining graph.
echo "
set term png font '$FONT,$TIC_LABEL_FONTSIZE' 
set title '$TIMELEFT_TITLE' font '$FONT,$TITLE_FONTSIZE'
set nokey
set border
set mytics '1'
set grid ytics
set xdata time
set timefmt '%b-%d-%H:%M:%S'
set format x \"%b %d \n %l:%M%p\"
set yrange [0.0:60.0]
set xlabel \"\n$TIMELEFT_X_LABEL\" font '$FONT,$X_LABEL_FONTSIZE'
set ylabel '$TIMELEFT_Y_LABEL' font '$FONT,$Y_LABEL_FONTSIZE'
set format y '%10.2f'
set ytics '5'
set mytics '1'
plot '$DATAPATH/timeleft' using 1:2  with $TIMELEFT_STYLE lw $TIMELEFT_LINE_WEIGHT lc rgb '$TIMELEFT_LINE_COLOR'
" | $GNUPLOT > $HTMLPATH/TimeLeft.png

# Create plain HTML page.
echo "
<HTML>
<TITLE>$UPSMODEL Statistics</TITLE>

<META HTTP-EQUIV="Refresh" CONTENT="$REFRESH">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">

<BODY>
<DIV ALIGN="center">
		<IMG SRC="LineVoltage.png">
		<BR><BR>
		<IMG SRC="BatteryLoad.png">
		<BR><BR>
		<IMG SRC="TimeLeft.png">
		<BR><BR>
</DIV>
<DIV ALIGN="left">
<FONT="$HTMLFONT">$APCACCESSINFO</FONT>
</DIV>
" > $HTMLPATH/index.html

