Termostato

Da raspibo.
Jump to navigation Jump to search

Le applicazioni dei termostati sono svariate, in questo caso partiamo con la realizzazione di un termostato per il controllo della caldaia di casa che può comunque essere ampliato con sensori o attuatori aggiuntivi ad esempio per il controllo del condizionatore.

Per rendere il termostato più flessibile la gestione è modulare perciò i dati vengono salvati su [1]redis per la sua velocità, e la possibilità di sincronizzazione master/slave.

Per rendere più facile la gestione viene utilizzata una interfaccia web implementata sul server web [2]nginx con [3]php e librerie [4]Flotr2 per la rappresentazione grafica dei dati.

Schema di massima

Sensori utilizzati

Per la misura della temperatura si possono uitlizzare i sensori DALLAS vedi voce Raspberry Pi-Lettura Temperatura per la semplicità d'uso, la possibilità di collegamento su un bus digitale in modo da usare pochi pin del GPIO.

Questi sensori utilizzano un pin del gpio, possono essere collegati su bus lineare o a stella la lunghezza massima del collegamento arriva a 200 metri.

Possono essere utilizzati anche altri sensori grazie alla modularità del sistema basta infatti che i dati vengano inseriti in redis.

Installazione del software

Innanzitutto modificare il file /etc/modules inserendo i moduli per la gestioe del bus 1 wire:

echo 'wire' >> /etc/modules
echo 'w1_gpio' >> /etc/modules
echo 'w1_therm' >> /etc/modules

Riavviare il Raspberry ed installare i sensori.

Al riavvio nella dir /sys/bus/w1/devices/ si trovano i files relativi ai sensori:

root@raspberrypi:~/termostato# ls -l /sys/bus/w1/devices/
totale 0
drwxr-xr-x 2 root root 0 mar 21 21:33 ./
drwxr-xr-x 4 root root 0 mar 21 21:33 ../
lrwxrwxrwx 1 root root 0 mar 21 21:33 28-0000040520d3 -> ../../../devices/w1_bus_master1/28-0000040520d3/
lrwxrwxrwx 1 root root 0 mar 21 21:33 28-000004052c94 -> ../../../devices/w1_bus_master1/28-000004052c94/
lrwxrwxrwx 1 root root 0 mar 21 21:38 w1_bus_master1 -> ../../../devices/w1_bus_master1/

Si può procedere all'installazione vera e propria del software:

il server redis per la memorizzazione dei dati

sudo apt-get install redis-server bc 

il comando elink per la lettura della temperatura esterna da inernet

sudo apt-get install elinks

il software per la gestione via web

sudo apt-get install nginx php5-fpm php5-cli php5-curl php5-cgi php-pear php5-gd

Lettura sensori e salvataggio su redis

Per la lettura si utilizza uno script in bash (/root/termostato/04_leggi_temperatura.sh):

#!/bin/bash
sensori[0]='28-000004052c94'
sensori[1]='28-0000040520d3'
#controllo che lo script venga lanciato con 1 parametro
if [ $# != 1 ]
 then
 echo -n "Lancia lo script: $0 [all"
 for i in "${sensori[@]}"
 do
   echo -n "|$i"
 done
 echo ']'
else 
 if [ $1 == "all" ] # Se lanciato con il parametro all visualizza la lettura di tutti i sensori
 then
  for i in "${sensori[@]}"
  do
    $0 $i 
  done
 else
 sensore=$1

 for x in 1 2 3 4
 do
  lettura=`paste -s /sys/bus/w1/devices/${sensore}/w1_slave | grep YES` # esegue la lettura verificando il CRC
 # echo $?
 # echo lettura
  if [ $? == 0 ]
   then temp=$lettura; break
   else temp='ERR' ; break
  fi
 done

 temperatura=`echo $temp | paste -s | awk -F "=" '{print $3/1000}'`

 echo $temperatura
 fi
fi

Per la memorizzazione su Redis si lancia uno script che richiama il precedente per ogni sensore e lo associa alla zona da monitorare inoltre memorizza la data corrente(/root/termostato/05_memorizza_temp.sh):

#!/bin/bash
sensore[0]='28-000004052c94'
sensore[1]='28-0000040520d3'
d_sensore[0]='cucina'
d_sensore[1]='camera'
x=0
for i in "${sensore[@]}"
do
 temp=`/root/termostato/04_leggi_temperatura.sh $i`
 if [ "$temp" != "-0.062" ]
  then
  if [ "$temp" != "85" ]
   then
    /usr/bin/redis-cli rpush ${d_sensore[${y}]} $temp
  fi
 fi
y=`expr $y + 1` 
done
/usr/bin/redis-cli rpush lettura "`date "+%Y-%m-%d %H:%M:%S"`"
/usr/bin/redis-cli rpush timestamp "`date "+%s"`"

Per la lettura della temperatura esterna nel mio caso ho fatto riferimento alla centralina meteo più vicina e leggo i dati via web(/root/termostato/06_display_letture.sh):

#!/bin/bash
temp=`/usr/bin/elinks -dump "http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=IITALIAB2&format=1"|awk -F "," '{print $2}'| grep '[0-9]\.[0-9]'| tail -1`
/usr/bin/redis-cli rpush temp_esterna $temp

Una volta lanciati gli script precedenti si può verficare se vengono memorizzati correttamente su Redis:

#!/bin/bash
echo "Visualizzazione elementi lista in redis"
redis-cli keys "*"
echo "Display valori lista primo sensore: cucina"
redis-cli lrange cucina -10 -1
echo "Display valori lista primo sensore: camera"
redis-cli lrange camera -10 -1
echo "Display valori lista temperatura esterna"
redis-cli lrange temp_esterna -10 -1


Configurazione

Per il setup dei valori su redis si può utilizzare questo script che crea le variabili in cui memorizzare la programmazione settimanale creando due fasce orarie G=giorno e N=notte oguna con temperatura minima e massima. Vengono create anche le variabili per lo stato del rele ed altre variabili di appoggio per gli script successivi:

#!/bin/bash
for x in `seq 0 6`
do
 redis-cli rpush lun N
 redis-cli rpush mar N
 redis-cli rpush mer N
 redis-cli rpush gio N
 redis-cli rpush ven N
 redis-cli rpush sab N
 redis-cli rpush dom N
done
for x in `seq 7 23`
do
 redis-cli rpush lun G
 redis-cli rpush mar G
 redis-cli rpush mer G
 redis-cli rpush gio G
 redis-cli rpush ven G
 redis-cli rpush sab G
 redis-cli rpush dom G
done
redis-cli lrange lun 0 23
redis-cli lrange mar 0 23
redis-cli lrange mer 0 23
redis-cli lrange gio 0 23
redis-cli lrange ven 0 23
redis-cli lrange sab 0 23
redis-cli lrange dom 0 23
redis-cli set t_min_giorno 21
redis-cli set t_max_giorno 21.5
redis-cli set t_min_notte 21
redis-cli set t_max_notte 21.5
redis-cli get t_min_giorno 
redis-cli get t_max_giorno 
redis-cli get t_min_notte
redis-cli get t_max_notte 
redis-cli lpush rele 0 
redis-cli lrange rele 0 -1 
redis-cli lpush timestamp 0 
redis-cli lrange timestamp 0 -1 
redis-cli rpush min 0
redis-cli rpush max 0
redis-cli lrange min 0 -1 
redis-cli lrange max 0 -1

Script di gestione del termostato

Lo script che regola la temperatu è in bash e va schedulato con la giusta frequenza in crontab in modo che la caldaia non si accenda e spenga in continuazione ad esempio ogni 10 minuti.

Lo script legge i dati da redis e decide in base all'ora di sistema la fascia di temperature da usare per il confronto con l'ultima lettura. La tolleranza sulla temperatura impostata di più o meno 0.25 grado, viene memorizzata su Redis anche una stringa che contiene tutti i dati utilizzati per le decisione presa.

#!/bin/bash
ora=`date "+%H"`
camera=`redis-cli lrange camera -1 -1` 
cucina=`redis-cli lrange cucina -1 -1` 
rele=`redis-cli lrange rele -1 -1`
t_min_notte=`redis-cli get t_min_notte`
t_max_notte=`redis-cli get t_max_notte`
t_min_giorno=`redis-cli get t_min_giorno`
t_max_giorno=`redis-cli get t_max_giorno`
data_ora=`date "+%H:%M:%S"`
giorni[1]="lun"
giorni[2]="mar"
giorni[3]="mer"
giorni[4]="gio"
giorni[5]="ven"
giorni[6]="sab"
giorni[7]="dom"
gg_sett=`date "+%u"`
n_giorno=${giorni[$gg_sett]}
#ricavo la temperatura per l'ora corrente
temp_att=`redis-cli lindex ${n_giorno} ${ora}` 
#case "$temp_att" in
#N) echo "Programma attuale: notte"
#controllo="${data_ora} Temp camera= ${camera}     - Invariato - notte  - min ${t_min_notte}/max ${t_max_notte} - Temperature: ${camera}/${cucina}"
case "$temp_att" in
N) echo "Programma attuale: notte"
min=${t_min_notte}
max=${t_max_notte}
if (( `echo "$camera<${t_min_notte}" | bc -l` )) 
then
rele=1
controllo="${data_ora} Temp camera= ${camera} < ${t_min_notte} - notte - min ${t_min_notte}/max ${t_max_notte} - Temperature: ${camera}/${cucina}"
fi
if (( `echo "$camera>${t_max_notte}" | bc -l` )) 
then
rele=0
controllo="${data_ora} Temp camera= ${camera} > ${t_max_notte} - notte - min ${t_min_notte}/max ${t_max_notte} - Temperature: ${camera}/${cucina}"
fi
 ;;
G) echo "Programma attuale: giorno"
min=${t_min_giorno}
max=${t_max_giorno}
if (( `echo "$cucina<${t_min_giorno}" | bc -l` )) 
then
rele=1
controllo="${data_ora} Temp cucina= ${cucina} < ${t_min_giorno} - giorno - min ${t_min_giorno}/max ${t_max_giorno} - Temperature: ${camera}/${cucina}"
fi
if (( `echo "$cucina>${t_max_giorno}" | bc -l` )) 
then
rele=0
controllo="${data_ora} Temp cucina= ${cucina} > ${t_max_giorno} - giorno - min ${t_min_giorno}/max ${t_max_giorno} - Temperature: ${camera}/${cucina}"
fi
  ;;
S) echo "Programma attuale: spento"
min=0
max=0
controllo="${data_ora} Temp camera= ${camera},Temp cucina= ${cucina} - termo spento"
rele=0
  ;;
esac
/usr/bin/redis-cli rpush rele $rele > /dev/null
#echo "d4=$rele" | /usr/bin/telnet localhost 2000
if [ ! -d /sys/class/gpio/gpio25 ] 
then
  echo "25" > /sys/class/gpio/export
  echo "out" > /sys/class/gpio/gpio25/direction
fi
if [ $rele -eq 1 ] 
then 
echo "0" > /sys/class/gpio/gpio25/value
else
echo "1" > /sys/class/gpio/gpio25/value
fi
/usr/bin/redis-cli rpush controllo "$controllo"  > /dev/null
/usr/bin/redis-cli rpush min "$min" > /dev/null
/usr/bin/redis-cli rpush max "$max" > /dev/null
#echo "camera=${camera} cucina=${cucina}"
echo "Rele: $rele"
echo "Controllo: $controllo" 


Configurazione del software installato

Va configurato il server web nginx editando il file:

/etc/nginx/sites-enabled/default

aggiungere index.php nela riga 25:

index index.php index.html index.htm;

aggiungere/verificare la gestione delle pagine php a partire dalla riga 40:

       location ~ \.php$ {
               fastcgi_split_path_info ^(.+\.php)(/.+)$;
               # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
               # With php5-cgi alone:
               # With php5-fpm:
               fastcgi_pass unix:/var/run/php5-fpm.sock;
               fastcgi_index index.php;
               include fastcgi_params;
       }

Installare phpredis facendo riferimento alle istruzioni sulla pagina dei sorgenti: https://github.com/nicolasff/phpredis

Una volta terminata l'installazione modificare il file php.ini copiando la riga dell'extension di redis dal file /etc/php5/cgi/php.ini e mettendola anche nel file /etc/php5/fpm/php.ini.

extension=/usr/lib/php5/20100525+lfs/redis.so

Restartare php5-fpm e nginx per applicare le modifiche.

A questo punto il server web dovrebbe essere funzionante.

Interfaccia web

Per la visualizzazione grafica si usa la libreria [5]Flotr2, seguire le istruzioni sul sito per l'installazione.

a questo punto si tratta di creare qualche pagina php per la visualizzazione e modifica dei dati.

Screen shoot

Imposta temperature
Imposta programma settimanale
Visualizzazzione grafica