KLD - I currently use a combination of munin (for logging) and a rather simple-minded shell script for control and logging.
A better solution is almost certanly temploggerd:
http://sourceforge.net/projects/owfs/files/temploggerd/ which annoyingly isn't in Debian yet, although I'm planning to fix that at some point. I keep meaning to set this up, but my current bodge works just fine so leaving it alone all summer has seemed like a good plan :-)
Here's the munin tank-log script:
#!/bin/sh
#
# Plugin to monitor heating sensors.
#
# Usage: Place in /etc/munin/node.d/ (or link it there using ln -s)
#
# Parameters understood:
#
# config (required)
# autoconf (optional - used by munin-config)
#
# Magic markers - optional - used by installation scripts and
# munin-config:
#
#%# family=auto
#%# capabilities=autoconf
#read owfs config, then export it so backticks work
. /etc/default/owfs
export CLIENT_OPTS
if [ "$1" = "autoconf" ]; then
if owdir $CLIENT_OPTS ; then
echo yes
exit 0
else
echo no
exit 1
fi
fi
if [ "$1" = "config" ]; then
MAX="126"
MIN="-4"
# if [ "$scaleto100" = "yes" ]; then
# graphlimit=100
# else
# graphlimit=$PERCENT
# fi
WARNING="80"
CRITICAL="95"
echo 'graph_title Tank Temperatures'
echo "graph_order tank5 tank4 tank3 tank2 tank1"
# echo "graph_args --base 1000 -r --lower-limit 0 --upper-limit $graphlimit"
echo 'graph_vlabel Degrees Celcius'
# echo 'graph_scale no'
echo 'graph_info This graph shows hot water tank temperatures.'
echo 'graph_category solar'
echo 'graph_period minute'
echo 'tank1.label tank-base'
echo 'tank1.draw LINE2'
echo "tank1.max $MAX"
echo "tank1.min $MIN"
echo 'tank1.type GAUGE'
echo "tank1.warning $WARNING"
echo "tank1.critical $CRITICAL"
echo "tank1.info Temp at base of tank"
echo 'tank2.label tank2'
echo 'tank2.draw LINE1'
echo "tank2.min $MIN"
echo "tank2.max $MAX"
echo "tank2.warning $WARNING"
echo "tank2.critical $WARNING"
echo 'tank2.type GAUGE'
echo 'tank2.info Temp 20cm up tank'
echo 'tank3.label tank3'
echo 'tank3.draw LINE1'
echo "tank3.min $MIN"
echo "tank3.max $MAX"
echo "tank3.warning $WARNING"
echo "tank3.critical $WARNING"
echo 'tank3.type GAUGE'
echo 'tank3.info Temp 40cm up tank'
echo 'tank4.label tank4'
echo 'tank4.draw LINE1'
echo "tank4.min $MIN"
echo "tank4.max $MAX"
echo "tank4.warning $WARNING"
echo "tank4.critical $WARNING"
echo 'tank4.type GAUGE'
echo 'tank4.info Temp 60cm up tank'
echo 'tank5.label tank-top'
echo 'tank5.draw LINE2'
echo "tank5.min $MIN"
echo "tank5.max $MAX"
echo "tank5.warning $WARNING"
echo "tank5.critical $WARNING"
echo 'tank5.type GAUGE'
echo 'tank5.info Temp at top of tank'
echo 'pump.label solar-pump'
echo 'pump.draw LINE'
# echo 'pump.color black'
echo "pump.min 0"
echo "pump.max 5"
echo 'pump.type GAUGE'
echo 'pump.info Solar pump runnning'
echo 'dump.label heat-dump-on'
echo 'dump.draw LINE'
# echo 'dump.color black'
# echo "dump.min 0"
# echo "dump.max 1"
echo 'dump.type GAUGE'
echo 'dump.info Heat dump runnning'
#if [ "$scaleto100" = "yes" ]; then
# echo "system.cdef system,$NCPU,/"
# echo "user.cdef user,$NCPU,/"
# echo "nice.cdef nice,$NCPU,/"
# echo "idle.cdef idle,$NCPU,/"
#fi
exit 0
fi
TANK1SENSOR="28.850874010000"
TANK2SENSOR="10.AD188A010800"
TANK3SENSOR="10.634B8A010800"
TANK4SENSOR="10.E7EE89010800"
TANK5SENSOR="10.AEEA89010800"
TANK1=`owread $CLIENT_OPTS $TANK1SENSOR/temperature`
TANK2=`owread $CLIENT_OPTS $TANK2SENSOR/temperature`
TANK3=`owread $CLIENT_OPTS $TANK3SENSOR/temperature`
TANK4=`owread $CLIENT_OPTS $TANK4SENSOR/temperature`
TANK5=`owread $CLIENT_OPTS $TANK5SENSOR/temperature`
IOREG=`cat /sys/bus/i2c/devices/0-0038/read`
PUMP=$(($IOREG & 4 )) # bit 2 set
if [ $PUMP = 0 ]; then PUMP=6; else PUMP=0; fi
DUMP=$(($IOREG & 56 )) # bits 3,4,5 set
if [ $DUMP = 0 ]; then DUMP=3; else DUMP=0; fi
# awk '/^cpu / { print "user.value " $2 "\nnice.value " $3 "\nsystem.value " $4
"\nidle.value " $5 }' < /proc/stat
echo "tank1.value $TANK1"
echo "tank2.value $TANK2"
echo "tank3.value $TANK3"
echo "tank4.value $TANK4"
echo "tank5.value $TANK5"
echo "pump.value $PUMP"
echo "dump.value $DUMP"
The munin server connects and runs this script. RRDtool collates and compresses the data and draws nice graphs. The catch is that the recorded data resolution drops over time, which may not be what you want.
Here's my control script, which is GPLed so feel free to use it. It mixes control and logging, which would be separated in a sensible software design. This logs to a simple log file. (It used to log to an rrd database).
#!/bin/bash
#set -x
. /etc/default/owfs
#PANEL_SENSOR=28.D23974010000
PANEL_SENSOR=10.B8E089010800
#TANK_SENSOR=28.850874010000
TANK_SENSOR=10.AD188A010800
TANK_TOP_SENSOR=10.AEEA89010800
SOLAR_PUMP=4 #bit 2
CH_PUMP=8 #bit 3
CH_VALVE=16 #bit 4
DHW_VALVE=32 #bit 5
TEMPSTART=10
TEMPSTOP=5
OVERHEAT=90
IOREG_DEV="/sys/bus/i2c/devices/0-0038"
function turnonoff ()
{
ioreg=`cat $IOREG_DEV/read`
case $1 in
pump)
facility="solar pump"
twiddlebits=$SOLAR_PUMP
;;
dump)
facility="heat dump"
twiddlebits=$(($CH_PUMP + $CH_VALVE + $DHW_VALVE))
;;
esac
case $2 in
on)
pumpstat="on"
echo "$(($ioreg & ~$twiddlebits))" > $IOREG_DEV/write
;;
off)
pumpstat="off"
echo "$(($ioreg | $twiddlebits))" > $IOREG_DEV/write
;;
esac
echo "Turning $facility $pumpstat"
logger -i -s -p local0.notice -t solar "$facility $pumpstat"
}
function higher ()
# returns 1 if $1+tempdiff> $2, otherwise returns zero. * status is $1<$2
case `echo "a=$1;b=$2;d=$3;r=-1;if(a-d<=b)r=0;if(a-d>b)r=1;r"|bc` in
0) return 0
;;
1) return 1
;;
*) return 0
;;
esac
}
while true
do
owdir ${CLIENT_OPTS} > /dev/null
sleep 20
echo `date`
PANEL_TMP=`owread ${CLIENT_OPTS} $PANEL_SENSOR/temperature`
PANEL_TMP=${PANEL_TMP#"${PANEL_TMP%%[! ]*}"}
TANK_TMP=`owread ${CLIENT_OPTS} $TANK_SENSOR/temperature`
TANK_TMP=${TANK_TMP#"${TANK_TMP%%[! ]*}"}
TANKTOP_TMP=`owread ${CLIENT_OPTS} $TANK_TOP_SENSOR/temperature`
TANKTOP_TMP=${TANKTOP_TMP#"${TANKTOP_TMP%%[! ]*}"}
higher $PANEL_TMP $TANK_TMP $TEMPSTART
RET1=$?
higher $PANEL_TMP $TANK_TMP $TEMPSTOP
PANEL_TMP=${PANEL_TMP#"${PANEL_TMP%%[! ]*}"}
TANK_TMP=`owread ${CLIENT_OPTS} $TANK_SENSOR/temperature`
TANK_TMP=${TANK_TMP#"${TANK_TMP%%[! ]*}"}
TANKTOP_TMP=`owread ${CLIENT_OPTS} $TANK_TOP_SENSOR/temperature`
TANKTOP_TMP=${TANKTOP_TMP#"${TANKTOP_TMP%%[! ]*}"}
higher $PANEL_TMP $TANK_TMP $TEMPSTART
RET1=$?
higher $PANEL_TMP $TANK_TMP $TEMPSTOP
RET2=$?
higher $TANKTOP_TMP $OVERHEAT 0
RET3=$?
higher $PANEL_TMP $TANKTOP_TMP 4
RET4=$?
if [ "$RET3" = "1" ]; then
turnonoff dump on; #Overheat status
else
# normal operation
turnonoff dump off;
fi
if [ "$RET1" = "1" ]; then turnonoff pump on; PUMP=1; fi
if [ "$RET4" = "1" ]; then turnonoff pump on; PUMP=1; fi
if [ ! "$RET2" = "1" ]; then turnonoff pump off; PUMP=0; fi
# rrdtool update /var/log/solar.rrd N:$PANEL_TMP:$TANKTOP_TMP:$TANK_TMP:$PUMP
echo "Panel:$PANEL_TMP Tank Base:$TANK_TMP Tank:$TANKTOP_TMP"
logger -i -s -p local0.notice -t solar "Panel:$PANEL_TMP Tank Base:$TANK_TMP Tank$
done