Per quanto riguarda la creazione dei grafici ho utilizzato il pacchetto di openwrt rrdtool.
Per prima cosa bisogna creare i database che anche se sono di tipo round robin (occupano poco spazio) ho preferito posizionarli su una partizione su chiave usb.
Ho voluto creare un database che che mi permettesse di visualizzare le temperature dell'ultima ora, ultime 6 ore, ultime 12 ore, ultime 24 ore, 1 settimana, 1 mese ed ultimo anno.
Per ottenere ciò ho creato il database con il seguente comando (nella partizione usb che ho chiamato "database_rrdtool"):
rrdtool create temperatura.rrd --start N --step 300 \
DS:temp_sensore1:GAUGE:900:U:U \
DS:temp_sensore2:GAUGE:900:U:U \
DS:temp_sensore3:GAUGE:900:U:U \
DS:temp_sensore4:GAUGE:900:U:U \
RRA:AVERAGE:0.5:1:12 \
RRA:AVERAGE:0.5:1:72 \
RRA:AVERAGE:0.5:1:144 \
RRA:AVERAGE:0.5:1:288 \
RRA:AVERAGE:0.5:12:168 \
RRA:AVERAGE:0.5:12:720 \
RRA:MAX:0.5:1:12 \
RRA:MAX:0.5:1:72 \
RRA:MAX:0.5:1:144 \
RRA:MAX:0.5:1:288 \
RRA:MAX:0.5:12:168 \
RRA:MAX:0.5:12:720 \
RRA:MIN:0.5:1:12 \
RRA:MIN:0.5:1:72 \
RRA:MIN:0.5:1:144 \
RRA:MIN:0.5:1:288 \
RRA:MIN:0.5:12:168 \
RRA:MIN:0.5:12:720 \
RRA:LAST:0.5:1:12 \
RRA:LAST:0.5:1:72 \
RRA:LAST:0.5:1:144 \
RRA:LAST:0.5:1:288 \
RRA:LAST:0.5:12:168 \
RRA:LAST:0.5:12:720
Le temperature verranno immagazzinati ogni 5 minuti nel database temperatura.rrd (per maggiori chiarimenti
http://oss.oetiker.ch/rrdtool/I sensori saranno letti come accennato qualche post prima tramite bus 1-wire e con il pacchetto owfs che crea un filesytem che permette di leggerli con un semplice "cat /mnt/sda2/usb/1-wire/28.D6CF96030000/temperature" (x esempio nel mio caso).Sarà più chiaro nei prossimi script (spero).
Per popolare il database ho creato lo script in /usr/sbin/agg_generale.sh che legge le temperature e messo nel crontab per essere esguito ogni 5 minuti.
#!/bin/bash
if [ -f /mnt/sda2/usb/1-wire/1D.B6CC0F000000/counters.A ]; then
minute=`date +%M`
hour=`date +%H`
day=`date +%d`
week=`date +%u`
month=`date +%m`
year=`date +%y`
SOURCE="/mnt/sda2/usb/database_rrdtool"
WIRE_C=`cat /mnt/sda2/usb/1-wire/1D.B6CC0F000000/counters.A &`
wait
WIRE_S1=`cat /mnt/sda2/usb/1-wire/28.D6CF96030000/temperature &`
wait
WIRE_S2=`cat /mnt/sda2/usb/1-wire/28.CBDE96030000/temperature &`
wait
WIRE_S3=`cat /mnt/sda2/usb/1-wire/28.92AF96030000/temperature &`
wait
WIRE_S4=`cat /mnt/sda2/usb/1-wire/28.08A696030000/temperature &`
wait
DB_DAY="powerkw_day.rrd"
DB_WEEK="powerkw_week.rrd"
DB_MONTH="powerkw_month.rrd"
DB_YEAR="powerkw_year.rrd"
DB_5YEAR="powerkw_5years.rrd"
RRD_H_D_W_M_Y="/etc/centralina/rrd_h_w_m_y.ini"
MEMORY="/etc/centralina/lettura_pre_prova.ini"
cd $SOURCE
######### Aggiorno db sensori temperatura ########
temp_sensore1=$(printf "%1.1f" $WIRE_S1)
temp_sensore2=$(printf "%1.1f" $WIRE_S2)
temp_sensore3=$(printf "%1.1f" $WIRE_S3)
temp_sensore4=$(printf "%1.1f" $WIRE_S4)
rrdtool update temperatura.rrd N:$temp_sensore1:$temp_sensore2:$temp_sensore3:$temp_sensore4
if [ -e $MEMORY ] || [ -e $RRD_H_D_W_M_Y ]; then
########### Calcolo potenza e aggiorno db ###########
lettura_pre=$(sed -n '1p' $MEMORY)
lettura=$WIRE_C
impulsi_eff=$((lettura-lettura_pre))
sed -i '1c\'"$lettura"'' $MEMORY
potenza=$(echo "scale=2; $impulsi_eff / 2" | bc | sed 's/^\./0./')
power=$(echo "scale=2; $potenza / 0.0833" | bc | sed 's/^\./0./')
rrdtool update powerw.rrd N:$power
############# Controllo se devo aggiornare db contatore kwh (h,m,w,y) ################
check_h=$(sed -n '1p' $RRD_H_D_W_M_Y)
#echo $check_h
check_d=$(sed -n '2p' $RRD_H_D_W_M_Y)
#echo $check_d
check_w=$(sed -n '3p' $RRD_H_D_W_M_Y)
#echo $check_w
check_m=$(sed -n '4p' $RRD_H_D_W_M_Y)
#echo $check_m
check_y=$(sed -n '5p' $RRD_H_D_W_M_Y)
#echo $check_y
if [ "$check_h" != "$hour" ]; then
lettura_pre=$(sed -n '2p' $MEMORY)
lettura=$WIRE_C
impulsi_eff=$((lettura-lettura_pre))
consumo=$(echo "scale=2; $impulsi_eff / 2000" | bc | sed 's/^\./0./')
sed -i '1c\'"$hour"'' $RRD_H_D_W_M_Y
sed -i '2c\'"$lettura"'' $MEMORY
rrdtool update $DB_DAY N:$consumo
#echo "Aggiorno db contatore consumo giornaliero"
fi
if [ "$check_d" != "$day" ]; then
lettura_pre=$(sed -n '3p' $MEMORY)
lettura=$WIRE_C
impulsi_eff=$((lettura-lettura_pre))
consumo=$(echo "scale=2; $impulsi_eff / 2000" | bc | sed 's/^\./0./')
sed -i '2c\'"$day"'' $RRD_H_D_W_M_Y
sed -i '3c\'"$lettura"'' $MEMORY
rrdtool update $DB_WEEK N:$consumo
#echo "Aggiorno db contatore potenza consumo settimanale"
fi
if [ "$check_w" != "$week" ]; then
lettura_pre=$(sed -n '4p' $MEMORY)
lettura=$WIRE_C
impulsi_eff=$((lettura-lettura_pre))
potenza=$(echo "scale=2; $impulsi_eff / 2000" | bc | sed 's/^\./0./')
sed -i '3c\'"$week"'' $RRD_H_D_W_M_Y
sed -i '4c\'"$lettura"'' $MEMORY
rrdtool update $DB_MONTH N:$consumo
#echo "Aggiorno db contatore potenza consumo mensile"
fi
if [ "$check_m" != "$month" ]; then
lettura_pre=$(sed -n '5p' $MEMORY)
lettura=$WIRE_C
impulsi_eff=$((lettura-lettura_pre))
consumo=$(echo "scale=2; $impulsi_eff / 2000" | bc | sed 's/^\./0./')
sed -i '4c\'"$month"'' $RRD_H_D_W_M_Y
sed -i '5c\'"$lettura"'' $MEMORY
rrdtool update $DB_YEAR N:$consumo
#echo "Aggiorno db contatore potenza consumo annuale"
fi
if [ "$check_y" != "$year" ]; then
lettura_pre=$(sed -n '6p' $MEMORY)
lettura=$WIRE_C
impulsi_eff=$((lettura-lettura_pre))
consumo=$(echo "scale=2; $impulsi_eff / 2000" | bc | sed 's/^\./0./')
sed -i '5c\'"$year"'' $RRD_H_D_W_M_Y
sed -i '6c\'"$lettura"'' $MEMORY
rrdtool $DB_5YEAR N:$consumo
#echo "Aggiorno db contatore potenza consumo 5 anni"
fi
else
#### Inizializzo impulsi e date ####
for i in 1 2 3 4 5 6; do
echo $WIRE_C >> $MEMORY
done
for i in $hour $day $week $month $year; do
echo $i >> $RRD_H_D_W_M_Y
done
fi
fi
exit 0
In realtà questo script aggiorna anche gli altri database (kw e kwh).
Per i soli sensori di temperature il codice è il seguente:
SOURCE="/mnt/sda2/usb/database_rrdtool"
WIRE_S1=`cat /mnt/sda2/usb/1-wire/28.D6CF96030000/temperature &`
wait
WIRE_S2=`cat /mnt/sda2/usb/1-wire/28.CBDE96030000/temperature &`
wait
WIRE_S3=`cat /mnt/sda2/usb/1-wire/28.92AF96030000/temperature &`
wait
WIRE_S4=`cat /mnt/sda2/usb/1-wire/28.08A696030000/temperature &`
wait
cd $SOURCE
######### Aggiorno db sensori temperatura ########
temp_sensore1=$(printf "%1.1f" $WIRE_S1)
temp_sensore2=$(printf "%1.1f" $WIRE_S2)
temp_sensore3=$(printf "%1.1f" $WIRE_S3)
temp_sensore4=$(printf "%1.1f" $WIRE_S4)
rrdtool update temperatura.rrd N:$temp_sensore1:$temp_sensore2:$temp_sensore3:$temp_sensore4
Nel crontab:
root@OpenWrt:/usr/sbin# crontab -l
*/5 * * * * /usr/sbin/agg_generale.sh
Ok adesso il database verrà popolato.
Per creare i grafici ho creato lo script "/usr/sbin/sensori.sh":
#!/bin/bash
#Pulisco la ram
ram_hot="$(free | grep "Mem" | awk '{ print $3 }')"
if [ $ram_hot -ge 25000 ];then
sync; echo 3 > /proc/sys/vm/drop_caches
fi
#Percorso su pendrive usb
data="/mnt/sda2/usb/database_rrdtool"
cd $data
start=$1
start1=$2
titolo[1]="Variazione ultima ora"
titolo[2]="Variazione ultime 6 ore"
titolo[3]="Variazione ultime 12 ore"
titolo[4]="Variazione ultime 24 ore"
titolo[5]="Variazione ultima settimana"
titolo[6]="Variazione ultimo mese"
titolo[7]="Variazione ultimo anno"
case $4 in
Tutti)
rrdtool graph temperature.png \
--start -$start$start1 --slope-mode \
-h 400 -w 700 \
--vertical-label "Temperatura [C°]" \
--y-grid 2:1 \
-t "${titolo[$3]}" \
-c "BACK#000000" \
-c "SHADEA#757373" \
-c "SHADEB#757373" \
-c "FONT#DDDDDD" \
-c "CANVAS#202020" \
-c "GRID#666666" \
-c "MGRID#AAAAAA" \
-c "FRAME#202020" \
-c "ARROW#FFFFFF" \
DEF:intMedia=temperatura.rrd:temp_sensore1:AVERAGE \
DEF:intMin=temperatura.rrd:temp_sensore1:MIN \
DEF:intMax=temperatura.rrd:temp_sensore1:MAX \
DEF:intCorrente=temperatura.rrd:temp_sensore1:LAST \
DEF:boilerMedia=temperatura.rrd:temp_sensore2:AVERAGE \
DEF:boilerMin=temperatura.rrd:temp_sensore2:MIN \
DEF:boilerMax=temperatura.rrd:temp_sensore2:MAX \
DEF:boilerCorrente=temperatura.rrd:temp_sensore2:LAST \
DEF:estMedia=temperatura.rrd:temp_sensore3:AVERAGE \
DEF:estMin=temperatura.rrd:temp_sensore3:MIN \
DEF:estMax=temperatura.rrd:temp_sensore3:MAX \
DEF:estCorrente=temperatura.rrd:temp_sensore3:LAST \
DEF:freMedia=temperatura.rrd:temp_sensore4:AVERAGE \
DEF:freMin=temperatura.rrd:temp_sensore4:MIN \
DEF:freMax=temperatura.rrd:temp_sensore4:MAX \
DEF:freCorrente=temperatura.rrd:temp_sensore4:LAST \
COMMENT:" \n" \
LINE2:intCorrente#0000FF:"Interno" \
GPRINT:intMedia:AVERAGE:" Media\: %5.2lf%s\t" \
GPRINT:intMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:intMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:intCorrente:LAST:" Ultima\: %5.2lf%s\t" \
COMMENT:" \n" \
LINE2:boilerCorrente#00BC14:"Boiler" \
GPRINT:boilerMedia:AVERAGE:" Media\: %5.2lf%s\t" \
GPRINT:boilerMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:boilerMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:boilerCorrente:LAST:" Ultima\: %5.2lf%s\t" \
COMMENT:" \n" \
LINE2:estCorrente#FF0000:"Esterno" \
GPRINT:estMedia:AVERAGE:" Media\: %5.2lf%s\t" \
GPRINT:estMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:estMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:estCorrente:LAST:" Ultima\: %5.2lf%s\t" \
COMMENT:" \n" \
LINE2:freCorrente#FFBC14:"Freezer" \
GPRINT:freMedia:AVERAGE:" Media\: %5.2lf%s\t" \
GPRINT:freMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:freMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:freCorrente:LAST:" Ultima\: %5.2lf%s\t"
;;
Boiler)
rrdtool graph temperature.png \
--start -$start$start1 --slope-mode \
--y-grid 1:1 \
-h 400 -w 700 \
--vertical-label "Temperatura [C°]" \
-t "${titolo[$3]}" \
-c "BACK#000000" \
-c "SHADEA#000000" \
-c "SHADEB#000000" \
-c "FONT#DDDDDD" \
-c "CANVAS#202020" \
-c "GRID#666666" \
-c "MGRID#AAAAAA" \
-c "FRAME#202020" \
-c "ARROW#FFFFFF" \
DEF:boilerMedia=temperatura.rrd:temp_sensore2:AVERAGE \
DEF:boilerMin=temperatura.rrd:temp_sensore2:MIN \
DEF:boilerMax=temperatura.rrd:temp_sensore2:MAX \
DEF:boilerCorrente=temperatura.rrd:temp_sensore2:LAST \
COMMENT:" \n" \
LINE2:boilerCorrente#FFBC14:"Boiler" \
GPRINT:boilerMedia:AVERAGE:" Media\: %5.2lf%s\t" \
GPRINT:boilerMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:boilerMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:boilerCorrente:LAST:" Ultima\: %5.2lf%s\t"
;;
Interno)
rrdtool graph temperature.png \
--start -$start$start1 --slope-mode \
-h 400 -w 700 \
--vertical-label "Temperatura [C°]" \
-t "${titolo[$3]}" \
-c "BACK#000000" \
-c "SHADEA#000000" \
-c "SHADEB#000000" \
-c "FONT#DDDDDD" \
-c "CANVAS#202020" \
-c "GRID#666666" \
-c "MGRID#AAAAAA" \
-c "FRAME#202020" \
-c "ARROW#FFFFFF" \
DEF:intMedia=temperatura.rrd:temp_sensore1:AVERAGE \
DEF:intMin=temperatura.rrd:temp_sensore1:MIN \
DEF:intMax=temperatura.rrd:temp_sensore1:MAX \
DEF:intCorrente=temperatura.rrd:temp_sensore1:LAST \
COMMENT:" \n" \
LINE2:intCorrente#FFBC14:"Interna" \
GPRINT:intMedia:AVERAGE:"Media\: %5.2lf%s\t" \
GPRINT:intMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:intMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:intCorrente:LAST:" Ultima\: %5.2lf%s\t"
;;
Esterno)
rrdtool graph temperature.png \
--start -$start$start1 --slope-mode \
-h 400 -w 700 \
--vertical-label "Temperatura [C°]" \
-t "${titolo[$3]}" \
-c "BACK#000000" \
-c "SHADEA#000000" \
-c "SHADEB#000000" \
-c "FONT#DDDDDD" \
-c "CANVAS#202020" \
-c "GRID#666666" \
-c "MGRID#AAAAAA" \
-c "FRAME#202020" \
-c "ARROW#FFFFFF" \
DEF:estMedia=temperatura.rrd:temp_sensore3:AVERAGE \
DEF:estMin=temperatura.rrd:temp_sensore3:MIN \
DEF:estMax=temperatura.rrd:temp_sensore3:MAX \
DEF:estCorrente=temperatura.rrd:temp_sensore3:LAST \
COMMENT:" \n" \
LINE2:estCorrente#FFBC14:"Esterno" \
PRINT:estMedia:AVERAGE:" Media\: %5.2lf%s\t" \
GPRINT:estMax:MAX:" Max\: %5.2lf%s\t" \
GPRINT:estMin:MIN:" Min\: %5.2lf%s\t" \
GPRINT:estCorrente:LAST:" Ultima\: %5.2lf%s\t" \
;;
Freezer)
rrdtool graph temperature.png \
--start -$start$start1 --slope-mode \
-h 400 -w 700 \
--vertical-label "Temperatura [C°]" \
-t "${titolo[$3]}" \
-c "BACK#000000" \
-c "SHADEA#000000" \
-c "SHADEB#000000" \
-c "FONT#DDDDDD" \
-c "CANVAS#202020" \
-c "GRID#666666" \
-c "MGRID#AAAAAA" \
-c "FRAME#202020" \
-c "ARROW#FFFFFF" \
DEF:freMedia=temperatura.rrd:temp_sensore4:AVERAGE \
DEF:freMin=temperatura.rrd:temp_sensore4:MIN \
DEF:freMax=temperatura.rrd:temp_sensore4:MAX \
DEF:freCorrente=temperatura.rrd:temp_sensore4:LAST \
COMMENT:" \n" \
LINE2:freCorrente#FFBC14:"Freezer" \
GPRINT:freMedia:AVERAGE:" Media\:%5.2lf%s\t" \
GPRINT:freMax:MAX:" Max\:%5.2lf%s\t" \
GPRINT:freMin:MIN:" Min\:%5.2lf%s\t" \
GPRINT:freCorrente:LAST:" Ultima\:%5.2lf%s\t"
esac
ram_hot="$(free | grep "Mem" | awk '{ print $3 }')"
if [ $ram_hot -ge 25000 ];then
sync; echo 3 > /proc/sys/vm/drop_caches
fi
exit
A questo punto ho creato la pagina per la webif (proseguo sotto perchè superato il limite di 20000 caratteri spero qualche admin riunisca tutto)