Im Folgenden wird beschrieben, wie der Datenaustausch zwischen Alexa und dem ESP32 erfolgen soll.
Inhaltsverzeichnis
Hinweis: Die Erläuterungen zur Konfiguration des Routers beziehen sich auf eine Fritz!Box 6660 Cable mit FRITZ!OS:7.57.
Nachdem nun das Skill-Modell erstellt wurde und prinzipiell funktioniert, muss festgelegt werden, wie Alexa mit dem ESP32 kommunizieren soll. Auf dem ESP32 läuft ein Web-Server. Dieser reagiert auf HTTP-Requests. Wie solch ein Request aufgebaut wird, habe ich bei der Analyse der ESP8266-Webserver-Klasse beschrieben.
Bei diesem Projekt geht es hauptsächlich darum, die Kommunikation zwischen Alexa und einem ESP32 zu demonstrieren. Die Kommunikation findet im lokalen WLAN statt und es werden keine "systemkritischen" Funktionalitäten implementiert. Aus diesem Grund wurde auf den Zusatzaufwand sowohl für eine Authentifizierung der Requests (Passwort) als auch für eine Verschlüsselung der Kommunikation (https) verzichtet.
Es gibt verschiedene Möglichkeiten, ein Alexa-Kommando auf einen HTTP-Request abzubilden. Hier wird zur Unterscheidung der Intents (=Funktion) ein passender Pfad benutzt. Für die Variablen (Slot bei Alexa) wird ein HTTP-Parameter verwendet. Der Befehl "Schalte den Fernseher an" wird übersetzt in den Request "http://url:port/tv?action=an". Offen sind noch url und port. Der Pfad ist tv, der Parameter hat den Namen action und den Wert an. Analog führt "programmwahl prosieben" zu "http://url:port/tv?channel=prosieben". Wie gesagt, gibt es verschiedene Möglichkeiten, den HTTP-Request zu gestalten. Diese Art der Codierung hat den Vorteil, das die Analyse der Pfade bereits in der Web-Server-Bibliothek des ESP32 implementiert ist.
Es erleichtert ungemein, wenn man darauf achtet, dass bei den Daten, die an den ESP32 übermittelt werden und die von diesem zurück geliefert werden, keine Umlaute verwendet werden. Alexa codiert im UTF-8-Format, während beim ESP32 in der Arduino-Umgebung das ASCII-Format verwendet wird. Diese sind in den Codes 0x00..0x7F identisch. Umlaute sind in diesem Bereich nicht enthalten. Im UTF-8-Format werden hierfür 2-Byte-Codes verwendet (oder mehr) und beim ASCII-Format die Codes 0x80..0xFF. Man müsste also eine Umcodierung der Zeichen vornehmen.
Der Port ist eine Zahl zwischen 0 bis 65.535 ( 216−1). Im Prinzip kann man eine beliebige Zahl verwenden. Man sollte jedoch Konflikte mit den standardisierten Ports vermeiden. Im Projekt wurde der Port 7235 gewählt.
Die AWS-Lambda-Funktion wird nicht im Echo-Dot ausgeführt, sondern auf einem Amazon-Server. Die IP dieses Servers ist z.B. 54.216.143.240. Das bedeutet, dass der Zugriff von außen auf den ESP32 erlaubt sein muss. Da mein WLAN eine IPv4-Adresse besitzt, bietet sich die Port-Weiterleitung (port forwarding) hierfür an (s.u.).
Die für den Router vergebene globale IP-Adresse ist nicht fix. Der Provider kann sie ändern und tut dies auch mehr oder weniger regelmäßig. Im Alexa-Code muss jedoch eine feste Adresse angegeben werden. Abhilfe schafft ein Dyn-DNS-Service. Dies ist eine Technik, um Domains im Domain Name System (DNS) dynamisch zu aktualisieren.
Ein DNS-Service liefert -kurz gesagt- die IP-Adresse die zu einen Domain-Namen gehört. ullisroboterseite.de wird z.B. übersetzt in 81.169.145.72 (IPv4) oder 2a01:238:20a:202:1072:: (IPv6).
Wenn man sich bei einem Dyn-DNS-Anbieter angemeldet hat, erhält man einen festen Domain-Namen. Eine Übersicht aktueller Anbieter erhält man aus dem Netz, z.B. https://www.ionos.de/digitalguide/server/tools/dyndns-anbieter-im-ueberblick/. Viele sind für Privatpersonen kostenlos.
Der Domain-Name ist i.d.R. zusammengesetzt aus einer Anbieter-Kennung und einem frei wählbaren Teil. Bei dynv6 sieht das z.B. so aus:
Mit diesen Angaben erhält man den Domain-Namen: ullisroboterseite.dynv6.net. Geht man weiter in der Anameldung, erhält man Instruktionen, wie man seinen Router einrichten muss, damit dieser bei jeder Änderung der globalen IP-Adresse die Änderung an den Dyn-DNS-Anbieter weiter leitet.
Bei meiner Fritz!Box sieht das z.B. so aus:
Ein Router, der beispielsweise mit einem privaten lokalen Netz und dem Internet verbunden ist, wartet dabei an einem bestimmten Port auf Datenpakete. Wenn Pakete an diesem Port eintreffen, werden sie an einen bestimmten Computer und gegebenenfalls einen anderen Port im internen Netzwerk weitergeleitet. Alle Datenpakete von diesem Computer und Port werden, wenn sie zu einer eingehenden Verbindung gehören, per Netzwerkadressübersetzung (NAT) so verändert, dass es im externen Netz den Anschein hat, der Router würde die Pakete versenden.
In meiner Fritz!Box wird einer Port-Weiterleitung wie folgt eingestellt. Nach der Anmeldung an der Fritz!Box wird die Seite Internet/Freigaben/Portfreigaben ausgewählt. Unten findet man die Schaltfläche Gerät für Freigaben hinzufügen.
m zweiten Schritt muss das Gerät ausgewählt werden, an das die HTTP-Anfragen weiter geleitet werden sollen. In der DropDown-Box findet man alle dem Router bekannten Geräte. Ich habe für meinem ESP32 den Host-Namen Alexa Server vergeben.Die Fritz!Box zeigt die Verbindungsdaten zu dem ausgewählten Gerät an und ist nun bereit neue Freigaben anzulegen (Schaltfläche Neue Freigabe, rechts unten).
Im nächsten Fenster wird begonnen, die Art der Freigabe festzulegen. Die Standardvarianten passen leider nicht, so dass eine individuelle Konfiguration notwendig wird. Gewählt wird Portfreigabe und als Anwendung Andere Anwendung.
Die Bezeichnung der Portfreigabe, das Protokoll und die verwendeten Ports müssen im nächsten Fenster festgelegt werden:
Im letzten Schritt wird noch einmal eine Zusammenfassung angezeigt. Die Portfreigabe wird über die Schaltfläche Übernehmen abgeschlossen.
Es erscheint wieder die Übersicht angelegten Freigaben. Nun mit der neu angelegten Port-Weiterleitung.
Wenn alles korrekt eingerichtet ist, muss der Web-Server nun auch über die globalen IP-Adressen des Routers erreichbar sein, also