RavenSystem – Wir basteln uns eine HomeKit LED Lampe
Nach der anfänglich vorgestellten Schaltgruppe, die bislang ausschließlich in der und für die "innere" HomeKit-Infrastruktur wertvolle Zusatzfunktionen wie besagte Speicherplätze, Timer oder die Fähigkeit zu Zählen bereitstellt, will ich heute mal mit einfachsten Mitteln aus einem ESP8266 eine dimmbare Lampe basteln, die noch dazu von "außen" per beliebigem physischen Schalter bedient werden kann. Dies, um prinzipiell die Outboard-Möglichkeiten des ESP einführend vorzustellen, durch die eine Vielzahl an Hardware (Sensoren, Schalter, Motoren, Relais etc.) für den Bau eigener HomeKit Gerätschaften mit dem RavenSystem genutzt werden kann.
Dabei soll wiederum in erster Linie die Nachvollziehbarkeit des Scripts für Anfangende im Vordergrund stehen, um eigene Projekte anzuregen. Über eine praktische Verwendungsmöglichkeit der im Beispiel behandelten, vermutlich "kleinsten" HomeKit-Lampe der Welt darf jeder für sich fantasieren.
Wenn ich ESP8266 schreibe, meine ich den hier im Beitrag von allen derzeitigen Teilnehmern unabgesprochen erwählten konkreten Kandidaten (Wemos) D1 Mini, der praktischerweise bereits viel Nützliches an Board hat, das uns für alle möglichen (und unmöglichen) Projekte direkt zur Verfügung steht. Tatsächlich gibt es zahlreiche andere ESP8266 in unterschiedlichsten Baugrößen und mit mehr oder weniger Erweiterungen, dies sowohl in der im folgenden beschriebenen Anleitung als Einzelmodul als natürlich auch in fest verbauter Form fertiger, käuflich zu erwerbender Produkte wie den allseits bekannten Shellys.
Im besagten D1 Mini stehen uns zur Verfügung:
- 1x integriertes Wireless Local Area Network oder kurz WLAN nach IEEE 802.11.b/g/n
- 1x 10-Bit-Analog-Digital-Umsetzer
- 11x General Purpose Input Output Pins oder kurz GPIOs
- 1x I2C Schnittstelle
- 1x SPI Schnittstelle
- 1x asynchrone serielle Schnittstelle (UART)
- 1x Status LED (blau)
- 1x Reset Schalter
- 1x Micro USB Anschluss
Die Pin-Belegung ist im folgenden Bild übersichtlich beschrieben. Insbesondere die Zuordnung der GPIOs wird damit nachvollziehbar, denn die eigentliche Board-Beschriftung schweigt sich dazu aus bzw. zeigt eine eigene Logik. Diese GPIO-Belegung ist essentiell für die richtige Wahl der gewünschten Pins, die im RavenSystem Script korrekt angegeben werden müssen.
Der Vollständigkeit halber zeigt die nachfolgende Tabelle zudem alle Besonderheiten der einzelnen Pins inkl. Übersicht, wofür diese speziell im D1 Mini genutzt werden können. Es wird u.a. ersichtlich, dass bestimmte Pins in verschiedener Weise verwendet werden können.
| PIN | Input | Output | Info |
|---|---|---|---|
| ADC | Analog | X | Pin um analoge Werte zu messen 0-1 Volt |
| GPIO16 | Kein Interrupt | Kein PWM und 12C | Kann binäre Zustände einlesen/ausgeben, Weckt den ESP aus dem Deep-Sleep wenn auf GND gezogen. HIGH beim Booten |
| GPIO5 | OK | OK | Oft für SCL (12C) verwendet |
| GPIO4 | OK | OK | Oft für SDA ) (12C) verwendet |
| GPIO0 | Pull-up | OK | Beim flashen auf GND ziehen, kann so nicht booten |
| GPIO2 | Pull-up | OK | Kann nicht booten wenn auf GND gezogen HIGH beim booten |
| GPIO14 | OK | OK | SPI SCLK |
| GPI012 | OK | OK | SPI MISO |
| GP013 | OK | OK | SPI MOSI |
| GPIO15 | Pull-down | OK | SPI CS Kann nicht booten wenn auf HIGH gezogen |
| GPI03 | OK | RX Pin | Serieller Pin zum Senden von Daten
HIGH beim booten |
| GPIO1 | TX Pin | OK | Serieller Pin zum Empfangen von Daten
Kann nicht booten wenn auf GND gezogen HIGH beim booten |
Ich beginne mal mit dem Ausgangsscript für RavenSystem, das eine einfache Lampe definiert ("t":30), die in diesem Fall allerdings keine virtuelle, sondern eine reale Lampe in Form der im ESP verbauten Status LED werden soll. Um dies zu erreichen, wähle ich als erstes also den Type "ty":1. Wir erinnern uns, der Type "ty":0 definierte die Lampe im Schaltgruppen-Beispiel zur virtuellen Leuchte, die ausschließlich in der Home-App leuchtet. Diesmal soll eine Lampe bzw. LED zusätzlich auch die wirkliche Welt "erleuchten".
Das tut sie allerdings in diesem Stadium noch nicht, allein weil wir dem ESP erst noch mitteilen müssen, was ihn dazu bewegt, seine aufgelötete LED an- und auszuschalten.
Ich hole für das Verständnis noch etwas aus. Zwar ist die LED wie gesagt auf dem ESP verlötet, dennoch ist sie über einen für sie reservierten GPIO im Sinne eines Outs ansprechbar. Hätte ich einen ESP ohne aufgelötete LED, würde ich das gleiche Ergebnis erhalten, wenn ich eine separate LED an denselben anlöte. Beim D1 Mini ersparen wir uns also den Kauf einer solchen separaten LED samt Anbringungsprozedere per Lötung oder per Steckfeld. Beim D1 ist der für die verbaute LED entscheidende GPIO = 2, und zwar mit einer zusätzlichen Besonderheit: Die LED leuchtet auf, wenn dessen GPIO Zustand "low" ist. Was heißt das nun wieder?
Kommen wir zum grundsätzlichen Prinzip, Schaltungen per GPIOs auszuführen. GPIOs sind – allein schon namentlich erahnbar – frei definierbare Pins, die wahlweise als digitale Ausgänge (bspw. um Relais oder Lampen zu schalten) oder als digitale Eingänge (bspw. um mit Schaltern, Sensoren Aktionen auszulösen) definiert werden können. Dem ESP kann man den gewünschten Schaltbefehl u.a. physisch dadurch mitteilen, dass man den Zustand des GPIOs ändert. Je nach Ausführung eines GPIOs verfügt derselbe entweder über einen sogenannten Pull-Up- oder einem Pull-Down-Widerstand oder gar keinen Widerstand. In obiger Tabelle ist dies für den D1 Mini in der Spalte "Input" ersichtlich. Besagte Widerstände wirken sich auf die Grundzustände der GPIOs aus, was in erster Line für Inputs relevant wird, um u.a. stabile Zustände zu erreichen. Die GPIO Zustände werden dadurch im ESP erkannt, dass entweder eine Spannung (3,3V) am ESP anliegt = "high" oder die Spannung komplett abfällt = "low". Wer sich zum Thema schlauer machen will, kann hier detaillierte Infos zu den GPIO-Zuständen erhalten.
Ich komme zurück zur LED auf dem D1 Mini. Ich merkte eben noch an, dass diese verbaute LED aufleuchtet, wenn ihr reservierter GPIO 2 den Zustand "low" hat, umgekehrt erlischt sie in dem Moment, da der Zustand auf "high" wechselt. Übersetzt auf das Script benötige ich nun also einen Key, der genau diese Zustände auslöst und GPIO 2 als Output definiert. Hierfür sieht RavenSystem die "RGBW GPIO Channels" mit dem Key "g" vor, die je nach LED auch mehrere GPIOs für mehrkanalige Regelungen zulässt. Da wir die einfachste Form einer 1-kanaligen LED im Beispiel verwenden, reicht also die Angabe der GPIO Nummer 2. Die Besonderheit, dass die LED im Zustand "low" also quasi invers einschaltet, kann durch einfache Addition der GPIO mit der dafür definierten Zahl 100 erreicht werden, in unserem Fall also 102:
Der ESP ist somit zum vollwertigen HomeKit Lampen-Device umgewandelt und kann nun über die Home App oder Siri sowohl ein- und ausgeschaltet als auch gedimmt werden (wobei Letzteres nur in entsprechender Demoqualität zu genießen ist).
Jetzt drängt sich gleich die nächste Frage auf: Wie kann die LED über einen einzigen GPIO mit 2 möglichen Zuständen gedimmt werden? Hierbei kommt die sogenannte Puls-Weiten-Modulation oder kurz PWM in’s Spiel, die sehr vereinfacht gesagt durch schnelles frequenzveränderndes Ein- und Ausschalten der LED eben den Effekt erzielt, dass die LED bei schnellerem Ein- und Ausschalten heller, bei langsamerem Hin- und Her entsprechend dunkler zu leuchten scheint. Diese PWM erledigt das RavenSystem, ohne dass wir uns für das Script weitere Gedanken machen müssen. Die Standardfrequenz liegt ohne weitere Code-Eingaben übrigens bei 305 Hz, was für die eigenen Anforderungen frei verändert werden kann (was an dieser Stelle allerdings nicht weiter beleuchtet werden soll).
Wir haben uns über den sehr überschaubaren Code also mal eben eine HomeKit-Lampe gebastelt, die zwar nicht unbedingt atemberaubende Lichtatmosphären erzeugt, immerhin aber bspw. als Status-LED einen gewinnbringenden Einsatz in unserem Smarthome zuließe. Das Beispiel lässt natürlich auch den Einsatz von separaten LEDs oder LED-Streifen zum Zwecke einer Raumbeleuchtung zu, die man an den ESP respektive an ausgewählte GPIOs anlötet und in gleicher Weise in RavenSystem codiert. Bishin zu RGB-CW-WW LEDs kann alles über das RavenSystem direkt in HomeKit gebracht werden.
Haben wir eben mal ein Beispiel für einen GPIO als Output kennengelernt, soll die eben gebastelte Lampe im Folgenden durch einen eigenen physischen Schalter ergänzt werden, der die Lampe unabhängig von HomeKit direkt ein- oder ausschalten soll = Wir nutzen dazu einen weiteren GPIO als Input.
Spätestens an dieser Stelle müssen wir entweder Lötarbeiten in Betracht ziehen oder wir nutzen den beliebten Weg aller ESP-Bastelnden und investieren in ein sogenanntes Breadboard, oder auch altdeutsch Steckbrett genannt, samt verschiedener Jumper Wires oder auch Steckbrücken. Wobei entweder/oder nicht ganz richtig ist, denn auch mit Steckbrett müssen wir zumindest den D1 Mini löttechnisch mit den zumeist mitgelieferten Pin Sätzen versehen, damit derselbe auf das Steckbrett gesteckt werden kann. Danach kann dann aber Vieles durch einfaches Umstecken von Kabeln für die ersten Experimente verwirklicht werden.
Als besagten physischen Lampen-Schalter können wir alles verwenden, was 2 Pole ein- und ausschalten kann, also beliebige Kipp-, Druckschalter samt allem, was mit Taster an- oder aufhört. Und selbst ganz ohne Schalter können wir das Experiment ausprobieren und einfach nur ein Steckkabel ein- und ausstecken.
Der für unser Script nötige Basis-Key definiert die "Digital Inputs" unserer Lampe mit einem "b" als sogenannten alleserklärenden "Binary Input". Dadurch weiß das System also, dass etwas in den ESP und die definierte Lampe "reinkommt". Es ist leicht zu erahnen, dass wir wiederum einen freien GPIO benötigen, diesmal wie gesagt als Input, der in gleicher Weise wie der Output durch den Key "g" samt Nummer des GPIO gewählt werden kann. Im Beispiel verwende ich einfach mal den GPIO 13, der der ESP-Beschriftung "D7" entspricht. Sobald ich diesen GPIO 13 mit Ground (im ESP als "G" bezeichnet) verbinde bzw. davon trenne, erhalte ich die gewünschte Umschaltung zwischen „low“ und „high“.
Nun muss ich dem ESP noch mindestens mitteilen, wie die Zustandsänderung von "low" und "high" schalttechnisch für die Lampe interpretiert werden soll. Habe ich also einen Taster, der nach jedem Loslassen wieder in den low-Zustand verfällt, soll ja die Lampe trotzdem eingeschaltet bleiben und erst bei der nächsten Tasterbetätigung ausgeschaltet und damit getoggled werden. Habe ich dagegen einen Schalter, der An und Aus durchgängig hält, soll die LED entsprechend anders geschaltet werden.
Der dafür notwendige Key nennt sich vielsagend "Press Type" und wird durch "t" definiert. RavenSystem bietet exakt 6 Möglichkeiten, von denen in diesem Beispiel 2 angewendet werden sollen. Den meisten HomeKit Freunden sind die Types "Single", "Double" als auch "Long-Press" sicherlich durch zahllose kommerzielle HomeKit-Schalter geläufig. Wir benötigen für das Tasterbeispiel nur den klassischen "Single Press" mit der Nummer 1, also "t":1. Das ergibt zusammen mit dem GPIO- und Input-Key den fertigen Code:
Gleich dazu ein grundsätzlicher Hinweis: "t":1 ist in RavenSystem als ein default- also Standardwert gekennzeichnet. ALLE derartigen Werte können im Code entfallen, was wiederum Speicherplatz im ESP zu sparen hilft. Der obige Code kann also nochmal reduziert werden, ohne dass sich funktionell irgend etwas ändert.
Fehlt noch die eben erwähnte alternative Schaltmöglichkeit per Schalter statt eines Tasters. Doch wie soll das gehen, schließlich macht der Schalter grundsätzlich nichts anderes als der Taster, außer dass er das Einschalten quasi festhält, wenn man ihn loslässt? Tatsächlich könnten wir denselben Code auch mit einem Schalter nutzen, müssten dann aber immer nach dem Einschalten erst einmal aktionslos ausschalten, um dann wieder einzuschalten, was wir natürlich nicht wollen. RavenSystem bietet exakt für diesen Fall den Press Type "t":0 an, der das "Gegenteil" von "t":1 bewirkt. Da wir beide Types für den GPIO 13 aktivieren wollen, notieren wir einfach beide Keys mit Kommatrennung als Array.
Oder wiederum um den Standardwert gekürzt:
Jede Schalteränderung wechselt ab sofort den Schaltstatus der Lampe. So war’s gewollt. Es gilt noch zu bedenken, dass Schaltungen über die Home App zwar selbstverständlich noch ausgeführt werden, dass sich dadurch aber natürlich die Schaltpositionen des physischen Schalter vertauschen. Solche Schalter mit eindeutigen Symbolen für den Schaltzustand können also womöglich irritieren, wenn derselbe also auf "Ein" steht, zwischenzeitlich aber per App umgeschaltet wurde, sodass man gegen die langjährige analoge Erfahrung den Schalter auf "Aus" schalten muss, um die Lampe wieder einzuschalten.