IoT Heizungssteuerung 2 (Web Interface)

Ein Web Interface ist besonders hilfreich, wenn man seinen Pi von unterwegs steuern möchte. Ich habe hier eine sehr einfach gehaltene Lösung für meinen Anwendungsfall IoT Heizungssteuerung (LCD Panel) erstellt.
Diese Lösung lässt sich beliebig anpassen. Was allerdings noch fehlt, ist ein responsive  Design, das auch auf Smartphones und Tablets ohne Zoomen gut aussieht.

rustimation_php

Damit das funktioniert, müsst ihr einen Webserver sowie php installieren. Welchen Webserver ihr verwendet ist eigentlich egal. Ich verwende Lighttpd. Er ist relativ schlank und trotzdem leistungsfähig. Anleitungen zur Installation gibts im Web zuhauf.

Ich habe mich an diese hier gehalten: http://www.penguintutor.com/linux/light-webserver. Die Anleitung enthält auch die Schritte zur Installation von PHP. Mysql braucht ihr nicht zu installieren. Eine sehr gute Anleitung auf Deutsch gibt es auch bei Kampis Elektroecke.

PHP mag ich nicht besonders. Zumal das Debuggen nicht ganz einfach ist. Hat man einen schwerwiegenderen Fehler gemacht (und sei es nur ein vergessenes Semicolon am Ende einer Programmzeile) gibt es einfach ein weißes Browserfenster.

Wem das Editieren mit einem der im Pi eingebauten Editoren (nano, vi) oder auf dem Desktop z.B. mit Idle zu mühsam ist, dem empfehle ich diesen Artikel hier.

Programmstruktur

Okay, ich gebs zu, meine html Skripte sind nicht besonders schön. Außerdem habe ich aus Bequemlichkeit teilweise mit Frames (gelten als veraltet) gearbeitet und auch noch iFrames dazugemischt.

Im Prinzip gibt es 5 einzelne Seiten, die miteinander über die Frame Definitionsseite index.html oder das PHP Formular verbunden sind:

  • index.html enthält die Frame Definitions
  • top Frame.html einen beliebigen Seitenkopf
  • leftFrame.php das Menü und die Buttons inklusive einem iFrame, der ein Log der Ein- und ausschaltvorgänge anzeigt
  • log.php zum Auslesen und anzeigen der vergangenen Schaltvorgänge in oben erwähntem iFrame
  • set_temp.php zum Wegspeichern der Werte nachdem der „Speichern“ Button geklickt wurde.

 

Index.html

Das Ganze ist wie folgt aufgebaut, zuersteinmal kommt die Datei index.html zum Zug, die den Seitenaufbau im Bereich <frameset ….> bis </frameset> definiert. Oben wird ein schöner Überschriftsbereich namens topFrame.html definiert, darunter kommt der eigentliche Eingabebereich leftFrame.php und dann noch ein Ausgabebereich set_temp.php

topFrame.html

Diese Seite hat lediglich eine gestalterische Funktion und kann nach eigenen Wünschen angepasst werden.

LeftFrame.php

Die wesentlichen Punkte sind unterhalb des Programmlistings erklärt

Was passiert da?
Nach den Headerinformationen über Schriftart und so weiter folgt ein PHP Abschnitt mit einem kurzen Debug Snippet, das wenigstens die gröbsten Fehler auswirft.

Dann wird die Datei settings.dat geöffnet und ausgelesen. Ist diese nicht vorhanden, werden Default Werte genommen. Anschließend werden aktuelle Temperatur und  aktueller Status ausgelesen.

Wenn ihr mit Raspbian Wheezy arbeitet, muss das Python Skript get_temperature.py als sudo aufgerufen werden. Das geht aber nicht so ohne weiteres, weil der Webserver-User www-data aus Sicherheitsgründen nicht als sudo arbeiten darf. Deshalb müsst ihr eine Ausnahme einstellen. Das geschieht mit dem Befehl sudo visudo .
Dort tragt ihr als Letztes
folgende Zeile ein:
www-data ALL=(ALL) NOPASSWD: /home/pi/heizung/get_temperature.py
(natürlich müsst ihr den Pfad eintragen, der zu eurem Python Programm führt.)
Visudo ist nicht ohne. Wenn ihr hier einen Fehler macht, und diesen wegspeichert, kann es sein, dass ihr den Superuser getötet habt und so auch keinen sudo mehr verwenden könnt. Visudo ist aber so nett und warnt einen, dass die Datei so nicht funktionieren wird. In diesem Fall lieber abbrechen, kontrollieren und neu eingeben. Mit Strg-X speichert ihr eure Eingabe und kommt auf den Prompt zurück.
All das ist bei Raspbian Jessie nicht mehr nötig, der Sensor kann ohne sudo abgefragt werden..

Dann kommt der Formularbereich mit den Drop Down Feldern für Temperatur und Uhrzeit. Die vorbelegten bzw. ausgelesenen Parameter für Temperatur- und Nachtzeiteinstellung werden dabei als Voreinstellung übernommen. Das Ganze ist etwas mühsam und mit viel Schreibarbeit verbunden.

In das Skript ist noch ein iFrame zur Anzeige des Logs eingebettet, welches wir über das folgende Skript erzeugen:

log.php

Im PHP Teil werden über den Shell Befehl tail die letzten 250 Zeilen des vom Python Programm erzeugte Logs eingelesen. Da normale Zeilenumbrüche chr(10) in html nicht funktionieren, werden sie noch über die Funktion str_replace in den html Zeilenumbruch <br> umgewandelt.

Über den Javascript Teil wird erreicht, dass im Iframe ganz nach unten gescrollt wird.

set_temp.php

Dieses Skript wird nach dem Klicken auf „Einstellungen speichern“ erneut aufgerufen und speichert dann die in den Drop Down Feldern (auch Comboboxen genannt) eingestellten Werte in der Datei settings.dat. Diese Steuerdatei wird wiederum von der Python Routine verwendet um den Temperatur Soll-/Istvergleich vorzunehmen.

Die Werte werden nur gespeichert, wenn der Parameter „nightstart“ vom aufrufenden Programm gesetzt wurde. Beim ersten Aufruf der Website wird set_temp.php zwar auch geladen, nightstart ist jedoch leer und es findet deshalb keine Speicherung und keine Anzeige statt.

Das wars eigentlich schon. Ganz schön viel Holz für so eine kleine Anwendung!

Abschluss und Optimierung

Autostart

Das Python Programm – bei mir heißt es lcd_menu_integrated.py- muss jetzt noch beim Systemstart automatisch hochgefahren werden. Das geschieht über die Crontab welche ihr mit sudo crontab -e aufruft und dann am Ende folgende Zeile eintragt:

reboot

Mit Strg-X wird gespeichert und ihr verlasst den Editor.

Wie immer müsste ihr den korrekten Pfad und Skriptnamen verwenden.

SD Kartenverschleiß vermeiden

Wie ihr vielleicht wisst, ist die SD Karte des Raspberry Pi vor allem im Dauerbetrieb einem ziemlichen Verschleiß unterworfen. Schreibvorgänge in Logs oder laufend weggeschriebene Statusinformationen führen nach ein paar Monaten Dauerbetriebs unweigerlich zu (Datei-)Korruptionen wie sie beim IOC oder der FIFA nicht schlimmer sein könnten 🙂

Das können wir vermeiden, indem wir in einem ersten Schritt die laufende Statusinformation, die im Verzeichnis /tmp abgelegt wird, nicht auf die SD Karte sondern auf eine Art RAMdisk schreiben. Die RAMdisk liegt im Arbeitsspeicher des Pi und unterliegt keinem Verschleiß. Dazu legen wir einfach das Verzeichnis /tmp in den Arbeitsspeicher. Allerdings ist es wichtig zu wissen, dass Dateien im RAM beim Ausschalten oder einem Neustart verloren gehen.
Indem ihr die fstab – das ist die die File System Table – editiert,

sudo nano /etc/fstab

könnt ihr /tmp (und natürlich auch andere Verzeichnisse) ins RAM legen.

Am Ende der fstab folgenden Eintrag vornehmen:

tmpfs /tmp tmpfs defaults,noatime,nosuid,size=100m 0 0

Nach dem nächsten Start wird das Verzeichnis im Arbeitsspeicher angelegt. Das Schöne an tmpfs ist, dass nur der Platz reserviert wird, der tatsächlich benötigt wird. Auch wenn wie oben die maximale Größe mit 100MB angegeben ist, sind es tatsächlich nur wenige Byte, die wir für das Statusfile brauchen.

Nun könnte man auf die Idee kommen, einfach auch das sehr beanspruchte Log Verzeichnis /var/log ins RAM zu verlegen. Das funktioniert nur teilweise, denn der Lighty Webserver weigert sich dann zu starten.

Im deutschsprachigen Raspberry Pi Forum gibt es aber eine hervorragende Anleitung von der „Raspberry Pi Legende“ Meigrafd, wie man das doch hinbekommt:

http://www.forum-raspberrypi.de/Thread-tutorial-var-log-in-eine-art-ramdisk-auslagern-weitere-optimierungen-bezgl-logs

Passwortschutz für das Webinterface

Wenn ihr bis hierher gekommen seid, liegt der Gedanke nahe, das Webinterface auch von unterwegs aufzurufen. Dazu müsst ihr euren Router so konfigurieren, dass eine von euch gewählte Portadresse auf den Pi umgeleitet wird. Wie das mit einer Fritzbox funktioniert, habe ich im Kapitel Portfreischaltung meines Artikels „Dynamische IP Adresse mit Bordmitteln“ beschrieben. Weiter unten in demselben Artikel steht auch, wie man das Verzeichnis eures Webinterfaces mit einem Passwortschutz versieht. Ihr wollt ja sicher nicht, dass irgend welche bösen Buben eure Heizung manipulieren.

Eine weitere, sehr gute Möglichkeit einzelne Webseiten Verzeichnisse mit einem verschlüsselten Passort zu sichern, ist im nachfolgenden Link beschrieben: http://jacobsalmela.com/password-protect-a-lighttpd-web-server-on-a-raspberry-pi-using-mod-auth/

Viel Spaß und gutes Gelingen!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Wordpress Anti-Spam durch WP-SpamShield