Im Smart Home ist die Sprachsteuerung eine immer wichtiger werdende Komponente. Amazon stellt hierfür Skills zur Verfügung, die auf Amazon Echo Dot, Fire TV Sticks, Smartphones und weiteren Geräten laufen. So lassen sich auch Raspberry Pi Alexa Skills auf einfache Art und Weise erstellen.
Die Skills können optional veröffentlicht werden und sogar damit Geld verdient werden. In diesem Tutorial erstellen wir einen Alexa Skill, der Befehle auf unserem lokalen Raspberry Pi ausführt. Dafür gehen wir alle Punkte Schritt für Schritt durch.
Verschiedene Anbieter wie Google („OK Google“), Apple (Siri) und Microsoft (Cortana) haben ebenfalls Sprachassistenten und bieten Möglichkeiten an, eigene Skills zu schreiben. Bei Interesse können wir das in zukünftigen Tutorials zeigen.
Dieses Tutorial beinhaltet eine einfache LED Steuerung, aber durch kleine Anpassungen können viele weitere Szenarien gebaut werden.
Zubehör
Die Software läuft komplett auf dem Pi. Daneben benötigen wir die Hardware, welche per Sprachsteuerung bedient werden soll. Wir verwenden hierfür:
- Raspberry Pi
- eine LED
- optimal: Widerstände
- Stromversorgung (USB Typ C)
Daneben ist ein Amazon Gerät mit Alexa nötig. Diese sind:
Vorbereitung und Raspberry Pi Programmierung
Bevor wir den eigentlichen Alexa Skill erstellen, müssen wir ein paar Sachen einrichten und konfigurieren. Zunächst benötigen wir einen Amazon Entwickleraccount. Wir erstellen als erstes auf developer.amazon.com einen Account bzw. loggen uns mit dem existierenden Amazon Account ein.
Anschließend kümmern wir uns um die Einrichtung auf dem Raspberry Pi.
Raspberry Pi Hardware anschließen und Software installieren
Bevor du den Pi startest, verbinde eine einfache LED mit dem langen Ende an GPIO 17 und mit dem kurzen Ende an Ground. Hier siehst du die Pinbelegung:
Idealerweise kannst du auch einen kleinen Widerstand (220Ω) zwischen Ground und die LED schalten.
Da dieses Beispiel sehr einfach gehalten ist, möchte ich hier noch einige bessere Projektideen mitgeben:
- LED Strip Effekte per Sprachsteuerung ändern (und dimmen)
- Steuerung eines Thermostats
- Den Garten auf Befehl wässern
- Temperatur von anderen Zimmern abfragen
- Videoaufnahmen von Überwachungskameras starten
- uvm.
Installation
Verbinde dich nun z.B. per SSH mit dem Raspberry Pi. Zunächst installieren wir die benötigte Software. Wir nutzen die Python Pakete Flask bzw. Flask-Ask, womit man sehr einfach Amazon Alexa Skills schreiben kann:
python3 -m pip install Flask-Ask pip3 install --upgrade setuptools pip3 install 'cryptography<2.2'
Wie du siehst nutzen wir eine Version kleiner als 2.2 vom Package Cryptography. Bei neueren Versionen kommt es häufig zu Fehlern in Verbindung mit Flask.
Jetzt erstellen wir die Python Datei, die unseren Code enthält:
sudo python3 alexaskill.py
Diese Datei bekommt folgenden Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import logging import os from flask import Flask from flask_ask import Ask, request, session, question, statement import RPi.GPIO as GPIO app = Flask(__name__) ask = Ask(app, "/") logging.getLogger('flask_ask').setLevel(logging.DEBUG) STATUSON = ["anzuschalten","anzumachen","anmachen","anschalten","an"] # alle Werte, die als Synonyme im Slot Type definiert wurden STATUSOFF = ["auszuschalten","auszumachen","ausmachen","ausschalten","aus"] @ask.launch def launch(): speech_text = 'Wilkommen zur Raspberry Pi Automatisierung.' return question(speech_text).reprompt(speech_text).simple_card(speech_text) @ask.intent('LightIntent', mapping = {'status':'status'}) def Gpio_Intent(status,room): GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(17,GPIO.OUT) if status in STATUSON: GPIO.output(17,GPIO.HIGH) return statement('Licht wurde angeschaltet') elif status in STATUSOFF: GPIO.output(17,GPIO.LOW) return statement('Licht wurde ausgeschaltet') else: return statement('Sorry, der Befehl ist leider nicht möglich.') @ask.intent('AMAZON.HelpIntent') def help(): speech_text = 'You can say hello to me!' return question(speech_text).reprompt(speech_text).simple_card('HelloWorld', speech_text) @ask.session_ended def session_ended(): return "{}", 200 if __name__ == '__main__': if 'ASK_VERIFY_REQUESTS' in os.environ: verify = str(os.environ.get('ASK_VERIFY_REQUESTS', '')).lower() if verify == 'false': app.config['ASK_VERIFY_REQUESTS'] = False app.run(debug=True) |
Speichere die Datei mit Strg + O und beende den Editor mit Strg + X. Anschließend führen wir die Datei aus:
python3 alexaskill.py
Erreichbarkeit außerhalb des lokalen Netzwerks
Wir haben zwar nun einen Raspberry Pi Server laufen, allerdings ist dieser nur über das lokale Netzwerk erreichbar. Damit Amazon unseren Raspberry Pi später aufrufen kann, muss dieser öffentlich zugänglich sein.
Wir könnten hierfür entweder einen dDNS Service nutzen und die Ports im Router freigeben, oder aber einen Service wir ngrok nutzen. Das hat den Vorteil, dass wir uns die Konfiguration sparen.
Öffne ein neues Terminal (das alte nicht schließen) und gib folgendes ein:
wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip unzip ngrok-stable-linux-arm.zip
Anschließend können wir bereits starten:
./ngrok http 5000
Die zweite URL (https) benötigen wir im Anschluss für Amazon.
Achtung: Als nicht registrierter User wird nach 8 Stunden die Verbindung resettet und du bekommst eine neue URL. Dies kannst du ändern, indem du dich registrierst und deinen Token angibst:
./ngrok authtoken <TOKEN>
Außerdem ist es möglich die Subdomain selbst zu wählen. Weitere Infos zu ngrok findest du in der Dokumentation.
./ngrok http -subdomain=myveryownamazonalexaskill 5000
Übrigens: Beide Befehle (Python Skript und ngrok) können wir auch per Autostart starten lassen.
Einrichten des Raspberry Pi Alexa Skills im Amazon Developer Account
In der Amazon Developer Console drücken wir den „Create Skill“ Button. Hier vergeben wir einen Namen (z.B. „Raspberry Pi“), wählen die Sprache und das „Custom“ Modell. Die Hosting Methode ist „Privision your own“. Anschließend klicken wir oben rechts auf „Create Skill“.
Anschließend drücken wir das Plus Zeichen neben „Slot Types“ (Interaction Models) und legen einen neuen Typ namens „STATUS“ an:
Hierfür legen wir noch zwei „Values“ an. Diese bekommen die Namen „on“ bzw. „off“ und wir definieren zusätzlich alle möglichen Synonyme (dies sind die gleichen Synonyme, die auch im Python Skript angegeben sind):
Als letzten Konfigurationsschritt erstellen wir ein „Intent“ (Klick auf das Plus Zeichen) mit dem Namen „LightIntent“ (selber Name, der auch im Skript angegeben wurde):
Im unteren Teil fügen wir zunächst den „Intent Slot“ hinzu. Hier wählen wir als Typ „STATUS“ und nennen ihn ebenfalls „status“ (kleingeschrieben):
Im oberen Teil kannst du nun alle möglichen Sprachbefehle angeben, wie bspw. „schalte das licht aus“. Per Doppelklick auf ein Wort, kannst du es mit dem Slot ersetzen:
Überlege dir dabei verschiedene Kombinationen, welche du später nutzen willst. Normalerweise ist der Aufruf z.B. folgender:
Alexa, sage Raspberry Pi, [schalte das Licht an/das Licht auszuschalten/…]
Der hintere Teil ist also wichtig und sollte in diesem Teil definiert werden. Speichere das Model und drücke „Build Model“.
Hier noch einmal die generierte JSON Datei. Du kannst sie auch einfach einfügen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
{ "interactionModel": { "languageModel": { "invocationName": "raspberry pi", "modelConfiguration": { "fallbackIntentSensitivity": { "level": "LOW" } }, "intents": [ { "name": "AMAZON.FallbackIntent", "samples": [] }, { "name": "AMAZON.CancelIntent", "samples": [] }, { "name": "AMAZON.HelpIntent", "samples": [] }, { "name": "AMAZON.StopIntent", "samples": [] }, { "name": "AMAZON.NavigateHomeIntent", "samples": [] }, { "name": "LightIntent", "slots": [ { "name": "status", "type": "STATUS" } ], "samples": [ "das licht {status}", "schalte das licht {status}", "mach das licht {status}" ] } ], "types": [ { "name": "STATUS", "values": [ { "id": "off", "name": { "value": "off", "synonyms": [ "auszuschalten", "auszumachen", "ausmachen", "ausschalten", "aus" ] } }, { "id": "on", "name": { "value": "on", "synonyms": [ "anzuschalten", "anzumachen", "anmachen", "anschalten", "an" ] } } ] } ] } } } |
Zu guter letzt müssen wir noch die Server URL angeben, an die die Befehle gesendet werden. Klicke dazu auf der linken Seite auf „Endpoint“, wähle HTTPs und füge bei „Default Region“ die URL von ngrok ein. Wähle außerdem folgende Option: „My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority„.
Vergiss nicht zu speichern.
Neuen Raspberry Pi Alexa Skill testen – Lokal und auf Amazon Echo Geräten
Wir wollen den Raspberry Pi Alexa Skill nun testen. Dafür gibt es verschiedene Möglichkeiten, auf die wir eingehen. Idealerweise werden beide hintereinander ausgeführt:
1. Amazon Developer Console – Test
In der Developer Console gibt es unter dem Tab „Test“ die Möglichkeit per Sprachaufnahme oder mittels Text Befehle zu senden. Dazu musst du deinem Browser erlauben, dass der dein Mikrofon benutzen darf. Aud der rechten Seite siehst du, wie der Befehl an
2. Live Testen auf Amazon Echo (Dot), Fire TV Stick, etc.
Wir wollen unseren entwickelten Skill dauerhaft auf den Amazon Geräten laufen lassen. Dazu müssen wir zunächst alle Geräte zu unserem Account hinzufügen. Wie dies geht, ist u.a. hier beschrieben. Du siehst alle Alexa Geräte entweder in der Smartphone App (Android, iOS) oder im Amazon Dashboard.
In den Apps kannst du auch neue Geräte einfach hinzufügen. Sobald das Gerät mit dem Account verknpüft ist, kann der Skill bereits verwendet werden.
Welche Projekte habt ihr damit vor? Weitere Ideen und Anregungen als Kommentare sind herzlich willkommen.
16 Kommentare
Hallo,
hat alles gut funktioniert, bis ich das script ausführen wollte, dann habe ich in der Historie nachgesehen und diese Fehlermeldung gefunden.
Installing collected packages: aniso8601, PyYAML, six, pyOpenSSL, Flask, Flask-Ask
The script flask is installed in ‚/home/pi/.local/bin‘ which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use –no-warn-script-location.
Ich bin Anfänger und ratlos. Bitte um Hilfe
Gruß
Dieter
Das Problem hatte ich auch eben.
Ich habe den angemeckerten Pfad unter „/etc/profile“ eingetragen.
Dazu den Nano-Editor mit „sudo nano /etc/profile“ aufrufen.
In Zeile 4ff steht folgendes oder ähnliches.
if [ „`id -u`“ -eq 0 ]; then
PATH=“/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/openhabian/.local/bin“
else
PATH=“/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/openhabian/.local/bin“
Den angemeckerten Pfad mit einem „:“ getrennt hinten anhängen. Bei mir war es „/home/openhabian/.local/bin“.
Ich hoffe es hilft noch.
Hallo
Ich finde in der App keine Developer Option um ein Gerät hinzuzufügen.
Wie komme ich zu dieser Option ?
Danke und Gruss
Alfred
Ich habe leider das Problem, dass beim Ausführen des „alexaskill.py“ skriptes ein Fehler auftritt.
Traceback (most recent call last):
File „alexaskill.py“, line 5, in
from flask_ask import Ask, request, session, question, statement
File „/home/openhabian/.local/lib/python3.5/site-packages/flask_ask/__init__.py“, line 9, in
from .core import (
File „/home/openhabian/.local/lib/python3.5/site-packages/flask_ask/core.py“, line 10, in
from werkzeug.contrib.cache import SimpleCache
ImportError: No module named ‚werkzeug.contrib‘
Beim Importieren von „from flask_ask import Ask, request, session, question, statement“ scheint dieser Fehler aufzutreten. Kann mir jemand sagen, was ich tun kann, um das Beispiel doch noch ans laufen zu bekommen?
Hallo,
ich habe das gleiche Problem auf meinem Raspberry Pi 4 mit Debian Strech Light.
Wäre echt toll hier Hilfe zu bekommen, oder hast du das Problem evtl. schon Gelöst?
MfG
Das liegt an der aktuellen Werkzeug Modul
es muss eine ältere Version installiert werden.
sudo pip uninstall werkzeug
sudo pip install werkzeug==0.16.0
Damit geht es!!
Hallo,
bei mir hat bisher alles geklappt ohne Fehlermeldungen o.ä.
Nur bin ich jetzt an dem Punkt, an dem ich alles einmal testen möchte. Weder live noch in der Developer Console kann ich den Befehl ausführen, Rückmeldung: „Tut mir leid, ich kann kein Gerät mit dem Namen licht finden“
Ebenso wird rechts im Bildschirm weder JSON Input noch Output angezeigt.
Mache ich was falsch?
same here 🙁
bei mir das gleiche, bitte um Hilfe 🙁
habe es gelöst bekommen in dem ich in der Developer Console bei „Invocation“ den „Skill Invocation Name“ den Namen „raspberry pi“ gegeben habe (neu builden nicht vergessen). Danach reagiert er nun auf Alexa, sage Raspberry pi….. 🙂 Hoffe das hilft einem 🙂
Hat leider nicht geholfen. Gleiches Problem hier.
Gibt es auch die Möglichkeit eine bestimmt Variable in einem Python-Skript abzufragen btw. zu setzen?
„Wie lautet der Sensorwert von SensorXY?“ Oder „Setze die Variable X auf 50.“
Ich sehe zwar den Skill in meeiner Alexa App und kann diesen auch aktivieren, aber wenn ich dann den Statsatz bei Alexa sage, kann Alexa den Skill nicht finden. Das Vorgehen wie oben beschrieben (https://developer.amazon.com/de-DE/docs/alexa/ack/dev-kit-device-registration.html) passt nicht, weil man ja keinen QR Code hat.
Hi ich habe eine Verbindung zu meinem Pi, kann die Funktionen die ich möchte über den Befehl auslesen lassen, jedoch keine Rückgabewerte an die Alexa zurück senden. Es kommt nur :“Bei der Antwort des angeforderten Skill ist ein Problem aufgetreten“. Kennt jemand die Antwort?
Hallo, diesen Fehler bekomme ich auch. Hat jemand eine Lösung gefunden?
wenn ich bei test den Sprachbefehl ausführe, sagt alexa sie könne diesen Skill nicht erreichen. :/