Eine in die Jahre gekommene, mittels eines PIC AT89 implementierte Heizungssteuerung soll nach einem Jahrzehnt durch eine neue Variante ersetzt werden. Da die Hardware, sowie die Programmierung in Assembler recht aufwändig war, möchte ich auf etwas einfacheres zurückgreifen.
Da ich viel mit Linux Arbeite, bietet es sich an die Heizungssteuerung direkt unter Linux zu implementieren, und auf die Vorteile eines kompletten Betriebssystems zurückgreifen zu können. Hierzu gehören der einfache Netzwerkanschluss für Wartung, die Möglichkeit Datenbanken für Temperaturwerte zu verwenden, sowie ein Touchscreen als Interface anzuschliessen. Früher aufwändige arbeiten, wie das anschließen eines DCF Empfängers (Funkuhr) sind unötig, da einfach NTP zur Zeitsyncronisierung übers Netzwerk verwendet werden kann.
Der Quellcode für die neue Heizungssteuerung ist via SVN verfügbar.
Die Kosten für einen kompletten PC sind mittlerweile recht gering, besonders wenn es sich um SingleBoard PCs handelt. Der Aufbau auf Standard PC Hardware ermöglicht, diese noch Lange in Betrieb zu halten, und auch in 10 Jahren noch auf entsprechende Hardwar zurückgreifen zu können.
sudo apt-get install rrdtool phpmyadmin mysql-server-5.5 owfs-fuse
Die Sensoren werden mittels owfs ausgelsen, siehe dazu Artikel Temperaturmessung mit Linux mittels DS9490R-USB
sudo mkdir /media/1-wire sudo owfs --allow_other -u /media/1-wire ls -lah /media/1-wire/
Die Datenbank beinhaltet die Werte der letzten 2Jahre in 2Minuten Takt angegeben: 120*24*365*2=525600 zu speicherenden Werten.
/home/pi/heating/init_rrdtool.sh (Der Quellcode ist via SVN verfügbar.)
#!/bin/bash # rrdtool Datenbank für Statistiken als Grafik anlegen cd ~ mkdir .temperature rrdtool create .temperature/temp.rrd --step 60 DS:tempOutside:GAUGE:300:-30:60 RRA:LAST:0.5:2:525600 DS:tempInside:GAUGE:300:-30:60 RRA:LAST:0.5:2:525600 DS:tempWaterReturn:GAUGE:300:-30:60 RRA:LAST:0.5:2:525600 DS:tempWaterTarget:GAUGE:300:-30:60 RRA:LAST:0.5:2:525600 DS:burnerActive:GAUGE:300:-30:60 DS:burnerAmount:GAUGE:300:-30:60 RRA:LAST:0.5:2:525600/home/pi/heating/create_graph_quick.sh (Der Quellcode ist via SVN verfügbar.)
#!/bin/bash # Heizungstatistikten als Bilder erstellen cd ~ #36h nice rrdtool graph -w1000 -h310 /var/www/temp_day.png -a PNG --full-size-mode --title="Temperatur 36h" --start -129600 --vertical-label "Grad Celsius" --x-grid HOUR:1:HOUR:2:HOUR:2:86400:%H \ 'DEF:probe1=.temperature/temp.rrd:tempOutside:LAST' \ 'DEF:probe2=.temperature/temp.rrd:tempInside:LAST' \ 'DEF:probe3=.temperature/temp.rrd:tempWaterReturn:LAST' \ 'DEF:probe4=.temperature/temp.rrd:tempWaterTarget:LAST' \ 'DEF:probe5=.temperature/temp.rrd:burnerActive:LAST' \ 'DEF:probe6=.temperature/temp.rrd:burnerAmount:LAST' \ 'LINE1:probe1#008000:Außen' \ 'LINE1:probe2#0000C0:Innen' \ 'LINE1:probe3#FF0000:Rücklauf' \ 'LINE1:probe4#C05800:Sollwert' \ 'LINE1:probe5#000000:Brenner' \ 'LINE1:probe6#808000:Verbrauch m³' \ 'GPRINT:probe1:LAST:Außentemp.\: %2.1lf°' #8tage nice rrdtool graph -w1000 -h310 /var/www/temp_week.png -a PNG --full-size-mode --title="Temperatur 8 Tage" --start -691200 --vertical-label "Grad Celsius" \ 'DEF:probe1=.temperature/temp.rrd:tempOutside:LAST' \ 'DEF:probe2=.temperature/temp.rrd:tempInside:LAST' \ 'DEF:probe3=.temperature/temp.rrd:tempWaterReturn:LAST' \ 'DEF:probe4=.temperature/temp.rrd:tempWaterTarget:LAST' \ 'DEF:probe6=.temperature/temp.rrd:burnerAmount:LAST' \ 'LINE1:probe1#008000:Außen' \ 'LINE1:probe2#0000C0:Innen' \ 'LINE1:probe3#FF0000:Rücklauf' \ 'LINE1:probe4#C05800:Sollwert' \ 'LINE1:probe6#808000:Verbrauch m³'
sudo apt-get install mysql-server-5.5 (hierbei wird mysql root passwort vergeben) sudo apt-get install phpmyadmin
Mit Mysql Datenbank als root verbinden, und Benutzer, Datenbank und Tabellen anlegen.
mysql --user=root mysql --password
CREATE DATABASE `heating` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; CREATE USER 'heating'@'localhost' IDENTIFIED BY 'hiereinpasswort'; GRANT SELECT , INSERT , UPDATE , DELETE , CREATE , DROP , FILE , INDEX , ALTER , CREATE TEMPORARY TABLES , CREATE VIEW , EVENT, TRIGGER, SHOW VIEW , CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON * . * TO 'heating'@'localhost' IDENTIFIED BY 'hiereinpasswort' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; GRANT ALL PRIVILEGES ON `heating\_%` . * TO 'heating'@'localhost';
Die Tabellen in dieser Datenbank, welche die gelesenen Werte und vom Benutzer getätigten Eisntellungen vorhalten, werden automatisch von den Skripten angelegt.
/home/pi/heating/insert_new_temp.sh (Der Quellcode ist via SVN verfügbar.) Die Sensorenkonfiguration muss den gegebenheiten angepasst werden, bei mir lautet ein Sensor z.B. 10.2D9E8D020800.
#!/bin/bash
# Sensoren abfragen
# alte messmethode über digitemp
# temp hat danach werte wie 23.123412
# t0 bis tn müssen den entsprechenden Sensoren zugewiesen werden
#outsideTemp="`cd ~; timeout 15 digitemp_DS9097 -o "%.1C" -t0 -q && touch .last_value_read1`"
# neue Meßmethode über DS9490R USB Adapter
outsideTemp=`cat /media/1-wire/10.2D9E8D020800/temperature | tr -d ' '`
tempWaterReturn=`cat /media/1-wire/10.7BAA77020800/temperature | tr -d ' '`
insideTemp=`cat /media/1-wire/10.1EB78D020800/temperature | tr -d ' '`
# Heizung an ;)
#outsideTemp=12
echo outside_temp: $outsideTemp
echo inside_temp : $insideTemp
echo return_temp : $tempWaterReturn
mysql --host=localhost --user=heating --password=hiereinpasswort heating << EOF
INSERT INTO sensor_values (name, value, unit, timestamp) VALUES ('outside_temp', '$outsideTemp', 'celsius', NOW());
INSERT INTO sensor_values (name, value, unit, timestamp) VALUES ('return_temp', '$tempWaterReturn', 'celsius', NOW());
INSERT INTO sensor_values (name, value, unit, timestamp) VALUES ('inside_temp', '$insideTemp', 'celsius', NOW());
EOF
cd /var/www/
# Status Heizung jede Minute setzen
php ./update_status.php
# der Verbrauch an Gas wird errechnet (skript gibt nur zahl ohne Newline zurück)
gasAmount=`php ./get_burner_amount.php`
echo gasAmount : $gasAmount
# Die soll rücklauftemperatur wird errechnet
tempWaterTarget=`php ./get_target_return_flow_temp.php`
# target return temp wird von update_status.php eingetragen, wird hier nur ausgelesen
#tempWaterTarget=`expr $tempWaterTarget \* 1`
echo target_temp : $tempWaterTarget
# Ob der Brenner ein/aus ist, wird errechnet
burnerActive=`php ./get_burner_status.php`
# Brenner soll von 0/1 auf 5/10 umgewandelt werden, damit es im Diagramm lesbar ist
burnerActive=`expr $burnerActive \* 5 + 5`
# burner status wird von update_status.php eingetragen, wird hier nur ausgelesen
echo burner active : $burnerActive
cd ~
echo rrdtool update .temperature/temp.rrd N:"$outsideTemp":"$insideTemp":"$tempWaterReturn":"$tempWaterTarget":"$burnerActive":"$gasAmount" && touch .last_value_read
# Gemessene Temperatur in RRDTool eintragen
rrdtool update .temperature/temp.rrd N:"$outsideTemp":"$insideTemp":"$tempWaterReturn":"$tempWaterTarget":"$burnerActive":"$gasAmount" && touch .last_value_read
/home/pi/heating/cleanup.sh (Der Quellcode ist via SVN verfügbar.)
/etc/crontab*/2 * * * * pi cd /home/pi && ./heating/watchdog.sh 0 2 * * * pi cd /home/pi && ./heating/cleanup.sh * * * * * pi cd /home/pi && ./heating/insert_new_temp.sh >> /dev/null */5 * * * * pi cd /home/pi && ./heating/create_graph_quick.sh >> /dev/null 5 */2 * * * pi cd /home/pi && ./heating/create_graph_slow.sh >> /dev/null
Damit ohne Superuserrechte auf die GPIO Ports zugegriffen werden kann (InterfaceGpio.class.php), muss folgender Code in die /etc/rc.local eingetragen werden.
echo "Init 1Wire" owfs --allow_other -u /media/1-wire echo "Init GPIO" #Watchdog soll nicht direkt anspringen touch /home/pi/.last_value_read chown pi /home/pi/.last_value_read echo "17" > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio17/direction chmod 666 /sys/class/gpio/gpio17/value chmod 666 /sys/class/gpio/gpio17/direction echo "0" > /sys/class/gpio/gpio17/value echo "22" > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio22/direction chmod 666 /sys/class/gpio/gpio22/value chmod 666 /sys/class/gpio/gpio22/direction echo "0" > /sys/class/gpio/gpio22/value echo "23" > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio23/direction chmod 666 /sys/class/gpio/gpio23/value chmod 666 /sys/class/gpio/gpio23/direction #input port. Wird 1 wenn pin auf 3.3V gelegt wird echo "11" > /sys/class/gpio/export echo "in" > /sys/class/gpio/gpio11/direction chmod 666 /sys/class/gpio/gpio11/value chmod 666 /sys/class/gpio/gpio11/direction #Blinken mit LED um fertigen Startvorgang zu melden echo "0" > /sys/class/gpio/gpio23/value; sleep 1 echo "1" > /sys/class/gpio/gpio23/value; sleep 1 echo "0" > /sys/class/gpio/gpio23/value; sleep 1 echo "1" > /sys/class/gpio/gpio23/value; sleep 1 echo "0" > /sys/class/gpio/gpio23/value; sleep 1 echo "1" > /sys/class/gpio/gpio23/value; sleep 1 echo "0" > /sys/class/gpio/gpio23/value; sleep 1 echo "1" > /sys/class/gpio/gpio23/value;
Für die Heizung soll ein 8-10Zoll Touchscreen verwendet werden. Um die Bedieunung zu vereinfachen werde ich das UI auf Basis von jQuery Mobile aufbauen. Die geplante Menüführung hat folgenden Aufbau