Montag, 29. September 2014

Im Keller brennt Licht oder auch nicht

Zu unserer Mietwohnung gehört ein Kellerraum, wo ich mir eine kleine Bastelwerkstatt mit Lötkolben, UDOO-Board und Bierkühlschrank und all so Kram eingerichtet habe. Der Zugang zu der Kellerwerkstatt ist zu meinen Hauptbastelzeiten ohne künstliche Beleuchtung meist stockfinster. Wir haben zwar Licht im Keller, doch dafür gibt es nur einen Schalter am Anfang des Gangs, an dessen Ende unser Kellerraum ist. Ich habe daher drei mögliche Kellerlichtstrategien:

  1. Ich stokele im Dunkeln durch den Keller,
  2. ich schalte das Flurlicht an, öffne meinen Keller, schalte dort Licht an, latsche den langen Gang zurück um das Flurlicht auszuschalten und dann wieder in meinen Keller. Das Spielchen mache ich beim Rausgehen dann rückwärts.
  3. Oder ich lasse das Licht brennen, während ich in der Werkstatt bin. Das ist aber Verschwendung und außerdem fühle ich mich dann "beobachtet". 
Die Lösung der Problematik ist - denke ich - jedem sofort klar: Ein netzwerkgesteuertes Kellerlicht muss her. Konkret heißt das:
  • Eine LED in einer transparenten Android-Figur dient als Licht.
  • Das Licht wird mittels eines GPIO-Ports meines UDOO Boards gesteuert.
  • Ein Webserver auf dem UDOO Board steuert wiederum den GPIO-Port und liefert Rückmeldung über dessen Status. Der Server ist im LAN erreichbar.
  • Ein optionaler Android Client ermöglicht eine komfortable Fernsteuerung des Lichts.
An diesem Projekt gefällt mir besonders, dass es recht viele Disziplinen involviert aber jede auf einem sehr einfachen Niveau:
  • Handwerk
    LED in die Android-Figur einpflanzen, Kabel verlegen
  • Elektrizität
    LED korrekt und sicher am UDOO-Board anschließen
  • GPIO-Steuerung
    Programmatisch mit den GPIO-Ports interagieren
  • Webserver
    • CSS
    • HTML
    • GET Requests
      LED-Status dynamisch anzeigen
    • POST-Requests
      Zum Steuern der LED
  • Python
    Webserver mit GPIO-Steuerung implementieren
  • Daemon
    Den Server mit Systemstart im Hintergrund ausführen auf Linux
  • Android
    Für den optionalen Client
Das Projekt wollte ich hier erst präsentieren, wenn ich damit fertig bin. Ich merke nun aber, dass das eine ganze Menge Arbeit ist. Entsprechend wird der Text auch länger als erwartet. Daher hier nun also nicht das große Ganze, sondern dies und das Vorhandene. ;)

Daemon

Ein Teilaspekt des Projekts ist die Ausführung der Servers als Dienst auf Linux. Dienste sind Programme, die mit dem System starten und im Hintergrund laufen. So einen Dienst nennt man in der Linuxwelt Daemon.
Meinen Server habe ich in Python geschrieben. Damit kann man grundsätzlich auch Skripte zu einem Daemon machen. Ich hatte damit aber meine Schwierigkeiten und stieß dann auf eine elegante Lösung, die unabhängig von Python ist. Doch zunächst:

Quick & dirty

Grundsätzlich kann man unter Linux Prozesse im Hintergund ausführen, wenn man die startende Kommandozeile mit "&" abschließt, also etwa so:

python server.py &

Das System zeigt dann die Prozess ID (PID) an. Diese benötigt man z.B., um den Prozess später mit kill zu beenden.

Der Prozess endet spätestens mit der Sitzung. Schließt man also das Terminalfenster oder bricht die Verbindung ab, wird unser Server beendet. Um dies zu verhindern, kann man nohup verwenden. Das Programm unterdrückt das HUP-Signal (Hang up) für den Prozess:

nohup python server.py &

Das schöne an dieser Lösung ist, dass sie sofort funktioniert. Man muss nichts weiter implementieren oder konfigurieren. Für erste Tests ist sie daher gut geeignet. Sie hat aber einen provisorischen Charakter, vor allem weil der Start nicht automatisch erfolgt.

start-stop-daemon

Oft möchte man, dass nur eine Instanz eines Dienstes ausgeführt wird. Diese möchte man unkompliziert starten und stoppen können, insbesondere wenn das System startet respektive stoppt. Beides wird unter Linux häufig mit Hilfe einer pid-Datei erreicht. Beim Start des Daemons wird dessen PID in eine Datei geschrieben. Ist die Datei vorhanden und läuft ein Prozess unter der darin enthaltenen Prozess-ID, läuft der Dienst bereits. Anhand der PID kann er z.B. beendet werden
Das Programm start-stop-daemon nimmt einem genau diese Logik ab und ersetzt darüber hinaus nohup und "&".

Wie man das benutzt, kann man prima bei Stephen C Phillips nachlesen. Dort steht auch, wie man den ganzen Kram mit dem System startet.

Ich hatte bei der Anwendung mit dem einen oder anderen Problem zu kämpfen:

Um ein Python-Script "direkt" ausführbar zu machen, muss man am Anfang der Datei ein Shebang mit dem Python Interpreter einbauen. Damit das klappt, muss die Datei UNIX Zeilenumbrüche (und nicht Windows Zeilenumbrüche) enthalten. Das war für mich auch deshalb verwirrend, weil mein Python-Script funktionierte, wenn ich es als Argument für Python gestartet hatte:
python server.py

Der Aufruf
./server.py
lieferte leider nur
: Datei oder Verzeichnis nicht gefunden

Das Tool dos2unix rettete mich aus dieser Lage.

Weiterhin erreichte mich die Meldung nicht, dass mein Script mit dem Nutzer, den ich für den Daemon vorgesehen hatte, keine Berechtigung hatte, die GPIO-Ports zu manipulieren. Auf dem UDOO-Board ist die voreingestellte Gruppe mit Schreibrecht auf die GPIO-Ports ugpio.

Ausblick

Wie man sieht habe ich über einen der letzten Punkte aus meiner Liste berichtet. Das liegt daran, dass die Arbeit an dem Projekt schon recht fortgeschritten ist. Den Code des Servers gibt's bei github. Falls ich keine Lust mehr habe, über das Projekt zu berichten, kann man dort wenigstens den Code einsehen. :)

Dienstag, 16. September 2014

13. Braunschweiger Webmontag

Am gestrigen Montag fand der 13. Braunschweiger Webmontag statt. Ich war dort und habe einen der Vorträge gehalten und ein paar Internetseiten mit verschiedenen Knobeleien vorgestellt. Und so sah das aus:

13. Braunschweiger webMontag Teil.2 from Christian Cordes on Vimeo.

Die Vorträge der anderen Teilnehmer waren ebenfalls interessant. Es ging um Ambient Assisted Living, die Epson Moverio Smartglasses und ein App-Baukastensystem für Geschäftskunden.

Hier noch mal die Links zu den Rätseln meines Vortrags:

  • Mathe- und Programmierrätsel
Danke an Stefan Winterfeld für's Zeigen!

  • Browserrätsel

Abkürzung Ouverture Facile

  • Kombination aus beidem

  • Bonus

Danke an Hannes für:

Freitag, 12. September 2014

Roots bloody roots

Alter! Irgendwann zwischen Internetanschluss und Abi - so '96 / '97' vielleicht - entdeckte ich das MP3-Format für mich. Mein Rechner war damals nicht in der Lage, eine 128kbit-MP3-Datei in voller Qualität abzuspielen. Der Player bot zum Glück die Möglichkeit, die Qualität zu reduzieren.

Wonach ich aber eigentlich gesucht hatte, war die Möglichkeit, Musik von Konsolenspielen abzuspielen. Ich hatte die Hoffnung, dass auf den Konsolen sowas wie die Amiga-MOD-Dateien verwendet werden. Insbesondere auf dem Super Nintendo gibt es ein Spiel, dessen Musik ich echt gern mag.

In den 17 Jahren seither guckte ich vielleicht noch ein oder zwei mal halbherzig nach einer Abspielmöglichkeit - vergebens.

Heute habe ich ein Plugin für foobar2000 gefunden, das Musikdateien von diversen Konsolen abspielt. Jetzt höre ich frisch gerenderte Musik auf dem besagten Super Nintendo Spiel und freue mich, dass das ausgerechnet am Video Games Day passiert ist! Alter! :)

Montag, 1. September 2014

Langsam in Fahrt kommen

Nach Fusion Festival und Urlaub kehrt nun langsam wieder der geregelte Tagesablauf ein und damit Zeit und Lust für Basteleien.

Da mir der Weg in meinen Bastelkeller zu dunkel bzw. die Bedienung der Beleuchtung zu umständlich ist, begann ich vor einiger Zeit mit dem Bau einer netzwerkgesteuerten Lampe. Ein interessanter Aspekt dabei sind für mich die simplen Teilaufgaben auf Einsteigertutorialniveau, die sich aber auf viele Domänen verteilen. Ich werde berichten, wenn ich halbwegs fertig bin.

Gerade eben habe ich meinen Yamaha-Verstärker repariert. Seit Jahren nervte mich, dass man mit dem großen Lautstärkeknopf am Gerät die Lautstärke de facto nicht mehr regeln konnte. Ich hatte in einem Hifi-Laden mal ein Ersatzteil bestellt, die Bestellung verlief aber leider im Sande. Ein zweiter Versuch neulich hat mir dann jetzt auch zu lange gedauert. Also habe ich noch mal intensiv recherchiert und siehe da: ich stehe doch nicht allein mit dem Problem da. Dieses Video hat mich dann nach weiterer Suche motiviert, den Schraubendreher zu schwingen und siehe da: DER GEHT!


Was mich in dem Umfeld nun noch nervt ist, dass sich mein Raspberry Pi mit XBMC nicht überreden lässt, Audio sowohl per HDMI als auch analog auszugeben. So muss ich zum Musikhören leider den Fernseher einschalten oder umständlich im Menü den Audioausgang umstellen (wofür ich natürlich auch den Fernseher brauche). Naja. Vielleicht klärt sich das ja noch.