Auszug aus den Lehrveranstaltungen Infoumsatz IV und V MSR via TCP/IP Aufsetzen eines Webservers mittels Ubuntu 12.04, Datenbankzugriffe via Perl und PHP, Programmierung der GPIO des Raspberry PI unter Perl und Python Jürgen Wehling 06.11.2013 J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 0 Inhalt 1 Der Ansatz nach L.A.M.P. ................................................................................................................ 3 2 Aufsetzen eines Webservers (Ubuntu 12.04).................................................................................. 4 3 4 2.1 Das Grundsystem .................................................................................................................... 4 2.2 Der Desktop ............................................................................................................................. 5 2.2.1 Dateimanager .................................................................................................................. 6 2.2.2 Editor ............................................................................................................................... 7 2.2.3 Netzadresse ändern......................................................................................................... 7 2.3 Der Apache Webserver ........................................................................................................... 8 2.4 Der Apache und Perl ................................................................................................................ 9 2.5 Der Apache und SSI ............................................................................................................... 10 2.6 Der Apache und php .............................................................................................................. 11 2.7 Das RDBMS MySQL ................................................................................................................ 12 2.8 phpMyAdmin einrichten ....................................................................................................... 13 Datenbanken ................................................................................................................................. 15 3.1 ER-Diagramme ....................................................................................................................... 15 3.2 SQL - Abfragesprache für Datenbanken ................................................................................ 16 3.3 Datenbankzugriffe mit dem Modul DBI unter Perl ............................................................... 17 3.4 Datenbankzugriff unter php .................................................................................................. 17 One step further: Raspberry Pi ...................................................................................................... 19 4.1 Aufsetzen eines L.A.M.P. Servers .......................................................................................... 20 4.1.1 Freigabe für CGI-Skripten .............................................................................................. 21 4.1.2 Freigabe für Server Side Includes .................................................................................. 22 4.1.3 Freigabe für php in den Nutzer-Verzeichnissen ............................................................ 22 4.2 Die Schnittstelle GPIO............................................................................................................ 23 4.3 GPIO-Programmierung in Python .......................................................................................... 24 4.3.1 Ausgabe binärer Daten .................................................................................................. 24 4.3.2 Einlesen binärer Daten .................................................................................................. 25 4.4 GPIO-Programmierung in Perl ............................................................................................... 27 4.4.1 Ausgabe binärer Daten .................................................................................................. 29 4.4.2 Einlesen binärer Daten .................................................................................................. 30 4.5 GPIO-Zugriff für registrierte Nutzer....................................................................................... 32 4.5.1 Vorbereitungen für die Ausgabe von Daten.................................................................. 32 4.5.2 Die Ausgabe von Daten mittels Python ......................................................................... 32 4.5.3 Die Ausgabe von Daten mittels Perl .............................................................................. 33 J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 1 4.5.4 Vorbereitungen für das Einlesen von Daten ................................................................. 34 4.5.5 Hinweise für das Einlesen von Daten ............................................................................ 34 4.6 mySQL-basierte Speicherung sensorischer Daten................................................................. 34 4.6.1 Der Datenbankzugriff mittels Perl ................................................................................. 35 Abbildungen Abbildung 1: Visualisierung des L.A.M.P.-Ansatzes................................................................................. 3 Abbildung 2: Screenshot des Midnight Commander (mc) ...................................................................... 6 Abbildung 3: Screenshot des x-Terminals ............................................................................................... 7 Abbildung 4: Screenshot des Editors nano mit dem Inhalt der datei php5.conf .................................... 7 Abbildung 5: Screenshot der Datei interfaces unter dem Dateimanager mc ......................................... 8 Abbildung 6: Screenshot der Datei httpd.conf unter dem Dateimanager mc ...................................... 11 Abbildung 7: Screenshot des Ergebnisses von test_php.php ................................................................ 12 Abbildung 8: Screenshot des mysql-Befehls “show databases“ ........................................................... 13 Abbildung 9: Screenshot von phpMyAdmin Version 3.4.10 ................................................................. 14 Abbildung 10: ER-Diagramm, Beispiel ................................................................................................... 16 Abbildung 11: Raspberry Pi, UK-Version 2, Typ B ................................................................................. 19 Abbildung 12: Konfigurationsmenü, Aufteilung des Arbeitsspeichers ................................................. 20 Abbildung 13: Freigabe von CGI-Skripten ............................................................................................. 22 Abbildung 14: Freigabe von php für die Nutzer-Verzeichnisse ............................................................. 23 Abbildung 15: Anschlussbelegung des GPIO-Leiste auf dem Raspberry Pi Board ................................ 24 Abbildung 16: Binäre Datenausgabe über Pin 11 (GPIO 17) ................................................................. 25 Abbildung 17: Bildschirmausgabe des Python-Programms gpioinput.py ............................................. 26 Abbildung 18: Binäre Dateneingabe über Pin 12 (GPIO 18).................................................................. 27 Abbildung 19: Das Verzeichnis Device-BCM2835-1.8 im home-Verzeichnis des Nutzers pi ................ 28 Abbildung 20: Auszug exportfähige Konstanten ................................................................................... 29 Abbildung 21: Bildschirmausgabe des Perl-Programms gpioinput.pl ................................................... 31 Abbildung 22: Screenshot der Wetterdatenbank ................................................................................. 35 Abbildung 23: HTML-Ausgabe einer Datenbank-Abfrage ..................................................................... 36 J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 2 1 Der Ansatz nach L.A.M.P. „Eine sinnvolle Kombination von Open-Source-Software stellt der Ansatz nach L.A.M.P. dar, der in Abbildung 1 visualisiert ist. Abbildung 1: Visualisierung des L.A.M.P.-Ansatzes Hier wird deutlich, dass der Webserver Apache das zentrale Bindeglied zwischen Nutzer und Server 1 darstellt. Er regelt den Datenaustausch mit dem RDBMS durch Einsatz der Skriptsprachen PHP / Perl. Apache, MySQL und PHP / Perl laufen unter dem Betriebssystem Linux. Die Wahl von MySQL als RDBMS impliziert gleichzeitig, wie oben bereits erwähnt, die Verwendung von PHP und Perl als serverseitige Programmiersprachen zur dynamischen Generierung von WebSeiten bzw. zur Implementierung administrativer Vorgänge. Da sowohl MySQL als auch PHP und Perl freie Software sind und eine breite Unterstützung innerhalb der Gemeinschaft der Linux-Anwender finden, besteht der nächste konsequente Schritt darin, ein UNIX-basiertes Betriebssystem oder eines der vielen UNIX-Derivate einzusetzen. Die meisten UNIX-Derivate, wie Debian, Red Hat oder SuseLinux stehen ebenfalls kostenlos als Open-Source-Produkte zur Verfügung. Es bleibt anzumerken, dass MySQL auch für Windows-basierte Betriebssysteme verfügbar ist; ebenso PHP und auch der Apache-Webserver. Es würde also nichts dagegen sprechen, beispielsweise einen Ansatz nach W.A.M.P. zu verfolgen; leider existiert zu dieser Thematik kaum Literatur. Da Windowsbasierte Betriebssysteme kommerziell vertrieben werden, würde dieser Umstand außerdem einer konsequenten Umsetzung des Open-Source-Ansatzes widersprechen. Es sei kurz angemerkt, dass es neben PHP und Perl alternative Möglichkeiten wie ASP und ASP.Net von Microsoft, ColdFusion von Macromedia oder VelociGen von VelociGen Inc. 2 gibt. Sie sind jedoch nicht unter allen relevanten Betriebssystemen einsetzbar, bzw. verfügen nur über einen geringen Sprachumfang, sind propriertär ausgerichtet oder werden durch hohe Lizenzgebühren indiskutabel.“ [siehe: Wehling, J: MultimediaDatenbank für die Techniklehrerausbildung in: Technische Bildung in Unterrichtsforschung und Lehrerbildung, Lang, Frankfurt am Main, 2005, ISBN: 3-631-53225-3, S. 155-164] 1 Mit Server ist in diesem Fall die konkrete Hardware, also der Rechner selbst, gemeint. Der Webserver Apache ist ein reines Softwareprodukt. 2 VelociGen ist das eingetragene Warenzeichen von Blue Titan Software. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 3 2 Aufsetzen eines Webservers (Ubuntu 12.04) 2.1 Das Grundsystem Ein (fast) beliebiger Rechner kann hier als Server dienen. Ubuntu ist ein Linux-System auf der Basis von Debian. Es soll im Folgenden gezeigt werden, wie ein Webserver nach L.A.M.P. mit OpenSSH aufgesetzt werden kann. Der Vorgang ist relativ einfach und weitestgehend menügeführt. Es sind allerdings, wie üblich, ein paar Dinge zu beachten, damit die Server-Installation auch erfolgreich ist. Unter der offizielle Website zum Betriebssystem Ubuntu (link: http://www.ubuntu.com/download) existieren u.a. zwei Links für den Download: Ubuntu Desktop 12.10 und Ubuntu Server 12.04; es empfiehlt sich, die Server-Software herunterzuladen, da es hier eine Menüführung für spezielle Serverinstallationen gibt. Dank ihrer Größe lässt sie sich auch gut als iso-file auf eine CD packen, was bei der Desktop-Version bedingt durch ihre Größe von 753 MB problematisch ist. Als Sprache sollte man auf keinen Fall Deutsch wählen, da Ubuntu – so traurig es klingen mag – immer noch oder auch jetzt schon wieder, Probleme mit der Darstellung von Umlauten hat. Also: eine englische Version sollte es sein. Bei der Angabe eines Rechner-Namens lässt Ubuntu keinen Unterstrich zu, man sollte, je nach Fall, einen Bindestrich wählen (z.B. ubuntu-fred12). Für den Namen des Nutzers trägt man einen Vor- und Zunamen (z.B. juergen wehling) ein. Der Vorname wird später als Nutzername für einen zu erstellenden Account vorgeschlagen. Danach kann man wählen, ob der entsprechende Ordner verschlüsselt werden soll oder nicht. Als Zeitzone wählt man Berlin aus. Jetzt empfiehlt es sich, die automatische Netzwerkerkennung abzubrechen, da sonst u.U. DHCP genutzt wird; für einen Server ist aber eine statische IP-Adresse wesentlich besser. Bei der anschließenden manuellen Eingabe der entsprechenden Daten kann für die Suchdomäne einfach domain.de eingetragen werden – die existiert zwar nicht, der Eintrag vermeidet aber spätere Fehlermeldungen serverseitig auszuführender Programme. Letztlich sollt das System samt LVM (logical volume manager) installiert werden. Nachdem jetzt somit die gesamte HD (oder SSD) plus swap-Partition als systemrelevant ausgewählt wurden, kann das Grundsystem installiert werden. Es wird kein proxy-Server gewählt und auch der Punkt automatische Aktualisierungen wird nicht angewählt. Anschließend konfiguriert sich das System mittels apt (advanved packaging tool) durch ein Herunterladen von ca. 65 Dateien aus dem Netz. Nachdem dieser Vorgang abgeschlossen ist, wird ein Auswahlmenü präsentiert, um den Server zu konfigurieren. Hier wählt man für ein allgemeines Aufsetzen eines einfachen Webservers OpenSSH Server und LAMP Server an. Das System begibt sich jetzt in den Download von ca. 196 Dateien und installiert diese. Während dieses Vorgangs wird man nach dem Passwort für das relationale Datenbanksystem mySQL gefragt. Anschließend räumt das System auf und installiert bei Bedarf noch den Boot-Manager grub, was sich bei nur einem einzigen Betriebssystem auf einer Festplatte sicherlich erübrigt. Wer möchte, der kann jedoch grub im MBR (master boot record) installieren. Nach abschließender Systemprüfung (Nutzer, Passwörter, Zeiteinstellungen, Laufwerke, etc.) erfolgt ein Installationsbericht mit anschließendem Neustart. Das Grundsystem ist jetzt installiert und betriebsbereit und erwartet die ersten Eingaben am üblichen Systemprompt: J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 4 juergen@ubuntu-fred12:~$ Für diejenigen, die es ganz genau und mit Screenshots haben wollen, sei der folgende Link empfohlen: http://www.ubuntugeek.com/step-by-step-ubuntu-12-04-precise-lamp-server-setup.html . 2.2 Der Desktop Unter Ubuntu existieren mehrere Möglichkeiten, einen Desktop zu wählen. Die beiden bekanntesten sind wahrscheinlich der Gnome- und der KDE-Desktop. Der Gnome-Desktop heißt mittlerweile lightdm und wird mit dem Kommando juergen@ubuntu-fred12:~$ sudo apt-get install ubuntu-desktop Installiert. Hier taucht der befehl sudo erstmalig auf. Er bedeutet ein Umschalten des bisherigen Nutzers auf den sog. Superuser, der alle Rechte an allen Verzeichnissen und Dateien besitzt. Hier wird das Passwort des Superusers, das bei der Grundinstallation eingetragen wurde, zusätzlich abgefragt. Es gibt somit keinen Nutzer mehr mit dem Namen root, wie es in vergangenen Versionen von Ubuntu üblich war. Möchte man anstelle des Gnome-Desktop lieber den KDE-Desktop installieren, so lautet die Befehlszeile: juergen@ubuntu-fred12:~$ sudo apt-get install kubuntu-desktop Das k ist hier der einzige Unterschied. Dann startet ein etwas längerer Download (ca. 500 MB), um die zusätzlichen Dateien zu installieren. Standardmäßig wird ein einfaches Office-System mit installiert. Möchte man das verhindern und ein wirklich schlankes Serversystem haben, so empfiehlt sich das Kommando: juergen@ubuntu-fred12:~$ sudo apt-get install –no-install-recommands kubuntu-desktop Falls sich kein KDE-Desktop aufrufen lässt, startet man das GUI (graphical user interface) mit juergen@ubuntu-fred12:~$ startx Anschließend sollte der Rechner neu gestartet werden und von nun an wird der KDE-Desktop automatisch aufgerufen. Um trotz aufgerufenen Desktops wieder auf die Ebene des Betriebssystems zu gelangen, helfen die Tastenkombinationen Strg-Alt-F1 zum Ausblenden des Desktops sowie Strg-Alt-F7 zum erneuten Anzeigen des Desktops. Ein Herunterfahren des Rechner kann jetzt über KDE-GUI erfolgen oder auf Systemebene durch den Befehl: juergen@ubuntu-fred12:~$ sudo shutdown –h now Ein Neustart kann mit juergen@ubuntu-fred12:~$ sudo shutdown –r now erfolgen. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 5 2.2.1 Dateimanager Um Änderungen am System durchzuführen sind ein paar wesentliche Dinge notwendig. Dazu gehört beispielsweise ein graphischer Dateimanager. Unter dem KDE-Desktop findet sich im Menü Computer das Muon Software Center. Über die Suche-Funktion lässt sich hier z.B. der Midnight Commander (mc) als Dateimanager installieren; die Installation ist menügeführt. Abbildung 2: Screenshot des Midnight Commander (mc) Der Midnight Commander findet sich nach der Installation im Menü Applications unter Utilities und wird in einem eigenen Fenster geöffnet. Die Tastenkombination Strg-O Blendet die Benutzeroberfläche des mc ein oder aus. Bei ausgeblendeter Benutzeroberfläche lässt sich am Systemprompt dann z.B. ein administratives Fenster öffnen: das x-Terminal juergen@ubuntu-fred12:~$ xterm J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 6 Abbildung 3: Screenshot des x-Terminals 2.2.2 Editor Ubuntu stellt eine Reihe an Editoren für den einfachen Gebrauch zur Verfügung; dabei ist allerdings allen gemeinsam, dass sie gewöhnungsbedürftig sind. Der am leichtesten zu handhabende Editor ist offensichtlich nano. Nutzt man mc und möchte eine Datei mit F4 editieren, so öffnet sich erstmalig ein Menü, in welchem man den Editor seiner Wahl anwählen kann. Für ein wirklich einfaches, schlankes Editieren liegt die Wahl beim Editor nano. Abbildung 4: Screenshot des Editors nano mit dem Inhalt der datei php5.conf 2.2.3 Netzadresse ändern Ein Ändern der bestehenden Netzwerk-Konfiguration erfolgt durch Editieren der Datei interfaces unter: /etc/network/interfaces Dazu ist können die Dateiattribute geändert werden oder aber die Datei wird gleich im xterm-Fenster als Superuser mit dem Editor nano geändert: juergen@ubuntu-fred12: /etc/network$ sudo nano interfaces Nach Eingabe des Passwortes lassen sich unterhalb der Zeile iface eth0 inet static J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 7 die entsprechenden Änderungen durchführen. Nach dem letzten Stand ist der Server nach Änderung der Netzadresse neu zu starten. Eine systemgebundene Administration mittels network-manager respektive networking restart führen zu keinem veränderten Ergebnis. Eine Ausgabe der jeweiligen Netzwerk-Konfiguration erfolgt mittels ifconfig Die nachfolgende Abbildung zeigt die entsprechenden Änderungen in der Datei interfaces, wobei die Adresszeilen für ein LAN auskommentiert sind. Abbildung 5: Screenshot der Datei interfaces unter dem Dateimanager mc 2.3 Der Apache Webserver Unter dem LAMP-Ansatz des Ubuntu-Servers wird der Apache Webserver in der Version 2.2 eingerichtet. Eine relativ gute Referenz zum Apache unter Ubuntu findet man im Netz unter dem Link: http://wiki.ubuntuusers.de/apache . Möchte man jetzt auf den Webserver zugreifen, so geschieht das durch Eingabe der IP-Adresse des Webservers im Client-Rechner. Da bis jetzt lediglich ein Grundsystem eingerichtet ist, zeigt der Apache dem anfragenden Client eine standardisierte Seite an, die signalisieren soll, dass der Apache arbeitet: „It works!“ Diese Webpage (index.html) ist zu finden unter: /usr/share/apache2/default-site/index.html oder auch unter /var/www/index.html J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 8 Damit ist erst einmal sichergestellt, dass der Apache als Webserver läuft. Jetzt ist es natürlich sinnvoll, auf einen bestimmten User-Account zugreifen zu können. Da ein User-Account in einem komplett anderen Verzeichnis liegt, sollte für den Apache das Modul userdir freigeschaltet sein. Dazu wechselt man wieder zum Superuser und führt den Befehl a2enmod (apache2 enable module) aus: juergen@ubuntu-fred12:~$ sudo a2enmod userdir Damit dieses Modul auch ausgeführt wird, ist ein Neustart des Apache notwendig. Das lässt sich auf unterschiedliche Art bewältigen, nämlich einmal klassisch juergen@ubuntu-fred12:~$ sudo /etc/init.d/apache2 restart oder auch systemgebunden durch die Befehlsfolge juergen@ubuntu-fred12:~$ sudo service apache2 restart Der Apache lässt sich über start, restart und stop steuern. Unter Umständen ist noch notwendig, den Pfad für das so frei geschaltete Modul anzupassen. Dazu muss ein entsprechender Eintrag in der Datei userdir.conf vorhanden sein. Zu finden unter: /etc/apache2/mods-enabled/userdir.conf Jetzt kann mittels z.B. WinScp vom Client-Rechner eine sftp-Verbindung zum entsprechenden UserAccount aufgebaut werden, wobei sich der Rechnername zusammensetzt aus dem User-Account und der zugehörigen IP-Adresse verbunden durch ein @, beispielsweise: [email protected] Der sftp-Server ist hier schon etabliert durch die Installation der secure shell OpenSSH-Server. 2.4 Der Apache und Perl Zu den nachfolgenden Anweisungen findet sich im Netz eine Referenz für die Umsetzung dynamischer Inhalte mittels CGI unter dem Link: http://httpd.apache.org/docs/2.2/howto/cgi.html . Um den Apache Webserver für User-Accounts zu konfigurieren, muss die Datei httpd.conf geändert werden. Zu finden ist sie unter /etc/apache2/httpd.conf Bevor diese Datei jedoch geändert werden kann, müssen die Nutzer-Rechte richtig gesetzt sein. Das geschieht beispielsweise durch: juergen@ubuntu-fred12:~$ sudo chmod 0666 httpd.conf Dadurch ist die Datei jetzt schreibbar und es sollten die folgenden Einträge aufgenommen werden: LoadModule cgi_module modules/mod_cgi.so Falls dieser Eintrag nach dem Neustart von Apache zu einer Fehlermeldung führen sollte, liegt der Pfad für modules eventuell nicht richtig. Dann sollte der Eintrag folgendermaßen lauten: LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so Anschließend erfolgen die Einträge für mögliche User-Accounts mit dem ausführbaren Verzeichnis cgi-bin: J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 9 <Directory /home/*/public_html/cgi-bin> Options +ExecCGI AddHandler cgi-script .cgi .pl </Directory> Letztlich sollte die Datei httpd.conf wieder schreibgeschützt werden durch juergen@ubuntu-fred12:~$ sudo chmod 0644 httpd.conf und der Apache sollte neu gestartet werden, um die Änderungen zu übernehmen: juergen@ubuntu-fred12:~$ sudo service apache2 restart Fehlermeldungen des Apache werden zusätzlich in einer error-Datei abgelegt. Es ist daher sinnvoll, dort von Zeit zu Zeit nachzusehen. Sie ist zu finden unter: /var/log/apache2/error.log Hinweis: Das Modul cgi.pm ist schon unter Perl eingebunden und muss nicht mehr nachinstalliert warden. 2.5 Der Apache und SSI Das Einbinden von server side includes (SSI) folgt fast analog der Einbindung von Perl. Auch dieses Mal ist wieder die Datei htppd.conf zu ändern, zB. im xterm-Fenster: juergen@ubuntu-fred12: /etc/apache2$ sudo nano httpd.conf Hier ist zuerst das Modul mod_include.so einzubinden LoadModule include_module /usr/lib/apache2/modules/mod_include.so Anschließend erfolgen die Einträge für mögliche User-Accounts: <Directory /home/*/public_html> Options +IncludesNOEXEC AddType text/html .shtml AddOutputFilter INCLUDES .shtml </Directory> Die Option IncludesNOEXEC verhindert eine Ausführung von Programmen mittels SSI. Auch hier sollte der Apache neu gestartet werden, um die Änderungen zu übernehmen: juergen@ubuntu-fred12:~$ sudo service apache2 restart Jetzt ist der Webserver für die Darstellung dynamischer Inhalte mittels Perl und SSI eingestellt. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 10 Abbildung 6: Screenshot der Datei httpd.conf unter dem Dateimanager mc 2.6 Der Apache und php Gegebenenfalls sollte ein php-Update auf die neueste Version durchgeführt werden mit anschließendem Neustart des Apache mittels juergen@ubuntu-fred12:~$ sudo apt-get install php5 juergen@ubuntu-fred12:~$ sudo service apache2 restart Wie schon erwähnt, führt der Webserver php-Dateien standardmäßig im Verzeichnis /var/www aus. Genau dort sollte jetzt eine Datei vorhanden sein, die Informationen über die Installation von php enthält. Diese Datei muss erst noch erstellt werden. Sie heißt test_php.php und hat den folgenden Inhalt: <? php phpinfo(); ?> Über den URI http://132.252.134.180/test_php.php kann die o.g. Datei jetzt aufgerufen und ausgeführt werden. Das ergibt u.a. den nachfolgenden Screenshot unter Chrome. Damit php auch in einem User-Account lauffähig ist, muss die Konfigurationsdatei von php5 geändertwerden: /etc/apache2/mods-available/php5.conf Durch die jetzt schon mehrfach beschriebene Vorgehensweise muss folgende Zeile mit einem # auskommentiert werden: php_admin_value engine off J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 11 Der Apache muss jetzt neu gestartet werden und damit ist php nunmehr für alle User-Accounts freigeschaltet. Sofern sich die o.g. Datei jetzt in einem User-Account findet, kann sie aufgerufen werden durch den URI http://132.252.134.180/~juergen/test_php.php . Abbildung 7: Screenshot des Ergebnisses von test_php.php 2.7 Das RDBMS MySQL Als relationales Datenbank Management System (RDBMS) ist unter dem Ansatz nach L.A.M.P. mySQL eingerichtet worden. Nach dem Einloggen mittels putty kann die Funktionalität von mySQL kurz geprüft werden: juergen@ubuntu-fred12:~$ mysql –u root –p Der user (u) ist in diesem Fall root und das Passwort (p) ist das bei der Einrichtung von mySQL gewählte. Nach erfolgreichem Einloggen ist man auf der Ebene von mySQL: mysql> Hier lassen sich dann mit mySQL-spezifischen Befehlen z.B. die schon im System vorhandenen Datenbanken anzeigen, wobei datenbankspezifische Befehle immer mit einem Semikolon abgeschlossen werden. mysql> show databases; J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 12 Abbildung 8: Screenshot des mysql-Befehls “show databases“ Jetzt lässt sich eine neue Datenbank anlegen durch: mysql> create database mmdb; Ein expliziter Nutzer lässt sich dann anlegen mit: mysql> create user nutzer@localhost identified by ‘********‘; Er kann dann auch alle ihm zustehenden Rechte erhalten mit der Befehlssequenz: mysql> grant all on mmdb.* to nutzer@localhost; Mit exit verlässt man die mySQL Ebene. mysql> exit; 2.8 phpMyAdmin einrichten Der Ansatz nach LAMP implementiert das Vorhandensein eines MySQL-Systems. Am einfachsten ist ein solches System handhabbar, wenn eine graphisch orientierte Benutzeroberfläche die Administration erleichtert: dafür steht die Software phpMyAdmin. Die Installation erfolgt durch: juergen@ubuntu-fred12:~$ sudo apt-get install phpmyadmin Da diese Software nicht Bestandteil von Ubuntu Server 12.04 ist, wird sie aus dem Netz nachgeladen. Nach erfolgreicher Installation erfolgt ein Aufruf mittels http://132.252.134.180/phpmyadmin.php . J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 13 Anschließend muss man sich mit Nutzername und Passwort anmelden; beide sind schon bei der Einrichtung von mySQL als Grundsystem angelegt worden. Einen ersten Eindruck der Benutzeroberfläche vermittelt der nachfolgende Screenshot. Abbildung 9: Screenshot von phpMyAdmin Version 3.4.10 J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 14 3 Datenbanken RDBMS steht für „relational database management system“. Gemeint ist hier ein relational arbeitendes System für die Handhabung datenbankbasierter Informationen, wie beispielsweise PostgreSQL oder aber MySQL. Allgemein betrachtet besteht die Handhabung datenbankbasierter Informationen aus drei wesentlichen ineinander greifenden Elementen. 1. Die Grundlage datenbankrelevanter Prozesse bildet das sog, „management system“. Als opensource Software bieten sich die beiden o.g. RDBMS an; kommerzielle Produkte gibt es von Oracle, IBM oder SAP. 2. Auf dieser Basis kann das eigentliche anwendungsbezogene System aufgesetzt werden und es besteht im Wesentlichen aus Tabellen, die über bestimmte Beziehungen miteinander verknüpft sind und so datenbankbasierte Informationen organisieren. 3. Um mit dem anwendungsbezogenen System zu arbeiten, muss eine Art Frontend existieren, dass es dem Nutzer ermöglicht, Anfragen an das System zu stellen. Oft scheint es daher nicht klar zu sein, was genau eine Datenbank eigentlich ist. Während die einen ein „management system“ (Punkt 1) meinen, sprechen die anderen über verknüpfte Tabellen (Punkt 2), während zusätzlich noch eine Gruppe (das ist übrigens die weitaus größte Gruppe) existiert, die das Frontend, also die spezielle Ein-/Ausgabemaske für nutzergebundene Anfragen, für die eigentliche Datenbank hält. Oft werden dann Schwächen im Frontend mit einem fehlerhaften RDBMS verbunden; das führt dann oft zu der unreflektierten Aussage: „Wenn diese Datenbank nicht funktioniert, dann wird eben eine andere genommen.“ Es erscheint in diesem Zusammenhang als empfehlenswert, sich auf Punkt 2 als einfache Definition einer Datenbank zu einigen. Wenn also im Folgenden von einer Datenbank die Rede ist, so ist ein System von verknüpften Tabellen auf Basis eines RDBMS gemeint. 3.1 ER-Diagramme Verknüpfte Tabellen bilden das eigentliche anwendungsbezogene System, da hier spezifiziert werden kann, was genau die Datenbank eigentlich leisten soll. Eine solche tabellarisch organisierte Verknüpfung wird als ER-Diagramm bezeichnet. ER steht für Entity Relationship und bezeichnet die Beziehungen zwischen den in Tabellenform organisierten Datenstrukturen. So enthält beispielsweise eine Entität mit dem Namen nutzer eine den Nutzer beschreibende Struktur mit nachname, vorname, strasse, wohnort, u.s.w. Angenommen, ein zentrales Element dieser Datenbank sind multimedial orientierte Objekte, auf welche der Nutzer zugreifen möchte, so besteht zwischen den beiden Entitäten nutzer und objekte eine 1:N Beziehung, was bedeutet, dass ein Nutzer natürlich auf alle, also N, Objekte zugreifen kann. Jedes Objekt selbst kann jetzt durch einen eigenen Datensatz beschrieben werden, z.B. durch eine Beschreibungssyntax namens dcmi (Dublin Core Metatag Initiative). In diesem Fall würde zu jedem Objekt nur eine einzige signifikante Beschreibung existieren, was wiederum zu einer 1:1 Beziehung zwischen diesen beiden Entitäten führt. Zusätzlich enthalten alle Entitäten wenigstens ein spezifisches Schlüsselelement, mit welchem sie sich anderen Entitäten gegenüber identifizieren und so angesprochen werden können. Dieser Zusammenhang ist in der nachfolgenden Graphik beispielhaft dargestellt; erstellt wurde sie mit xtgdm 2.3.4, dem xtg data modeller. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 15 Abbildung 10: ER-Diagramm, Beispiel Mit der vorgenannten Software xtg data modeller würde sich das graphisch dargestellte Konstrukt der Datenbank direkt auf einen LINUX-Server übertragen lassen. Ohne diese Software muss die Datenbankstruktur händisch übertragen werden. Die in php programmierte Benutzeroberfläche phpMyAdmin leistet dabei wertvolle Hilfestellung. 3.2 SQL - Abfragesprache für Datenbanken „Grundlage für alle datenbankgebundenen Operationen ist die Programmiersprache SQL. SQLorientierte DBMS speichern Daten nach festgelegten Kriterien. Es sind aktive Datenbanken, die in der Regel über Triggerfunktionen 3 verfügen und sicherstellen, dass die Integrität der gespeicherten Daten nicht verletzt wird. SQL ist als Programmiersprache international standardisiert. Ihr Befehlssatz wird in unregelmäßigen Abständen aktualisiert und erweitert. Viele SQL-orientierte DBMS richten sich nach dem 1992 geschaffenen Standard ANSI-SQL/92, jedoch nutzen immer mehr DBMS proprietäre SQL-Dialekte bei der Behandlung der von ihnen zu verwaltenden Datensätze. Es bleibt anzumerken, dass dieser Standard 1999 überarbeitet wurde (ANSI-SQL/99), jedoch immer noch nicht einheitlich genutzt wird. Der zunehmende Einsatz proprietärer SQL-Dialekte ist für kleinere Entitäten mit geringem Datenaufkommen relativ unerheblich, entwickelt sich bei komplexen Anwendungen mit starker Nutzer-Frequentierung jedoch zu einem ernsthaften Problem. Oracle nutzt eine eigens entwickelte Programmiersprache (PL/SQL), Informix arbeitet mit SPL, Microsoft und Sybase unterstützen T-SQL, während DB2 von IBM einen ganz anderen Ansatz verfolgt und Programmiersprachen wie Rexx, COBOL, C und Java favorisiert. PL/SQL, T-SQL, und SPL sind sog. "block-structured languages" mit eigenen Regeln und einer eigenen Syntax; sie sind aus diesem Grunde bzgl. unterschiedlicher DBMS nicht portierbar. DB2 beispielsweise stellt ein digitales Klassifikationssystem dar und ist deshalb hervorragend für eine Verwendung in digitalen Bibliotheken geeignet, weniger jedoch als multimedialer Lehr- und Lernserver (siehe DuEPublico der Uni Due). Es beschränkt sich auf die Elementarfunktionen add und 3 Trigger erlauben die Aktivierung einer gespeicherten Prozedur bei Eintreten eines bestimmten Ereignisses. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 16 access, wobei ihm jegliche Interaktivität (execute/process) fehlt: so stellt es z. B. keine Schnittstelle für PHP zur Verfügung, während aber ein explizit ausgeführter Befehlssatz für ein Ansprechen der DBI-Schnittstelle, über die sowohl MySQL als auch PostgreSQL verfügen, unter PHP vorhanden ist; gerade für die Skriptsprache Perl werden über das Comprehensive Perl Archive Network (CPAN) Module zur Programmierung der DBI-Schnittstelle angeboten, denn DBI ist die standardisierte Datenbankschnittstelle unter Perl.“ [siehe: Wehling, J: Multimedia-Datenbank für die Techniklehrerausbildung in: Technische Bildung in Unterrichtsforschung und Lehrerbildung, Lang, Frankfurt am Main, 2005, ISBN: 3-631-53225-3, S. 155-164] 3.3 Datenbankzugriffe mit dem Modul DBI unter Perl An dieser Stelle soll der Datenbankzugriff mit dem Modul dbi.pm dargestellt werden. Es wird Bezug genommen auf die vorhergehende Abbildung, wobei nach Eingabe eines Nutzernamens mit zugehörigem Passwort die zugehörige Nutzer-ID ermittelt wird; der Ausdruck mmdb ist in diesem Fall der Name der zu referenzierenden Datenbank. Nach Festlegung der Variablen und Konstanten wird das Programm durch eine Einbindung der notwendigen Perl-Module initialisiert: use CGI qw/:standard :html3/; use DBI; Nachdem Nutzernamen und Passwort des registrierten Nutzers erfolgreich verifiziert wurden, erfolgt die Ermittlung der zugehörigen nutzer_id: $DSN = "DBI:mysql:mmdb"; $dbh = DBI->connect($DSN, 'root', '********') or die "Verbindungsaufnahme nicht moeglich"; $sth = $dbh->prepare("SELECT nutzer_id FROM nutzer WHERE (nutzername = '$nutzername' AND passwort = '$passwort')"); $sth->execute(); while ( @result = $sth->fetchrow_array ){ for ($i = 0; $i < @result; $i++) { $nutzerdaten[$i] = $result[$i]; } }; $sth->finish(); $dbh->disconnect; Das Modul dbi.pm stellt die Verbindung zu einer mySQL-Datenbank her. Würde man beispielsweise DuEPublico, das digitale Klassifikationssystem der Uni Due ansprechen wollen, so müsste man als Schnittstelle das Perl-Modul db2.pm nutzen müssen. Das Perl Modul dbi.pm stellt hier eine Verbindung für den Nutzer root mit dem Passwort ******** her. Anschließend wird aus der Entität nutzer die nutzer_id ausgewählt, die zu den übermittelten Daten nutzername und passwort gehören. Die zugehörigen Nutzerdaten werden anschließend durch das Array @result für ggfs. weitere Verarbeitungsschritte bereitgestellt. Abschließend wird die Verbindung zur Datenbank wieder geschlossen. 3.4 Datenbankzugriff unter php Zuerst sollte das folgende Modul, falls nicht schon geschehen, installiert werden: Loadmodule mysqli module J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 17 Hiermit wird sichergestellt, dass sowohl objektorientierter als auch funktionsorientierter Code verwendet werden kann. Dieses Modul wird ab Version 4.1.3 empfohlen. Mit Bezug zum vorgenannten Beispiel host, user und password festgelegt werden; anschließend erfolgt ein einfacher Connect. <?php $host = "localhost"; $user = "root"; $password = "********"; $dbc = mysql_connect($host, $user, $password); if (!$dbc) { echo "Verbindungsaufnahme nicht moeglich\n"; } else { echo "Verbindung aufgebaut\n"; } $anfrage = "SELECT nutzer_id FROM nutzer WHERE (nutzername = '$nutzername' AND passwort = '$passwort')"; $datensatz = mysql_query($anfrage); $row = mysql_fetch_row($datensatz); echo "Nutzer-ID: $row[0]\n"; mysql_close(); ?> J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 18 4 One step further: Raspberry Pi Wurden bisher lediglich sog. embedded systems betrachtet, so eröffnet die neueste Entwicklung einen Blick auf komplett ausgestattet Kleinstrechner im Scheckkartenformat. Der erste und sicherlich berühmteste ist der Raspberry Pi, kurz RASPI genannt. Abbildung 11: Raspberry Pi, UK-Version 2, Typ B Er ist ein ungekühlter Kleinstrechner mit allen wichtigen Anschlüssen, wie Ethernet, USB, HDMI, etc. sowie genügend Arbeitsspeicher, um eine kleinere Linux-Distribution aufzuspielen. In seiner letzten Ausführung ist er denkbar gut geeignet für Bereiche der Hausautomation, sowie eben für Belange aus den Bereichen Messen, Steuern, Regeln (MSR). Er ist deshalb prädestiniert für genau diese Anwendungsbereiche, weil er über eine fest im Prozessor implementierte Schnittstelle verfügt, nämlich den general purpose input output, kurz GPIO genannt. Leider ist seit der Version 2, Typ B das Pin-Layout des GPIO geändert wurden, so dass dieser Modelltyp nicht anschlusskompatibel zu den beiden Vorgängermodellen ist. Immerhin ist dieser Rechnertyp mit seinem Layout deutlich an die didaktische Konzeption eines legendären Vorläufermodells angelehnt: dem Commodore C-64! Auch der C64 verfügte über nach außen geführte IO-Kanäle, dem User-Port und dem Expansion-Port und war daher schon prädestiniert für Aufgaben aus dem Bereich MSR. Der Raspberry Pi hat keinerlei mechanische Komponenten und ist in der Lage, von einer SD-Card zu booten. Natürlich sind schon Nachfolgemodelle am Markt, wie das Cubieboard oder ähnliche Derivative, die höher getaktet sind, über mehr Arbeitsspeicher verfügen und sogar eine SATA-Schnittstelle aufweisen; sie haben allerdings auch größere Abmessungen – auf die Größe einer Scheckkarte bringt es keiner. Der RASPI ist flexibler einsetzbar und auch deutlich günstiger als ein ARDUINO-System ist (aber daher leider auch deutlich komplexer zu administrieren), soll im Folgenden gezeigt werden, wie dieses System als Web-Server aufgesetzt und genutzt werden kann. Zuerst sollte ein Linux-Betriebssystem aufgesetzt werden. Die erste Anlaufstelle ist in diesem Fall die URI http://www.raspberrypi.org/downloads . Die Vorgehensweise ist relativ einfach und dort auch deutlich beschrieben: hat man kein funktionsfähiges Linux-System zur Verfügung, so empfiehlt es sich, eine SD-Karte unter Windows zu formatieren und ein Raspbian Wheezy Image auf die Karte zu J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 19 spielen; Raspian Wheezy ist ein relativ schlankes Linux-Betriebssystem auf Basis von Debian. Günstige SD-Karten für mittlere Ansprüche erhält man übrigens bei einem bekannten Lebensmitteldiscounter, beispielsweise 2x16 GB für 15 EUR. 4 Man lädt also beispielsweise die Datei 2013-02-09-wheezy-raspbian.zip herunter und hat somit schon die Image-Datei des zu installierenden Betriebssystems. Anschließend erledigt man mit der Windows-Software Win32DiskImager den Rest, wie formatieren der SD-Karte, entpacken des Images und installieren von Raspbian Wheezy. Nach der Installation setzt man die SD-Karte in den raspberry pi und startet das System: per default ist der Nutzer pi mit dem Passwort raspberry angelegt. Falls bis hierhin immer noch Unklarheit herrscht, sollte man sich das entsprechende Tutorial unter http://elinux.org/RPi_Easy_SD_Card_Setup ansehen sowie das Quick Start Guide unter http://www.raspberrypi.org/wp-content/uploads/2012/12/quick-start-guide-v1.1.pdf. 4.1 Aufsetzen eines L.A.M.P. Servers Da ein raspberry pi der zweiten Generation verwendet wird mit einem Arbeitsspeicher von 512 MB, sollte in diesem Fall eine geeignete Speicheraufteilung erfolgen. Der Befehl pi@raspberrypi ~ $ sudo raspi-config führt in ein Benutzermenü, wo viele wichtige Einstellungen vorgenommen werden können. Um sich wiederholende Elemente abzukürzen, soll ab jetzt die Befehlsfolge pi@raspberrypi ~ $ sudo durch # ersetzt werden. Abbildung 12: Konfigurationsmenü, Aufteilung des Arbeitsspeichers In diesem Fall sollte für die graphische Ausgabe ein relativ kleiner Wert von z.B. 32 MB eingestellt werden. Damit steht dem raspberry pi als Webserver genügend Speicher zur Verfügung. Bevor ein Webserver aufgesetzt werden kann, sollten noch ein paar wenige Einstellungen vorgenommen werden. So sollte die Zeitzone richtig gewählt sein sowie das letzte Update bzw. ein Upgrade des Komplettsystems eingespielt sein: # dpkg-reconfigure tzdata # apt-get update 4 Möchte man einen Medienserver mittels XBMC oder openELEC aufsetzen, so empfiehlt sich eine SD-Karte mit größerer Kapazität und schnelleren Schreib-Lese-Zugriffen, allgemein bekannt als Class 10. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 20 # apt-get upgrade Der zuletzt genannte Befehl ist immer relativ zeitintensiv. Anschließend geht alles über quasi eine einzige Befehlszeile, um den Apache, php und MySQL inklusive phpMyAdmin mit den zugehörigen Bibliotheken zu installieren: # apt-get install apache2 php5 libapache2-mod-php5 mysql-server mysql-client php5-mysql phpmyadmin Eine Secure Shell (ssh) zu installieren ist nicht notwendig, da diese automatisch durch openssh aktiviert ist; auch der RSA-key für eine asymmetrische Verschlüsselung der Daten ist fertig eingerichtet und braucht nur noch bestätigt zu werden. Das wiederum bedeutet, dass beispielsweise der fernsteuernde Aufruf mittels putty klappt. Bleibt noch zu erwähnen, dass für die Administration des MySQL-Servers ein Nutzer mit Passwort erforderlich ist, beispielsweise root mit dem Passwort technik. Damit ist der L.A.M.P-Server im Prinzip eingerichtet. Was jetzt noch fehlt, ist eine adäquate NutzerVerwaltung. Dieser Vorgang ist schon in einem vorhergehenden Kapitel beschrieben worden (siehe z.B. Aufsetzen eines Webservers unter Ubuntu 12.04): # adduser juergen In diesem Zusammenhang ist darauf zu achten, dass der Webserver eine öffentliche IP-Adresse erhält (z.B. 132.252.134.250), ein Dateimanager installiert ist sowie ein einfacher Editor (z.B. nano). Des Weiteren sollte die Ausführung von CGI-Skripten zulässig sein, genauso wie die Ausführung von Server Side Includes- Befehlen (SSI); auch sollte php nicht nur für das ohnehin freigegebene Verzeichnis var/www freigegeben sein, sondern auch sämtliche Nutzer-Verzeichnisse: 4.1.1 Freigabe für CGI-Skripten Abweichend von der Ubuntu 12.04 Installation muss in diesem Fall die Datei 000-default editiert werden. Sie findet sich im Verzeichnis /etc/apache2/sites-enabled # nano 000-default Der nachfolgende Screenshot zeigt die Veränderungen, die in der besagten Datei vorzunehmen sind, um CGI-Skripten mit den Endungen .cgi und .pl in den ausführbaren Nutzer-Verzeichnen lauffähig zu bekommen. Dabei ist lediglich der Eintrag zwischen den auskommentierten Zeilen wichtig. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 21 Abbildung 13: Freigabe von CGI-Skripten 4.1.2 Freigabe für Server Side Includes Für die Freigabe von SSI muss lediglich ein Modul aus dem Verzeichnis /etc/apache2/mods-available mit folgendem Befehl geladen werden: # a2enmod include Damit steht einer Ausführung von SSI-Skripten nichts mehr im Wege. 4.1.3 Freigabe für php in den Nutzer-Verzeichnissen Da php standardmäßig nicht für die einzelnen Nutzer-Verzeichnisse freigegeben ist, muss die Datei php5.conf editiert werden. Zu finden ist sie im Verzeichnis /etc/apache2/mods-enabled J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 22 Der nachfolgende Screenshot zeigt die Veränderung, die in der besagten Datei vorzunehmen ist: lediglich die drittletzte Zeile php_admin_value engine Off ist auszukommentieren. Abbildung 14: Freigabe von php für die Nutzer-Verzeichnisse 4.2 Die Schnittstelle GPIO Definiert als allgemeine Schnittstelle lässt sie sich für die unterschiedlichsten Anwendungsfälle in den unterschiedlichsten Hochsprachen programmieren. Daher soll an dieser Stelle die folgende Einschränkung gelten: • • es sollen nur binäre Daten eingelesen bzw. ausgegeben werden als Hochsprachen kommen Perl und Python zum Einsatz Bezogen auf eine datenbankgestützte Erfassung von Messdaten wird der Schwerpunkt in der Hochsprache Perl liegen. Darüber hinaus gehende Möglichkeiten einer Nutzung des GPIO zu unterschiedlichsten Zwecken findet sich unter den Link von Adafruit: http://learn.adafruit.com/category/raspberry-pi . Eine weiterer sehr gut aufbereiteter Link findet sich unter http://elinux.org/RPi_Lowlevel_peripherals . Hier werden auch verschiedene Möglichkeiten einer Programmierung des GPIO besprochen. Es sind Beispiele in den Hochsprachen C/C++, Perl Python, Ruby, Java und sogar in Basic wiedergegeben. Die nachfolgende Abbildung zeigt die Anschlussbelegung des GPIO. Hier ist zu beachten, dass die Steckleiste auch nummeriert ist. Ganz oben befinden sich z.B. die Anschlüsse 1 (3,3V), 2 (5 V) und 3 (GPIO 2 (SDA1)), ganz unten beispielsweise 23 (GPIO 11 (SCKL)), 24 (GPIO 8 (CS0)), 25 (frei) und schließlich 26 (GPIO 7 (CS1)). Die dunkler hinterlegten Felder haben in der letzten Revision 2.0 des Raspberry Pi Änderungen in ihrer Funktionalität erfahren. Dies ist beim Arbeiten mit älteren Versionen zu berücksichtigen! J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 23 Funktion Pin Pin Funktion 3,3V 1 2 5V GPIO 2 (SDA1) 3 4 -- GPIO 3 (SCL1) 5 6 GND GPIO 4 (GPCLK0) 7 8 GPIO 14 (TXD) -- 9 10 GPIO 15 (RXD) GPIO 17 11 12 GPIO 18 (PCM_CLK) GPIO 27 13 14 -- GPIO 22 15 16 GPIO 23 -- 17 18 GPIO 24 GPIO 10 (MOSI) 19 20 -- GPIO 9 (MISO) 21 22 GPIO 25 GPIO 11 (SCLK) 23 24 GPIO 8 (CS0) -- 25 26 GPIO 7 (CS1) Abbildung 15: Anschlussbelegung des GPIO-Leiste auf dem Raspberry Pi Board In den nachfolgenden Programmen wird entweder Bezug genommen auf die Nummerierung der Anschlüsse (Pins) oder auf ihre angegebenen Funktionsbezeichnungen. Im Folgenden soll der Einfachheit halber die Programmierung des GPIO für den root-Zugriff betrachtet werden. 4.3 GPIO-Programmierung in Python Einen relativ einfachen Einstieg in die Programmierung des GPIO bietet die Hochsprache Python. Bei Python ist allerdings zu beachten, dass beispielsweise Programmschleifen nur dann korrekt ausgeführt werden, wenn die Weite der Einrückungen stimmig ist. Ansonsten führt eine erste Compilierung zu einem sog. Indentation error. Sowohl für die Programmierung in Python als auch in Perl werden jeweils die gleichen I/OBelegungen verwendet: Pin 11 (GPIO 17) wird als Ausgabekanal, Pin 12 (GPIO 18) als Eingabekanal definiert. 4.3.1 Ausgabe binärer Daten Auf der Grundlage von Abbildung 15 soll Pin Nummer 11 (das entspricht der Funktionsbezeichnung GPIO 17) als Ausgang definiert werden und anschließend durch eine Endlosschleife für einen Zeitraum von 500 Millisekunden gesetzt und wieder zurückgesetzt werden. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 24 import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setup(11, GPIO.OUT) while True: GPIO.output(11, True) time sleep(0.5) GPIO.output(11, False) time sleep(0.5) Wichtig an diesem Programm (gpiooutput.py) ist die dritte Zeile, in welcher bestimmt wird, dass auf die sog. Boarddefinition der Schnittstelle Bezug genommen wird. Gestartet wird das Programm durch: # python gpiooutput.py Der Schaltungsaufbau kann mittels sog. Pi Cobbler erfolgen, der als Teil einer Bauteilebibliothek von beispielsweise Adafruit zur Verfügung gestellt wird. Link: http://www.adafruit.com/blog/2012/07/30/fritzing-library-update-adafruit-pi-cobbler-forraspberry-pi/ Abbildung 16: Binäre Datenausgabe über Pin 11 (GPIO 17) 4.3.2 Einlesen binärer Daten Wiederum auf der Grundlage von Abbildung 15 soll Pin Nummer 12 (das entspricht der Funktionsbezeichnung GPIO 18 (PWM)) als Eingang definiert werden und anschließend durch eine Schleifensteuerung den Schriftzug "+3,3 V" ausgeben, wenn der Eingang mit einem High-Signal belegt wurde; liefert der Eingang ein Low-Signal, so wird der Schriftzug "0 V" ausgegeben. Das Programm heißt gpioinput.py. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 25 import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setup(12, GPIO.IN) while (1): input_value = GPIO.input(12) if input_value == True: print("+3,3 V") time.sleep(1) else: print("0 V") time.sleep(1) Gestartet wird das Programm durch: # python gpioinput.py Der nachfolgende Screenshot zeigt das Ergebnis einer solchen Abfrage im root-Terminal. Wie schon erwähnt, ist bei der Programmerstellung auf eine konsequente Einhaltung der Einrückungen zu achten, da diese für die Schleifen- und Unterprogrammsteuerung zuständig sind. Abbildung 17: Bildschirmausgabe des Python-Programms gpioinput.py Die Realisierung einer Abfrage durch die zugehörige Hardware zeigt die nachfolgende Abbildung: durch einen Pulldown-Widerstand ist der Dateneingang Pin 12 (GPIO 18) dauerhaft auf Masse (0 V) gelegt. Die kurze Betätigung des Schließers liefert dann +3,3 V. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 26 Abbildung 18: Binäre Dateneingabe über Pin 12 (GPIO 18) 4.4 GPIO-Programmierung in Perl Bevor mit einer Programmierung in Perl begonnen werden kann, muss noch ein wesentliches Programmpaket installiert werden, da sonst kein Zugriff auf diese Schnittstelle möglich ist: • BCM2835 perl library von CPAN Zu finden ist diese Library unter dem Link: http://search.cpan.org/~mikem/DeviceBCM2835/lib/Device/BCM2835.pm . Hier findet sich die momentan aktuelle Version 1.8 wieder. Die Installation läuft dabei wie folgt ab: tar xvfz Device-BCM2835-1.8.tar.gz cd Device-BCM2835-1.8 perl MakeFile.pl make sudo make install Der nachfolgende Screenshot zeigt ein Listing des home-Verzeichnisses des Nutzers pi. Um die neuen Funktionalitäten zu prüfen kann mit dem Befehl sudo make test die korrekte Installation geprüft werden. Dieser Test sollte allerdings nur dann durchgeführt werden, wenn Probleme auftauchen, er ist letztlich sehr zeitintensiv. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 27 Abbildung 19: Das Verzeichnis Device-BCM2835-1.8 im home-Verzeichnis des Nutzers pi Jetzt erst kann ein Perl-Programm erstellt werden, um Dateneingänge und -ausgänge zu nutzen. Die mit Perl erstellten Programme sehen allerdings deutlich komplexer aus, als die mit Python erstellten. Bzgl. der Angaben zur Handhabung des betreffenden Perl-Moduls seien hier einige wichtige Auszüge der Beschreibung sowie der exportfähigen Konstanten von der vorgenannten Website des CPAN zitiert: my $ret = Device::BCM2835::init(); Initialise the library by opening /dev/mem and getting pointers to the internal memory for BCM 2835 device registers. You must call this (successfully) before calling any other functions in this library (except Device::BCM2835::set_debug). If Device::BCM2835::init() fails by returning 0, calling any other function may result in crashes or other failures. Prints messages to stderr in case of errors. return 1 if successful else 0 Device::BCM2835::gpio_fsel($pin, $mode); Sets the Function Select register for the given pin, which configures the pin as Input, Output or one of the 6 alternate functions. pin GPIO number, or one of RPI_GPIO_P1_* from RPiGPIOPin. mode Mode to set the pin to, one of BCM2835_GPIO_FSEL_* from \ref bcm2835FunctionSelect my $value = Device::BCM2835::gpio_lev($pin); Reads the current level on the specified pin and returns either HIGH or LOW. Works whether or not the pin is an input or an output. pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. return the current level either HIGH or LOW Device::BCM2835::gpio_write($pin, $on); Sets the output state of the specified pin pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. on HIGH sets the output to HIGH and LOW to LOW. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 28 delay ($millis); Delays for the specified number of milliseconds. Uses nanosleep(), and therefore does not use CPU until the time is up. millis Delay in milliseconds Lediglich die in der Farbe Türkis hinterlegten exportfähigen Konstanten werden für die Ein- und Ausgabe binärer Daten benötigt. .. BCM2835_GPIO_FSEL_ALT4 BCM2835_GPIO_FSEL_ALT5 BCM2835_GPIO_FSEL_INPT BCM2835_GPIO_FSEL_MASK BCM2835_GPIO_FSEL_OUTP BCM2835_GPIO_PADS BCM2835_GPIO_PUD_DOWN .. Abbildung 20: Auszug exportfähige Konstanten Weitere Elemente sind für ein erstes Programmieren der GPIO-Schnittstelle mittels Perl vorerst nicht notwendig. 4.4.1 Ausgabe binärer Daten Ein erstes einfaches Programm zur binären Ausgabe von Daten ist gpiooutput.pl . Nach dem Einbinden und dem Initialisieren der entsprechenden Library wird Pin 11 (GPIO 17) als Ausgang festgelegt. Hierfür wird der Befehl gpio_fsel (function select) genutzt; die exportfähige Konstante BCM2835_GPIO_FSEL_OUTP legt den Modus für Pin 11 fest. Die Ausgabe von Daten erfolgt durch eine Endlosschleife mittels gpio_write-Befehl als High oder Low-Zustand und muss nicht weiter kommentiert werden. Das Listing sieht folgendermaßen aus: J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 29 #!/usr/bin/perl # gpiooutput.pl, juergen wehling, 10.05.2013 # datenausgabe use Device::BCM2835; use strict; Device::BCM2835::init() || die "Initialisierung der Library fehlgeschlagen"; # variablen definition, pin 11 oder gpio 17 wird angesprochen my $ausgabe_pin = 17; # initialisierung, pin 11 oder gpio 17 als ausgang festlegen Device::BCM2835::gpio_fsel($ausgabe_pin, BCM2835_GPIO_FSEL_OUTP); # hauptprogramm while (1) { # pin 11 oder gpio 17 auf low legen Device::BCM2835::gpio_write($ausgabe_pin, LOW); # 1000 millisekunden halten Device::BCM2835::delay(1000); # pin 11 oder gpio 17 auf high legen Device::BCM2835::gpio_write($ausgabe_pin, HIGH); # 1000 millisekunden halten Device::BCM2835::delay(1000); } 4.4.2 Einlesen binärer Daten Der wesentliche Befehl zum Einlesen binärer Daten mittels Perl ist gpio_lev (level). Dieser Befehl liest den log. Zustand eines spezifizierten Pins ein. Im Hauptprogramm erfolgt schließlich eine permanente Überprüfung des jeweiligen log. Zustands und eine Terminalausgabe. Die permanente Überprüfung kann in unterschiedlicher Art und Weise realisiert werden. Hier ist einfach eine Schleifenkonstruktion mittels goto-Befehl realisiert worden. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 30 #!/usr/bin/perl # gpioinput.pl, juergen wehling, 10.05.2013 # dateneingabe use Device::BCM2835; use strict; Device::BCM2835::init() || die "Initialisierung der Library fehlgeschlagen"; # variablen pin 12 oder gpio 18 wird angesprochen my $eingabe_pin = 18; # initialisierung # pin 12 oder gpio 18 als eingang festlegen Device::BCM2835::gpio_fsel($eingabe_pin, BCM2835_GPIO_FSEL_INPT); # hauptprogramm schleife: # daten ueber pin 12 oder gpio 18 einlesen und in der variablen $daten speichern my $daten = Device::BCM2835::gpio_lev($eingabe_pin); if ($daten == 0) { print "LOW-Level an pin 12 oder gpio 18\n"; Device::BCM2835::delay(1000); } else { print "HIGH-Level an pin 12 oder gpio 18\n"; Device::BCM2835::delay(1000); } goto schleife; Der Hardwareaufbau ist in Abbildung 18 wiedergegeben. Abbildung 21: Bildschirmausgabe des Perl-Programms gpioinput.pl J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 31 4.5 GPIO-Zugriff für registrierte Nutzer Bisher wurde lediglich der Zugriff auf das GPIO durch den Nutzer root betrachtet. Es kann aber nicht zielführend sein, immer mit Superuser-Rechten zu arbeiten. Da der Raspberry Pi als Web-Server arbeitet, müssen auch einzelne registrierte und angemeldete Nutzer Zugriff auf das GPIO haben. Leider wird ein solcher Versuch durch das System nicht gestattet, aber es gibt einen trickreichen Ausweg. 4.5.1 Vorbereitungen für die Ausgabe von Daten In den Systemdateien des Raspberry Pi mit dem Betriebssystem Debian Wheezy finden sich exportFunktionen für das GPIO. Das ganze kann dann folgendermaßen aussehen: ein einzelner Nutzer mit eingeschränkten Rechten kann nicht direkt auf das GPIO zugreifen, aber indirekt. Der indirekte Zugriff läuft über eine Steuerung mittels Datei. So regelt beispielsweise die Datei direction, ob ein Kanal als Ein- oder als Ausgabe definiert wird, ebenso regelt die Datei value, ob eine log. „1“ oder eine log. „0“ ausgegeben oder eingelesen wird. Mit anderen Worten: der einfache Nutzer muss sich nur noch mit Dateizugriffen auskennen. Die wesentliche Vorgehensweise bei der Freigabe des GPIO für Nutzer mit eingeschränkten Rechten sieht dann so aus: Man muss als root eingeloggt sein. Das geschieht am besten durch ein Einloggen als Nutzer pi. Der Befehl sudo –i wechselt den Nutzer: aus pi wird root. Dann wird festgelegt, welcher GPIO Pin zu exportieren ist. Soll beispielsweise GPIO Pin 18 exportiert werden, so wird durch den Befehl echo 18 > /sys/class/gpio/export ein neues Verzeichnis mit mehreren Dateien angelegt. Das neue Verzeichnis heißt jetzt gpio18 und enthält u.a. die Dateien direction und value. Die weiteren vorhandenen Dateien sind für die weitere Vorgehensweise hier uninteressant. Soll jetzt der GPIO Pin 18 als Ausgang fungieren und den initiierenden Wert log. „1“ erhalten, so lauten die Befehlsfolgen: echo out > /sys/class/gpio/gpio18/direction echo 1 > /sys/class/gpio/gpio18/value Abschließend sollten noch die Nutzerrechte so gesetzt werden, dass alle registrierten Nutzer Zugriffsmöglichkeiten auf diese Dateien haben. Das geschieht beispielsweise durch: chmod 666 /sys/class/gpio/gpio18/direction chmod 666 /sys/class/gpio/gpio18/value 4.5.2 Die Ausgabe von Daten mittels Python Nach dieser relativ einfachen Vorbereitung steht einer Nutzung des GPIO Pins 18 nichts mehr im Wege. Ein Python-Programm zur Ansteuerung dieses Ausgangs als Blinker mit einer Periodendauer von zwei Sekunden sieht dann so aus: J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 32 #!/usr/bin/python # Toggle GPIO pin 18. # Output frequency is about 25 kHz (varies due to other activity). import time value_path = '/sys/class/gpio/gpio18/value' f = open(value_path, 'w') # Blink T=2s while 1: f.write('1') f.flush() time.sleep(1) f.write('0') f.flush() time.sleep(1) f.close() Im Wesentlichen wird die Datei value zum Schreiben geöffnet, anschließend startet eine Endlosschleife, wobei immer nur zwischen log. „1“ und log. „0“ gewechselt wird. In diesem Zusammenhang taucht das Problem auf, dass die im Zwischenspeicher liegenden Daten nur dann in eine Datei geschrieben wird, wenn diese geschlossen wird. Der close()-Befehl wird aber bedingt durch den vorzeitigen Abbruch der Schleife nie erreicht werden. Daher kommt der flush()-Befehl ins Spiel, der den Zwischenspeicher wieder freimacht und seinen Inhalt in die Datei schreibt. Diese Datei wird durch das GPIO kontinuierlich ausgelesen und erzeugt daher ein Rechtecksignal mit ca. 25 kHz. 4.5.3 Die Ausgabe von Daten mittels Perl Unter der Programmiersprache Perl sieht das gleiche Programm vom Aufbau identisch aus, lediglich die Syntax ist anders. #!/usr/bin/perl -w my $value_path = "/sys/class/gpio/gpio18/value"; my $old_fh; open(DATEI, ">$value_path") or die "kann Datei value nicht oeffnen"; while(1) { print DATEI 1; $old_fh = select(DATEI); $| = 1; select($old_fh); sleep(3); print DATEI 0; $old_fh = select(DATEI); $| = 1; select($old_fh); sleep(3); } Unter Perl muss eine Befehlssequenz genutzt werden, die dem autoflush-Befehl ähnlich ist, da ansonsten keine Daten in die Datei value geschrieben werden können. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 33 Sowohl bei der nutzerspezifischen Ausgabe von Daten durch Python als auch durch Perl werden die Inhalte von Dateien genutzt, um darüber den GPIO anzusprechen. Ein so generiertes Rechtecksignal beschreibt eine Datenzelle der SD-Karte ca. 25.000 Mal in der Sekunde! Vorgänge dieser Art sind für eine nachhaltige Nutzung der SD-Karte sicherlich kontraproduktiv. 4.5.4 Vorbereitungen für das Einlesen von Daten Die Vorbereitungen für das Einlesen von Daten sind ähnlich den schon vorher beschriebenen Vorbereitungen das Ausgeben von Daten betreffend. Auch in diesem Fall muss man als root eingeloggt sein. Das geschieht am besten durch ein Einloggen als Nutzer pi. Dann wird festgelegt, welcher GPIO Pin zu exportieren ist. Soll beispielsweise GPIO Pin 17 exportiert werden, so wird durch den Befehl echo 17 > /sys/class/gpio/export ein neues Verzeichnis mit mehreren Dateien angelegt. Das neue Verzeichnis heißt jetzt gpio17 und enthält u.a. die Dateien direction und value. Soll jetzt der GPIO Pin 17 als Eingang fungieren, so lauten die Befehlsfolgen: echo in > /sys/class/gpio/gpio17/direction cat /sys/class/gpio/gpio17/value Die letzte Zeile liest den Inhalt, also den laufenden Wert der Datei value. Abschließend sollten noch die Nutzerrechte wie gehabt gesetzt werden, dass alle registrierten Nutzer Zugriffsmöglichkeiten auf diese Dateien haben. 4.5.5 Hinweise für das Einlesen von Daten Es sollen an dieser Stelle keine fertigen Programme vorgestellt werden, die das Einlesen von Daten mittels Python oder Perl erlauben. Es ist im Zusammenhang mit Dateioperationen zu beachten, dass insbesondere beim Lesen von Dateiinhalten der interne Dateizeiger nach jedem Schreibvorgang immer wieder auf den Anfang der Datei zurückzusetzen ist, da sonst keine eingelesenen Werte angezeigt werden können. Die allgemeine Syntax ist: filehandle, position innerhalb der Datei, offset bzgl. Anfang, Mitte oder Ende der Datei. Näheres ist dann den Programmierhandbüchern zu entnehmen. Unter Python geht das mit dem Befehl os.lseek(fd, pos, how) und unter Perl mit seek (fh, pos, whence) 4.6 mySQL-basierte Speicherung sensorischer Daten Im weiteren Verlauf soll jetzt nicht mehr auf die nutzerspezifische Handhabung des GPIO eingegangen werden; daher werden ab jetzt ausschließlich root-Zugriffe betrachtet und zwar ausschließlich unter Perl, d.h. Python wird ab jetzt außen vor bleiben und nicht weiter vertieft werden. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 34 Die Problemstellung soll folgendermaßen aussehen: Über eine HTML-Datei wird durch einen Submit-Button das Einlesen von Daten über den GPIO gestartet. Die durch diesen Vorgang aufgerufene Datei ist ein Perl-Skript, das a) direkten Zugriff auf den GPIO hat und b) die eingelesenen Daten direkt in eine Datenbank schreibt. Der Vorgang des Einlesens von Daten ist aus Sicherheitsgründen auf eine Dauer von 10 Sekunden beschränkt. Nach Abschluss des Einlesens werden die Daten aus der Datenbank abgerufen und als HTML-Datei wiedergegeben. Eine graphische Aufbereitung kann anschließend mittels CSS erfolgen, stellt hier aber keinen Gegenstand dar. 4.6.1 Der Datenbankzugriff mittels Perl Zuerst sollte eine geeignete mySQL-Datenbank existieren. Im folgenden Beispiel wurde die Datenbank Wetterdaten angelegt. Es wurden anschließend einige fiktive Werte aufgenommen – der Vorgang sollte hinreichend bekannt sein. Nachfolgend ein Screenshot unter phpMyAdmin: Abbildung 22: Screenshot der Wetterdatenbank Wetterdaten ist denkbar einfach aufgebaut. Es gibt lediglich 5 Spalten: - Wetterdaten_id Temperatur Druck Luftfeuchte Zeit Die Spalte Wetterdaten_id stellt inkrementelle Werte dar und die Spalte Zeit enthält den sog. Unixstamp. Der Zugriff mittels Perl erfolgt mit Hilfe der Module cgi.pm und dbi.pm. Beides sind Standardmodule und müssen nicht nachträglich installiert werden. Ein zentrales Element stellt die Abfrage der Datenbank an sich dar: J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 35 ###################################### Datenbankabfrage ############ my $dbh = DBI->connect( "dbi:mysql:dbname=mydb_juergen", "juergen", "juergen", { RaiseError => 1 }, ) or die $DBI::errstr; my $sth = $dbh->prepare("SELECT * FROM Wetterdaten WHERE Wetterdaten_id=4"); $sth->execute(); while ( @result3 = $sth->fetchrow_array ){ for ($i = 0; $i < @result3; $i++) { $objektdaten[$i] = $result3[$i]; } }; $sth->finish(); $dbh->disconnect(); ##################################################################### Mit diesem Grundgerüst lässt sich jetzt eine auf Perl basierende HTML-Seite aufrufen, die den vierten Datensatz (Wetterdaten_id=4) wiedergibt: Abbildung 23: HTML-Ausgabe einer Datenbank-Abfrage Der nächste Schritt könnte zeigen, wie Daten über eine Perl basierte HTML-Seite als neuer Datensatz in die Datenbank übernommen werden. J. Wehling, Auszug aus den Lehrveranstaltungen Infoumsatz IV und V (2013) 36