summaryrefslogtreecommitdiff
path: root/thinkwatt
diff options
context:
space:
mode:
Diffstat (limited to 'thinkwatt')
-rwxr-xr-xthinkwatt304
1 files changed, 0 insertions, 304 deletions
diff --git a/thinkwatt b/thinkwatt
deleted file mode 100755
index aa408b9..0000000
--- a/thinkwatt
+++ /dev/null
@@ -1,304 +0,0 @@
-#!/bin/bash
-#
-# thinkwatt:
-# record power consumption, calculate average and create a gnuplot graph
-#
-# TO-DO:
-# * add more options (e.g. for specifying a different gnuplot title or png output)
-# * allow time input in minutes and hours
-
-# utilities {{{
-message() {
- cat << EOF
-usage: thinkwatt -r (seconds) (-q) (-o file)
- thinkwatt [ -p | -a ] (-q) file
-
-options:
- -r, --record record power consumption and optionally create a graph from the gathered data
- -p, --plot create a plot image from a specified data file
- -a, --average calculate the average power consumption from a specified data file
- -q, --quiet makes thinkwatt less chatty
- -o, --output the output file. can be prepended by a path.
- -h, --help show this help text
-
-examples:
- thinkwatt -r (will record to a temp file until cancelled)
- thinkwatt -r 300 -o /foo/bar/consumption.dat (will record for 5 minutes to the specified file)
- thinkwatt -p /foo/bar/consumption.dat (will create a graph from the specified file)
-EOF
- exit 1
-}
-
-errorout() { echo "error: $*" >&2; exit 1; }
-
-check_ac() {
- [[ "$quiet" ]] && return 0
- [[ $(cat /sys/class/power_supply/*/online) = 0 ]] || echo 'it seems your AC adapter is plugged in'
-}
-check_datafile() {
- [[ -f "$@" ]] || errorout "$@ does not exist"
- local valid_file=$(file "$@" | grep -s "^$@: ASCII text$")
- [[ "$valid_file" ]] || errorout "$@ is not a valid data file"
- local valid_data=$(cat "$@" | grep -s '^[0-9]*[,.]\?.*[0-9]$')
- [[ "$valid_data" ]] || errorout "$@ does not contain valid data"
-}
-countdown() {
- [[ "$quiet" ]] || echo "ctrl+c to plot/exit"
- if [[ "$seconds" =~ ^[0-9]+$ ]];then
- # count down
- secs="$seconds"
- while [ "$secs" -gt 0 ];do
- [[ "$die" == yes ]] && return 0
- sleep 1 &
- cat "$powerfile" >> "$tmpfile1"
- printf "\rrecording (%02d/$seconds)" $((secs))
- secs=$(( $secs - 1 ))
- wait
- done
- else
- # count up
- secs=1
- while true;do
- [[ "$die" == yes ]] && return 0
- sleep 1 &
- cat "$powerfile" >> "$tmpfile1"
- printf "\rrecording ($secs)"
- secs=$(( $secs + 1 ))
- wait
- done
- fi
- echo
-}
-# if we abort the recording process with ctrl+c this will give the option to plot the already recorded data
-trap ctrl_c INT
-function ctrl_c() {
- echo
- read -p "plot data? y/n "
- [[ "$REPLY" = "y" ]] && die=yes || exit 0
-}
-# }}}
-
-# default output dir and png file {{{
-# use $TDIR to have thinkwatt save files in a different directory.
-# thinkwatt will save two files:
-# 1) a .plt file (containing plot instructions) in case you want to reuse/modify it
-# 2) a .png file (the plot graphic)
-TDIR="/tmp/thinkwatt"
-PLOTFILE="$TDIR"/$$.plt
-# }}}
-
-# record {{{
-record() {
-
- local seconds="$1"
-
- #[[ "$seconds" =~ ^[0-9]+$ ]] || errorout 'please specify the time in seconds"
- [[ -d "$output" ]] && errorout "$output is a directory"
- [[ -d "$TDIR" ]] || mkdir -p "$TDIR" 2>/dev/null || errorout "could not create $TDIR"
-
- if [[ -f "$output" ]];then
- read -p "overwrite $output? y/n "
- [[ "$REPLY" = "y" ]] || exit 0
- elif [[ -e "$output" ]];then
- errorout "$output exists and can/should not be written to"
- fi
-
- local tmpfile1=/tmp/$$.dat
- local tmpfile="$TDIR"/$$.dat
-
- if [[ "$output" ]];then
- local dir=$(dirname "$output")
- local file=$(basename "$output")
- [[ -d "$dir" ]] || mkdir -p "$dir"
- [[ -w "$dir" ]] || errorout "you don't have permissions to write to $dir"
-
- outputfile="$output"
- [[ "$dir" ]] && TDIR="$dir"
- PNGFILE="$TDIR"/$(basename "$file" .dat).png
- #PLOTFILE="$TDIR"/$(basename "$output" .dat).plt
- else
- [[ -w "$(pwd)" ]] || errorout "you don't have permissions to write to $(pwd)"
- local file=$(basename "$tmpfile")
- outputfile="$tmpfile"
- local istemp=true
- fi
-
- SMAPI=$(lsmod | grep -s tp_smapi)
- if [[ "$SMAPI" ]];then
- local powerfile=/sys/devices/platform/smapi/BAT0/power_now
- else
- echo "for more accurate results with thinkpads use tp_smapi"
- local powerfile=/sys/class/power_supply/BAT0/power_now
- fi
-
- touch "$tmpfile1" || errorout "could not create $tmpfile1"
- trap "rm $tmpfile1" EXIT
-
- # do the actual recording included in countdown()
- countdown
-
- # file formatting
- if [[ "$SMAPI" ]];then
- # we strip the leading "-" from the data file
- sed -i 's/-//g' "$tmpfile1"
- else
- # strip the trailing last 3 characters
- sed -i 's/.\{3\}$//' "$tmpfile1"
- fi
- # and divide by 1000 to convert from mW to W
- cat "$tmpfile1" | awk '{print $1/1000}' > "$tmpfile"
-
- [[ "$output" ]] && mv "$tmpfile" "$output"
-
- [[ "$quiet" ]] || echo average was $(average "$outputfile") W
-
- plot "$outputfile"
-
-}
-# }}}
-
-# calculate average {{{
-average() {
-
- [[ "$@" ]] || errorout 'please specify a file to read from.'
- [[ -f "$@" ]] || errorout 'file not found.'
- check_datafile "$@"
-
- awk 'BEGIN{s=0;}{s+=($1);}END{print s/NR;}' "$@"
-
-}
-# }}}
-
-# make the plot file {{{
-makeplotfile() {
-
- cat << EOF
-# gnuplot file
-# created by thinkwatt
-# $DATE
-
-set title "$TITLE"
-set xlabel "$XLABEL"
-set ylabel "$YLABEL"
-set terminal $TERMINAL
-set output "$PNGFILE"
-EOF
- [[ "$YRANGE" ]] && echo "set yrange $YRANGE"
- [[ "$XRANGE" ]] && echo "set yrange $YRANGE"
- [[ "$GRID" == yes ]] && echo "set grid"
- [[ "$YTICS" ]] && echo "set ytics $YTICS"
- [[ "$MYTICS" ]] && echo "set mytics $MYTICS"
- [[ "$XTICS" ]] && echo "set xtics $XTICS"
- [[ "$MXTICS" ]] && echo "set mxtics $MXTICS"
- [[ "$GRIDSET" ]] && echo "set grid $GRIDSET"
-
- echo
- if [[ "$TITLE1" ]];then
- echo "plot \"$datafile\" using (\$1) with lines title \"$TITLE1\" lt 2, \\"
- else
- echo "plot \"$datafile\" using (\$1) with lines lt 2, \\"
- fi
-
- if [[ "$TITLE2" ]];then
- if [[ "$avg" ]];then
- echo "\"$datafile\" using (\$1) smooth bezier title \"$TITLE2\" lt 1, \\"
- else
- echo "\"$datafile\" using (\$1) smooth bezier title \"$TITLE2\" lt 1"
- fi
- else
- if [[ "$avg" ]];then
- echo "\"$datafile\" using (\$1) smooth bezier lt 1, \\"
- else
- echo "\"$datafile\" using (\$1) smooth bezier lt 1"
- fi
- fi
-
- [[ "$avg" ]] && echo "$avg title \"$file (average, $avg W)\""
-
-}
-# }}}
-
-# do the plotting
-plot() {
-
- # check if we have gnuplot and $TDIR is present
- have_gnuplot=$(find $(sed 's/:/ /g' <<<$PATH) 2>/dev/null | grep -is gnuplot)
- [[ "$have_gnuplot" ]] || errorout 'please install gnuplot first'
- [[ -d "$TDIR" ]] || mkdir -p "$TDIR" || errorout "could not create $TDIR"
-
- # is input file a valid data file?
- local datafile="$@"
- check_datafile "$datafile"
- [[ "$datafile" ]] || errorout 'please specify a file to read from.'
- [[ -f "$datafile" ]] || errorout 'filplotfilee not found.'
-
- # define some of the variables for the plot file
- DATE=$(date +%Y-%m-%d,\ %T)
- TITLE="power consumption of my laptop, created by thinkwatt on $DATE"
- XLABEL="sec (seconds)"
- YLABEL="W (Watt)"
- TERMINAL="png"
- GRID=yes
- #TITLE1="your custom title for line1"
- #TITLE2="your custom title for line2"
- #TITLE3="your custom title for line3"
- # some more options for gnuplot, enable and modify them here if you like
- MYTICS=2
- MXTICS=2
- #YTICS=1
- #XTICS=(better leave this alone)
- GRIDSET="mytics"
- #YRANGE="[4000:16000]"
- #XRANGE="[0:2000]"
- # moar
- local avg=$(average "$datafile" | cut -c1-4)
- local dir=$(dirname "$datafile")
- local file=$(basename "$datafile")
- [[ -z "$TITLE1" ]] && local TITLE1="$file (actual)"
- [[ -z "$TITLE2" ]] && local TITLE2="$file (trend)"
- [[ "$PNGFILE" ]] || PNGFILE=$(basename "$datafile" .dat).png
-
- # now we can plot
- makeplotfile > "$PLOTFILE" || errorout "could not write the plotfile (permission issue?)"
- gnuplot "$PLOTFILE" || errorout "could now write graph (permission issue?)"
-
- [[ "$quiet" ]] || echo "graph saved as $PNGFILE"
-
-}
-
-# parse options {{{
-parse_options() {
-
- [[ -z "$1" ]] && message
-
- while [[ -n "$1" ]];do
- case "$1" in
- -h|--help) message ;;
- -q|--quiet) quiet=true ;;
- -o|--output) output="$2" ;;
- -r|--record) mode='record' ;;
- -p|--plot) mode='plot' ;;
- -a|--average) mode='average' ;;
- *) args+=( "$1" ) ;;
- esac
- shift
- done
-}
-# }}}
-
-# main {{{
-main() {
-
- case "$mode" in
- record) record "${args[@]}" ;;
- average) average "${args[@]}" ;;
- plot) plot "${args[@]}" ;;
- *) errorout 'invalid mode. use -r, -p or -a.' ;;
- esac
-
-}
-# }}}
-
-parse_options "$@"
-check_ac
-main