„Computer – Tee, Earl Gray, heiß” – was noch vor 10 Jahren wie Science Fiction klang, ist heute dank Alexa, Google Home oder Siri zum Alltag geworden. Die Sprachassistenten von Amazon, Google oder Apple lauschen unseren Worten und reagieren darauf, wenn auch nicht immer wie erwartet. Wer nun für diese Systeme seine eigene Applikation schreiben will, um von der Spracherkennung Gebrauch zu machen, wird schnell feststellen, dass sein Home-Assistent nicht ganz das ist, was er zu sein scheint. All diese Systeme reagieren auf ein Schlüsselwort, das in der Regel vorgegeben ist oder sich nur aus einer begrenzten Liste auswählen lässt. Nachdem wir den Assistenten mit dem Schlüsselwort aktiviert haben, wird alles, was dieser an Tonsignalen erfasst, direkt an die Server des jeweiligen Herstellers des Assistenten gesendet. Die eigentliche Erkennung der gesprochenen Worte erfolgt dann nicht lokal, sondern in der Cloud des Anbieters. Dabei ist eine Cloud nichts anderes als ein Rechnerverbund, der irgendwo in irgendeinem Rechenzentrum steht. Was mit den Daten passiert, können wir als Anwender und App-Entwickler nicht einsehen. Wir können nur daran glauben, dass der Anbieter mit unseren Daten gemäß den hier geltenden Datenschutz-Bestimmungen umgeht. Amazons Alexa wurde in den USA auch schon mal als „Zeuge“ in einem Mordfall vorgeladen.

Es gibt allerdings auch andere Lösungen wie Snips – das ist eine Spracherkennung, die komplett offline arbeitet und die Daten im eigenen Hausnetzwerk hält. Es ist auch keine permanente Internetverbindung oder ein Verbund von Rechnern notwendig, damit die Spracherkennung ihren Dienst verrichten kann. Für den Start reicht das Snips Voice Interaction Kit, mit einem Raspberry Pi 3B+ als Basis.
Neben dem Raspberry brauchen wir noch ein paar Komponenten mehr für die Spracherkennung. Schauen wir uns einmal an, was im Kit enthalten ist.



Das Kit wird in einem schlicht gehaltenen blauen Pappkarton geliefert. Nach dem Öffnen kommen die einzelnen Teile des Kits und eine Schnellstartanleitung zum Vorschein. Enthalten in dem Kit sind der Raspberry Pi 3B+, ein Netzteil (das 5 V bei 3 A liefert), ein Relais, ein Temperatur- und Luftfeuchtigkeitssensor, ein Lautsprecher, ein ReSpeaker 2-Mics Pi HAT, eine Grundplatte mit Montagematerial und eine SD-Karte mit vorinstalliertem System.



Damit erhalten wir alle Zutaten für unseren eigenen kleinen Sprachassistenten. Beim Zusammenbau des Kits müssen die passenden Abstandshalter und Schrauben verwendet werden. Leider schweigt sich die Anleitung an einigen Stellen darüber aus, welche Schrauben wo hinkommen müssen. Mit etwas Geduld und Probieren findet man es aber heraus. Der Pi ist für das Entfernen und Einsetzen der SD-Karte leider nicht ganz optimal platziert.

Die Lochplatte

Als Basis für die Hardware wird eine Lochplatte mitgeliefert, auf der die einzelnen Komponenten angeschraubt werden können. Durch das Raster, in denen die Löcher angeordnet sind, kann damit der Aufbau zu einem gewissen Grad variiert werden.

Die Sensoren und Aktuatoren

Bei dem Temperatur- und Luftfeuchtigkeitssensor handelt es sich um einen Sensirion SHT31 als Grove-Modul. Die Temperatur soll mit ±0,3 °C und die Luftfeuchtigkeit mit ±2 % Ungenauigkeit gemessen werden.
Als Relais kommt ein Grove-Modul von Seeed Studio zum Einsatz. Es ist für 250 VAC / 30 VDC mit maximal 5 A spezifiziert und soll eine Lebensdauer von 100.000 Schaltzyklen erreichen. Wegen der Konstruktion des Moduls ist aber von der Verwendung von Netzspannung abzusehen, da eventuell unter Spannung stehende Teile berührt werden könnten. Solange sich der Wert im Rahmen der Sicherheitskleinspannung (< 25 VAC / < 30 VDC) und innerhalb der Relaisparameter bewegt, kann mit dem Relais experimentiert werden. Damit sich das System auch verständlich machen kann, enthält das Kit auch einen kleinen Lautsprecher. Von diesem sollte kein HiFi-Klang erwartet werden, er ist mehr als Feedback des Sprachassistenten gedacht.

ReSpeaker 2-Mics Pi HAT

Das Herz des Ganzen ist neben dem Pi das Aufsteckboard ReSpeaker 2-Mics Pi HAT. Dieses ist um einen WM8960 Audio-Codec aufgebaut. Dieser wird leider noch nicht direkt aus Raspbian unterstützt, und der Treiber hat auch noch ein paar Bugs. Daher muss der Treiber, wenn man das Shield mit einem nackten Raspbian-Image verwendet, selbst für den Raspberry übersetzt werden. Hier ist beschrieben, wie man den Treiber in sein System bekommt. Der WM8960 integriert eine Class-D-Endstufe mit 1 W @ 8 Ω pro Kanal und beinhaltet auch die Beschaltung für Mikrofone. Zwei Mikrofone sind auf dem Board verbaut; die Anschlüsse für einen Lautsprecher oder Kopfhörer sind ebenfalls vorhanden.
Auf der Platine sind auch drei RGB-LEDs (APA102) integriert, die per SPI an den Raspberry Pi angebunden werden. Diese können signalisieren, wenn der Sprachassistent anfängt zuzuhören (oder etwas nicht verstanden hat). Für Interaktionen mit dem System steht ein Mikrotaster bereit. Abschließend gibt es noch die Anschlüsse für das Relais, den Temperatur- und Luftfeuchtigkeitssensor.
Für den komfortablen Anschluss der Spannungsversorgung des Pi ist auf einer Seite noch ein Micro-USB-Anschluss vorhanden. Auf das HAT lassen sich aber leider keine weiteren HATs stecken, so dass die Verwendung eines SPI-TFTs für eine GUI leider ausfällt.
Auch beim Anschluss des Relais sowie des Luftfeuchtigkeits- und Temperatursensors sollte darauf geachtet werden, dass die Kabel mit den richtigen Ports verbunden sind. Nachdem alles zusammengebaut und die SD-Karte eingesetzt ist, kann der erste Start erfolgen. Ein HDMI-Monitor und eine USB-Tastatur sind hier vorteilhaft, damit der erste Bootprozess des Pi verfolgt werden kann.
Nach dem Boot ist das System bereit für den ersten Test. Mit dem Satz „Hey Snips – Whats the temperature?” liefert das System die aktuelle Temperatur zurück, mit „Hey Snips – Turn Relay on“ wird das Relais eingeschaltet. Dies sollte soweit ohne eigene Konfiguration funktionieren. Nun können wir zum interessanteren Teil kommen: eigene Applikationen/Befehle mit der Spracherkennung zu realisieren.

Einrichtung

Der Raspberry Pi braucht nun auch Zugang zu unserem Netzwerk, am einfachsten gelingt das per Kabel. Wenn man das Ganze per WLAN machen möchte, muss die SD-Karte aus dem Pi genommen werden und in dem Laufwerk mit dem Namen boot die Datei wpa_supplicant.conf angelegt werden. Als Inhalt muss
 
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=<your_country_id>
network={
ssid="<your_ssid>"
psk="<your_password>"
}
 
enthalten sein. Die entsprechenden Einträge für Land, SSID und Passwort müssen an das eigene WLAN angepasst werden.
Über snips-base.local kann man sich per SSH mit dem Raspberry Pi verbinden und sich ein wenig auf dem System umschauen. Die Snips-Software ist schon auf dem System vorinstalliert.

Nach der grundlegenden Einrichtung des Raspberry, die hier recht unkompliziert vonstatten geht, installieren wir Sam. Sam ist ein Kommandozeilen-Interface, mit dem sich dann die Snips-Software auf dem Raspberry Pi überwachen und managen lässt. Um Sam zu installieren, müssen wir ein Terminal öffnen und sudo npm install -g snips-sam eingeben. Wir können uns nun mit sam connect snips-base.local mit der Snips-Software auf dem Raspberry Pi verbinden. Mit sam status lassen wir uns danach den Zustand und die Versionsnummern der einzelnen Komponenten ausgeben. Die Ausgabe sollte wie in Listing 1 aussehen.
 
Connected to device snips-base.local
OS version ................... Raspbian GNU/Linux 9 (stretch)
Installed assistant .......... MakerKitBundle_EN
Language ..................... en
Hotword ...................... hey_snips
ASR engine ................... snips
Status ....................... Live

Service status:

snips-analytics .............. 0.60.8 (running)
snips-asr .................... 0.60.8 (running)
snips-audio-server ........... 0.60.8 (running)
snips-dialogue ............... 0.60.8 (running)
snips-hotword ................ 0.60.8 (running)
snips-nlu .................... 0.60.8 (running)
snips-skill-server ........... 0.60.8 (running)
snips-tts .................... 0.60.8 (running)


Da die Software immer noch rege Updates erhält, kann es sein, das die eine oder andere Version mitunter nicht richtig läuft. Um die aktuellste Version zu erhalten, führen wir nun ein sam update aus. Damit lädt der Pi die aktuellste Version herunter und installiert diese. Abschließend müssen wir noch ein sam update-assistant ausführen. Damit werden dann auch die Applikationen aktualisiert und alle Komponenten von Snips sollten wieder online sein. Wenn wir nun sam status eingeben, müssten alle Komponenten (außer snips-analytics) laufen und der Raspberry sollte auf die Beispielkommandos aus der Anleitung reagieren.

Eigene Applikation

Nach dem Anlegen eines Accounts können wir mit der Web-Oberfläche unsere eigene Applikation erstellen, und noch besser, den Assistenten auf eigene Sprachbefehle trainieren. Als kleine Demo soll uns der Sprachassistent die aktuelle Uhrzeit ausgeben.
Wir legen zuerst einen neuen Assistenten an, in diesem Fall nennen wir ihn WhatTimeItIs. Innerhalb eines Assistenten können nun Apps angelegt werden. Wir legen eine App mit dem Namen „currentTime“ an. Diese App ist dann dafür zuständig, auf Kommando die aktuelle Uhrzeit auszugeben.
Damit die App ein Sprachkommando verstehen kann, müssen wir dieses als Intent, (Kurzform für Intention = Absicht) anlernen.



Es gibt ein paar eingebaute Module, die uns die Arbeit erleichtern können, wenn wir z. B. Zahlen sprechen oder ein Datum. Da unsere Schlüsselwörter für die Frage nach der Zeit nicht als fertiges Modul vorhanden sind, müssen wir diese anlegen. Wir wollen auf „Time“ hören, sowie ein paar Synonyme.
Wenn wir nun das Anlernen beendet haben, können wir uns um die Aktion kümmern, die unser Sprachbefehl auslösen soll. Dazu gehen wir in den Punkt Actions und wählen für unsere Demo Code Snippets. Aktuell können wir über die Web-Oberfläche Python3- und Python2-Code schreiben und als „Action“ ausführen lassen.



Für die Details kann die Dokumentation von Snips herangezogen werden.
Für die Ausgabe der Zeit benutzen wir den Python3-Code in Listing 2.
 
import time
now = time.localtime()
if len(intentMessage.slots.DateTime_Req) > 0:
    date_or_time = intentMessage.slots.DateTime_Req.first().value # We extract the value from the slot
    result_sentence = "Current time is : {} {} ".format(str(now.tm_hour), str(now.tm_min))◦ # The response that will be said out loud by the TTS engine.
else:
    result_sentence = "Time is running out"
current_session_id = intentMessage.session_id
hermes.publish_end_session(current_session_id, result_sentence)


Dieser Code wird ausgeführt wenn das Wort „Time“ oder eines der Synonyme erkannt wurde. Als Antwort bauen wir einen String zusammen, der dann an das Text-To-Speech-Modul der Software gesendet wird und uns die Zeit vorliest.
Damit haben wir unsere erste Applikation erstellt und können diese testen. Dazu müssen wir diese noch auf den Raspberry Pi transferieren. In unserem Pi geben wir dazu sam install assistent ein und lassen den neu erstellten Assistenten installieren. Danach können wir mit „Hey Snips, what’s the time“ nach der Uhrzeit fragen.

Zusammenfassung

Beim Kit ist alles dabei, was man zum Start und für erste Experimente braucht, Lautsprecher, Mikrofone, Sensor und Relais. Leider ist der Ton der beiden verbauten Mikrofone etwas verrauscht. Die Spracherkennung stört dies nicht weiter, wer aber der Anleitung folgt und ein neues Schlüsselwort zur Aktivierung des Sprachassistenten aufzeichnen möchte, benötigt leider ein anderes Mikrofon. Beim Zusammenbau der Hardware muss man aufmerksamer sein als eigentlich nötig wäre; ein bis zwei Seiten mit weiteren Illustrationen für das Platzieren der Abstandshalter wären hilfreich gewesen.
Etwas unschön ist die Tatsache, das aktuell für die Soundkarte noch keine Treiber im offiziellen Raspbian enthalten sind. Will man sein eigenes Image auf Basis von Raspbian erstellen, dann müssen die Treiber selbst kompiliert und gepatcht werden. Auch beim Aktualisieren der Software sind bestimmte Schritte zu beachten. Sollte Snips in einer neuen Version installiert werden, so müssen die Assistenten noch einmal aktualisiert oder neu installiert werden.
Am Ende des Tages und nach etwas Gewöhnung an die Snips.ai-Weboberfläche macht es Spaß, mit dem System zu arbeiten und die Möglichkeiten zu erkunden. Vor allem freue ich mich, dass ich am Ende des Tages immer noch Herr meiner Daten bin.