Alexa Skill & AWS Lambda & npm Pakete & Cumulocity

Das folgende Beispiel zeigt die Erstellung einer einfachen Alexa Anwendung (Skill) mit Hilfe von ‚Alexa Developer Console‘ und ‚AWS Lambda‘.

Alexa Developer Console

Die ‚Alexa Developer Console‘ hilft uns dabei, das sogenannte ‚Interaction Model‘ zu erstellen. Dieses Modell dient dazu, die gewünschte Anwendung zu beschreiben und die Sätze und Parameter zu definieren, worauf Alexa später reagieren sollte. Die Programmierung der Logik wird NICHT in der Developer Console vorgenommen sondern in AWS Lambda.

Das ‚Interaction Models‘ setzt sich für eine einfache Anwendung wie folgt zusammen:

InvocationBei den selbst erstellten Skills ist es so, dass man zuvor die Name der Anwendung sagen muss z.B. „Alexa, starte ’name der Anwendung‘. Bei ‚invocation‘ handelt es sich um diesen Namen.
Intents, Samples & SlotsIntents
Alexa stellt bestimmte Funktionen wie z.B. AMAZON.StopIntent zur Verfügung. Diese Funktion wird aufgerufen, sobald der Anwender „Alexa, Stop‘ sagt. Wir haben zusätzlich zu den bereits existierenden Intents auch die Möglichkeit, eigene Funktionen zu definieren, die auf bestimmte Sätze, die wir zuvor definieren reagieren.

Samples
Die zuvor definierten Sätze, die zu einer Funktionsaufruf führen, werden als Samples bzw. ‚Sample Utterances‘ bezeichnet z.B. kann auf die Aussage „Ich heisse Aaron‘ eine Funktion aufgerufen werden, der mich anschließend namentlich begrüßt.

Slots
Die zuvor definierten Sätze sind statisch. Slots dienen dazu, einzelnen Passagen innerhalb der statischen Sätze dynamisch d.h. mit Lückenfüller zu ersetzen z.B. „Ich heiße {name}“.
Slot TypesJeder Slot ist von einem bestimmten Typ z.B. AMAZON.FIRST_NAME, AMAZON.Room usw.

Das oben genannte ‚Interaction Model‘ kann auf der Linken Seite konfiguriert werden:

Auf der rechten Seite befindet sich eine Checkbox der uns jederzeit anzeigt, ob wir alle Merkmale der Anwendung z.B. die Erstellung von einem ‚Intent‘ usw. bereits vorgenommen haben.

Sobald das ‚Interaction Model‘ richtig ausgefüllt wurde, springen die entsprechenden Marker auf grün:

Erstellung einer Anwendung

Skill Erstellung

Name der Anwendung, Sprache und Auswahl einer ‚Custom‘ Anwendung:

Die Anwendung soll mit „Alexa, starte begrüße mich“ gestartet werden:

Als nächstes geben wir den Namen der Funktion an, der durch ‚begrüße mich‘ aufgerufen wird:

Ich nenne die Funkion, die später noch implementiert wird ‚begruesseMich‘:

Die gewünschte Funktion wird anschließend auf der linken Seite angezeigt:

Da die Anwendung mich zunächst nach meinem Namen fragen wird und auf eine Antwort reagieren sollte, können wir auf der rechten Seite die unterschiedlichen Arten einer Antwort angeben d.h. in diesem Fall erwartet die Anwendung diese Antworten.

Als nächstes muss die Anwendung gebaut werden:

Bevor wir den letzten Abschnitt (Endpoints) Konfigurieren, schauen wir uns an, wie die ‚high level‘ Kommunikation stattfindet:

AWS Lambda

Lambda ist ein Produkt aus der Amazon Web Services (AWS) Familie und bietet uns unter anderem die Möglichkeit, die gewünschten Funktionen mit Hilfe einer web-basierten IDE zu schreiben und auszuführen. Die Ausführung erfolgt durch einen Trigger z.B. durch den Alexa Skill.

Eine Lambda Funktion wird wie folgt erstellt:

Nach Aufruf von Lambda können wir wie folgt eine neue Funktion erstellen. Als Region muss ‚N.Virginia‘ ausgewählt werden.

Als nächstes können weitere Details der Funktion definiert werden z.B. die Name der Funktion und die gewünschte Programmiersprache.

Im nächsten Schritt sagen wir der Funktion, wodurch sie aufgerufen werden sollte. In unserem Fall möchten wir, dass Alexa die Funktion aufruft (Trigger).

Weiter unten können wir mit Hilfe eine ID den Aufruf auf eine bestimmte Anwendung einschränken. D.h. nur die Anwendung mit der hier hinterlegten ID darf diese Funktion aufrufen.

Die Qualifikations-ID bzw. Skill ID finden wir innerhalb der ‚Alexa Developer Console‘:

Zusätzlich muss unter ‚Default Region‘ angegeben werden, welche Function innerhalb welcher Region für die Verarbeitung zuständig ist. Die ‚Default Region‘ ID erhalten wir an folgender Stellen:

Im letzten Schritt kann der Skill gebaut werden. Hierzu einfach ‚Build Model‘ auswählen:

Innerhalb von Lambda erhalten wir durch Auswahl der Funktion ‚begruesseMich‘ Zugriff auf die web-basierte IDE. Dadurch, dass wir zuvor die Vorlage “alexa-skill-kit-sdk-factskill“ verwendet haben, wurden alle benötigten Bibliotheken bereits importiert:

Die Funktion wird wie folgt aufgebaut:

Anschließend kann die Anwendung online unter ‚Test‘ getestet werden:

Praktisches Beispiel

In diesem Beispiel möchte ich die Cumulocity IoT Platform damit beauftragen, die Temperatur eines Gerätes zu ändern.

var unirest = require(‚unirest‘);

unirest.post(‚http://tenant.cumulocity.com/measurement/measurements/‘).headers({
‚Accept‘ : ‚application/vnd.com.nsn.cumulocity.measurement+json‘,
‚Content-Type‘ : ‚application/json‘,
‚Authorization‘ : ‚Basic WEY………………….FyISEy‘
}).send({
„c8y_TemperatureMeasurement“: {
„T“: {
„value“: 10,
„unit“: „C“ }
},
„time“:“2013-06-22T17:03:14.000+02:00″,
„source“: {
„id“:“4473883″ },
„type“: „c8y_TemperatureMeasurement“
}).end(function(response) {
console.log(response.body);
});

Wie man hier sehen kann, möchte ich für mein Vorhaben die externe Bibliothek von ‚Unirest‘ verwenden.

Um die Bibliothek innerhalb von AWS Lambda zu nutzen, muss man wie folgt vorgehen:

  1. Die benötigten Bibliotheken lokal installieren
  2. Code Anpassung (index.js)
  3. Den Code und die Libs als *.zip packen
  4. Die *.zip Datei (Funktion) uploaden. Bei einem Upload wird die Funktion und alle vorhandenen Bibliotheken ersetzt. Daher müssen wir die Bibliotheken ebenfalls mit uploaden.

Die Installation der Pakete wird wie folgt vorgenommen:

  • npm install alexa-sdk
  • npm install unirest

Nach der Installation der npm Paketes sind die gewünschten Abhängigkeiten im dem Ordner ’nodes_modules‘ zu finden.

Durch den Import der beiden externen Bibliotheken ist das Bereitstellungspaket jedoch so große, dass man den IDE nicht mehr nutzen kann, weshalb ich an der Stelle mit einem standalone IDE weiterarbeiten werde.

Bevor wir das Script und die Abhängigkeiten nach AWS Lambda importieren, werden wir den Code einmal lokal testen.

Da die Lokale Ausführung funktioniert hat, können wir den Inhalt des Ordners einmal zippen:

Das uploaden der *.zip Datei können wir am einfachsten mit der AWS-CLI vornehmen.

Nach der Installation der CLI müssen wir unter der folgenden Seite wie folgt ein IAM Benutzer anlegen s. Anleitung.

Vor dem Upload muss die AWS CLI mit dem Befehl ‚aws configure‘ konfiguriert werden:

Jetzt können wir wie folgt mit dem Upload beginnen. Wie man sehen kann, wird hier der Name der Funktion (c8y-device-temperature) mit angegeben.

aws lambda update-function-code –function-name c8y-device-temperature –zip-file fileb://cumulocity.zip

Jetzt kann der Code via Alexa ausgeführt werden:

index.js Bsp.

‚use strict‘;
const Alexa = require(‚alexa-sdk‘);
const APP_ID = ‚xxxxxxx‘;

const handlers = {
‚LaunchRequest‘: function () {
this.response.speak(„Gewünschte Temperatur?“).listen(„value“);
this.emit(„:responseReady“);
},
‚cumulocity‘: function () {
var temperature = this.event.request.intent.slots.grad.value;
this.response.speak(`ok ${temperature}`);

setTemperature(parseInt(temperature,10));

this.emit(„:responseReady“);
},
};

function setTemperature(temperature) {
var unirest = require(‚unirest‘);

unirest.post(‚http://xxxxxxx.cumulocity.com/measurement/measurements/‘).headers({
‚Accept‘ : ‚application/vnd.com.nsn.cumulocity.measurement+json‘,
‚Content-Type‘ : ‚application/json‘,
‚Authorization‘ : ‚Basic xxxxxxx‘
}).send({
„c8y_TemperatureMeasurement“: {
„T“: {
„value“: temperature,
„unit“: „C“ }
},
„time“:“2013-06-22T17:03:14.000+02:00″,
„source“: {
„id“:“5499151″ },
„type“: „c8y_TemperatureMeasurement“
}).end(function(response) {
console.log(response.body);
});
}

exports.handler = function (event, context, callback) {
const alexa = Alexa.handler(event, context, callback);
alexa.APP_ID = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};