Kampis Elektroecke

Portables GPIO-Interface für den Raspberry Pi

In diesem Beitrag stelle ich eine Realisierungsmethode für ein portables Webinterface, mit dem die GPIOs des Raspberry Pi geschaltet werden, vor. Die Applikation wird in Python mittels Flask realisiert und anschließend in einem Docker-Container untergebracht.

Docker auf dem Raspberry Pi:

Eine Kernkomponente dieses Projektes ist die Containerverwaltung Docker. Docker ermöglicht es einzelne Anwendungen zu virtualisieren, sodass diese ohne Installation etc. auf jedem System lauffähig sind. Das Prinzip ist dem einer virtuellen Maschine (z. B. VirtualBox) sehr ähnlich, nur das Docker ohne Hypervisor arbeitet und das Betriebssystem als Ausgangsbasis für die Virtualisierung verwendet.

Damit Docker auf dem Raspberry Pi genutzt werden kann, muss es erst installiert werden. Dazu muss als erstes der GPG-Schlüssel von Docker hinzugefügt werden:

Jetzt wird die Paketliste /etc/apt/sources.list erweitert:

Die erweiterte Paketliste muss nun noch eingelesen werden. Im Anschluss daran kann Docker installiert werden:

Docker ist nun einsatzbereit und der Virtualisierung von Containern steht nichts mehr im Weg.

Das Webinterface:

Mit Hilfe des Webinterfaces sollen die I/Os des Raspberry Pi geschaltet werden können. Für die Erstellung des Webinterfaces wird Flask verwendet. Dieses Modul habe ich, zusammen mit einem SocketIO Modul, in einer seperaten Klasse für den Webservice untergebracht. In dieser Klasse wird der Webservice initialisiert und die Routing-Regeln für den Webzugriff festgelegt:

Der komplette Webserver läuft in einem eigenen Thread und kann mit der Methode Run() gestartet werden. 

Über die ObserveableData-Klasse kann die Applikation auf Daten, die mittels JavaScript an den Webserver gesendet werden, reagieren. Jedes ObserveableData-Objekt kann mit Callbacks versehen werden, die immer dann ausgelöst werden, sobald die Daten geändert wurden. Dazu wird eine Variable in einem globalen Daten-Dictionary, welches an den Webserver gegeben wird, angelegt:

Das Dictionary Data wird mit einem ObserveableData-Objekt erweitert, welches mit dem Schlüssel gpio_on versehen wird. Anschließend wird der dazu gehörige Callback festgelegt. Zu guter letzt wird der Variablenname noch an den Webservice weitergegeben:

Damit wäre der Python-Code vollständig. Jetzt muss nur noch das Webinterface designed und die entsprechende Javascript-Applikation entworfen werden.

Die Kommunikation mit dem Webservice wird durch die JavaScript-Methode SendJSON() realisiert.

Diese Methode erwartet zwei Parameter, wobei der erste Parameter der Schlüssel der jeweiligen Variable ist (z. B. gpio_on) und der zweite Parameter ist der Wert, der an den Webservice gesendet werden soll (in diesem Beispiel die Nummer des I/Os).

Damit die einzelnen I/Os geschaltet werden können habe ich für jeden I/O zwei Radio-Buttons vorgesehen, einen zum Einschalten und den anderen zum Ausschalten. Der Name der Radio-Buttons entspricht dabei immer der I/O-Bezeichnung, wodurch die Radio-Buttons entsprechend gruppiert werden können. Zudem wird der Name für die Identifizierung des I/Os im Python-Skript verwendet.

Die Radio-Buttons, die zum Einschalten vorgesehen sind, bekommen das onChange-Event OnClick() und die Radio-Buttons, die zum Ausschalten vorgesehen sind, bekommen das onChange-Event OffClick() zugewiesen.

Über den Elementnamen gpio_on und gpio_off der Methode SendJSON() werden im Python-Code die entsprechenden Callbacks ausgelöst, die dann einen I/O an- bzw. abschalten. Die Identifizierung des I/Os findet über den Namen des aufrufenden Objektes (this.name) statt.

Damit ist auch das Webinterface fertig designed. Die Anwendung kann nun ausgeführt werden:

Über die IP-Adresse localhost:5000 ist das Webinterface anschließend zu erreichen:

Erstellen eines Docker-Containers:

Nun soll die Anwendung in einen Docker-Container portiert werden. Dazu wird im dem root-Verzeichnis der Application eine Datei namens dockerfile angelegt und wie folgt ausgefüllt:

Die Datei requirements.txt beinhaltet alle zusätzlichen Pakete, die mit Hilfe des RUN-Befehls bei der Containererstellung durch pip installiert werden sollen:

Mit diesen beiden Dateien kann der Container erstellt werden:

Dieser Vorgang dauert beim ersten Ausführen relativ lange, da alle notwendigen Pakete noch heruntergeladen werden müssen. Wenn alles geklappt hat, erscheint die folgende Ausgabe:

Jetzt kann der Container gestartet werden:

Da der Container auf die Hardware des Prozessors (hier die I/Os) zugreifen will muss entweder der Zusatz

oder

verwendet werden. Über den Parameter

wird der Port 3000, der über das Dockerfile verfügbar gemacht werden sollte, des Hosts auf den Port 5000 des Containers (der Default-Port von Flask) gemappt. Der Container ist nun im Netzwerk errreichbar und die I/Os können geschaltet werden.

Das komplette Projekt ist bei GitHub zum Download verfügbar.

Schreibe einen Kommentar

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