Gewächshaussteuerung – Raspberry – Teil 1 Webplattform (Fleck, Haas, Strieder)

Ziel dieser Übung ist es Sensordaten bezüglich Temperatur und Feuchtigkeit zu sammeln und diese in einer SQLite Datenbank zu speichern. Diese Daten dienen der anschließenden Anzeige auf einem Webserver.

Schritt 1 – Installation & Erstkonfiguration Raspbian Zuerst wird die vorhandene Speicherkarte mittels SDFormatter formatiert.

r06

Anschließend wird ein aktuelles Image Raspian Wheezy heruntergeladen (Quelle: https://www.raspberrypi.org/downloads/) und extrahiert.

r07

Das extrahierte Image wird danach mittels Win32DiskImager (Quelle: http://sourceforge.net/projects/win32diskimager/) auf die Speicherkarte kopiert.

r05

Sollte es zu Problemen kommen findet man eine detailierte Anleitung hier: https://www.raspberrypi.org/documentation/installation/installing-images/windows.md

Schritt 2 – Raspbian Einstellungen raspi-config, Filesystem, IP static

Aufruf der Konfigurationsdatei mittels sudo raspi-config. Anpassungen der Ländereinstellungen wie Zeitzone auf CET und Tastaturlayout auf deutsch.

4 Internationalisation Options   Set up language and regional settings to match your location

Zusätzlich musste um den vollen Speicherplatz der SD Karte zu nutzen ein expand Filesystem in dieser Konfig Datei ausgeführt werden.

1 Expand Filesystem              Ensures that all of the SD card storage is available to the OS

Anschließend wurden mit FINISH die Änderungen bestätigt.

Es folgt die Anpassung der IP Adresse des Raspberry damit dieser zukünftig via SSH immer mit der gleichen IP angesprochen werden kann. Dazu öffnet man die Einstellungen der Netzwerkkarte.

sudo nano /etc/network/interfaces

und kommentiert die Zeile mit eth0 aus und erstellt einen neuen Eintrag:

iface eth0 inet static
    address 192.168.7.100
    netmask 255.255.255.0
    gateway 192.168.7.150
danach muss die Netzwerkkarte neu gestartet werden:
sudo /etc/init.d/networking restart
Mittels ping auf http://www.orf.at wird die Funktion und die Übernahme der Einstellungen geprüft auf Konnektivität.

Schritt 3 – Temperatur und Luftfeuchtigkeit (Humidity) auslesen

Zu aller erst verkabeln wir den Sensor korrekt auf einem Prototype Board. Wir verbinden dazu GPIO22, GND und 3,3V mit dem Sensor wie auf Foto ersichtlich:

sensor1

sensor2

Da wir den DHT22 mittels bereits vorgefertigter Platine nutzen ersparen wir uns die Verwendung einen zusätzlichen Widerstandes Resistors.

sensor3

Um den Sensor ansprechen zu können müssen wir uns eine entprechende Library downloaden.

Bevor man neue Software installiert sollte immer ein

sudo aptget update

sudo aptget upgrade y

ausgeführt werden.

Um C Librarys mittels Pyhton nutzen zu können benötigen wir einige Pakete mitsamt seinen Abhängigkeiten.

python development package provides the necessary header files for your version of Python

Wir erstellen ein Verzeichnis für die Library und wechseln in dieses.

mkdir -p /home/pi/sources

cd /home/pi/sources

git clone https://github.com/adafruit/Adafruit_Python_DHT.git

mittels ls im Verzeichnis in sources erkennt man nun das ein neues Verzeichnis dazugekommen ist:

Adafruit_Python_DHT wir wechseln in dieses mittels cd Adafruit_Python_DHT

Wir installieren die Library:

sudo python setup.py install

das war’s nun sollten wir das Script ausführen können und bereits Werte erhalten:

sudo /home/pi/sources/Adafruit_Python_DHT/examples/AdafruitDHT.py 22 22

Als Übergabe Werte dienen als erster Wert der Chipsatz der DHT Sensors 22. Der zweite Wert stellt den GPIO Port dar an welchem der Sensor angeschlossen ist. In unserem Falle auch 22.

Hätte man z.B. den alten DHT11 Sensor auf 13 angeschlossen würde diese Zeile wie folgt lauten:

sudo /home/pi/sources/Adafruit_Python_DHT/examples/AdafruitDHT.py 11 13

sensor4

 

Um zukünftig auch von außen via öffentlicher IP Adresse auf den Raspberry zuzugreifen (SSH oder Webzugriff) wird es notwendig ein Portforwarding einzurichten sowie einen DNS Service.

11

 

12

 

Dazu wurde ein Account beim Anbieter no-ip angelegt und im Router 2 Regeln definiert. Eine für den SSH Zugriff und eine für einen Webzugriff.

13

 

 

Schritt 4 – Installation node.js, sqlite

Was ist Node.js? Wikipedia schreibt hierzu folgende Definition:

Node.js ist eine serverseitige Plattform zum Betrieb von Netzwerkanwendungen. Insbesondere lassen sich Webserver damit realisieren. Node.js basiert auf der JavaScript-Laufzeitumgebung „V8“, die ursprünglich für Google Chrome entwickelt wurde, und bietet daher eine ressourcensparende Architektur, die eine besonders große Anzahl gleichzeitig bestehender Netzwerkverbindungen ermöglicht.

Zur Installation könnten wir nun einfach

sudo apt-get install node eingeben. Dies hätte aber den Nachteil dass uns das System hier ein veraltetes Node Paket liefern würde.

Daher werden wir uns selbständig die zum Projektzeitpunkt aktuellste Stable Version downloaden und installieren.

Wir erstellen ein Arbeitsverzeichnis im Home Directory (cd ~ ) Names node_source und wechseln anschließend in diese;

mkdir node_source

cd node_source

Danach holen wir uns das aktuellste Paket mittels

git clone https://github.com/joyent/node.git

01

Damit wir das Paket auf unserer Plattform kompilieren können benötigen wir noch ein zusätzliches Paket:

sudo apt-get install build-essential

Anschließend bearbeiten wir die Konfigurationsdatei von zuvor heruntergeladenen Nodepaket und  welchseln dazu in das Verzeichnis node_source / node /:

cd node

nano configure

Unsere Konfigurationsdatei sieht wie folgt aus:

02

Nun kompilieren wir das Paket:

sudo make

03

und anschließend installieren das kompilierte Paket

sudo make install

Nachdem die Installation abgeschlossen wurde, installieren wir einen Node eigenen Webserver express.js. Dazu nutzen wir den Package Manger von Node.js npm.

sudo npm install -g express

und natürlich benötigen wir noch ein Datenbank System für die Unterstützung von SQLite

sudo npm install dblite

Warum dblite anstatt sqlite?

Hinweise des Autors:

I’ve created dblite module because there’s still not a simple and straight forward or standard way to have sqlite in node.js without requiring to re-compile, re-build, download sources a part or install dependencies instead of simply apt-get install sqlite3 or pacman -S sqlite3 in your *nix system.

dblite has been created with portability, simplicity, and reasonable performance for embedded Hardware such ARM boards, Raspberry Pi, Arduino Yun, Atmel MIPS CPUs or Linino boards in mind.

Weitere Infos: https://github.com/WebReflection/dblite

Am Bild erkennt man gut, was passiert wenn man sudo npm install sqlite3 eingibt:

04

 

Damit unsere Javascripts mit der GPIO Schnittstelle kommunizieren können benötigen wir noch ein entsprechendes Node Modul:

npm install rpigpio

Die Installation aller benötigten Komponenten ist nun abgeschlossen.

 

Schritt 5 – Programmierung der benötigten Scripte / Schnittstellen

Erstellung einer einer Datenbank local.db inkl. Anlage von Tabellen zur Speicherung der Sensordaten.

05

Erstellung der Serverdatei server.js

06

Wir laden nun alle am lokalen Rechner erstellten CSS, Javascript und HTML Dateien hoch zum Raspberry und starten den Server von Node mittels

node server.js

beenden können wir diesen mittels STRG+C

08

09

10

 

 

Testaufbau Nr. 2 – Eigenständiger externer PHP, MySQL Webserver

Schritt 1 bis 3 sind ident

Schritt 4 – Webserver Testumgebung

Ziel dieser Übung ist es Sensordaten bezüglich Temperatur und Luftfeuchtigkeit zu sammeln und diese anschließend an einen entfernten Webserver zu senden um diese dort in einer MySQL Datenbank zu speichern. Dadurch sollen die Ressourcen des Raspberry Pi’s geschont werden.
Erstellung eines Web FTP Accounts, einer MySQL Datenbank und einer ersten Tabelle in welche die Sensordaten gespeichert werden.
Da unser Projektteam ohnehin einen gemieteten Webserver besitzt der mit PHP, Python und MySQL Unterstützung kommt, haben wir einen Teil dieses Webservers reserviert für das Gewächshaus Projekt. raspberry.itc-haas.at

r01
Anschließend haben wir eine MySQL Datenbank angelegt. In weiterer Folge wurde der MySQL Dumper auf diesem Webspace installiert. Dieser dient in dazu um Sicherungen der ganzen Datenbank anlegen zu können. Des weiteren ist es mit dem Programm komfortabler zu arbeiten als mit dem standardmäßig installiertem Phpmyadmin.

r02

 

Dazu muss man die Installationdateien downloaden, entpacken und in ein Verzeichnis seiner Wahl auf dem Webserver laden. Anschließend muss man ein Verzeichnis mit dem Namen work erstellen und diesem die Berechtigung 777 erteilen.

Es folgt die Installation des dumpers mit Hilfe des Aufrufes des Verzeichnis indem der Dumper liegt. Eine Schritt für Schritt Anleitung begleitet durch die Installation. Diese ist nicht sonderlich schwierig man muss lediglich die Datenbank Verbindungsdaten kennen und diese eingeben.

Nach vollendeter Installation wird man darauf hingewiesen dass man einen Verzeichnisschutz anlegen muss um den Dumper und die dahinter liegenden Datenbanken abzusichern. Dieser kann einfach in der Administrationsoberfläche des Hostinganbieter angelegt werden.

r03

 

Anlage User Tabelle, Login Scripte, Abgesicherter Dashboardbereich

Damit nicht jeder Zugriff auf das Projekt hat wird nun ein gesicherter Nutzerbereich erstellt.
r08
Login:
r9
Weiterleitung in den noch leeren Nutzerbereich / Dashboardbereich: r10
Erstellung Musterdaten zu Testzwecken Dazu wird zunächst ein sampledata.php Script erstellt welches die Aufgabe hat die Tabelle sensordata zu befüllen.

r11
Bevor dieses Script nun ausgeführt werden darf muss ein Backup zu Sicherungszwecken angelegt werden. Dieses Backup wird mittels MySQL Dumper erstellt. Jetzt kann man das Script bedenkenlos ausführen. Die Ausführung funktioniert. Es wurde ein Fehler entdeckt und zwar musste die Tabellenstruktur der Tabelle sensordata angepasst werden. Und zwar war der decimal(2,2) Wert falsch gewählt. Es wurde nun geändert zu decimal (8,2). Ein zu kleiner Wert für zu „abgeschnittenen“ Werten. Es stehen nun 1000 Testwerte zur Verfügung: r12

 

Schritt 5 – Darstellung der Daten Die nun erzeugten Daten sollen nun dargestellt werden. Dazu bedienen wir uns dem Javascript Framework ChartJS. Dieses ist open source und bietet ein breites Anwendungsspektrum. Um diese Library zu verwenden müssen wir lediglich ein paar Javascript Dateien im Header einbinden.

02

Danach müssen wir ein PHP Script erstellen, welche die Daten aus der Datenbank ausliest und in ein brauchbares JSON Format wandelt.

03

Die JSON Daten werden einer Variable gespeichert welche dann mittels JAVASCRIPT dargestellt werden können.

04

(Am Bild  ist noch ein zusätzlicher Datenblock ersichtlich mit Zufallswerten, dient nur zur Testzwecken)

Wir schaffen nun in unserer Raspberry Webplattform einen eigenen Bereich zur Darstellung der Charts:

05

Schritt 6 – Aufbau einer Verbindung zum Raspberry Pi

Um entfernte Scripte, am entfernten Raspberry Pi ausführen zu können muss neben einer bekannten URL (Stichwort DynDNS Service) und einem offenen Port am Router / Gateway natürlich zusätzlich eine Technologie gewählt werden welche die Kommunikation zum Raspberry und retour ermöglicht. Es gibt viele Möglichkeiten aber nur 2 welche seitens unseres Shared Hosters angeboten werden. Nämlich cURL oder SSH. Um den Raspberry so weit wie möglich zu entlasten möchten wir darauf verzichten Zusatzsoftware am Raspberry zu installieren. Wir versuchen daher eine Verbindung mittels SSH via PHP aufzubauen. Auf der Suche nach einer passenden Möglichkeit via SSH eine Verbindung aufzubauen, sind wir auf das SSH2 Framework phpseclib aufmerksam geworden. Wir kopieren das gesamte  Verzeichnis auf unsere Webplatform und binden die neuen Ressourcen korrekt in unsere neue Datei raspcontroller.php ein.

r17

Wie auf dem Bild ersichtlich haben wir auch bereits eine erstes Testscript geschrieben welches wir versuchen aufzurufen. Dieses Script macht nichts anders als „Hello World“ zurückzugeben.

r18

Wir rufen nun die raspcontroller.php auf:

r19

Es wurde nun erfolgreich eine Verbindung zum Raspberry aufgenommen und ein Rückgabewert geliefert.

Um das ganze jetzt in Verbindung mit Button zu verwenden um später verschiedene Scripte anzusteuern, wird das Ganze nun mit AJAX und JQuery verknüpft.

Zuvor erstellen wir eine weitere MySQL Tabelle welche den derzeitigen Zustand der Sensoren speichert. Die Tabelle trägt den Namen sensorstatus.

06

und hat zum Test nun 2 Einträge:

07

Wir greifen nun in der raspcontroller.php auf die neu erzeugte Tabelle sensorstatus zu:

08

Das dazugehörige AJAX JQuery Script übernimmt nun 2 Werte den Namen des Sensors und die durchzuführende Aktion. 1 für ein und 0 für aus. Es ruft dann wieder eine PHP Datei auf und liefert ein Ergebnis zurück.

09

Die PHP Datei sensor.php welche verantwortlich ist für die Abarbeitung der SSH Verbindung sieht wie folgt aus:

10

Die „Rückggabewerte“:

11

Es wird in der Webplattform nun wieder ein neuer Bereich geschaffen:

12

Klickt man nun auf den Button wird ein Ereignis ausgelöst nämlich die Werte dem Script übergeben. Es wird nun zum Raspberry kommuniziert und bei Erfolg der Wert 1 zurückgegeben. Danach wird darauf basierend ein Feedback geladen der Bestätigt dass das Script ausgeführt wurde. Um die Ansicht zu aktualisieren, da sich ja der Zustand der Sensoren geändert hat wird nun auch noch ein JAVASCRIPT Countdown ausgeführt von 3 sec. Dadurch wird ein Siterefresh ausgelöst.

13

nach den 3 sec, der Status und die Uhrzeit haben sich geändert:

14

 

Schritt 7 – Raspberry Speicher und Prozesswerte übertragen 

Dazu dient uns ebenfalls das Framwork rund um phplibsec. Wir schaffen einen neuen Bereich Taskmanager. Dazu stellen wir ein eigenen PHP Script bereit Namens taskmanager.php und top.php.

Top.php beinhaltet den Verbindungsaufbau zum Raspberry und die Abwicklung der commands.

15

die dazugehörige taskmanager.php beinhaltet zusätzlich ein Script zum automatischen Refresh der Seite alle 6 Sekunden. Zur gewollten Verzögerung im Script ergeben sich ein automatischer Refresh von 10sec.

17

Das Resultat:

16

Der Prototyp der Webplattform ist somit fertig. Wir können nun das Scripten am Raspberry starten.

Schritt 8 – Erstellen eines Python Script zur Speicherung der Sensordaten in der Remote MySQL Datenbank

Im gleichen Ordner in dem derzeit das Script zum Auslesen des DHT22 Sensor liegt, erstellen wir nun ein weiteres Script welches automatisch alle gewissen Sekunden Daten an den entfernten MySQL Webserver sendet.

Wir befinden uns im Ordner:
soures/Adafruit_Python_DHT/examples

dort liegt derzeit bereits das Script:
AdaFruitDHT.py

Es wird ein neues Script mit dem Namen:
dht22_to_mysql.py
angelegt.

python

Damit dieses Script ach so funktioniert wie es soll, müssen wir noch ein Paket installieren.

sudo apt-get install python-mysqldb

Wir starten nun das Script:

sudo python dht22_to_mysql.py

 

Das Logfile sieht vielversprechend aus:

python2

 

 

Die entfernte MySQL Datenbank enthält nun alle Einträge:

python3

Ich habe die Struktur der Tabelle ein klein wenig angepasst und die Lüfterumdrehung rausgenommen. Des weiteren habe ich die Tabelle um einen timestamp erweitert. Somit wird jede neu hinzugekommen Zeile automatisch mit einem Datum versehen des MySQL Servers. Erweitert habe ich die bestehende Tabelle um eine sensorid. Zur Unterscheidung wenn mehrere DHT Sensor aktiv sein sollten.

Die Tabellenstruktur sieht nun wie folgt aus:

mysql2

Gefüllt mit Daten so:

mysql3

Nach Anpassung der chart.php zur Korrekten Anzeige der Daten:

chart1

chart2

 

chart3

Darstellung der Daten:

chart4

 

Zudem wurde im Bereich Raspberry Controller die Anzeige des derzeitigen Wertes:

mysql4

die Ausgabe:

mysql5

Zum Testen des Script über einem längeren Zeitraum via Putty empfiehlt es sich das Paket screen zu verwenden. Damit das Script im Hintergrund aktiv bleibt sobald man die Putty Session beendet. In der Produktivphase wird das Script selbstverständlich in weiterer Folge von einen Cronjob aufgerufen werden.

sudo apt-get install screen

Neue Screen Session Namens Script

screen -S script

und nun das Script einfach ausführen. Ich habe es jetzt auf 15 Minuten gestellt und werde es jetzt 2 Tage lang testen.

Die Putty Session kann ich nun schließen.

Das Ganze ist nun 2 Tage lang gelaufen und ich verbinde mich erneut auf den Raspberry mittels SSH Putty.

Um die Screen Session zurückzuholen führe ich den Befehl

screen -r 

aus.

01

Es hat alles bestens funktioniert.

02

Wir haben nun auch ein Script erstellt, welches nun von der Ferne am Raspberry ein LED ein- und ausschalten kann. Dieses LED könnte eine Pumpe zur Bewässerung symbolisieren.

03

Die zugrunde liegende MySQL Tabelle wurde ebenfalls ein wenig angepasst:

04

Der Datensatz zur LED:

05

Das PHP Script am Webserver empfängt aus einem AJAX Post 3 Variablen. Anhand derer wird entschieden was zu tun ist. Type: LED, Aktion: 0 oder 1, ein oder aus, GPIO Pin Nummer:

06

 

07

das Python Script am Raspberry:

08

Die Funktion:

Mittels Button klickt wird 3 Variablen per Post an ein AJAX Script gesandt. Daraufhin wird eine SSH Verbindung zum Raspberry aufgebaut und ein Befehl abgesetzt. Das Script am Raspberry lieft einen Rückgabewert und sendet diesen zurück an den Webserver. Dieser wiederrum updated auf dieser Grundlage unsere Tabelle sensorstatus und aktualisiert den timestamp der letzten Änderung. Danach wird eine Bestätigung der User angezeigt dass die Aktion erfolgreich oder nicht war. Es wird eine Verzögerung eingeleitet von x Sekunden um dem Raspberry Zeit zu geben das Script auszuführen und die Rückmeldung zur veranlassen. Danach lädt sich die Seite raspcontroller.php erneut und man erhält den aktuellen Buttonstatus.

in Bildern – Led ist aus:

pi1

Aktivieren Button wird betätigt. Led geht an.
Bestätigung wird angezeigt:

pi3

 

Nach Ablauf der Zeit (3 Sekunden) wird der Status der LED aktualisiert:

pi4

Als kleine Fazit können wir sagen, dass beide Varianten, Webserver direkt am Raspberry oder extern geeignet sind um den Raspberry zu steuern. Beide haben ihren Vorteil.

Direkt am Raspberry hat man interactivere Möglichkeiten Daten abzufragen (REST) und den Raspberry zu steuern. Der Nachteil ist allerdings sollte der Raspberry ausfallen hat man keinen Zugriff auf die Weboberfläche. Außerdem kann es vorkommen dass sich der Raspberry von einem auf den anderen Tag nicht mehr starten lässt und Daten verloren gehen.

Diese Nachteile hat man auf einem externen Webserver nicht. Daten können nicht verloren gehen. Am Raspberry laufen lediglich ein paar Script. Die externe Weboberfläche funktioniert immer auch ohne Raspberry. Alte Daten können also immer angesehen werden. Nachteil: Das ganze kann nicht ganz so interaktiv gestaltet werden.

Wobei das Ganze bei einem ordentlichen externen Serverumgebung anders aussieht dort kann man dann auch diverse Services nutzen (REST) usw.

Uns stand nur eine Apache mit PHP und MySQL zur Verfügung.