Der Alexa-Skill und der Web-Server werden so erweitert, dass der Web-Server Kommandos von Alexa versteht und Rückmeldung über die Ausführung gibt.
Wie im Kapitel Verbindung zwischen Alexa und dem ESP32 beschrieben wurde, werden die Intents auf den Pfad des HTTP-Request abgebildet. Es müssen passende Handler angelegt werden. Der Handler handleRootRequest wird nicht länger benötigt. Dafür müssen Handler für die Pfade tv und channnel für die Intents TvOnOffIntent und TvChannelIntent angelegt und beim Web-Server registriert werden.
Die Registrierung für handleRootRequest wird gelöscht und dafür die beiden Handler handleTvRequest und handleChannelRequest registriert:
...
// Web-Server konfigurieren
// -------------------------------------------------------------------------
server.on("/", handleRootRequest);
server.on("/tv", handleTvRequest);
server.on("/channel", handleChannelRequest);
server.onNotFound(handleNotFound);
...
Der Code für die beiden Handler muss ergänzt werden:
...
// Handler für HTTP-Requests
// -------------------------------------------------------------------------
void handleRootRequest() {
Serial.printf("RootRequest from %s, Argumente sind %s %s %s\n", server.client().remoteIP().toString().c_str(),
server.arg(0).c_str(), server.arg(1).c_str(), server.arg(2).c_str());
server.send(200, "text/html", "Fernseher " + server.arg(0) + " geschaltet.");
}
void handleTvRequest() {
Serial.printf("TvRequest from %s, Argument ist %s\n", server.client().remoteIP().toString().c_str(), server.arg(0).c_str());
server.send(200, "text/html", "Fernseher " + server.arg(0) + " geschaltet.");
}
void handleChannelRequest() {
Serial.printf("ChannelRequest from %s, Argument ist %s\n", server.client().remoteIP().toString().c_str(), server.arg(0).c_str());
server.send(200, "text/html", "Programm " + server.arg(0) + " eingeschaltet.");
}
void handleNotFound() {
server.send(404, "text/plain", "ich verstehe nicht, was gemeint ist.");
}
...
Das Versenden vom IR-Codes erfolgt im nächsten Kapitel.
Es muss nur die Lambda-Funktion erweitert werden. Es wird ein neuer Import für den Datentransfer benötigt:
...
from ask_sdk_model import Response
import requests # Import für HTTP-Requests
...
Beim Versenden von HTTP-Requests können Exceptions auftreten, auf die reagiert werden muss. Den Request packt man deshalb sinnvoller Weise in eine Funktion, die die Exceptions behandelt:
def getFromEsp(path, action):
try:
r = requests.get("http://xxxxx.dynv6.net:7235/" + path, params = {'action': action}, timeout=3) # IP-Adresse ersetzen!
return r.text
except requests.exceptions.Timeout:
return "der ESP32 hat nicht rechtzeitig geantwortet!"
except requests.exceptions.HTTPError as errh:
return "der ESP32 kann den Befehl nicht verstehen!"
except requests.exceptions.ConnectionError as errc:
return "ich kann den ESP32 nicht finden!"
except requests.exceptions.RequestException as e:
return "es hat leider nicht funktioniert!"
Diese Funktion führt den Request aus und liefert den vom ESP32 versendeten Antworttext zurück. Wenn eine Exception aufgetreten ist, wird statt dessen ein entsprechender Text zurück gegeben.
In den Intent-Handlern wird der feste Text für die Sprachausgabe ersetzt durch einen Aufruf der Funktion getFromEsp:
class TvOnOffIntentHandler(AbstractRequestHandler):
...
speak_output = "fernseher " + state.value
speak_output = getFromEsp("tv", state.value)
...
class TvChannelIntentHandler(AbstractRequestHandler):
...
speak_output = "programm " + channel.value + " wurde eingestellt"
speak_output = getFromEsp("channel", channel.value)
...
Nach der Änderung des Codes das Speichern und Installieren (Schaltflächen Save und Deploy) nicht vergessen!
Der Datenaustausch zwischen Alexa und dem ESP32 sollte nun funktionieren, sowohl im Simulator als auch per Sprache mit einem Echo-Dot.
Das Protokoll eine Session im Alexa-Simulator:
Die zugehörige Ausgabe auf dem ESP32:
Das ZIP-Archiv Alaxa-ESP32.ZIP enthält im Order 4. Kommunikation zwischen Alexa und dem ESP32 einen Export des angepassten Skills und das komplette Visual Micro Projekt für den Web-Server. Arduino-IDE-Anwender nutzen nur die .ino-Datei.