Vom Raspberry Pi zum Smart Home: Mein erstes IoT-Projekt
Raspberry Pi, Node.js, Kaffee per Klick und SBB-Verbindungen: ein Rückblick auf meine Hausautomation von 2016, ihre Architektur und die Lektionen aus meinem ersten IoT-Projekt.
- Raspberry Pi
- Node.js
- Socket.IO
- IoT
- Home Automation
- Retrospective

Engineering Journal · Rückblick auf 2016
Ein Klick im Browser, und zuhause geht das Licht an oder die Kaffeemaschine startet: Das war die Idee hinter meinem ersten IoT-Projekt. 2016 verband ich Raspberry Pi, Node.js und Socket.IO zu einer eigenen Haussteuerung. Hier schaue ich auf den damaligen Aufbau zurück – mit Originalbildern, den improvisierten Lösungen und dem, was ich heute anders angehen würde.

Eine neue Wohnung, eine eigene Haussteuerung
Ich war gerade in eine neue Wohnung gezogen und wollte herausfinden, wie sich Alltagsgeräte mit eigener Software verbinden lassen. Statt nur einzelne Geräte fernzusteuern, wollte ich eine gemeinsame Oberfläche für meine Wohnung bauen.
Zur Auswahl standen C# und ein Web-Stack. Ich entschied mich für Node.js, weil mich eine Webanwendung mit Echtzeitkommunikation reizte. Express lieferte die Oberfläche aus, Socket.IO übertrug Ereignisse zwischen Browser und Server.
Das Dashboard zeigte Uhrzeit, Wetter und die nächsten Verbindungen nach Bern. Auch der Hintergrund wechselte je nach Tageszeit. Die Oberfläche sollte morgens genauso nützlich sein wie beim Ausschalten der Lichter am Abend.
Die Dashboard-Illustration wurde für diesen Rückblick neu gestaltet.
Licht und Szenen in einer Oberfläche
Die Oberfläche bündelte Szenen wie «Zuhause», «Unterwegs», «Gute Nacht» und «Kino». Ich wollte häufige Abläufe mit wenigen Klicks erreichbar machen und mehrere Geräte von derselben Oberfläche aus bedienen.
Die Hue-Lampen waren ein konkreter Teil dieser Lichtsteuerung. Weitere Sensoren für Bewegung, Temperatur und Licht sowie eine Pflanzenbewässerung gehörten zu den geplanten Erweiterungen.
Philips Hue: Lichtsteuerung über die Bridge
Für meine Hue-Lampen nutzte ich die Hue Bridge und das Node.js-Paket node-hue-api. Der Server schickte die Lichtbefehle direkt an die Bridge im lokalen Netzwerk. Im damaligen Code waren deren IP-Adresse und der API-Zugang fest hinterlegt.
Ein Schalter im Browser löste ein Socket.IO-Ereignis aus. LightOben steuerte eine einzelne Lampe, LightAll schaltete die drei eingebundenen Lampen gemeinsam. Node.js setzte den gewünschten Zustand über api.setLightState(...) und verteilte Ereignisse wie LightObenTrue oder LightAllFalse an die verbundenen Browser. Dort aktualisierte JavaScript die Schalter.
Browser → Socket.IO → Node.js → Hue Bridge → Lampen
Node.js → Socket.IO → Schalter in den verbundenen Browsern
Der Ablauf DayNight schaltete die erste Lampe sofort aus, die zweite nach fünf Sekunden und die dritte nach zehn Sekunden. Aus einem einzelnen Klick wurde damit eine kleine zeitliche Abfolge.
Eine wichtige Grenze sehe ich heute bei den Rückmeldungen: Die Socket-Ereignisse aktualisierten die Oberfläche, bestätigten aber noch nicht den tatsächlichen Zustand jeder Lampe. Heute würde ich Befehle, erfolgreiche Antworten der Bridge und beobachtete Lampenzustände getrennt behandeln. Für ein zuverlässiges Smart Home müssen Anzeige und Gerätezustand zusammenpassen.
SBB-Verbindungen direkt auf dem Dashboard
Zum Smart Home gehörte für mich auch die Frage: Wann fährt meine nächste Verbindung? Deshalb integrierte ich eine Fahrplananzeige für Bern Europaplatz → Bern. Zusammen mit Uhrzeit und Wetter standen die Informationen für den Weg aus der Wohnung auf derselben Oberfläche wie die Gerätesteuerung.
Die Daten kamen über die offene Schweizer ÖV-API transport.opendata.ch. Im Code nannte ich die Integration «SBB»; die Abfrage lief über diese offene API. Angezeigt wurden die nächsten vier Verbindungen mit Gleis, Abfahrtszeit und Ankunftszeit.
Der damalige Datenfluss hatte einen eigenen Umweg: Der Browser holte die JSON-Antwort mit $.getJSON und schickte das gesamte Verbindungsobjekt als Socket.IO-Ereignis SBB an Node.js. Der Server extrahierte die einzelnen Werte und schickte sie als Ereignisse wie SBBZEIT0, SBBGLEIS0 und SBBANKUNFT0 zurück. Im Browser landeten sie dann in den entsprechenden Tabellenzellen.
ÖV-API → Browser → Socket.IO → Node.js
Node.js → Socket.IO → Fahrplantabelle im Browser
Auch die Grenzen des damaligen Beispiels sind interessant: Die Spalte «Verspätung» war bereits angelegt, wurde im veröffentlichten Code aber noch nicht befüllt. Ein leeres Gleis ersetzte ich pauschal durch «Tram». Heute würde ich Verkehrsmittel und Verspätungen aus den passenden Datenfeldern ableiten, fehlende Angaben bewusst darstellen und den Zeitpunkt der letzten Aktualisierung anzeigen.
Diese Integration machte aus einer Fernbedienung für die Wohnung ein Dashboard, das auch bei der Planung des nächsten Weges half.

Wie Browser und Geräte miteinander sprachen
Ein zentraler Raspberry Pi sollte die Webanwendung bereitstellen. Weitere Raspberry Pis oder Arduinos waren als Geräte- und Raumcontroller vorgesehen. In meiner Hardwareliste standen ein Raspberry Pi 2, ein Pi Zero und 5V-Relais.
Die Raspberry-Pi-Gerätecontroller liefen als kleine Webserver. Feste IP-Adressen und PHP-Endpunkte wie espresso.php oder Doppio.php ordneten einen Aufruf einer Aktion zu. Die PHP-Datei startete das jeweilige Skript, das die GPIO-Pins und Relais ansteuerte. Hue hatte einen eigenen Weg über die Bridge-API.
Der ungewöhnlichste Teil lag dazwischen: Ich wusste damals noch nicht, wie ich direkt aus Node.js einen HTTP-Aufruf an die anderen Geräte sende. Deshalb schrieb Node.js einen GPIO-Wert. Ein separates Skript prüfte die Pins in einer Schleife und löste den passenden curl-Aufruf aus.
Das war ein Umweg, aber er zeigt meinen damaligen Lernstand ziemlich gut: Ich kombinierte die Werkzeuge, die ich bereits verstand, um die nächste Verbindung im System herzustellen.
Die ursprüngliche Architekturzeichnung zeigt das geplante Zusammenspiel der zentralen Steuerung und der Gerätecontroller.

Das Konzept hinter den Erweiterungen
Diese ergänzende Konzeptgrafik zeigt die Idee hinter dem System: Ein Raspberry Pi verbindet Sensoren und Relais mit Geräten im Alltag. Feuchtigkeit, Temperatur und Bewegung stehen für die geplante Sensorik; Licht, Kaffeemaschine, Pflanzenbewässerung und Storen für mögliche Anwendungen.
Die Grafik veranschaulicht das Konzept. Sie zeigt auch Erweiterungen, die damals noch nicht vollständig umgesetzt waren.

Das greifbarste Ergebnis: Kaffee per Klick
Für die Kaffeemaschine verwendete ich eine Nespresso Pixie. Relais übernahmen die Tastendrücke, und ein Bash-Skript steuerte die Reihenfolge: einschalten, aufwärmen, den Brühvorgang auslösen und zum Schluss abschalten.
Im damaligen Doppio-Skript wartete die Maschine zunächst 34 Sekunden. Danach folgten Schaltintervalle von 11,5, 10 und 10,9 Sekunden, getrennt durch kurze Pausen. Diese festen Zeiten machten aus einem Browserbefehl einen konkreten Ablauf an einem echten Gerät.
Gerade hier wurde die Grenze zwischen einem Softwarezustand und der Realität sichtbar: Ein ausgelöster Befehl bestätigt noch nicht, dass die Maschine bereit ist oder der Kaffee tatsächlich durchgelaufen ist. Heute würde ich diesen Ablauf mit Zustandsrückmeldungen und klaren Fehlerfällen modellieren.
Die Nespresso Pixie aus meinem damaligen Projekt, fotografiert vor dem Umbau.

Der Umbau: vom Gehäuse zu den Tasten
Die Bilder im Slider dokumentieren drei Schritte am Gerät: das geöffnete Gehäuse, die Tastenplatine mit den zusätzlich angeschlossenen Jumperkabeln und die Leitungsführung im Inneren. Über diese Verbindung konnte die externe Steuerung die vorhandenen Tasten in den programmierten Ablauf einbinden.
Die mechanische Arbeit gehörte genauso zum Projekt wie das Skript: Gehäuseteile öffnen, an die Bedienung gelangen und die zusätzlichen Leitungen nach aussen führen.
Originalfotos von 2016: Gehäuse → Tastenplatine → Innenansicht. Mit den Pfeilen kannst du zwischen den drei Bildern wechseln.

Relais und Verkabelung am Prototyp
Drei Relaismodule mit ihrer Verkabelung und der Raspberry Pi darunter zeigen die Verbindung zwischen Software und Gerät. Das Skript gab die Abfolge vor; die Relais übernahmen die Schaltkontakte. Die zweite Aufnahme zeigt die Platinenrückseite und die angeschlossenen Leitungen aus der Nähe.
So wird auf den Fotos sichtbar, was ein Architekturdiagramm nur als Verbindungslinie darstellen kann: Zwischen dem Browserbefehl und dem fertigen Kaffee lagen Kabel, Kontakte und eine zeitlich abgestimmte Steuerung.
Originalfotos von 2016: Relaisübersicht → Platinenrückseite. Beide Aufnahmen findest du im Slider.
Was ich heute anders angehen würde
Direkte Kommunikation. Den GPIO-Umweg würde ich durch direkte HTTP-Anfragen oder eine Kommunikation über MQTT ersetzen. Befehle und Rückmeldungen sollten klar voneinander getrennt sein.
Bestätigte Zustände. Ein Dashboard sollte unterscheiden, ob eine Aktion angefordert, ausgeführt oder fehlgeschlagen ist. Zeitüberschreitungen, Verbindungsabbrüche und Geräte, die gerade nicht erreichbar sind, gehören zum Ablauf.
Zugang und Konfiguration. Die veröffentlichten Beispiele enthielten feste IP-Adressen und einen Hue-Zugangswert im Code. Heute würde ich Konfiguration und Zugangsdaten auslagern und den Zugriff auf Oberfläche und Geräte bewusst absichern.
Ein gemeinsames Gerätemodell. Statt vieler ähnlicher Socket-Handler würde ich Geräte, Aktionen und Zustände einheitlich beschreiben. Neue Geräte könnten so über Konfiguration hinzukommen, ohne immer wieder denselben Code zu kopieren.
Was mir aus dem Projekt geblieben ist
Mich reizte, dass eine Zeile Code etwas ausserhalb des Bildschirms auslösen konnte. Gleichzeitig musste ich mich mit Timing, WLAN-Verbindungen und Abläufen beschäftigen, die sich nicht einfach durch einen neuen Seitenaufruf zurücksetzen lassen.
Heute sehe ich darin einen frühen Schritt, Systeme als zusammenhängende Prozesse zu verstehen: Oberfläche, Kommunikation, Gerät und Rückmeldung müssen zusammenpassen. Genau deshalb lohnt sich für mich dieser Rückblick – auch mit den Umwegen im damaligen Code.
Die ursprüngliche Architekturzeichnung und die Hardwarefotos stammen aus meiner Projektdokumentation von 2016. Die neu gestalteten Illustrationen ergänzen den Rückblick.