Gutes Echo mit ESP8266 oder ESP32

Intelligente Sprachassistenten à la Apple Homepod, Google Home oder Amazon Echo verkaufen sich zur Zeit wie warme Semmeln, und bilden das Zentrum so mancher Smart Home Lösung. Wie aber kann der Maker Geräte bauen, die sich dort relativ einfach integrieren lassen?

vorlesen Druckansicht 4 Kommentare lesen
Lesezeit: 12 Min.
Von
  • Dr. Michael Stal
Inhaltsverzeichnis

Intelligente Sprachassistenten à la Apple Homepod, Google Home oder Amazon Echo verkaufen sich zur Zeit wie warme Semmeln, und bilden das Zentrum so mancher Smart-Home-Lösung. Wie aber kann der Maker Geräte bauen, die sich dort relativ einfach integrieren lassen?

In diesem Beitrag liegt der Fokus auf Amazon Echo. Diese Wahl soll keine negative Bewertung der Lösungen von Google oder Apple assoziieren. Die Entscheidung für Amazon fällt einzig aus dem Grund, weil deren Produkte mittlerweile am meisten verbreitet sind. Demzufolge haben sich auch schon einige Open-Source.Entwickler auf diesem Gebiet engagiert. Grund genug, ein Auge auf die Möglichkeiten zu werfen, die sich dem Maker bieten.

Jetzt wäre es natürlich die naheliegendste Möglichkeit, sich als Amazon-Entwickler zu registrieren, um entsprechende Skills und Echo-kompatible Hardware bereitzustellen. Für viele sehr einfache Anwendungsfälle ist das aber gar nicht notwendig. Damit sind solche Beispiele gemeint, bei denen sich die Steuerung eines IoT-Geräts auf das Ein- und Ausschalten reduzieren lässt. Die Killerapplikation sind in diesem Zusammenhang Lampen oder Steckdosen, die sich von einem Microcontroller aus über Relais schalten lassen.

Findige Entwickler haben deshalb die Wemo-Lösung von Belkin unter die Lupe genommen. Wie jedes in Echo integrierbare Gerät, enthält eine Wemo-Steckdose Funktionalität, um sich über WLAN mit einem Echo, Echo Dot, Echo Spot, oder Echo View zu koppeln. Was liegt also näher als dieses Protokoll nachzubauen und in einer Bibliothek bereitzustellen. Damit können Maker ihre eigene Lösung als Belkin Wemo ausgeben.

Wie funktioniert überhaupt das Zusammenspiel zwischen Echo-Produkt und Geräten wie zum Beispiel einer Belkin Wemo Steckdose?

Fordert der Benutzer ein Echo-System zum Auffinden neuer Geräte auf, schickt es per UDP-Broadcast eine Meldung an alle Geräte im vorliegenden WLAN. Kopplungswillige, neue Geräte antworten mit ihrer URL-Adresse, worauf Echo sie um ihre Service-Beschreibung bittet. Daraufhin schickt das jeweilige Gerät die Gerätebeschreibung (setup.xml) zurück. Diese Zuordnung (Gerät, Name, Charakteristik, ...) merkt sich Echo in einer Geräteliste. Fordert der Nutzer per Sprache oder App ein bekanntes Gerät zu einer von diesem Gerät unterstützten Aktion auf, bittet Echo das Gerät per TCP/Webservice-Aufruf um entsprechende Zustandsänderung (SetBinaryState), was das angesprochene Gerät bestätigt.

Eine schlichte Steckdose des Typs Belkin Wemo beispielsweise kennt nur zwei alternierende Zustände, an und aus. Demzufolge hören sie auf sehr einfache Kommandos.

Um eine einfache Integrationsmöglichkeit in das Amazon-Echo-Universum zu illustrieren, ist ein ESP8266 oder ein ESP32 Board notwendig. In meiner Serie gab es zu beiden MCUs schon Artikel (ESP8266 Teil 1 und Teil 2, ESP32).

Empfehlenswert als Boards sind beispielsweise die NodeMCU-Varianten mit ESP32 oder ESP8266 (ESP-12e oder ESP 12-f). Prinzipiell sollte sich aber jedes Board eignen.

FĂĽr unsere Zwecke ist die Arduino IDE notwendig. Damit sie mit ESP-Boards umgehen kann, existieren sogenannte Arduino Cores fĂĽr ESP8266- beziehungsweise ESP32-Boards. Deren Installation in die IDE ist auf den Implementierungsseiten beschrieben.

Die Boards mit ESP8266 oder ESP32 verwenden üblicherweise andere UART-Hardware, sodass die Installation zusätzlicher Treiber notwendig ist, typischerweise die UART-to-USB-Treiber von SiLabs für CP210x-Chips oder die Treiber für CH34x-Chipsets.

Haben die Installationen von Arduino Core und USB-Driver geklappt, können Sie in der Arduino IDE unter dem Menü Tools den COM-Port und das jeweils verwendete Board spezifizieren, wobei es bei ESP8266-Boads meistens im Falle von NODEMCU das NODEMCU 1.0 (oder sonst Generic ESP8266 Module) tut, und bei ESP32-Boards ESP32 Dev Module. In meinem Fall lag ein Board des Typs Wemos Lolin vor.

Wir nutzen den Arduino Core fĂĽr ESP32 und ESP8266. Dadurch lassen sich die Boards im gewohnten Stil mit der Arduino IDE programmieren.

Allerdings sind zwei Bibliotheken notwendig, zum einen fauxmoESP, und zum anderen eine Bibliothek fĂĽr asynchrone Kommunikation.

Die essenzielle Bibliothek für unser "trojanisches Pferd" firmiert unter dem Namen fauxmoESP. Der Ursprung von fauxmoESP ist eine entsprechende Python-Bibliothek, die von Maker Musings stammt. Die C/C++- Umsetzung haben wir Bibi Blocksberg (der Name ist hoffentlich ein Pseudonym), Xose Pérez (ESP8266) und Frank Hellmann (ESP32) zu verdanken. Zudem benötigt fauxmoESP eine C++-Bibliothek zur asynchronen Kommunikation, entweder AsyncTCP für ESP32-Boards oder ESPAsyncTCP für ESP8266-Boards.

Beide Bibliotheken sollten Sie sich von Github holen und jeweils ĂĽber das MenĂĽ Sketch > Include Library > Add .ZIP Library der IDE bekannt machen.

In der Amazon Alexa App tauchen nach dem Koppeln die LEDs Merkel und Schulz auf

Falls Sie es interessieren sollte: Warum fauxmo funktioniert wie es funktioniert, erläutert der Ur-Vater von fauxmo in einem interessanten Artikel.

Kleine Warnung vorweg: Die Lösung scheint in Kombination mit ESP8266-Core und ES32-Core noch nicht für alle Generation beziehungsweise Typen von Echo-Hardware zu funktionieren - so soll es in Geräten der zweiten Generation unter Umständen zu Problemen kommen. Ich hatte beispielsweise damit zu kämpfen, dass Alexa beim Sprachbefehl "Alexa, suche neue Geräte!" meine Selbstbau-Fauxmos nicht finden konnte, diese sich aber hinterher trotzdem auf der Alexa App aufgelistet befanden, und über Sprache steuerbar waren. Generell scheint die Verwendung mit ESP8266 momentan weniger Zicken zu machen als mit einem ESP32-Board.

Die Verwendung der Bibliothek in eigenen Programmen ist äußerst simpel.

  • Eine Variable des Typs fauxmoESP definieren.
  • Ăśber diese Variable im Setup alle gewĂĽnschten Geräte anmelden, und fauxmo einschalten.
  • In den Callback-Routinen Aktionen ausfĂĽhren. Letzteres wird weiter unten eine Demoanwendung veranschaulichen.

Damit lautet das prinzipielle GerĂĽst eines fauxmo-basierten Sketches:

#include <fauxmoESP.h>  // Headerdatei inkludieren

fauxmoESP fauxmo; // Zugriff auf fauxmo

void setup() {

Serial.begin(115200);

... Mit WLAN verbinden...

fauxmo.addDevice("Gerät Eins"); // Zwei Geraete anmelden
fauxmo.addDevice("Gerät Zwei");

fauxmo.enable(true); // Jetzt fauxmo aktiv schalten

fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
});
fauxmo.onGetState([](unsigned char device_id, const char * device_name) {
return true; // Status zurĂĽckmelden
});

}

void loop() {
fauxmo.handle(); // Eigentliche Event-Loop
}

In der Arduino IDE haben die verschiedenen Ports einfache Zuordnungen, etwa D1 = 1 oder D2 = 2, was der Tatsache geschuldet ist, dass die IDE sich ursprünglich stark an Arduino-Boards angelehnt hat. Für ESP2866- oder ESP32-Boards mit Arduino Core verhält sich die Angelegenheit ein wenig schwieriger, da sie ein anderes Layout ihrer Ausgänge besitzen. Die BUILTIN_LED lautet bei einem NODEMCU 1.0 16 (= D0). Hier gibt es folgende Portzuordnungen:

ESP8266  Arduino IDE
D0       16
D1 5
D2 4
D3 0
D4 2
D5 14
D6 12
D7 13
D8 15
D9 3
D10 1

Als Beispielsanwendung sollen zwei schlichte LEDs zum Einsatz kommen. Beide meldet der Sketch als Wemo-Geräte bei Amazon Echo an, sodas sie sich mittels Alexa ein- und ausschalten lassen. Das Beispiel nutzt einen Baustein des Typs NodeMCU (Wemos Lolin) auf Basis des ESP8266. Stattdessen kann auch ein ESP32-Board zum Einsatz kommen, aber für das simple Beispiel ist bereits der ESP8266 unterfordert.

Die Schaltung verwendet lediglich die Ports D0, D1 des Boards zur Ansteuerung der LEDs

In der Schaltung sind zwei LEDs (rot und blau) jeweils über 220Ω Widerstände an die Ports D0 (= Pin 16 des Wemos Lolin v3 / NodeMCU Boards) und D1 (= Pin 5 des Wemos Lolin v3 / NodeMCU Boards) angeschlossen. GND des Boards wird mit den beiden LEDs gemeinsam über das Breadboard geerdet (blaue Verbindung).

In einem anwendungsnäheren Szenario würden die Ausgänge keine LEDs ansteuern sondern Relais, über die sich größere Lampen in einem 12V-Stromkreis ein- oder ausschalten lassen.

Der zugehörige Sketch folgt ganz dem Muster, das wir oben kennengelernt haben. Das Programm gaukelt dem Echo-System zwei Wemo-Geräte namens "Merkel" und "Schulz" vor. Wir hätten bis zu gut einem Dutzend Geräte einführen können.

Hinweis: Bei den meisten Boards mit ESP8266 oder ESP32 existiert eine Flash- beziehungsweise Boot-Taste neben einer Reset-Taste. Um das Board mit einem neuen Sketch bespielen zu können, muss beim Reset die Flash-Taste gedrückt sein. Das liegt daran, dass ein Sketch zusammen mit dem Arduino Core in Wirklichkeit eine Firmware bildet. Zwar führt die IDE beziehungsweise die Werkzeuge für ESP8266/ESP32-Programmierung eines Reset aus, aber es empfiehlt sich, die Reset-Taste selbst manuell bei gedrückter Flash-Taste zu betätigen. Dann klappt es mit dem Aufspielen des Sketches. Ohne Betätigen der Flash-Taste geht das Board einfach in den Ausführungsmodus und verweigert sich jedem Upload.

//***********************************************************
//
// Demoanwendung um mittels eines ESP32- oder ESP8266-Boards
// eine Belkin Wemo Steckdose zu simulieren
// Michael Stal, 2018
// Creative Commons
//
//************************************************************



#include <Arduino.h>


#ifdef ESP32 // Im Falle eines ESP32-Boards
#include <WiFi.h>
#else // bei einem ESP8266-Board
#include <ESP8266WiFi.h>
#endif

// Die wichtigste Bibliothek ist fauxmoESP
#include "fauxmoESP.h"

// Zwei Lampen
#define MERKEL_LED 5
#define SCHULZ_LED 16

// Volle Kanne am seriellen Port
#define SERIAL_SPEED 115200

#define WL_SSID "StalWLAN"
#define WL_PASS "4242424242"

#define LAMPE1 "Merkel"
#define LAMPE2 "Schulz"

fauxmoESP fauxmo; // Objekt zum Zugriff auf fauxmo


//***********************************************************
//
// wifiSetup dient zur Verbindung ins WLAN >>WL_SSID<<
//
//************************************************************

void wifiSetup() {
// Das ESP-Board wird zur Station gemacht:
WiFi.mode(WIFI_STA);

// Verbindungsaufbau
Serial.printf("[WIFI] Verbinden zu %s ", WL_SSID);
WiFi.begin(WL_SSID, WL_PASS);

// Warten bis Verbindungsaufbau erfolgt ist
while (WiFi.status() != WL_CONNECTED) {
Serial.print(">");
delay(100);
}
Serial.println();

// Verbunden!
Serial.printf("[WIFI] Client Modus, SSID: %s, IP Adresse: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}

//***********************************************************
//
// setup initiiert den WLAN setup,
// schaltet beide Lampen aus,
// aktiviert fauxmo,
// meldet beide Lampen an,
// und definiert dafĂĽr Callbackhandler
//
//************************************************************

void setup() {
// Seriellen Port initialisieren
Serial.begin(SERIAL_SPEED);
Serial.println();
Serial.flush();

// Hier erfolgt der Verbindungsaufbau zum WLAN
wifiSetup();

// Die beiden LEDs
pinMode(MERKEL_LED, OUTPUT);
digitalWrite(MERKEL_LED, LOW);

pinMode(SCHULZ_LED, OUTPUT);
digitalWrite(SCHULZ_LED, LOW);


// Die Bibliothek lässt sich aktivieren und deaktivieren.
// Im deaktivierten Modus lassen sich Geraete weder finden noch schalten

fauxmo.enable(true);

// Alexa virtuelle Geraete unterjubeln
fauxmo.addDevice(LAMPE1);
fauxmo.addDevice(LAMPE2);

// Callback, sobald Lampe von Alexa geschaltet wird:
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) Zustand: %s\n", device_id, device_name, state ? "AN" : "AUS");
if ( (strcmp(device_name, LAMPE1) == 0) ) {
Serial.println("Merkel wird geschaltet");

if (state) { // Abhaengig vom Zustand Lampe ein-/ausschalten
digitalWrite(MERKEL_LED, HIGH);
} else {
digitalWrite(MERKEL_LED, LOW);
}
}
if ( (strcmp(device_name, LAMPE2) == 0) ) {
Serial.println("Schulz wird geschaltet");
if (state) { // Abhaengig vom Zustand Lampe ein-/ausschalten
digitalWrite(SCHULZ_LED, HIGH);
} else {
digitalWrite(SCHULZ_LED, LOW);
}
}
});
}

//***********************************************************
//
// loop ist die Ereignisschleife unseres Fake Wemo
//
//************************************************************

void loop() {
// Asynchron auf Echo-Kontaktaufnahmen warten, und darauf reagieren
fauxmo.handle();
}

Nach dem Koppeln über Sprachbefehl "Alexa, suche neue Geräte" oder über die Alexa App (Android, iOS), finden sich die neuen Lampen als Wemo-Steckdosen in der Geräteliste, und lassen sich entweder von der App oder mit Sprachbefehlen steuern, etwa mit "Alexa, schalte Merkel an!". So einfach kann das Leben sein.

In der Amazon Alexa App tauchen nach dem Koppeln die LEDs Merkel und Schulz auf

In der vorliegenden Folge haben wir kennengelernt, wie sich an einem ESP32- oder ESP8266-Board angeschlossene Geräte über Amazon Echo ansteuern lassen. Das funktioniert allerdings nur, sofern diese Geräte wie eine Lampe oder Steckdose nur zwei Zustände kennen, nämlich ein und aus. Der Trick besteht darin, dass die Bibliothek fauxmoESP dem Echo-Gerät vorspielt, es verkörpere eine Belkin Wemo Steckdose. Wer einen Raspberry Pi, eine Synology-Workstation oder einen Linux/Mac-Computer nutzt, kann dort die Python-Version von fauxmo zum gleichen Zweck nutzen. Siehe die erweiterte Version von n8henrie oder die ursprüngliche Version von makermusings.

Für komplexere Interaktionen und Geräte müssen Maker wohl oder übel auf der Amazon-Plattform (Amazon Lambda) Hand anlegen und komplexere Skills implementieren.

()