Sie sind intuitiv zu bedienen, schnell, effizient und lassen dem Nutzer dabei sogar die Hände frei: sprachgesteuerte Interfaces. Mit Alexa stehen sie auch dem Heimautomatisierer offen.
Wer eine eigene Anwendung für die Heimautomatisierung über Amazon Alexa mit natürlicher Sprache steuern will, der hat zwei prinzipielle Möglichkeiten: Entweder er verwendet einen fertigen Alexa-Skill, wie ihn die Hersteller mancher Automatisierungskomponenten anbieten – das ist die einfachste Variante. Oder aber er schreibt sich selbst einen eigenen Skill.
Im erstgenannten Fall fällt wenig mehr als die reine Konfigurationsarbeit an – dafür bleiben die Möglichkeiten allerdings auf diejenigen beschränkt, die der fremde Skill-Programmierer vorgesehen hat. Im zweiten Fall sind die Fertigkeiten des Skills fast nur durch die Fantasie und das Programmier-Know-how begrenzt. Dafür macht dieser Weg aber auch deutlich mehr Arbeit und erfordert das Einarbeiten in das Konzept eines Sprachinterfaces.
Der vorliegende Artikel diskutiert beide Varianten an ein und demselben Beispiel, nämlich an der Steuerung eines Fernsehers und einer einfachen Lampe.
Hi-Fi-Geräte bedienen
Als Beispiel für einen vorgefertigten Skill bietet sich zum Beispiel die Universal-Fernbedienung Harmony von Logitech mit ihrem Hub an. Der Hub ist ein zentraler Sender, der den Geräten, die der Nutzer bedienen will, Signale per Infrarot, Bluetooth oder WLAN schickt. Die Fernbedienung, die man in der Hand hält, redet dann also nicht mehr direkt mit dem Fernseher, der Stereoanlage oder dem Videoplayer, sondern mit dem Hub, der seinerseits mit dem jeweiligen Gerät spricht. Dieser Hub lässt sich nun dank eines entsprechenden Alexa-Skills per Sprache bedienen, was zur Folge hat, dass eine große Palette aller möglichen Geräte der Heimelektronik im Wortsinn ansprechbar sind.
Das beschränkt sich nicht nur auf elementare Ein- und Ausschaltvorgänge, denn die lassen sich auch zu so genannten Aktionen kombinieren. Verwendet der Fensehzuschauer beispielsweise eine Soundbar für besseren Ton oder auch 3-D-Klangeffekte, dann kann er diese immer parallel zum Fernseher in und außer Betrieb nehmen, indem er die virtuellen Ein-/Ausschalter beider Geräte in einer Sequenz koppelt (Abbildung 1).

Abbildung 1: Zwei Screens der Harmony-App zur Definition einer Startsequenz für Fernseher und Blaupunkt Soundbar.
Solche Aktionen lassen sich dann wiederum via Alexa per Sprachbefehl auslösen, sodass ein knappes “Alexa, gute Nacht!” genügt, um Fernseher und Soundbar auszuschalten, das Licht zu dimmen, die Jalousien herunterzufahren und die Wohnungstür abzuschließen.
Was ist dafür zu tun? Zunächst gilt es, die Aktionen auf dem Smartphone oder Tablett zu definieren, und zwar in der Harmony-App. Diese App gibt es für Android und iOS. Harmony steuert über 270 000 verschiedene Geräte der meisten namhaften Hersteller, darunter beispielsweise solche von Bose, Philips, Denon, Sonos, Hue oder der Deutschen Telekom. Den Aktionen ließen sich auch Tasten der Fernbedienung zuweisen, sodass ein Tastendruck eine ganze Befehlskaskade auslöst. Im vorliegenden Beispiel soll aber Alexa die Aktionen anstoßen.
Dazu muss sich der Anwender in einer zweiten App, der Alexa-App auf dem Smartphone oder Tablet, zunächst den passenden Skill aus dem Amazon Alexa App Store besorgen. Der firmiert dort unter der Bezeichnung “Harmony” und hat ein blaues Logo. Achtung: Es gibt auch noch eine ältere Version dieses Skills mit einem roten Logo und der Bezeichnung “Harmony Zweites Hub”. Diese Variante empfiehlt sich nicht mehr, weil bei ihr immer die Floskel “mit Harmony” an die Kommandos anzuhängen war.
Nach dem Herunterladen muss der Anwender den Skill aktivieren und sich mit denselben Credentials anmelden, die er zuvor für sein Logitech-Konto verwendet hat. Daraufhin informiert sich der Alexa-Skill automatisch über die Harmony-Aktionen. Das war es im Prinzip.
Wer will, kann noch an den hinterlegten Formulierungen für die Sprachbefehle oder den Gerätenamen feilen; unbedingt nötig ist das aber nicht. Ab sofort funktionieren Sprachbefehle wie “Alexa, schalte den Fernseher ein” oder “Alexa, schalte die Xbox ein” – vorausgesetzt der Anwender hat zuvor eine entsprechende Aktion in der Harmony-App definiert. Man kann sagen “Alexa, umschalten zu Kanal 3” oder “Alexa, mach es lauter um vier Schritte” und so weiter.
Heimautomation
Fertige Alexa-Skills gibt es unter anderem auch für Funksteckdosen, allerdings jeweils spezifisch für einen bestimmten Hersteller. Beispielsweise gibt es einen Skill für die Geräteserie Kasa (WLAN-Steckdosen, Kameras, Leuchtmittel) des Herstellers TP-Link. Wieder richtet der Nutzer die Steckdose zunächst in einer TP-Link-Kasa-App ein und benennt sie. Auch hier braucht er dazu ein Konto, diesmal bei TP-Link. Danach lässt sich das Gerät in der Alexa-App auswählen und hinzufügen. Wer die Steckdose im ersten Schritt etwa “Leselicht” genannt hat, weil sie die Stehlampe am Relaxsessel bedient, der kann nun mit “Alexa, Leselicht ein” für Beleuchtung sorgen.
In beiden Fällen geht die Einrichtung einfach, bequem und zügig von der Hand. Wem die Grundfunktionen gängiger Geräte ausreichen, der hat also kaum einen guten Grund, selbst zum Skill-Programmierer zu werden. Es bleiben höchstens die selteneren Fälle, in denen es der Anwender mit exotischen Geräten zu tun hat oder in denen er Funktionen bedienen will, die vorgefertigte Skills nicht im Repertoire haben. Dann muss er den zweiten Weg nehmen und sich einen Skill programmieren.
Wer Alexa mit einem gesunden Misstrauen im Hinblick auf den Datenschutz begegnet, dem hilft das Selberprogrammieren übrigens nicht viel weiter: Auch in diesem Fall landet alles, was Alexa im Anschluss an das vereinbarte Signalwort als Kommando interpretiert, auf amerikanischen Servern und wird dort auch gespeichert.
Alexa-Skill im Eigenbau
Genau besehen steht der Skill-Programmierer sogar vor zwei recht unterschiedlichen Herausforderungen: Er muss erstens dafür sorgen, dass der Rechner, der seine Aktionen ausführen soll, im vorliegenden Beispiel ein Raspberry Pi, von Alexa, die den Sprachbefehl aufnimmt und interpretiert, erfährt, was zu tun ist. Neben dem RasPi wird dafür also auch noch einer von Amazons intelligenten Lautsprechern der Echo-Serie gebraucht, der die gesprochene Anweisung entgegennimmt und an seine Server weitergibt.
Der Programmierer muss zweitens auch die Aktion selbst programmieren, die er sich vorstellt. Das Beispiel in diesem Artikel geht aber nur auf Schritt 1 ein. Um anzuzeigen, dass er eine Anweisung bekommen und verstanden hat, lässt hier der Raspberry Pi eine von acht LEDs leuchten (Abbildung 2). Im Ernstfall könnte er über dieselbe GPIO-Leitung beispielsweise ein Relais schalten.

Abbildung 2: Der Schaltplan für die acht LEDs, die für erste Tests die Funktionsweise des Flask-Frameworks veranschaulichen.
Für das Experiment genügt ein Raspberry Pi der ersten Generation, auf dem die neueste Version von Raspbian “Stretch” Lite läuft. Die Lite-Variante des Betriebssystems verzichtet auf eine grafische Benutzeroberfläche und kommt daher besonders gut mit den knappen Ressourcen zurecht. Für das vorliegende Projekt ist ein GUI ohnehin nicht nötig. In der Lite-Variante von Raspbian fehlen allerdings einige Bibliotheken und Tools, die es zu installieren gilt, bevor der Anwender das in Python geschriebene Webframework Flask einspielen kann, das später benötigt wird.
Diese Installationen erledigen die Kommandos aus den ersten vier Zeilen von Listing 1, inklusive der Installation von Flask mit Hilfe von Pip, dem Verwaltungswerkzeug für Python-Module. Der Vorgang nimmt geraume Zeit in Anspruch – Zeit für eine Kaffeepause.
Listing 1
Flask und Ngrok einrichten
01 $ sudo apt update 02 $ sudo apt upgrade 03 $ sudo apt install python2.7-dev python-dev python-pip wiringpi 04 $ sudo pip install flask-ask 05 $ unzip /home/pi/ngrok-stable-linux-arm.zip 06 $ ./ngrok http 5000
Tunnelbauer
Noch fehlt auf dem Raspberry Pi ein Werkzeug, das einen sicheren Tunnel zwischen dem RasPi und den Amazon-Servern aufbaut. Dafür bietet sich Ngrok an, eine Lösung, die sich sehr leicht installieren und konfigurieren lässt. Bei der kostenlosen Version von Ngrok ändert sich allerdings nach jedem Neustart die URL des Tools. Wem das zu lästig erscheint, der muss wohl oder übel in den sauren Apfel beißen und eine kommerzielle Variante verwenden.
Zur Installation des Programms lädt der Anwender die Version für Linux ARM von der Ngrok-Webseite herunter und überträgt das Zip-Archiv auf den Raspberry Pi. Anschließend entpackt er es und ruft Ngrok direkt aus einem Terminal heraus auf (Listing 1, Zeilen 5 und 6). Die Optionen des Kommandos in Zeile 6 weisen Ngrok dazu an, den Port 5000 von Localhost weiterzuleiten und dort auf HTTP-Anfragen zu lauschen. Die Ausgabe sollte dabei jener ähneln, die Abbildung 3 zeigt.
Bei jedem Verbindungsaufbau generiert Ngrok neue, zufällige URLs. Die im Bild rot markierte Adresse muss der Anwender sich merken: Sie wird später benötigt, um sie in den Alexa-Skills als Kommunikationsendpunkt zu verwenden.
Steuerprogramm
Da der laufende Ngrok-Server jetzt das aktuelle Terminal blockiert, empfiehlt es sich, ein zweites Terminalfenster zu öffnen. Dort erstellt man nun eine Textdatei namens »haus.py« mit dem Inhalt von Listing 2. Dieses Python-Programm ruft dann später der Alexa-Skill auf. Das Programm stellt einen Server bereit, der drei Geräte kontrolliert: einen Fernseher, eine Lampe und eine Steckdose.
Listing 2
haus.py
01 # haus.py
02
03 import logging
04 import time
05 import RPi.GPIO as GPIO
06 from flask import Flask, render_template
07 from flask_ask import Ask, statement, question, session
08
09 GPIO.setmode(GPIO.BCM)
10 app = Flask(__name__)
11 ask = Ask(app, "/")
12 logging.getLogger("flask_ask").setLevel(logging.DEBUG)
13
14 @ask.launch
15 def gruss():
16 GPIO.setup(17, GPIO.OUT) # GPIO 0
17 GPIO.setup(18, GPIO.OUT) # GPIO 1
18 GPIO.setup(27, GPIO.OUT) # GPIO 2
19 gruss = render_template('gruss')
20 return question(gruss)
21
22 @ask.intent("FernseherIntent",mapping={'status': 'status'})
23 def fernseher(status):
24 print 'test=>{}'.format (status)
25 if status == "an":
26 print 'AN'
27 GPIO.output(17, GPIO.HIGH) # GPIO 0
28 if status == "aus":
29 print 'AUS'
30 GPIO.output(17, GPIO.LOW) # GPIO 0
31 status = render_template('fernseher', status=status)
32 return question(status)
33
34 @ask.intent("LichtIntent",mapping={'status': 'status'})
35 def licht(status):
36 if status == "an": GPIO.output(18, GPIO.HIGH) # GPIO 1
37 if status == "aus": GPIO.output(18, GPIO.LOW) # GPIO 1
38 status = render_template('licht', status=status)
39 return question(status)
40
41 @ask.intent("SteckdoseIntent")
42 def steckdose(status):
43 if status == "an": GPIO.output(27, GPIO.HIGH) # GPIO 2
44 if status == "aus": GPIO.output(27, GPIO.LOW) # GPIO 2
45 status = render_template('dose', status=status)
46 return question(status)
47
48 if __name__ == '__main__':
49 app.run(debug=True)
Für jedes der drei Geräte gibt es im Programm einen so genannten Intent, der genau diese eine Funktion steuert. Die entsprechenden Dekoratoren »@ask.intent()« definieren die Funktionen, die der jeweilige Intent dann beim Aufruf als Aktion ausführt.
Passende Begrüßung
Der Dekorator »@ask.launch()« sorgt für die Anzeige eines freundlichen Begrüßungstexts. Im vorliegenden Beispiel dient dazu das hessische “Guude”, ein Gruß, der zu jeder Tageszeit passt.
In den Funktionen werden die zur Ansteuerung der GPIOs nötigen Kommandos ausgeführt. Das Flask-Framework kapselt dabei die Komplexität sehr gut, die sich hinter einem Skill verbirgt. Weitere Daten stehen in der Ressourcendatei »templates.yaml«. Sie muss im selben Verzeichnis liegen wie das Python-Programm, das mit dem Skill kommuniziert. Diese Datei enthält Texte, die der Skill verwenden soll. Das erleichtert es, die Sprachausgaben bei Bedarf anzupassen, um etwa den Gruß umzustellen oder andere Geräte einzutragen. Die recht kompakte Ressourcendatei für das Beispiel aus diesem Artikel zeigt Listing 3.
Listing 3
templates.yaml
01 gruss: Guude
02 fernseher: Fernseher ist {{status}}
03 licht: Licht ist {{status}}
04 dose: Steckdose ist {{status}}
Das Shell-Kommando »python haus.py« startet den Python-Server. Ngrok und das Python-Programm laufen danach einfach weiter. Selbstverständlich darf man anschließend auch keines der Terminalfenster schließen. Der Anwender muss darauf achten, dass Ngrok läuft, wenn der Python-Server zum Zuge kommt, denn sonst lässt sich keine Verbindung zwischen dem Echo-Skill und dem Serverprogramm aufbauen.
Alexa-Skill einrichten
Für den nächsten Schritt beim Programmieren eines Alexa-Skills muss das verwendete Echo-Gerät bereits aktiviert sein. Der Anwender benötigt zunächst einen Account bei Amazon Web Services (AWS), den er kostenlos über die AWS-Homepage bekommt. Dazu braucht er lediglich eine Kreditkarte sowie einen Mobilfunkanschluss.
Über den AWS-Account lässt sich nun ein neuer Alexa-Skill erstellen. Der einfachste Weg dorthin führt über die Liste der aktuellen Alexa-Skills, die bei einem neuen Benutzerkonto noch leer steht (Abbildung 4). Dort klickt der Benutzer dann auf den Schalter »Create Skill«, um einen neuen Skill anzulegen.
Anschließend sollte der Skill einen deskriptiven Namen erhalten, und die gewünschte Sprache ist zu definieren. Ein Mausklick auf den »Next«-Schalter führt direkt zum nächsten Schritt, der Wahl des »Custom«-Modells: Es bietet den höchsten Grad an Flexibilität.
Ein weiterer Klick auf den Schalter »Create Skill« schließt den Assistenten ab. Nun erscheint die zum neuen Skill gehörende Homepage (Abbildung 5). Hier lassen sich noch weitere Parameter des Skills einstellen. Das Video unter »How to get started« oben auf der Seite hilft beim Einstieg in die Feinheiten der Skill-Erstellung.
Skills im Detail
Um genauer zu verstehen, wie sich ein Alexa-Skill zusammensetzt, lohnt ein Blick auf seine einzelnen Komponenten. Der Skill beschreibt ein so genanntes Interaction-Modell, das alle Verhaltensweisen und Bestandteile zusammenfasst. Das Interaction-Modell selbst besteht wiederum aus einer ganzen Reihe von Komponenten.
Dabei fungiert die Invocation (Einladung) als Name des Alexa-Skills und dient als Schlüsselwort für dessen Aktivierung. Es gibt einige Regeln, die man bei der Namensvergabe einhalten muss – die entsprechende Webseite erklärt sie ausführlich.
Ein Intent (Absicht) beschreibt eine Aktion, die der Anwender innerhalb des Skills ausführen möchte. Die einzelnen Intents benötigen mindestens ein definiertes Schlüsselwort (Sample Utterance), das die Aktion startet. Dabei lassen sich zu jedem Intent im Bedarfsfall mehrere Sample Utterances hinterlegen – beispielsweise die Varianten “jo”, “jepp” und “jawoll” für das einfache “ja”. Je mehr sinnvolle Utterances zu einem Intent zusammenkommen, um so betriebssicherer wird der Skill.
Bei den Slot Types handelt es sich um selbst definierte Datentypen, die innerhalb der Skills zum Einsatz kommen. Von der Idee her ähneln die Slot Types den Aufzählungsdatentypen, wie man sie aus fast allen Programmiersprachen kennt. Für die Frage nach einer Automarke, könnte der Slot Type beispielsweise »Automarke« heißen und Werte wie »BMW«, »Audi« oder »Ford« enthalten.
Mit dem JSON-Editor, einem einfachen Texteditor, bearbeitet der Nutzer die einzelnen Komponenten des Skills direkt im Interface. Das erfordert zwar entsprechendes Know-how, bei komplexen Skills bleibt auf diese Weise jedoch leichter die Übersicht erhalten.
Im Abschnitt »Interfaces« bindet der Anwender Multimedia-Inhalte direkt in einen Alexa-Skill ein. Derzeit existieren die drei Interfaces Audio Stream, Video Stream und Display Interface.
Die Endpoints legen fest, mit welchen Diensten im Internet der Alexa-Skill kommunizieren soll. Im vorliegenden Fall fungiert der Raspberry Pi, der über den Ngrok-Dienst mit dem Skill verbunden ist, als Endpoint.
Wie bereits erwähnt, soll der Beispiel-Skill drei Geräte steuern: einen Fernseher, das Licht und eine Steckdose. Dazu legt man für jedes der drei Geräte einen Intent an. Jeder Intent kennt die Kommandos, die das entsprechende Gerät benennen und den Status übermitteln. Als Schlüsselwort dient das Kommando “Haus”. Es ist unter »Invocation« zu definieren, danach klickt der Anwender auf den Schalter »Save Model« (Abbildung 6). Aus Erfahrung kann der Autor nur dazu raten, lieber einmal zu viel zu speichern, als sich später zu wundern, warum der Skill nicht so arbeitet wie er soll.
Slots und Intents
Ein Slot Type mit dem Namen »GPIO« dient dazu, den Status der einzelnen Geräte zu übermitteln. Dabei kann »GPIO« einen der beiden Werte »an« und »aus« annehmen. Der Slot Type lässt sich schon jetzt anlegen. Dazu klickt der Nutzer auf das »Add« hinter dem Eintrag »Slot Types« in der Seitenleiste.
Dort kann er dann einen Custom Slot Type wählen und ihm den Namen »GPIO« geben (Abbildung 7). Auf der folgenden Seite weist er ihm die Werte »an« und »aus« zu. Um die Werte zu speichern, muss der Anwender hier »Save Model« oben klicken.
Außerdem legt der Nutzer nun die Intents an. Das könnte er manuell erledigen, indem er sich durch die einzelnen Dialoge klickt. Wesentlich schneller kommt er jedoch zum Ziel, indem er den Inhalt von Listing 4 über den JSON-Editor in das Interaction-Modell kopiert.
Listing 4
Intents
01 # intents.json
02 {
03 "languageModel": {
04 "invocationName": "haus",
05 "intents": [
06 {
07 "name": "AMAZON.CancelIntent",
08 "slots": [],
09 "samples": []
10 },
11 {
12 "name": "AMAZON.HelpIntent",
13 "slots": [],
14 "samples": []
15 },
16 {
17 "name": "AMAZON.StopIntent",
18 "slots": [],
19 "samples": []
20 },
21 {
22 "name": "FernseherIntent",
23 "slots": [
24 {
25 "name": "status",
26 "type": "GPIO"
27 }
28 ],
29 "samples": [
30 "Fernseher {status}",
31 "tv {status}"
32 ]
33 },
34 {
35 "name": "LichtIntent",
36 "slots": [
37 {
38 "name": "status",
39 "type": "GPIO"
40 }
41 ],
42 "samples": [
43 "licht {status}"
44 ]
45 },
46 {
47 "name": "SteckdoseIntent",
48 "slots": [
49 {
50 "name": "status",
51 "type": "GPIO"
52 }
53 ],
54 "samples": [
55 "steckdose {status}"
56 ]
57 }
58 ],
59 "types": [
60 {
61 "name": "GPIO",
62 "values": [
63 {
64 "id": "",
65 "name": {
66 "value": "aus",
67 "synonyms": []
68 }
69 },
70 {
71 "id": "",
72 "name": {
73 "value": "an",
74 "synonyms": []
75 }
76 }
77 ]
78 }
79 ]
80 }
81 }
Dabei ist auf jeden Fall darauf zu achten, dass die Intents im Interaction-Modell dieselben Namen verwenden wie im Python-Programm, sonst klemmt es später bei der Ausführung des Skills.
Zudem gilt es, den Skill nach jeder Änderung am Interaction-Modell zu speichern und anschließend durch einen Klick auf »Build Model« neu zu bauen. Vergisst man das, dann passiert nichts und es bleibt beim alten Modell.
Nun fehlt nur noch die Kommunikation zwischen dem Skill und dem Python-Programm. Dazu klickt der Benutzer auf »Endpoint« und wählt dort die Option »HTTPS« aus. In das Feld »Default Region« trägt er die gerade von Ngrok verwendete URL ein. In der Ausklappbox darunter aktiviert er zudem noch die Option »My development endpoint is a subdomain of a domain that has a wildcard certificate from a certificate authority« (Abbildung 8). Ein Klick auf »Save Endpoints« im Kopf des Dialogs sichert die Änderungen.
Nach dem Abschluss aller Konfigurationsarbeiten gilt es, den Skill das erste Mal zu bauen. Der Schalter »Build Model« erscheint auf allen Seiten, auf denen sich das Modell verändern lässt. Im Beispiel klickt der Anwender erst auf »Invocation« und dann auf »Build Model« (Abbildung 9).
Für einen ersten Test wechselt er in den gleichnamigen Reiter des Skills. Über den Schieber unterhalb der Reiterleiste lässt sich der Testmodus aktivieren. Danach gibt er in das Textfeld das Aktivierungswort “Haus” ein. Der Skill sollte ihn dann umgehend auf Hessisch begrüßen. Danach lassen sich die angebundenen Geräte schalten. Die am GPIO des Raspberry Pi aufleuchtenden LEDs zeigen, dass der Skill funktioniert.
Genauso müsste schließlich auch die Steuerung über Amazon Echo klappen: Das Sprachkommando “Starte Haus” lädt den Skill, anschließend schaltet beispielsweise das Kommando “TV an” den Fernseher ein.














Jetzt fängt also auch das Linux-Magazin an, Artikel für noch mehr Überwachung zu propagieren.
Habt Ihr Euch mal überlegt, weshalb man Sprachschnippsel an Amazon schicken sollte “für mehr Bequemlichkeit…” und dann kommt wenige Seite später eine Anklage wegen Nicht-Datenschutz-Konformer Software.
Peinlich, Peinlich und wieder ein sicherheitsbewusster Leser (ich) weniger…