„Computer, Thee, Earl Gray, heet!” Tien jaar geleden klonk dat nog als Science Fiction, maar nu is het dankzij Alexa, Google Home of Siri de gewoonste zaak van de wereld geworden. De spraakassistenten van Amazon, Google of Apple luisteren naar onze woorden en reageren erop, al is het resultaat nog niet altijd wat we ervan hadden verwacht. Wie voor zo’n systeem een eigen applicatie wil schrijven, die gebruik maakt van de spraakherkenning, merkt al gauw dat de home-assistent niet precies is, wat hij lijkt te zijn. Al deze systemen reageren op een sleutelwoord, dat meestal van te voren is vastgelegd of dat alleen uit een klein lijstje te kiezen is. Nadat we de assistent met het sleutelwoord hebben geactiveerd, wordt alles wat hij aan audiosignalen registreert rechtstreeks naar de server van de fabrikant van de assistent gestuurd. De eigenlijke herkenning van de gesproken woorden gebeurt dan niet lokaal, maar in de cloud van de aanbieder. En een cloud is natuurlijk niets anders dan een computernetwerk, dat ergens in een of ander rekencentrum staat. Wat er met die data gebeurt, kunnen we als gebruiker of als app-ontwikkelaar niet zien. We kunnen alleen maar geloven, dat de aanbieder onze data behandelt conform de hier geldende wetgeving over gegevensbescherming. Amazon’s Alexa is in de USA al eens voorgedragen als „getuige“ in een moordzaak.

Maar er zijn ook andere oplossingen, zoals Snips, waarbij de spraakherkenning volledig offline werkt en de data in het eigen huisnetwerk blijft. Er is ook geen permanente Internetverbinding of computernetwerk nodig om de spraakherkenning te laten werken. De Snips Voice Interaction kit, met een Raspberry Pi 3B+ als basis, is voldoende om ermee te beginnen.
Naast de Raspberry hebben we nog een paar componenten meer nodig voor de spraakherkenning. Laten we maar eens kijken, wat er in die kit zit.



De kit wordt geleverd in een eenvoudige, blauwe kartonnen verpakking. Als we die openmaken zien we de onderdelen van de kit en een Quick Start Guide. De kit bevat de Raspberry Pi 3B+, een netvoeding (die 5 V bij 3 A levert), een relais, een temperatuur- en luchtvochtigheidssensor, een luidspreker, een ReSpeaker 2-Mics Pi HAT, een grondplaat met montagemateriaal en een SD-kaart met een voorgeïnstalleerd systeem.



Dat zijn alle ingrediënten voor onze eigen kleine spraakassistent. Bij het opbouwen van de kit moeten de juiste afstandsbussen en schroeven worden gebruikt. Helaas zegt de handleiding soms niets over welke schroeven waar moeten komen. Maar met wat geduld en proberen is er wel uit te komen. De Pi is helaas niet heel handig geplaatst voor het verwijderen en inzetten van de SD-kaart.

De grondplaat

Als basis voor de hardware wordt een plaat met gaatjes meegeleverd, waarop de individuele onderdelen kunnen worden vastgeschroefd. Doordat er een raster van gaten beschikbaar is, is er enige vrijheid in de opbouw.

De sensoren en actuatoren

De temperatuur- en luchtvochtigheidssensor is een Sensirion SHT31 als Grove-module. Deze zou de temperatuur meten met een nauwkeurigheid van ±0,3 °C en de luchtvochtigheid met een nauwkeurigheid van ±2 %.
Als relais wordt een Grove-module van Seeed Studio gebruikt. Deze is gespecificeerd voor 250 VAC / 30 VDC bij maximaal 5 A en zou een levensduur van 100.000 schakelcycli hebben. Gezien de constructie van de module is het beter om af te zien van het gebruik van netspanning, want daarbij is er een kans dat onder spanning staande delen worden aangeraakt. Zolang men zich beperkt tot veilige laagspanning (< 25 VAC / < 30 VDC) en binnen de specificaties van het relais blijft, kan er veilig mee worden geëxperimenteerd.
Om te zorgen dat het systeem ook antwoord kan geven, bevat de kit ook een kleine luidspreker. Daar moet u geen HiFi-geluid van verwachten, hij is meer bedoeld als feedback van de spraakassistent.

ReSpeaker 2-Mics Pi HAT

Het hart van het systeem wordt, naast de Pi, gevormd door de opsteekprint ReSpeaker 2-Mics Pi HAT. Die is opgebouwd rondom een WM8960 audio-codec. Helaas wordt die nog niet rechtstreeks ondersteund vanuit Raspbian, en de driver bevat ook nog een paar bugs. Daarom moet u de driver, als u het shield met een kaal Raspbian-image gebruikt, zelf compileren voor de Raspberry Pi. Hier wordt beschreven, hoe u de driver in uw systeem krijgt. De WM8960 bevat een klasse-D-eindtrap die per kanaal 1 W levert in 8 Ω. Ook de schakeling voor de microfoons is aan boord. Er zitten twee microfoons op de kaart. Er zijn ook aansluitingen voor een luidspreker of koptelefoon.
Verder zitten er op de print drie RGB-LED’s (APA 102), die via SPI met de Raspberry Pi zijn verbonden. Die kunnen aangeven, wanneer de spraakassistent begint te luisteren (of wanneer hij iets niet begrepen heeft). Er is ook nog een drukknop voor interactie met het systeem. Tenslotte zijn er nog aansluitingen voor het relais en de temperatuur- en luchtvochtigheidssensor.
Voor een comfortabele aansluiting van de voeding voor de Pi is er ook een microUSB-aansluiting beschikbaar. Er kunnen op de HAT helaas geen verdere HAT’s worden geprikt, dus het is niet mogelijk om een SPI – TFT te gebruiken voor een GUI.
Bij het aansluiten van het relais en de luchtvochtigheids- en temperatuursensor moet erop worden gelet, dat de kabels met de juiste poorten worden verbonden. Als alles is samengebouwd en de SD-kaart is geplaatst, kunnen we het systeem gaan starten. Daarbij is het handig om een HDMI-monitor en een USB-toetsenbord te gebruiken om het eerste bootproces van de Pi te kunnen volgen.
Na de boot is het systeem klaar voor de eerste test. Op de volzin „Hey Snips – What’s the temperature?” antwoordt het systeem met de huidige temperatuur. En met „Hey Snips – Turn Relay on“ wordt het relais ingeschakeld. Dat zou allemaal al moeten werken, zonder eigen configuratie. Nu kunnen we aan het interessantere werk beginnen: eigen toepassingen/commando’s met spraakherkenning realiseren.

Inrichting

De Raspberry Pi heeft nu ook toegang tot ons netwerk nodig, dat gaat het eenvoudigste met een netwerkkabel. Als we via WLAN willen werken, moet de SD-kaart uit de Pi worden gehaald en in de drive met de naam boot het bestand wpa_supplicant.conf worden geïnstalleerd. De inhoud moet
 
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=<your_country_id>
network={
ssid="<your_ssid>"
psk="<your_password>"
}
 
zijn. De invoervelden SSID en wachtwoord moeten worden aangepast voor uw eigen WLAN.
Via snips-base.local kunt u via SSH verbinding maken met de Raspberry Pi en een beetje rondkijken op het systeem. De Snips-software is voorgeïnstalleerd.

Na de basisinrichting van de Raspberry, die heel eenvoudig in zijn werk gaat, installeren we Sam. Sam is een commandline-interface, waarmee de Snips-software op de Raspberry Pi is te bewaken en beheren. Om Sam te installeren, moeten we een terminal openen en sudo npm install -g snips-sam invoeren. Nu kunnen we met sam connect snips-base.local verbinding maken met de Snips-software op de Raspberry Pi. Met sam status kunnen we daarna de toestand en de versienummers van de individuele componenten bekijken. De uitvoer moet er uit zien zoals in listing 1.
 
Listing 1. Uitvoer van de toestand en de versienummers van de individuele Snips-componenten.
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)


Omdat de software nog steeds regelmatig updates krijgt, kan het voorkomen, dat een bepaalde versie soms niet goed werkt. Met sam update kunnen we de meest actuele versie binnenhalen. De Pi downloadt dan de meest actuele versie en installeert hem. Tenslotte moeten we nog een sam update-assistant uitvoeren. Daarmee worden dan ook de applicaties geactualiseerd en zouden alle componenten van Snips weer online moeten zijn. Als we nu sam status invoeren, moeten alle componenten (behalve snips-analytics) draaien en de Raspberry moet reageren op de voorbeeldcommando’s uit de handleiding.

Eigen toepassing

Na het aanmaken van een account kunnen we met de web-interface onze eigen applicatie aanmaken, en nog beter, de assistent trainen met eigen spraakcommando’s. Als kleine demo willen we dat de spraakassistent de huidige kloktijd kan weergeven.
We maken om te beginnen een nieuwe assistent aan, in dit geval noemen we die WhatTimeItIs. Binnen een assistent kunnen nu apps worden geïnstalleerd. We maken een app met de naam „currentTime“ aan. Deze app moet ervoor zorgen, dat op commando de huidige kloktijd wordt weergegeven.
Om ervoor te zorgen dat de app een spraakcommando kan begrijpen, moeten we dit als Intent, (afkorting voor intention = bedoeling) aanleren.


Er zijn een paar ingebouwde modules, die ons het werk gemakkelijk kunnen maken, als we bijvoorbeeld getallen of data uitspreken. Omdat onze sleutelwoorden voor het vragen naar de tijd niet als complete module beschikbaar zijn, moeten we deze installeren. We willen luisteren naar „Time“, en naar een paar synoniemen.
Als we klaar zijn met het aanleren, kunnen we ons gaan bezighouden met de actie, die ons spraakcommando moet gaan uitvoeren. Daarvoor gaan we naar Actions en kiezen we voor onze demo Code Snippets. Op dit moment kunnen we via de web-interface Python3- en Python2-code invoeren en die als „Action“ laten uitvoeren.



Zie voor de details de documentatie van Snips.
Voor het weergeven van de tijd gebruiken we de Python3-code in listing 2.
 
Listing 2. De Python-code voor onze eigen applicatie.
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)


Deze code wordt uitgevoerd als het woord „Time“ of een van de synoniemen is herkend. Als antwoord stellen we een string samen, die dan naar de tekst-to-speech-module van de software wordt gestuurd en ons de tijd voorleest.
Daarmee hebben we onze eerste applicatie gemaakt en kunnen we hem gaan testen. Maar we moeten hem eerst nog overbrengen naar de Raspberry Pi. Daartoe voeren we op de commandline sam install assistent in en laten we de nieuw aangemaakte assistent installeren. Daarna kunnen we met „Hey Snips, what’s the time“ de kloktijd opvragen.

Samenvatting

De kit bevat alles wat we nodig hebben om aan de slag te gaan en voor de eerste experimenten: luidspreker, microfoons, sensor en relais. Helaas geven de beide ingebouwde microfoons een wat ruiserig signaal. Voor de spraakherkenning is dat geen probleem, maar wie de handleiding volgt en een nieuw sleutelwoord voor het activeren van de spraakassistent wil invoeren, zal helaas een andere microfoon moeten gebruiken. Bij het samenbouwen van de hardware moeten we beter opletten dan eigenlijk nodig zou moeten zijn; één of twee pagina’s met extra illustraties voor het plaatsen van de afstandsbussen zouden enorm hebben geholpen.
Ook is het jammer, dat er op dit moment nog geen driver voor de geluidskaart in de officiële Raspbian-distributie zit. Als we een eigen image willen maken op basis van Raspbian, dan moeten we de driver zelf compileren en patchen. Ook bij het actualiseren van de software moeten we bij bepaalde stappen goed opletten. Als een nieuwe versie van Snips moet worden geïnstalleerd, dan moeten de assistenten opnieuw worden geactualiseerd of opnieuw worden geïnstalleerd.
Uiteindelijk, als we eenmaal gewend zijn aan de Snips.ai-Web-interface, is het echt heel leuk om met het systeem te werken en de mogelijkheden te verkennen. En ik ben vooral blij, dat ik met Snips de baas blijf over mijn eigen data.