Internet of Things: Geräte übers Internet steuern mit dem ESP8266

Im ersten Teil zum Thema IoT mit dem ESP8266 habe ich die Arduino-Plattform und das Espressif ESP8266 SoC vorgestellt. Im diesem Beitrag erstellen wir eine konkrete Anwendung: Wir steuern Funksteckdosen fern via Web-Schnittstelle. Dazu verwenden wir mein quelloffenes ESP Framework für die effiziente Applikationsentwicklung mit dem Arduino Core auf dem ESP.

Das Ziel

Unser primäres Ziel ist es, elektrische Geräte via Internet von überall her komfortabel ein- und auszuschalten. Dies wollen wir manuell im Browser oder automatisch anhand von Ereignissen, Zeitsteuerung oder beliebiger Logik tun.

Viele IoT Lösungen verwenden einen Steuerserver, mit welchem sich das IoT-Gerät und der Benutzer verbinden. Wir wollen jedoch eine unabhängige, robuste, auch offline nutzbare Lösung, bei welchem der ESP selber die Rolle des Webservers (und bei Bedarf Wifi Access Point) übernimmt. Nicht zuletzt, weil es faszinierend ist, dass ein $4 Gerät dies alles kann!

Die Mittel

ESP8266 und Funksteckdosen 433MHzDie erste Idee zur Realisierung der Steuerung wäre via Relais, welche mit den s5V eines Arduino rsp. 3.3V eines ESP die 230V schalten können. Die meisten benötigen 5 oder bis 12V Steuerspannung – es gibt aber auch Module mit integriertem Transistor, welche direkt an den ESP gehängt werden können.

Wir wollen aber einen eleganteren Weg gehen, welcher die Steuereinheit (den ESP) und die Schaltgeräte kabellos verbindet (und nebenbei vollständig CE kompatibel ist). Wir verwenden darum handelsübliche Funksteckdosen, welche z.B. im Conrad erhältlich sind. Diese verwenden meist denselben Chip zur Funksignal-Decodierung. Dank der Arduino-Library RCSwitch, welche die Steuersignale für diese Funksteckdosen-Empfänger generiert, können wir mit einem simplen 433 MHz Funksender unsere Funksteckdosen ansteuern.

Material:

  • 1x ESP 12E Board
  • 1x Funksender
  • 1-3 Funksteckdosen

Das ESP8266 FrameworkArduino

Um gängige Aufgaben effizient zu lösen, habe ich vor einiger Zeit begonnen, ein ESP8266 Framework aufzubauen. Der Code ist open-source auf Bitbucket verfügbar.

Das Framework besteht (zurzeit) aus folgenden Libraries:

  • Framework: Basis-Funktionen wie Config, Log und Utilities. Wird von den anderen Libraries verwendet
  • Firebase: Ermöglicht das Ansteuern von webbasierten Firebase-Datenbanken, z.B. als Cloud-Datalogger oder zur remote-Konfiguration, etc.
  • DynDNS: Kann bei Dyn verwaltete DNS-Einträge dynamisch auf die aktuelle IP-Adresse des ESPs aktualisieren. Praktisch bei nicht statischer IP Adresse (DHCP), Verwendung des ESP in verschiedenen Netzwerken oder Zugang von ausserhalb des Heimnetzwerkes (via NAT) bei dynamischer IP.
  • WebComponents: Ermöglichen den standardisierten Web-Zugriff auf verschiedene Sensoren oder Aktuatoren. Jede WebComponent erstellt Webservice-Endpunkte unter <host>/api/ für die von ihr verwalteten Sensoren/Aktuatoren.
    • GeneralWebserver: Einfacher Webserver für statische Files (HTML, Bilder, JS etc.)
    • RemotePowerSwitch: Erstellt Routen für das Ein- und Ausschalten von Funksteckdosen
    • Routes: Erstellt eine Verzeichnis-Route (/api/directory), welche alle verfügbaren Routen auflistet und zu einer API zusammenfasst

Anwendungsbeispiele

1. Konfigurationswerte verwalten

Dazu wird eine Subklasse von Config angelegt, die Config-Werte als public Members angelegt und diese in den onLoad() / onSave() Events verarbeitet. Die Konfiguration wird als Json-Datei in den Flash-Speicher abgelegt (mithilfe des SPIFFS Dateisystems)

Achtung: Benötigt die ArduinoJson Library.

#include <ArduinoJson.h>;
#include <Log.h>;
#include <Config.h>;

class MyConfig : public Config {

public:

	int keyInt = 7;
	String keyString = "initial";

	MyConfig() : Config() {};
	MyConfig(char* configPath) : Config(configPath) {}

	void onLoad(JsonObject &json) {

		if (json.containsKey("keyInt")) keyInt = json["keyInt"];
		if (json.containsKey("keyString")) keyString = String(json["keyString"].asString());
	}

	void onSave(JsonObject &json) {

		json["keyInt"] = keyInt;
		json["keyString"] = keyString;

	}
};

MyConfig cfg = MyConfig("/config.json");
cfg.load();

Serial.println(cfg.keyString);

cfg.keyString = "updated";
cfg.save();

2. Daten in eine cloudbasierte Firebase-DB schreiben und auslesen

Die (volumenabhängig) kostenlose Firebase-DB [https://www.firebase.com/] kann mit dieser Library bequem als Remote-Speicher für Logdaten oder webbasierte Konfiguration etc. verwendet werden.

Achtung: Die Requests auf Firebase erfolgen via HTTPS/TLS, was dem ESP rund 22kB der ca. 36kB (bei Verwendung des Arduino Core) verfügbaren Speichers abverlangt! Im Zweifelsfall mit ESP.getFreeHeap() die Speicherverwendung prüfen.

#include <Firebase.h>;
#include <Log.h>;
#include <Util.h>;

// Convenience method for connecting (and getting some log output to serial)
Util::connectToWifi("my-ssid", "my-pw", WIFI_STA);

// Connect to Firebase and define a base path for all further operations
Firebase fb("my-own-db.firebaseio.com", "some-base-path");

// Set and read values
fb.setValue("node1/node2/mykey", "myvalue");
fb.getValue("node1/node2/mykey");

// Add a json row to a list
fb.addRow("somelist", "{\"name\":\"value\"}");

3. Einen Webserver für statische Files verwenden

Der ESP mit seinen bis zu 4 MB Flash kann für viele Anwendungen gut als Webserver fungieren. Dank dem SPIFFS Filesystem und dem zugehörigen Upload-Tool können Files vergleichsweise bequem im ESP gespeichert werden.

Das Servieren übernimmt die WebComponent GeneralWebserver, welche auf dem Beispielcode im ESP Core basiert und diesem Features wie Directory Browsing, Caching mittels ETag und GZip-Komprimierung hinzufügt.

Achtung: Wir sind immer noch auf einem SoC, keinem ausgewachsenen Server! Der Webserver kann nicht mit Apache & Co vergleichen werden. Für das Servieren von schicken Bedienoberflächen (z.B. Bootstrap-basierend) reicht es aber allemal.

Als Ausgangspunkt kann der im Framework mitgelieferte SPiffs-Filesystem-Data [https://bitbucket.org/bachi76/esp8266-framework/src/6e100a7781ffcd30f732e75c50d38f0a3fbdc67c/Spiffs-Filesystem-Data/?at=master] Ordner verwendet werden. Er enthält ein für den ESP angepasstes HTML-Template sowie Bootstrap, jquery, knockout.js und mehr.

Wie man seine statischen Files auf den ESP lädt, ist hier [https://github.com/esp8266/Arduino/blob/master/doc/filesystem.md#uploading-files-to-file-system ]beschrieben.

#include <ESP8266WiFi.h>;
#include <ESP8266WebServer.h>;
#include <ESP8266WebServerInspectable.h>;
#include <Log.h>;
#include <Util.h>;
#include <WC_GeneralWebserver.h>;

ESP8266WebServerInspectable server(80);
WC_GeneralWebserver wcGenWebserver("/www");

void setup() {

	Serial.begin(115200);
	Util::connectToWifi("my-ssid", "my-wifi-pw", WIFI_STA);

	// Start the underlying webserver
	server.begin();
	// Start the static file handlers
	wcGenWebserver.begin();
}

void loop() {
	server.handleClient();
}

Die fertige Steuerung

Wie sieht nun der Code für unsere webbasierte Funksteckdosen-Steuerung aus?

#include <ESP8266WiFi.h>;
#include <ESP8266WebServer.h>;
#include <ESP8266WebServerInspectable.h>;
#include <Log.h>;
#include <Test.h>;
#include <Util.h>;
#include <WC_Routes.h>;
#include <WC_RemotePowerSwitch.h>;

ESP8266WebServerInspectable server(80);
WC_Routes wcRoutes;

// Configure the data pin you connected your RF sender to
WC_RemotePowerSwitch wcSwitch(D7);
const char* TAG = "Main";

void setup() {

	Serial.begin(115200);
	Util::connectToWifi("my-ssid", "my-wifi-pw", WIFI_STA);

	// Add your radio-controlled power switches
	wcSwitch.addSwitch("light1", 1, 1);
	wcSwitch.addSwitch("light2", 1, 2);
	wcSwitch.addSwitch("heater", 1, 3);

	// Start the underlying webserver
	server.begin();

	// Show the configured routes
	Log::i(TAG, "Configured routes:");
	ESP8266WebServerInspectable::instance->routes.print();

}

void loop() {
	server.handleClient();
}

Mit dem IFTTT Maker Channel können wir den ESP auf beliebige Ereignisse reagieren lassen.
Mit dem IFTTT Maker Channel können wir den ESP auf beliebige Ereignisse reagieren lassen.

Die Adressierung der Geräte ist hier beschrieben. Wenn alles klappt, sollten auf dem ESP nun folgende Web-Routen zur Verfügung stehen und die entsprechenden Funksteckdosen ein- und ausschalten:

http://<esp-ip>/api/switch/light1/on
http://<esp-ip>/api/switch/light1/off
http://<esp-ip>/api/switch/light2/on
http://<esp-ip>/api/switch/light2/off
http://<esp-ip>/api/switch/heater/on
http://<esp-ip>/api/switch/heater/off
http://<esp-ip>/api/directory

Damit steht nun eine Webservice-API zur Verfügung, zu welcher man nach Bedarf eine schöne Benutzeroberfläche entwickeln kann. Oder deren Endpunkte man von seiner eigenen Applikation aus aufrufen kann. Oder via einem Service wie IFTTT.com Maker Channel verknüpfen, so dass z.B. das Licht angeht, wenn Google’s Börsenkurs um mehr als 3% sinkt. Im Gegensatz zur Nützlichkeit sind der Fantasie kaum Grenzen gesetzt.

Wer darf das Licht einschalten?

Möchte man die API auch von ausserhalb des heimischen Netzwerks aufrufen, muss auf dem Router/Firewall ein entsprechendes Port-Mapping eingestellt werden. Tut man dies ohne weitere Absicherung, stehen die URLs frei jedem zur Verfügung, und vermutlich wird zu Hause das Licht öfter mal an- und ausgehen. Basic Auth wäre einfach zu realisieren, ist aber über unverschlüsseltes HTTP keine gute Idee – und leider kann der ESP zwar in der Clientrolle, nicht aber in der Serverrolle HTTPS. Ein User-, Auth-, und Session-Handling fehlt dem ESP Framework noch (Pull Requests sind willkommen).

insign Hackathon

An unserem Team Hackathon haben unsere Entwickler den ESP und das ESP Framework ausgiebig ausprobieren können. Wir haben zusätzlich noch Temperatur- und Luftfeuchtigkeits-Sensoren verwendet, um aktive Steuerungen, Daten-Logger und mehr zu bauen. Ein Entwickler hat zudem einen 433 MHz Receiver verwendet, um einen „Steckdosen-RF-Protokoll-Sniffer“ zu bauen.

Fazit

Der ESP ist ein faszinierendes Stück Technologie. Hier werden auf einem einzelnen Chip Elektronik- und Webanwendungen vereinbar, und dies zu Preisen, welche die Massenfertigung erlauben. Dank der Arduino-Kompatibilität steht ein sehr umfangreiches Ökosystem an Tools und Libraries zur Verfügung. Wir sind uns sicher, dass der ESP8266 in vielen Produkten verwendet werden kann und wohl vielerorts wo eine Internetverbindung einen Mehrwert bringt, die betagten klassischen Atmel Arduino-Prozessoren verdrängen wird. Wir werden ihn für embedded / IoT Projekte auf jeden Fall gerne einsetzen.

insign Labs: ESP8266 Hackathon
insign Labs: ESP8266 Hackathon

Von Martin BachmannMartin Bachmann auf FacebookMartin Bachmann auf Google+Martin Bachmann auf Twitter Autoren-Webseite anschauen

Mitgründer und CTO @insigngmbh, Initiant von @android_schweiz, Android Evangelist und jetzt auch Papi.

Kommentare (1)

Pingback Liste

  1. Pingback: ESP8266 | wer bastelt mit?

  2. Pingback: Beta-Test für die Smartshopper App von Comparis | insign blog

Kommentar verfassen