Alexa is je nieuwe persoonlijke assistent – Gebruik de Alexa service van Amazon voor spraakherkenning

De afgelopen jaren is er steeds meer om ons heen geautomatiseerd. Niet alleen buiten, maar ook binnen door middel van home automation. Vaak bedienen we die apparaten nog met onze smartphone. Dat is echter niet altijd even handig. Wat als je je telefoon niet bij de hand hebt, of als je aan het eten bent? Met spraakherkenning kunnen deze problemen opgelost worden. Amazon was een van de eerste bedrijven die hier serieus mee aan de slag ging met hun Echo apparaten en de Alexa spraakherkenning dienst. In de rest van dit artikel lees je hoe je spraakherkenning in kunt zetten zodat je smartphone de deur uit kan J.

Johan Janssen

Alexa spraakherkenning service

Amazon heeft met Alexa een dienst gemaakt die je (Engelse) spraak kan herkennen. Door tegen deze dienst te praten kun je vragen wat het weer is, Wikipedia bevragen, je lampen en muziek bedienen, een pizza bestellen en nog veel meer. Dat alles is mogelijk zonder dat je op een knop hoeft te drukken. Je begint simpelweg te praten tegen een van de apparaten die in de volgende paragrafen besproken worden.

 

Alexa met apparaten van Amazon

Om de Alexa service te gebruiken zal je iets van een microfoon en wat andere hardware nodig hebben. Amazon heeft hiervoor een aantal kant en klare apparaten in het assortiment. Sommigen hebben wat betere speakers of een ingebouwde batterij. Ik zelf vond de 2e generatie Echo Dot de interessantste omdat die voor een euro of 60 verkrijgbaar is. Via Amazon zijn ze nog niet rechtstreeks in Nederland te bestellen, maar via Ebay en Conrad zijn ze hier wel verkrijgbaar.

Figuur 1 Amazon Echo Dot

Het is erg simpel om een Echo in gebruik te nemen. Je zorgt ervoor dat het apparaat stroom krijgt en je stelt je WIFI in via de Alexa app op je smartphone, of via de Alexa portal https://alexa.amazon.com. Als je Alexa iets wilt laten doen dan moet je een wakeword gebruiken. Standaard is het wakeword ‘Alexa’, maar er zijn een aantal andere opties. Als je buurmeisje Alexa heet, dan kan het wat raar overkomen als je ‘Alexa stop’ staat te schreeuwen.

Als je bijvoorbeeld ‘Alexa Wikipedia Java programming language’ zegt dan zal ‘Alexa’ ervoor zorgen dat het apparaat geactiveerd wordt en gaat luisteren. De tekst ‘Wikipedia Java programming language’ wordt vervolgens naar de cloud gestuurd. Als alles goed gaat dan vertelt Alexa vervolgens het antwoord. Als je een Amazon tablet of Fire TV met Alexa hebt, dan wordt het antwoord ook op het scherm getoond.

Alexa op je Raspberry Pi

Het gave is dat je ook zelf een Alexa apparaat kunt maken. Amazon heeft de software en instructies vrijgegeven waarmee je Alexa kunt gebruiken op je Raspberry Pi. Dus door een microfoon en luidspreker aan je Raspberry Pi toe te voegen kun je die gebruiken in plaats van een Amazon Echo. In figuur 2 is mijn Raspberry Pi te zien met touchscreen, microfoon en luidspreker. In eerste instantie was zelfbouw goedkoper dan een kant en klare oplossing, maar dat is inmiddels niet meer het geval. Daarnaast zijn de kant en klare oplossingen wat geavanceerder. Zo hebben ze meerdere microfoons die ervoor zorgen dat Alexa je beter kan verstaan.

Figuur 2 Alexa op een Raspberry Pi. De Raspberry Pi is vastgemaakt aan de achterkant van het touchscreen.

Voor de Raspberry Pi oplossing kun je opensource Java software gebruiken. Met de open source software kun je alles aanpassen naar jou behoeftes. Bijvoorbeeld als je bezorgd bent dat Amazon meer geluid opneemt en naar de cloud stuurt dan je zelf wilt. Om snel aan de slag te kunnen gaan raad ik echter een kant en klare oplossing aan.

Extra functionaliteit toevoegen

Standaard kan Alexa al een aantal dingen, maar waarschijnlijk wil je meer functionaliteit. Dat kan door zogenaamde Skills  te gebruiken. Skills lijken op applicaties voor je smartphone en kun je vanuit de Alexa portal installeren. Er zijn vele skills beschikbaar waarmee je van alles kunt doen, van het beluisteren van het laatste nieuws tot het bestellen van een pizza. Mocht er geen skill beschikbaar zijn voor hetgeen je wilt bereiken dan zou je ook IFTTT (If This Then That) kunnen gebruiken. IFTTT is een platform waarmee je dingen aan elkaar kunt knopen. Zo heb ik met IFTTT een koppeling tussen Alexa en mijn e-mail gemaakt. Als ik Alexa vraag om iets toe te voegen aan mijn TODO lijst, dan zorgt IFTTT ervoor dat ik een e-mail krijg met mijn nieuwe TODO lijst.

 

Custom skills

Mocht het niet lukken om de gewenste functionaliteit met Skills of IFTTT te realiseren, dan kun je ook zelf een skill maken. De custom skills kun je draaien op je eigen server, in de cloud of in AWS Lambda. AWS Lambda is een serverless oplossing van Amazon waarmee je simpelweg een applicatie kunt deployen zonder je druk te maken over de onderliggende hardware/software en zaken als schaalbaarheid. Je vraagt niet langer een server aan waarvoor je iedere maand betaald terwijl die wellicht (in bepaalde maanden) niet veel gebruikt wordt. In plaats daarvan deploy je je applicatie en betaal je per request en de afhandelingstijd per request. Gelukkig krijg je een flinke hoeveelheid requests per maand gratis waardoor je het waarschijnlijk kosteloos kunt gebruiken voor niet publieke toepassingen.

Om een skill te maken kun je een Java applicatie bouwen en de JAR file handmatig deployen in AWS Lambda. Vervolgens ga je naar de Amazon Developer portal waar je de skill aanmaakt en koppelt aan de zojuist gedeployde applicatie. De Echo Dot maakt verbinding met de Alexa cloud die door middel van de Amazon Developer omgeving uitkomt bij de Java applicatie in AWS Lambda zoals de zien is in figuur 3.

 

Figuur 3 AWS Lambda handmatige deployment

 

Op deze manier kun je snel een applicatie ontwikkelen en deployen, maar wat als je verder wilt werken aan de applicatie? Dan moet je iedere keer opnieuw naar de portal gaan en de JAR file handmatig uploaden. Dat is natuurlijk niet zo handig, maar gelukkig is daar een oplossing voor. Er zijn verschillende plugins voor bijvoorbeeld Maven en Jenkins waarmee je een Java applicatie automatisch kunt deployen naar AWS Lambda. In de links  vind je een voorbeeld hiervan dat ik gebouwd heb met Maven. De configuratie die je normaalgesproken in de AWS Lambda omgeving doet kun je nu in de POM.XML opnemen. Dit werkt een stuk makkelijker, maar initieel moet je wel even een paar zaken regelen in AWS. Vanuit Maven danwel Jenkins wordt de file geüpload naar Amazon S3, wat een opslag dienst is. Dus je moet een zogenaamde S3 bucket aanmaken. Daarnaast moet er een AWS role toegevoegd worden. De details daarvoor zijn in de README van het GitHub project te vinden. Het aanmaken van de S3 bucket en AWS role is een eenmalig iets, je kunt ze ook hergebruiken als je meerdere applicaties in AWS Lambda maakt. In figuur 4 zie je een overzicht van de geautomatiseerde deployment.

 

Figuur 4 AWS Lambda geautomatiseerde deployment

 

Het bouwen van de Java applicatie is vrij eenvoudig. Stel we willen een skill bouwen waar we ‘hello’ tegen kunnen zeggen. Dan zeggen we tegen Alexa ‘Alexa ask/tell firstSkill hello’. Daarbij is ‘firstSkill’ de ‘invocation name’, je kan dat zien als de roepnaam van de skill. De tekst ‘hello’ is de utterance, dat is de tekst die naar de ‘firstSkill’ gestuurd wordt.

 

Voor het maken van de skill dienen de verschillende utterances gespecificeerd te worden. Deze utterances koppelen we aan intents. Zo koppelen we de ‘hello’ utterance aan de ‘MyFirstIntent’ in SampleUtterances.txt. Intents kun je zien als verzamelbakken waaraan één of meerdere ‘uterances’ gekoppeld worden. Uiteindelijk programmeren we vooral tegen de Intents aan.

 

SampleUtterances.txt

 

MyFirstIntent hello

OtherNameIntent random number

 

Daarnaast specificeren we de verschillende Intents die door de skill gebruikt worden. In IntentSchema.json zie je de twee Intents die ik zelf verzonnen heb namelijk MyFirstIntent en OtherNameIntent. Daarnaast is er een Amazon HelpIntent, welke gebruikt kan worden om makkelijk een help functie in je skill te bouwen.

 

IntentScherma.json

  {
“intents”: [
{
“intent”: “MyFirstIntent”
},
{
“intent”: “OtherNameIntent”
},
{
“intent”: “AMAZON.HelpIntent”
}
] }

 

Nu kunnen we beginnen met de Java code. Allereerst implementeren we de SpeechletRequestStreamHandler in de MySpeechletRequestStreamHandler. Deze class wordt gebruikt als het beginpunt van de applicatie en hierin wordt de MySpeechlet aangeroepen.

public final class MySpeechletRequestStreamHandler extends SpeechletRequestStreamHandler {
// Be careful this makes your code available to anyone
static {

        System.setProperty(“com.amazon.speech.speechlet.servlet.

               disableRequestSignatureCheck”, “true”);
}

public MySpeechletRequestStreamHandler() {
super(new MySpeechlet(), new HashSet<String>());
}
}

 

 

De MySpeechletRequestStreamHandler implementatie werkt, maar is niet beveiligd. Daardoor kan iedereen je applicatie gebruiken. Het is beter als je in de Amazon developer portal het application ID van de skill op zoekt en deze in de applicatie specificeert zoals in te zien is in het supportedApplicationIds voorbeeld. Op die manier kan alleen jou skill gebruikmaken van de applicatie.

private static final Set<String> supportedApplicationIds =
new HashSet<String>();

static {
supportedApplicationIds.add(“amzn1.echo-sdk-ams.app.
[see https://developer.amazon.com/]”);
}

 

De meeste logica bevind zich in de implementatie van de Speechlet interface. Op basis van de Intent wordt bepaalde code uitgevoerd. In MySpeechlet zie je dat alleen de MyFirstIntent uitgewerkt is met een aanroep naar de getReponse methode. In de getReponse methode wordt eerst de ‘text’ aangemaakt die uiteindelijk als reactie wordt teruggegeven. Deze ‘text’ wordt op een ‘card’ gezet. Dit is optioneel en zorgt ervoor dat als de skill aangeroepen wordt de informatie op de ‘card’ getoond wordt in de Alexa portal. De code op het einde zorgt ervoor dat de ‘text’ ook uitgesproken wordt door Alexa.

 

public class MySpeechlet implements Speechlet {
@Override
public SpeechletResponse onIntent(final IntentRequest request,                final Session session) throws SpeechletException {
Intent intent = request.getIntent();
String intentName = (intent != null) ? intent.getName() : null;

if (“MyFirstIntent”.equals(intentName)) {
return getResponse();
} else if (“OtherNameIntent”.equals(intentName)) {

} else if (“AMAZON.HelpIntent”.equals(intentName)) {

} else {
throw new SpeechletException(“Invalid Intent”);
}
}

    private SpeechletResponse getResponse() {
String text = “Hello from my First Skill”;

// Card used in the Alexa interface
SimpleCard card = new SimpleCard();
card.setTitle(“Normal response”);
card.setContent(text);

// The text that will be spoken by Alexa
PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
speech.setText(text);

return SpeechletResponse.newTellResponse(speech, card);
}
}

Dit is een heel simpel voorbeeld, maar je kunt bijna alles maken wat je wilt. Zo is het ook mogelijk om de utterance niet vast te specificeren zoals ‘hello’, maar bijvoorbeeld een willekeurig getal mee te geven. Ook is het mogelijk om een soort sessie op te zetten, waarbij je in de skill blijft. Daardoor hoef je niet steeds de invocation name van de skill te gebruiken om commando’s te geven.

 

 

Conclusie

Ik en ook mijn collega’s waren erg onder de indruk van de mogelijkheden van Alexa. Ondanks het feit dat er nog geen ondersteuning is voor de Nederlandse taal en Alexa nogal op de Amerikaanse/Britse/Duitse markt gericht is. Ook kan het een inbreuk maken op je privacy aangezien hetgeen je zegt naar de cloud gestuurd wordt, dus wees je daarvan bewust. Het is erg gaaf om te zien dat je het zelfs op een Raspberry Pi kunt draaien. Maar vooral de vele mogelijkheden om zelf skills te schrijven in Java (of andere talen) is indrukwekkend. Zeker ook als je ziet hoe weinig code en configuratie er nodig is om spraakherkenning te doen en reacties te geven. Het werken met AWS Lambda beviel prima al adviseer ik wel om geautomatiseerd te deployen. Gebruik daarom een Maven/Jenkins plugin of kijk eens naar de Lambda-toolkit waarmee je ook lokaal Lambda’s kunt testen en debuggen. Ik kan het zeker aanraden om Alexa als je nieuwe persoonlijke assistent in te zetten en je leven leuker en makkelijker te maken.

 

 

Links

https://github.com/johanjanssen/AlexaExamples Voorbeeld Java skills met Maven integratie voor automatische deployment naar AWS Lambda

https://github.com/alexa/alexa-avs-sample-app Alexa Java Client voor de Raspberry Pi

https://github.com/amzn/alexa-skills-kit-java Voorbeeld Java skills

https://github.com/SeanRoy/lambda-maven-plugin AWS Lambda Maven plugin

https://github.com/lucioveloso/lambda-toolkit Lambda-toolkit

https://aws.amazon.com/ Amazon AWS

https://developer.amazon.com/ Amazon Developer portal

https://alexa.amazon.com/ Alexa portal