RRDTools график температуры воздуха за окном

RRDTools график температуры воздуха за окном

Доброго времени суток! Сегодня мы вновь добавим возможность для уже собранного нами сенсора DS18B20 по статье: 1-wire термо станция на FreeBSD — это рисование красивых градиентных графиков температуры воздуха с помощью RRDTools. Если RRDTools не установлен — смотрим тут: RRDtools – установка и использование FreeBSD.

Используемая система:

FreeBSD 9.1-RELEASE #0: Mon Jan 21 22:14:00 IRKT 2013 root@f02.24srv.ru:/usr/obj/usr/src/sys/GEN210113

Для начала создаём скрипт формирования базы данных RRDTools со сроком хранения данных — 1 год (cdb-temperature.sh). Нам пока больше не надо. Содержание скрипта следующее:

#!/bin/sh

rrdtool create db-temperature.rrd --step 60 \
DS:street:GAUGE:120:U:U \
RRA:AVERAGE:0.5:1:525600 \
RRA:AVERAGE:0.5:15:35040 \
RRA:AVERAGE:0.5:30:17520 \
RRA:AVERAGE:0.5:60:8760 \
RRA:MIN:0.5:1:525600 \
RRA:MIN:0.5:15:35040 \
RRA:MIN:0.5:30:17520 \
RRA:MIN:0.5:60:8760 \
RRA:MAX:0.5:1:525600 \
RRA:MAX:0.5:15:35040 \
RRA:MAX:0.5:30:17520 \
RRA:MAX:0.5:60:8760 \
RRA:LAST:0.5:1:525600 \
RRA:LAST:0.5:15:35040 \
RRA:LAST:0.5:30:17520 \
RRA:LAST:0.5:60:8760

Таким образом в директории запуска создаётся база данных RRDTools с именем: db-temperature.sh.

Теперь необходимо обновлять базу данных RRDTools и соответственно заполнять её данными. Для заполнения базы данных я не стал рисовать новый скрипт получения данных с датчика температуры, а модифицировал уже имеющийся скрипт из статьи Отправка смс о температуре воздуха + прогноз. Добавил туда условия для сенсора 14 (именно этот сенсор находится у меня за окном). Текст скрипта после последних изменений стал следующий:

#!/bin/sh

outopen=`date '+%H'`
minh=07
maxh=23

db_host=localhost
db_pass=пароль_бд
db_user=логин_бд
db_name=имя_бд

digitemp_dir=/mnt/soft/digitemp
digitemp_bin=$digitemp_dir/dt
digitemp_conf=$digitemp_dir/.digitemprc
digitemp_format=%.1C
digitemp_sensor=13

smssendbin=/usr/local/bin/sendsms
grad=4

idrp5=4475

rrddb=/mnt/rrd/db-temperature.rrd
rrdbin=/usr/local/bin/rrdtool
#######################################################
# Сам скрипт
#######################################################
# Выполняем получение данных с сенсоров
`$digitemp_bin -a -q -o $digitemp_format -c $digitemp_conf -l temperature.log`

# Процедура проверки временных файлов
TmpFiles ()
{
if ! [ -f $digitemp_dir/sensor${1}.dat ];
then
        touch $digitemp_dir/sensor${1}.dat;
        echo '100' >> $digitemp_dir/sensor${1}.dat;
fi
}
# Сверяем временной интервал
IsTime()
{
if [ "$1" -ge "$2" ]
        then
        if [ "$1" -lt "$3" ]
                then
                Gradaciya $ost $digitemp_sensor;
        fi
fi
}
Gradaciya()
{
if [ $1 -eq 0 ];
        then
        t_file=`cat $digitemp_dir/sensor${2}.dat`;
        MakeTmpl $2 $t_file;
fi
}
MakeTmpl()
{
if [ $t_cel -ne $2 ];
        then
        rm -f $digitemp_dir/sensor${1}.dat;
        echo $t_cel >> $digitemp_dir/sensor${1}.dat
        Ssms $1
fi
}
Ssms()
{
#####
# Отправка смс - настройка шаблонов в зависимости от сенсора
#####
# Шаблон для сенсора 13
if [ $1 -eq 13 ];
        then
        tpl="Temperatura Doma: ";
        $smssendbin 79230000000 "${tpl}${line}C";
fi
# Шаблон для сенсора 14
if [ $1 -eq 14 ];
        then
        tpl="Tempetarura v Krasnoyarske: ";
        #Подтягиваем прогноз
        prgn=`/usr/local/bin/curl -s http://rp5.ru/xml/${idrp5}/00000/ru | grep -E -i -m2 -w 'HHii|temperature' | sed -e :a -e 's/<[^>]*>//g;/</N;//ba' | tr -d '\n' | awk '{ print "V "$1" prognoz "$2"C"; }'`;
        $smssendbin 79230000000 "${tpl}${line}C; ${prgn}";
fi
}

cat temperature.log | while read line;
do
        #Добавление данных для графика с сенсора 14
        if [ $digitemp_sensor -eq 14 ];
        then
        `$rrdbin update $rrddb N:$line`
        fi
        #Всё
        TmpFiles $digitemp_sensor;
        t_cel=`echo $line | awk -F "." '{print $1}' `;
        ost=`let "$t_cel % $grad"`;
        IsTime $outopen $minh $maxh;
        sql="call update_temp($line,$digitemp_sensor);";
        digitemp_sensor=`expr $digitemp_sensor + 1`;
        `/bin/echo $sql | /usr/local/bin/mysql -h$db_host -u$db_user $db_name -p$db_pass`;
done
rm -f temperature.log;

Теперь о новом в данном скрипте:

rrddb=/mnt/rrd/db-temperature.rrd
rrdbin=/usr/local/bin/rrdtool

Данные настройки указывают путь к исполняемому файлу RRDTolls, а так же фактическое местонахождение нашей БД.

        #Добавление данных для графика с сенсора 14
        if [ $digitemp_sensor -eq 14 ];
        then
        `$rrdbin update $rrddb N:$line`
        fi
        #Всё

Тут как раз для сенсора № 14 выполняем отправку данных в базу RRDTools.

Сейчас пишем скрипт формирования графиков RRDTools по необходимым нам периодам: 1 день, 7 дней, 30 дней, 182 дня, 1 год. График будет красивым с использованием градиента при изменении температуры на 2 градуса в любую сторону, теплыми цветами будет отображаться положительная температура, холодными — отрицательная.

#!/bin/sh

export LANG=UTF-8
export LC_ALL=ru_RU.UTF-8

BASE="/mnt/rrd/db-temperature.rrd"
WWWPREFIX="/mnt/www/server.24srv.ru/data/images/rrd"
RRDCMD="/usr/local/bin/rrdtool"
PERIOD="1d 7d 30d 182d 1y"

for day in $PERIOD; do

$RRDCMD graph $WWWPREFIX/krsktemp${day}.png \
--width 760 \
--height 300 \
--imgformat PNG \
--start -${day} \
--end now \
--slope-mode \
--font-render-mode light \
--font DEFAULT:9:Tahoma \
--font TITLE:10:Arial \
--font AXIS:8:Arial \
--font UNIT:9:"Courier New" \
--font LEGEND:8:"Courier New" \
--font WATERMARK:1:Arial \
--color BACK#FFFFFF \
--color SHADEA#444444 \
--color SHADEB#444444 \
--color CANVAS#FFFFFF \
--color FONT#666666 \
--vertical-label "Температура воздуха, C" \
--title "Температура воздуха в Красноярске" \
DEF:street=$BASE:street:LAST \
CDEF:tp_17=street,0,GT,street,100,GT,34,street,IF,0,IF AREA:tp_17#FF0000 \
CDEF:tp_16=street,0,GT,street,32,GT,32,street,IF,0,IF AREA:tp_16#FF1100 \
CDEF:tp_15=street,0,GT,street,30,GT,30,street,IF,0,IF AREA:tp_15#FF2200 \
CDEF:tp_14=street,0,GT,street,28,GT,28,street,IF,0,IF AREA:tp_14#FF3300 \
CDEF:tp_13=street,0,GT,street,26,GT,26,street,IF,0,IF AREA:tp_13#FF4400 \
CDEF:tp_12=street,0,GT,street,24,GT,24,street,IF,0,IF AREA:tp_12#FF5500 \
CDEF:tp_11=street,0,GT,street,22,GT,22,street,IF,0,IF AREA:tp_11#FF6600 \
CDEF:tp_10=street,0,GT,street,20,GT,20,street,IF,0,IF AREA:tp_10#FF7700 \
CDEF:tp_09=street,0,GT,street,18,GT,18,street,IF,0,IF AREA:tp_09#FF8800 \
CDEF:tp_08=street,0,GT,street,16,GT,16,street,IF,0,IF AREA:tp_08#FF9900 \
CDEF:tp_07=street,0,GT,street,14,GT,14,street,IF,0,IF AREA:tp_07#FFAA00 \
CDEF:tp_06=street,0,GT,street,12,GT,12,street,IF,0,IF AREA:tp_06#FFBB00 \
CDEF:tp_05=street,0,GT,street,10,GT,10,street,IF,0,IF AREA:tp_05#FFCC00 \
CDEF:tp_04=street,0,GT,street,8,GT,8,street,IF,0,IF  AREA:tp_04#FFDD00 \
CDEF:tp_03=street,0,GT,street,6,GT,6,street,IF,0,IF  AREA:tp_03#FFEE00 \
CDEF:tp_02=street,0,GT,street,4,GT,4,street,IF,0,IF  AREA:tp_02#FFFF00 \
CDEF:tp_01=street,0,GT,street,2,GT,2,street,IF,0,IF  AREA:tp_01#ffff00 \
CDEF:tm_17=street,0,LT,street,-100,LT,-34,street,IF,0,IF AREA:tm_17#0000FF \
CDEF:tm_16=street,0,LT,street,-32,LT,-32,street,IF,0,IF AREA:tm_16#0011FF \
CDEF:tm_15=street,0,LT,street,-30,LT,-30,street,IF,0,IF AREA:tm_15#0022FF \
CDEF:tm_14=street,0,LT,street,-28,LT,-28,street,IF,0,IF AREA:tm_14#0033FF \
CDEF:tm_13=street,0,LT,street,-26,LT,-26,street,IF,0,IF AREA:tm_13#0044FF \
CDEF:tm_12=street,0,LT,street,-24,LT,-24,street,IF,0,IF AREA:tm_12#0055FF \
CDEF:tm_11=street,0,LT,street,-22,LT,-22,street,IF,0,IF AREA:tm_11#0066FF \
CDEF:tm_10=street,0,LT,street,-20,LT,-20,street,IF,0,IF AREA:tm_10#0077FF \
CDEF:tm_09=street,0,LT,street,-18,LT,-18,street,IF,0,IF AREA:tm_09#0088FF \
CDEF:tm_08=street,0,LT,street,-16,LT,-16,street,IF,0,IF AREA:tm_08#0099FF \
CDEF:tm_07=street,0,LT,street,-14,LT,-14,street,IF,0,IF AREA:tm_07#00AAFF \
CDEF:tm_06=street,0,LT,street,-12,LT,-12,street,IF,0,IF AREA:tm_06#00BBFF \
CDEF:tm_05=street,0,LT,street,-10,LT,-10,street,IF,0,IF AREA:tm_05#00CCFF \
CDEF:tm_04=street,0,LT,street,-8,LT,-8,street,IF,0,IF AREA:tm_04#00DDFF \
CDEF:tm_03=street,0,LT,street,-6,LT,-6,street,IF,0,IF AREA:tm_03#00EEFF \
CDEF:tm_02=street,0,LT,street,-4,LT,-4,street,IF,0,IF AREA:tm_02#00FFFF \
CDEF:tm_01=street,0,LT,street,-2,LT,-2,street,IF,0,IF AREA:tm_01#CDFFFF \
LINE1:street#1F4F82:"Street" \
GPRINT:street:LAST:"Последняя:%3.2lfCб╟" GPRINT:street:AVERAGE:"Средняя:%3.2lfCб╟" GPRINT:street:MAX:"Максимум:%3.2lfCб╟" GPRINT:street:MIN:"Минимум:%3.2lfCб╟\j" \
COMMENT:"                                www.savenkoff.com Krasnoyarsk temperature street last ${day}\n" \
> /dev/null 2>&1

done
exit 0

Записываем все скрипты в крон, на необходимый интервал выполнения. Для добавления данных cron отрабатывает 1 раз в минуту, для формирования графиков я выставил раз в 5 минут. Пример для формирования графика:

# Обновление изображения графика температуры воздуха
*/5     *       *       *       *       root    /mnt/rrd/img-temperature.sh