Clone wiki

iotalexahhz / MVP implementieren

Zurück zu Home

Agenda

Alexa

In dem gemeinsamen Brainstorming zu Beginn des Projektes ging als MVP der Service "Raumbelegung abfragen" hervor. Hierfür wird als externer Service das Webuntis des HHZs eingebunden und bei diesem die dort eingetragenen Vorlesungen pro Tag ausgelesen.

Um diesen Use Case mittels Alexa abzubilden ist es notwendig zu verstehen, wie Alexa arbeitet. Alexa bietet mit dem Alexa Skills Kit (ASK) eine Sammlung von APIs, Dokumentationen und Code Beispielen, die es ermöglichen einfach und schnell eigene Skills zu Alexa hinzuzufügen. Diese Skills werden von den durch AVS aus den Sprachdateien generierten JSON-Files getriggert. Die nachfolgende Abbildung beschreibt den groben Aufbau einer Alexa Anwendung. avs_getting_started_1.png

Um Standard-Fälle, wie zum Beispiel die Abfrage der Uhrzeit abzubilden, können die von Amazon bereit gestellten Skills verwendeten werden. Ein Skill kann mehrere Intents enthalten, die verschiedene Funktionen bereitstellen. In unserem "Raumbelegung abfragen" hätte der Skill den Namen "room" und die Funktion "is room 105 free today" ein Intent. Ein weiterer Intent könnte innerhalb dieses Skills die Funktion "is in room 105 a beamer".

Um eigene Befehle für Alexa zu implementieren, sind Custom Skills notwendig. Diese benötigen eine gewisse Struktur in den aufrufenden Sprachbefehlen: Ein Aufrufbefehl, der signalisiert, dass eine Aktion vonnöten ist. Beispiele: "Ask" und "Tell" Der Name des aufzurufenden Skills. Beispiele: "room" * Der Name des auszuführenden Intents. Beispiele "105 is it is free today"

Diese eigenen Skills können direkt im Amazon Developer Backend angelegt werden. Amazon_dev_1.PNG Die Abbildung zeigt das grundsätzliche Anlegen eines Skills. In diesem Fall unser konkreter Skill zur Abfrage der HHZ Räume. Im Feld "Invocation Name" wird der Name definiert, mit welchem der User später diesen Skill aufruft.

Amazon_dev_2.PNG

In der Abbildung ist die weitere Konfiguration des Skills zu sehen. Hier können im Feld "Intent Schema" die verschiedenen Intents des Skills definiert werden. Dieses Feld ist zu Beginn leer und der Aufbau des JSON-Files kann selbst definiert werden. In dem abgebildeten Beispiel wird ein Intent mit dem Namen "RoomIntent" angelegt. Dieser verfügt über zwei Slots, vergleichbar mit einer Variablen, "Room" und "Date". Diesen ist je ein Typ zugeordnet.

"Date" ist vom Typ "AMAZON.DATE". Dies ist ein eingebauter, von Amazon definierter Typ, der die übergebenen Daten im Datumsformat speichert. Diese von Amazon angebotenen Standardtypen können innerhalb des Developer Backends genutzt werden. "Room" ist vom Typ "LIST_OF_ROOMS". Dies ist ein selbstdefinierter Typ und kann im Bereich "Custom Slot Types" angelegt werden. Aus der Abbildung ist ersichtlich, dass in unserem Beispiel der Typ "LIST_OF_ROOMS" die Werte one hundred five | Have a break | one hundred annehmen kann. Diese sind die Räume, die wir für unser Beispiel abfragen.

Amazon_dev_3.PNG

Im Bereich "Sample Utterances" können Sätze definiert werden, die der Benutzer an Alexa als Befehl richtet. Durch das erste Wort einer jeden Zeile "RoomIntent" wird jeder Satz einem Intent zugeordnet. Diesen Zuordnungsparamter muss der User nicht übergeben. Die zu verwendeten Slots werden in geschweiften Klammern dargestellt. Hier kann der Benutzer einen Wert sagen, der inhaltlich zu dem Typ des jeweiligen Slots passt.

Beispiel für die erste Zeile "RoomIntent {Room} if it is free {Date}":

Benutzereingabe: "Ask room one hundred five if it is free today"

"Ask" ist der Befehl für Alexa, etwas zu tun. "room" ist der Aufruf des Skills. "one hundred five" ist die Belegung des Slots "Room" mit einem Wert des Typs "LIST_OF_ROOMS". "if it is free" signalisiert die Zuordnung zu dem Intent "RoomIntent". "today" kann von dem Amazoneigenen Typ "AMAZON.DATE" auf das heutige Datum umgewandelt werden.

Durch die Zuordnung der verschiedenen Permutationen zu dem Intent "RoomIntent" (wie in der Abbildung sichtbar) ist der Benutzer nicht an einen speziellen Satz gebunden, sondern es werden mehrere Satzbauarten mit der gleichen Funktion verknüpft.

Amazon_dev_4.PNG

Die Abbildung zeigt den Endpoint des konfigurierten Alexa-Services. Hier ist ein Service unseres Node-RED Prozesses angegeben. An diesen werden die generierten Daten des Alexa Webservice übergeben und der Prozess kann diese weiterverarbeiten. Näheres hierzu können Sie im Kapitel Node-RED weiter unten lesen.

Die komplette Systemlandschaft für unser beschriebenes Szenario ist in folgender Abbildung dargestellt:

Alexa_Systemlandschaft_V2.png

Bluemix

In Bluemix bilden wir für unseren Use Case "Raumbelegung abfragen" den Prozess ab. Hierfür haben wir innerhalb des Bluemix Accounts zwei verschiedene Instanzen aufgebaut: Eine Node-RED Instanz, um den übergreifenden Prozess abzubilden Einen Node.js Webserver, um den Zugriff auf das Webuntis per REST-Apis zu gewährleisten

Node-RED Instanz

Node-RED ist ein visuelles Tool, um im IoT-Umfeld verschiedene Services und APIs zusammenzuschalten. Durch die visuelle Darstellung ist es einfach Prozesse abzubilden.

Bluemix_Node-RED_3.PNG

Die Darstellung zeigt einen Ausschnitt unseres implementierten Node-RED Prozesses im Bluemix-Editors. Auf der linken Seite sind die verfügbaren Elemente dargestellt, welche zur Realisierung eines Prozesses verfügbar sind. Diese können per Drag&Drop in den Prozess gezogen werden und dort über ein einfaches UI konfiguriert werden. Der Prozess startet mit dem Eingehen von Daten aus dem Alexa Webservice. Diese werden im Befehl "Echo request" verarbeitet und an die nachfolgenden Schritte übergeben. Mit dem Befehl "Request Type" wird der zu verarbeitende Request-Typ ausgewählt. In unserem Fall werden nur Intents weiterprozessiert. Die dunkelgrünen Aktionen am Rande des Prozesses sind Debug-Outputs, wie zum Beispiel msg.payload.request.intent.slots. Dieses sind nur für die Entwicklung notwendig, um zu verstehen, wie die Nachrichten sich während der Laufzeit verändern. Mit der Aktion "Save Message" wird die Nachricht des Alexa Services in einem Objekt gespeichert. Mit den Informationen aus diesem Objekt wird über den Befehl "CallRoomWebservice" der Webservice zur Abfrage der Informationen aus dem Webuntis aufgerufen. Nähere Informationen finden Sie im Kapitel Node.js Webservice.

Bluemix_Node-RED_4.PNG

Die Antwort des Webservices wird von dem Befehl "Switch Room State" ausgewertet. Je nach Antwort "True", "False" oder "Otherwise" wird ein anderer Pfad zur weiteren Bearbeitung gewählt. Mit dem Befehl "No Date = today" wird, falls kein Datum im ursprünglichen Request enthalten war, ein anderer Pfad zur Ausführung genommen. In den einzelnen Funktionen jedes Pfades, wie zum Beispiel "is free today", wird je nach Ausprägung eine andere Nachricht zusammengebaut, die die Informationen darstellt. Diese Nachrichten werden im Befehl "Format response" zu einem JSON geparst und dieser an den aufrufenden Service, in diesem Fall unser Alexa Service, zurückgeschickt.

Node.js Webservice

In einer weiteren Instanz haben wir einen Webservice aufgesetzt, der die Stundenplanverwaltung des HHZs "Webuntis" anspricht und die für den Master-Studiengang Services Computing die Vorlesungen im iCal-Format importiert und ausliest. Danach vergleicht der Service die übergebenen Werte mit den Daten aus der iCal-Datei und gibt, je nachdem ob an dem übergebenen Tag der entsprechende Raum frei ist oder nicht, ein "True" oder "False" zurück. Dieser Webservice wird von dem oben beschrieben Node-RED Prozess aufgerufen.

Bluemix Service roomCheckerRequests.jpg

Die Abbildung zeigt unsere Implementierung des Webservices. In Zeile 9 wird der übergeben Raumparameter in der Variablen "room" gespeichert. In der If-Abfrage ab Zeile 17 wird überprüft, ob beim Aufruf des Services ein Datum mit übergeben wurde. Falls nicht, was in unserem Szenario möglich ist, wird das Datum des Abfragezeitpunkts als Datum herangezogen. Danach wird in Zeile 25 der Variablen der aufzurufende Link mit dem übergegebenen bzw. gesetzten Datum zugewiesen.

Bluemix Service roomCheckerRequests2.jpg

Die Webuntis-API sieht vor, dass zuerst ein allgemeiner Request benötigt wird, um die Hochschul-ID sowie die Studiengangs-ID ausgeführt wird. Die Antwort dieses Requests wird als codiertert Cookie auf dem anfragenden Gerät gespeichert und kann dann für genauere Requests wie die Datumsabfrage genutzt werden. Dieses Verhalten konnten wir während der Implementierung durch Reverse Engineering herausfinden. In Zeile 30 wird der erste Request an das Webuntis ausgeführt. Dieser ist für jede Abfrage gleich und gibt codiert die Hochschule Reutlingen (zu der das HHZ organisatorisch gehört) sowie den Studiengang Service Computing wieder. In Zeile 32 wird der spezielle Request an Webuntis gestartet. Für diesen wird die zuvor zusammengesetzte URL genutzt. Der Request liefert bei der Anfrage implizit den zuvor gespeicherten Cookie mit und so kann die spezielle Abfrage mit dem Datum realisiert werden. Zurück kommt eine Datei im iCal-Format. Diese wird in Zeile 36 in einen String geparst. Ab Zeile 38 werden alle Events dieser Datei durchlaufen und geprüft, ob in dem zu Beginn übergebenen Raum an dem übergebenen Tag eine Vorlesung stattfindet. Wenn ein Event in diesem Raum gefunden wurde, wird der Rückgabeparameter des Services "IsRoomFull" mit "True" gefüllt, ansonsten mit "False". Dieser Wert wird dem Gerät, dass den Webservice aufgerufen hat, zurückgegeben.

Kontinuierliche Entwicklertests

Die Funktionsweise der Implementierung wurde in kontinuierlichen Entwicklertests überprüft.

Live-Demo des MVP

Die Live-Demo des MVP wurde aufgezeichnet und auf YouTube hochgeladen.

Updated