Autor Thomas Eimers kam schon in der Kindheit mit Elektrotechnik in Berührung, der Vater war Rundfunkelektroniker. Beruflich ist Eimers "in einem größeren Umfeld der Softwareentwicklung tätig", beschäftigt sich als begeisterter Bastler in der Freizeit jedoch gern mit der Regel- und Steuerungstechnik. Und er ist, wie er selber sagt, bekennender Opensource-Fan. Hier stellt er sein Projekt einer Fußboden-Heizungssteuerung mit Linux und Raspberry Pi vor.
Die Anforderungen an den Regelkreis sind recht simpel: Der Brenner einer Heizung soll über die Regelung ein- und ausgeschaltet werden. Ob der Brenner ein- oder ausgeschaltet wird, hängt von den beiden Temperatursensoren (Außentemperatur und Temperatur des zurücklaufenden Wassers) ab. Die Pumpe, die im Wasserkreislauf für die Strömung sorgt, soll ebenso über die Regelung gesteuert werden und nur bei Bedarf laufen, was Strom spart.
Die Benutzer-Schnittstelle
Für die Heizungssteuerung wird ein 8 bis 10 Zoll großes Touchscreen verwendet werden. Das UI basiert auf jQuery Mobile, um die Bedienung zu vereinfachen. Die Menüführung weist den folgenden Aufbau auf:
Statistiken
Temperaturverlauf/Verbrauch für diesen Tag
Temperaturverlauf/Verbrauch für diese Woche
Temperaturverlauf/Verbrauch für diesen Monat
Temperaturverlauf/Verbrauch für dieses Jahr
Systemkonfiguration
Sollwertkurve Rücklauf
Pumpenkonfiguration
Nachtabsenkung
Temperaturfühler
Die aktuellen Informationen sind in einer Fußzeile auf jeder Seite abzulesen.
Entscheidung für den Raspberry Pi
Die Heizungssteuerung direkt unter Linux zu implementieren, bietet viele Vorteile, da man auf ein auf ein komplettes Betriebssystem zurückgreifen kann. Zu den Vorzügen gehören der einfache Netzwerkanschluss für Wartung, die Möglichkeit, Datenbanken für Temperaturwerte zu verwenden sowie einen Touchscreen als Interface anzuschließen. Frühere aufwändige Arbeiten wie das Anschließen eines DCF Empfängers (Funkuhr) werden damit unnötig, da hier beispielsweise das NTP des Internets zur Zeitsynchronisierung der Heizungssteuerung herangezogen werden kann.
Die Kosten für einen kompletten PC sind mittlerweile recht gering, besonders wenn es sich um Single-Board-PCs handelt. Der Aufbau mittels Standard-PC-Hardware ermöglicht, die Steuerung noch lange in Betrieb zu halten und auch in 10 Jahren noch auf Ersatzteile zurückgreifen zu können.
Bezug des Quellcodes
Der Quellcode steht unter der GPL-Lizenz, so dass die Steuerung nach Belieben für andere Zwecke angepasst werden kann.
Das Projekt Fußbodenheizungsteuerung ist auf Sourceforge verfügbar
Der komplette Quellcode für die neue Heizungssteuerung kann via SVN heruntergeladen werden
Download eines fertigen Images
Alle nachfolgenden Texte beschreiben die komplette Installation der Heizungssteuerung, die besonders wichtig sind, wenn die Steuerung für andere Zwecke eingesetzt werden soll. Ein fertiges Image der Steuerung als Download liegt alternativ ebenfalls bereit. Dies ist für den schnellen Einstieg oder für Linux- und PHP-Anfänger eine gute Wahl. Das Image ist auf Sourceforge verfügbar. Die Zugangsdaten für den SSH Login des fertigen Images lauten:
Benutzername "pi"
Password "raspheat"
Installation des kompletten Images (4-GByte-Speicherkarte nötig)
# Wichtig! /dev/sdX durch die Laufwerksbezeichnung der angeschlossenen Speicherkarte ersetzen
# (Liste kann mit "cat /proc/partitions" ermittelt werden)
# Der Vorgang dauert einige Minuten und erzeugt erst nach Fertigstellung eine Ausgabe
sudo su -
cat /proc/partitions
bunzip2 -dc dateiname_des_heruntergeladenen_images.img.bz2 | dd bs=1M of=/dev/sdX
Meldungen wie
"dd: »/dev/sdd" wird geschrieben: Auf dem Gerät ist kein Speicherplatz mehr verfügbar"
erfordern den Einsatz einer größeren Speicherkarte. Da nicht alle 4-GByte-Speicherkarten eine einheitliche Speicherkapazität aufweisen, empfiehlt sich die Verwendung einer 8-GByte-Karte.
Grundlagen für die Heizungssteuerung
Einige der verwendeten Tools/Bauteile/Software sind in den folgenden aufgeführten Artikeln teilweise ausführlicher beschrieben. Diese zu lesen ist nicht unbedingt erforderlich, sie können aber in Problemfällen hinzugezogen werden.
Die Hardwaresteuerung
Bei der Hardware handelt es sich um die externe Beschaltung (Platine), die die Schnittstelle zwischen dem Raspberry Pi und der Heizung darstellt. Die Platine ist über ein Flachbandkabel und einen Stecker mit dem Raspberry Pi verbunden. Der Raspberry Pi wird durch die Verwendung von Relais galvanisch getrennt. Über diese digitalen Ausgänge sollten Schütze angesprochen werden, die beispielsweise den Anlaufstrom der Pumpen verkraften.
Das Fertigen zweier Platinen ist für unter 20 Euro möglich. Um sich die Platine herstellen zu lassen, kann die Datei layout.brd an den Ätzservice eines Platinenbelichters gesendet werden, beispielsweise an den Service von Platinenbelichter.de.
Als Basissystem wird auf dem Raspberry Pi Raspbian, eine Debian-Variante, verwendet. Die Laufzeitumgebung ist eine typische LAMP-Umgebung, bestehend aus dem Apache Webserver, Mysql Datenbank, und PHP als Programmiersprache. Dies alles kann problemlos auf einer 4 GByte großen SD-Speicherkarte abgelegt werden.
Basissystem einrichten
Nun folgt die Einrichtung des Betriebssystems. Die einzelnen Schritte auf der Console können direkt unter Linux ausgeführt werden. An Stellen, an denen eventuelle Anpassungen vorgenommen werden müssen, erscheint ein entsprechender Vermerk.
wget "http://downloads.raspberrypi.org/raspbian_latest"
unzip raspbian_latest
# Ergebnis ist ein Image, mit einem Dateinamen ähnlich wie: 2014-01-07-wheezy-raspbian.img
# Wichtig! /dev/sdX durch die Laufwerksbezeichnung der Speicherkarte ersetzen
# (Liste der Speicherlaufwerke kann mit "cat /proc/partitions" angezeigt werden)
# Der folgende Vorgang dauert einige Minuten und erzeugt erst eine Ausgabe, wenn er fertig ist.
sudo dd bs=1024k if=2014-01-07-wheezy-raspbian.img of=/dev/sdX
Nun wird die erstellte SD-Karte in den Raspberry eingesteckt. Der Raspberry Pi verbindet sich mit dem Netzwerk, bootet und erhält dann über DHCP, etwa von einer Fritzbox, eine IP für das lokale Netzwerk. Der Netzwerkname ist mit "raspberrypi" voreingestellt. Das Passwort von Raspbian ist "raspberry", der SSH Benutzer ist "pi".
# auf den Raspberry über das Netzwerk verbinden, und
# mit dem Benutzer "raspberry" und dem Passwort "pi" anmelden
ssh -lpi raspberrypi
# Initiale Konfiguration
sudo raspi-config
#einmal "Expand Filesystem" aufrufen und einmal "Internationalisation Options", dort unter "Change Locale" de_DE.UTF-8 UTF-8
# stellen. Danach nochmal "Internationalisation Options" und dann "Change Timezone" auf "Europe/Berlin" stellen.
# danach das Passwort ändern "Change User Password" (im verfügbaren fertigen Image wurde dies auf 'raspheat' gestellt).
# dann im Hauptmenü Advanced Options - Hostname den Namen des Systems auf "heating" setzen.
#
# danach "Finish" und den Raspberry einmal neu starten lassen.
# erneut auf den Raspberry via Netzwerk verbinden
ssh -lpi heating
sudo rpi-update
sudo apt-get update; sudo apt-get upgrade
sudo apt-get install mc rrdtool owfs-fuse
# mit der Mysql-Installation wird das Mysql-Root-Passwort vergeben ('raspheat' habe ich genommen, bei mir im Image)
sudo apt-get install mysql-server-5.5
# als Server für phpmyadmin den Apache2 wählen. Konfiguration phpmyadmin mit dbconfig-common
# im Image wurde erneut das Passwort raspheat vergeben
sudo apt-get install htop apache2 libapache2-mod-php5 phpmyadmin php-pear php-apc secure-delete
# ist riesengroß und wird nicht gebraucht
sudo apt-get purge wolfram-engine
Der Apache-Webserver und phpmyadmin sind ab diesem Zeitpunkt verfügbar. Die Zugangsdaten für den phpmyadmin sind der Benutzer "root" und das Passwort "raspheat".
Temperatursensoren vorbereiten
Die Sensoren werden mittels owfs ausgelesen. Hierzu gibt es einen eigenen Artikel, Temperaturmessung mit Linux mittels DS9490R-USB, der ausführlich auf die Details eingeht. Der USB-Adapter und der Temperaturfühler sind vorab anzuschließen.
sudo mkdir /media/1-wire
sudo owfs --allow_other -u /media/1-wire
ls -lah /media/1-wire/
cat /media/1-wire/*/temperature
Eine Meldung, ähnlich dem folgenden Beispiel, erscheint.
pi@raspberrypi /media/l-wire $ cat /media/l-wire/*/temperature;
24.875 13.72321 _
Im vorliegenden Beispiel ist lediglich ein Sensor angeschlossen, der gerade 28.875 Grad misst. Es gibt auch Sensoren, die stets ausgelesen werden, unabhängig davon, ob ein Temperaturfühler angeschlossen ist. Dieser Sensor, der möglicherweise eingebaut ist, liefert immer unterschiedliche Temperaturen und ist zu ignorieren.
Hier ein Beispiel für den Raspberry Pi mit einem DS1820 Temperaturfühler sowie dem DS9490R USB Adapter:
Quellcode der Heizungssteuerung über das SVN Repository auschecken
Um die eingerichteten Temperaturfühler sinnvoll zu verwenden, wird nur der Quellcode des Projekts aus einem SVN Repository geladen.
sudo apt-get install subversion
cd ~
mkdir heating
cd heating
Wenn nur lesend auf das Project heatingcontrol zugegriffen werden soll:
svn checkout svn://svn.code.sf.net/p/heatingcontrol/code/trunk heatingcontrol-code
Wenn auch schreibender Zugriff auf das Projekt gewünscht ist (Sourceforge-Account vorausgesetzt):
svn checkout --username=euer_sourceforge_name svn+ssh://notdefine@svn.code.sf.net/p/heatingcontrol/code/trunk heatingcontrol-code
Konfiguration des Apache-Webservers
Im Folgenden ist der Inhalt der Datei "/etc/apache2/sites-available/default" dargestellt. Dieser Inhalt kann beispielsweise mit dem Befehl "sudo mcedit /etc/apache2/sites-available/default" angepasst werden, nachdem eine Verbindung mit dem Raspberry via SSH aufgebaut wurde.
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /home/pi/heating/www
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /home/pi/heating/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Der Apache-Webserver benötigt schreibenden Zugriff auf das temp-Verzeichnis:
cd ~/heating/www/common/temp
chmod 777 * -R .
Datenbank und Tabellen einrichten
Im Folgenden wird eine Verbindung zur Mysql-Datenbank als Root aufgebaut und danach ein Datenbankbenutzer inklusive Datenbank und dessen Tabellen angelegt.
mysql --user=root mysql --password
Folgender Befehl ist nun auszuführen:
CREATE DATABASE `heating` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
CREATE USER 'pi'@'localhost' IDENTIFIED BY 'raspheat';
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 'pi'@'localhost' IDENTIFIED BY 'raspheat' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
GRANT ALL PRIVILEGES ON `pi\_%` . * TO 'pi'@'localhost';
USE heating;
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE IF NOT EXISTS `desired_values` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`outside_temp` int(11) NOT NULL,
`return_flow_temp` float NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `outside_temp` (`outside_temp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Ruecklauftemperatur in abhaengigkeit der aussentemperatur.' AUTO_INCREMENT=61 ;
INSERT INTO `desired_values` (`id`, `outside_temp`, `return_flow_temp`) VALUES
(1, -35, 36), (2, -34, 36), (3, -33, 36), (4, -32, 36), (5, -31, 36), (6, -30, 36), (7, -29, 36), (8, -28, 36), (9, -27, 36), (10, -26, 36), (11, -25, 36),
(12, -24, 36), (13, -23, 36), (14, -22, 36), (15, -21, 36), (16, -20, 36), (17, -19, 36), (18, -18, 36), (19, -17, 36), (20, -16, 36), (21, -15, 36), (22, -14, 36),
(23, -13, 36), (24, -12, 36), (25, -11, 36), (26, -10, 36), (27, -9, 36), (28, -8, 36), (29, -7, 36), (30, -6, 36), (31, -5, 36), (32, -4, 36), (33, -3, 35),
(34, -2, 34), (35, -1, 32), (36, 0, 32), (37, 1, 32), (38, 2, 32), (39, 3, 32), (40, 4, 32), (41, 5, 31), (42, 6, 30), (43, 7, 30), (44, 8, 29), (45, 9, 29),
(46, 10, 28), (47, 11, 28), (48, 12, 27), (49, 13, 27), (50, 14, 26), (51, 15, 26), (52, 16, 26), (53, 17, 25), (54, 18, 25), (55, 19, 25), (56, 20, 25),
(57, 21, 11), (58, 22, 11), (59, 23, 11), (60, 24, 11);
CREATE TABLE IF NOT EXISTS `sensor_values` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8_bin NOT NULL,
`value` float NOT NULL,
`unit` varchar(100) COLLATE utf8_bin NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2657335 ;
CREATE TABLE IF NOT EXISTS `settings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_bin NOT NULL,
`unit` varchar(255) COLLATE utf8_bin NOT NULL,
`value` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=6 ;
INSERT INTO `settings` (`id`, `name`, `unit`, `value`) VALUES
(1, 'heater', 'bool', '1'),
(2, 'pump_follow_up_time', 'minutes', '45'), (3, 'slider_nighly_temperature_sink_substract', 'celsius', '13'),
(4, 'slider_nighly_temperature_sink_to', 'hour', '23'), (5, 'slider_nighly_temperature_sink_from', 'hour', '6');
quit
Cronjobs konfigurieren
Die Heizungssteuerung muss automatisch jede Minute aktiv werden, um die Temperaturen zu erfassen und gegebenenfalls einzugreifen. Zudem werden Diagramme in einem regelmäßigen Turnus generiert. Dafür wird das auf Linux-Systemen verfügbare Cronjob-Management verwendet. Folgend eine Liste der Cronjobs und deren Aufgaben:
• Watchdog - Prüft ob die Steuerung noch Werte ermitteln kann und startet das System im Fehlerfall neu.
• Cleanup - Beschränkt die in der Datenbank abgelegten gemessenen Werte und löscht Altdaten.
• Temperatur eintragen - Misst aktuelle Temperaturwerte und trägt diese in die Datenbank ein.
• Graphen erstellen - Erstellt mittels RRD-Tool die verschiedenen Temperaturgraphen (für den aktuellen Tag, für die Woche, usw.).
Die genauen Funktionen können im SVN-Quellcode angesehen werden.
Die Cronjobs des Benutzer pi kann man sich mit folgendem Befehl anzeigen lassen "crontab -l". Bearbeitet werden diese Cronjobs mit dem Befehl "crontab -e". Um diese Cronjobs nun auf den Raspberry zu übernehmen, müssen folgende Einträge (mittels "crontab -e") ergänzt werden:
#*/2 * * * * cd /home/pi && ./heating/watchdog.sh --> Inaktiv bis # entfernt wird, dass sollte gemacht werden, wenn alles komplett eingerichtet ist
0 2 * * * cd /home/pi && ./heating/cleanup.sh
* * * * * cd /home/pi && ./heating/insert_new_temp.sh >> /dev/null
*/5 * * * * cd /home/pi && ./heating/create_graph_quick.sh >> /dev/null
5 */2 * * * cd /home/pi && ./heating/create_graph_slow.sh >> /dev/null
Ob die Cronjobs auch aufgerufen werden, kann mit dem Befehl "tail -f /var/log/syslog" geprüft werden. Diese Logdatei zeigt jede Ausführung eines Cronjobs an.
RRD-Tool auf Jahres-, Wochen- und Tagesstatistiken vorbereiten
Um die gemessenen Werte grafisch darzustellen, wird das bekannte RRD-Tool verwendet.
Die Datenbank der Temperaturwerte wird so eingerichtet, dass sie die Werte der letzten zwei Jahre beinhaltet. Die gemessenen Werte werden alle zwei Minuten eingetragen (120*24*365*2=525600 Anzahl der zu speichernden Temperaturwerte für den Zeitraum von zwei Jahren). Das Skript 'init_rrdtool.sh' legt die dafür nötige RRDTool Datenbank an.
cd heating/jobs
./init_rrdtool_db.sh
Angeschlossenene Sensoren zuweisen
Eine Liste aller Sensoren erhält man mit folgenden Befehlen:
cd heating/jobs
./list_sensors.sh
Dies sollte eine Liste wie diese hier anzeigen. Hiermit kann man bestimmen, welcher Sensor welche Temperatur misst:
/media/1-wire/05.4AEC29CDBAAB Sensortyp: DS2405
/media/1-wire/10.49EE82020800 Sensortyp: DS18S20 Temperatur: 22.125
/media/1-wire/10.49EE83020800 Sensortyp: DS18S20 Temperatur: 32.125
/media/1-wire/10.49EE83020900 Sensortyp: DS18S20 Temperatur: 4.125
/media/1-wire/10.67C6697351FF Sensortyp: DS18S20 Temperatur: 63.5712
/media/1-wire/81.323132000000 Sensortyp: DS1420
Die einzelnen Sensoren weist man (leider etwas unkomfortabel) direkt im Cronjob zu. Hierzu bearbeitet man dieDatei insert_new_temp.sh mit "mcedit ~/heating/jobs/insert_new_temp.sh".
Tests einrichten
Um die Steuerungssoftware automatisiert zu testen, wird PHPUnit verwendet. Die Einrichtung ist für den Betrieb der Steuerung optional, aber für professionelle Softwareentwicklung unverzichtbar, besonders wenn Modifikationen an der Software gemacht werden sollen.
sudo apt-get install phpunit
Unleserliche xdebug "var_dump()" Befehle können durch den Eintrag der Konfigurationsvariablen
'xdebug.overload_var_dump=0' in die PHP Serverkonfigurationsdatei '/etc/php5/apache2/php.ini'
abgeschaltet werden. Die Tests (phpunit) werden mit folgenden Befehlen ausgeführt:
cd ~/heating/tests
phpunit
GPIO-Schnittstellenports vorbereiten
Um die externe Beschaltung auf der Platine ansprechen zu können, müssen die GPIO-Ports eingerichtet werden. Damit man ohne Super-User-Rechte auf die GPIO-Ports zugreifen kann (InterfaceGpio.class.php), sind zwei Schritte erforderlich:
1. Den Benutzer "www-data "in die Gruppe "gpio" eintragen.
2. Die "/etc/rc.local" anpassen.
sudo usermod -aG gpio www-data
Es muss folgender Code in die /etc/rc.local eingetragen werden:
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
/home/pi/heating/jobs/init_boot.sh
exit 0
Fertig - glücklich sein!
Die Steuerung ist nun komplett eingerichtet und kann an die Heizung angeschlossen werden. Bei mir läuft sie seit einem Jahr ohne Ausfälle im Betrieb.
Backup der Steuerung erstellen und Wiederherstellen
Heruntergeladene Pakete löschen:
sudo apt-get clean
sudo rm /var/log/*.gz
sudo rm /var/log/*.1
sudo rm /var/log/apache2/*.gz
sudo rm /var/log/apache2/*.1
cd ~
# Freien Speicherplatz mit "0" überschreiben, damit das Image kleiner gepackt werden kann
sfill -ll -f -z .
Backup erstellen
sudo dd bs=1M if=/dev/sdd of=heating_control_2014_02_09.img
Backup wieder herstellen
sudo dd bs=1M if=heating_control_2014_02_09.img of=/dev/sdd
(PC-Welt/ad)