In diesem Beitrag möchte ich dir ausführlich erläutern, wie du eine Temperaturabhängige Steuerung mit einem Shelly Mini und einem Wemos D1 Mini aufbaust. Die neuen Shelly Minis haben leider keine Schnittstelle für ein Addon wo man sonst Sensoren anschließen und über die Shelly Smart Control App auslesen und in eine intelligente Szene einbauen kann.
Inhaltsverzeichnis
- Warum benötigt man einen extra Mikrocontroller?
- Warum wird der Wemos D1 Mini eingesetzt?
- Wie werden die Geräte miteinander interagieren?
- Benötigte Ressourcen für dieses kleine Projekt
- Programmieren des Wemos D1 Mini
- Schritt 1 – steuern des Relais via Postman
- Schritt 2 – Auslesen der momentanen Leistungsaufnahme am Shelly 1PM Mini Gen3 via Postman
- Schritt 3 – Auslesen der Daten am Wemos D1 Mini
- Schritt 4 – Anzeigen der Daten auf einem OLED Display
- Schritt 5 – Auslesen des Temperatursensors SHT30
- Schritt 6 – Temperaturabhängige Steuerung des Shelly Mini mit dem SHT30 Sensor
- Fazit zu – Temperaturabhängige Steuerung eines Shelly Mini
Warum benötigt man einen extra Mikrocontroller?
Die Shelly Minis sind derzeit in der dritten Generation (Gen3) erhältlich und mitunter genauso leistungsstark wie die großen Shelly Plus Geräte. Das Einzige, was denen fehlt, ist eine Schnittstelle für ein Addon an welches wir Sensoren anschließen können. Wollen wir jedoch Sensorabhängig eine Szene oder das Relais aktivieren, so benötigen wir eine externe Quelle.
Warum wird der Wemos D1 Mini eingesetzt?
Der Wemos D1 Mini ist ein kleiner ESP8266, welcher recht günstig erhältlich ist und vor allem, was ich besonders cool finde, kann auf diesen Mikrocontroller Sensoren und Aktoren gesteckt werden.
Für den Wemos D1 Mini gibt es das Shield mit einem DS18B20, SHT30, DHT11 und DHT22 Sensor. Für diesen Beitrag verwende ich den Sensor SHT30.
Das DS18B20 Sensor Shield ist am digitalen Pin D2 angeschlossen, an diesem liegt jedoch auch die I2C Schnittstelle an und diese benötigen wir für das OLED Display somit fällt dieses hier raus.
Erhältliche Varianten des Wemos D1 Mini
Den kleinen Mikrocontroller Wemos D1 Mini erhältst du derzeit in der Version 4.0 mit einem ESP8266. Wenn du jedoch mehr Leistung (CPU, Speicher) benötigst, dann kannst du auch auf eine Variante mit einem ESP32-S2 zurückgreifen. Beide Varianten kannst du für dieses Projekt verwenden!
Die beiden gezeigten Mikrocontroller habe ich dir bereits in separaten Beiträgen vorgestellt und einige Schaltungen präsentiert.
Technische Daten des Wemos D1 Mini
Hier nun die technischen Daten des Wemos D1 Mini V4:
Wemos D1 Mini V4 | |
---|---|
Taktgeschwindigkeit | 80 / 160 MHz |
Betriebsspannung | 3.3 V |
Anzahl digitale Pins | 11 |
Anzahl analoge Pins | 1 |
Speicher | 4 MB |
Schnittstellen | I²C, SPI, UART |
USB-Anschluss | USB-Typ-C |
Wie werden die Geräte miteinander interagieren?
Der Shelly verfügt über ein Relais, mit welchem man einen Verbraucher schalten kann. Der Shelly 1PM Mini Gen3 hat den Vorteil, dass dieser noch zusätzlich die Leistungsaufnahme messen kann. Mit dem Wemos D1 Mini wollen wir temperaturabhängig das Relais aktivieren / deaktivieren und auf dem OLED Display den Zustand anzeigen. Zusätzlich können wir auch die momentane Leistungsaufnahme anzeigen.
Der Vorteil dieser Schaltung liegt in ihrer einfachen Erweiterbarkeit. Zum Beispiel kannst du einen zusätzlichen Taster einbauen, um das Relais manuell ein- und auszuschalten, oder andere Sensoren integrieren. Mit einem IR Shield und der passenden Fernbedienung könntest du zudem weitere Geräte steuern und dir so ein kleines, intelligentes Dashboard schaffen.
Benötigte Ressourcen für dieses kleine Projekt
Schauen wir uns zunächst an, welche Ressourcen benötigt werden, um das kleine Projekt umzusetzen:
- einen Shelly Mini
- einen Wemos D1 Mini V4*
- ein USB-C Datenkabel*
- ein SHT30 Shield*
- ein OLED Shield*
- eine Dual Base Plate*
Alternativ kannst du auch das Shield mit einem DHT11/DHT22 Sensor* verwenden.
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Für den Shelly 1PM Mini Gen3 benötigst du noch ein Anschlusskabel, hier kommt es auf den Einsatzzweck an, in meinem Fall verwende ich ein 3×1,5mm² flexibles Kabel mit einem Schukostecker.
Programmieren des Wemos D1 Mini
Den Shelly habe ich bereits mit der Cloud verbunden und damit Zugriff auf die Verbrauchsdaten und dem Relais. In diesem Abschnitt möchte ich dir gerne zeigen, wie der Wemos D1 Mini programmiert werden muss um das Relais zu steuern & die Verbrauchsdaten anzuzeigen.
Schritt 1 – steuern des Relais via Postman
Mit dem Tool Postman kann man Requests an Services senden und eine Antwort auswerten. Dabei kann der Request mit allen benötigten Informationen (Header, Body, Parameter etc.) bestückt werden. Das gute ist, dass man dazu erst einmal nichts programmieren muss, sondern man kann zunächst die URL und die benötigten Eigenschaften des Requests ermitteln.
//aktivieren des Relais
http://192.168.178.141/rpc/Switch.Set?id=0&on=true
//deaktivieren des Relais
http://192.168.178.141/rpc/Switch.Set?id=0&on=false
In der offiziellen, englischen Dokumentation zur Schnittstelle von Shelly findest du alle Informationen, welche Daten du abgreifen kannst.
Schritt 2 – Auslesen der momentanen Leistungsaufnahme am Shelly 1PM Mini Gen3 via Postman
Wenn du wie ich den Shelly 1PM Mini Gen3 verwendest, dann kannst du vom angeschlossenen Verbraucher noch zusätzlich Daten ermitteln. Du kannst neben dem aktuellen Energieverbrauch in Watt, die Stromaufnahme in Ampere ermitteln. Vom Stromnetz selber können wir die Spannung und die Netzfrequenz ermitteln.
http://192.168.178.141/rpc/Switch.GetStatus?id=0
Schritt 3 – Auslesen der Daten am Wemos D1 Mini
In der Arduino IDE kannst du dir Daten auf dem seriellen Monitor ausgeben lassen, das hat den Vorteil das wir nicht immer zwingend ein Display benötigen. Auf der seriellen Schnittstelle wollen wir zunächst die ermittelten Daten ausgeben.
Schritt 3.1 – Aufbau einer WiFi-Verbindung
Bevor wir etwas auslesen können, müssen wir eine WiFi-Verbindung zum lokalen Netzwerk herstellen.
#include <ESP8266WiFi.h> WiFiServer server(80); //Die Zugangsdaten zum WiFi-Netzwerk const char *ssid = "xxx"; const char *password = "xxx"; void initWifiModul() { Serial.println("Aufbau der Verbindung zu: " + String(ssid)); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.println("Mit " + String(ssid) + " erfolgreich verbunden!"); server.begin(); Serial.println("Server gestartet"); Serial.print("Adresse : http://"); Serial.println(WiFi.localIP()); } void setup() { Serial.begin(9600); initWifiModul(); } void loop() { // put your main code here, to run repeatedly: }
Auf der seriellen Schnittstelle wird bei erfolg die IP-Adresse des Wemos ausgegeben. (Für diesen Beitrag nicht relevant.)
Aufbau der Verbindung zu: FRITZBox7590GI24
.......
Mit FRITZBox7590GI24 erfolgreich verbunden!
Server gestartet
Adresse : http://192.168.178.68
Schritt 3.2 – Absenden eines HTTP-Request an den Shelly
Zum Absenden der Daten benötigen wir einen HTTPClient, natürlich senden wir diesen Request nur ab wenn die WiFi-Verbindung besteht!
#include <ESP8266HTTPClient.h> String shellyServerAdress = "http://192.168.178.141/rpc/"; String shellyGetStatus = "Switch.GetStatus?id=0"; void sendHttpRequest(String url) { if (WiFi.status() == WL_CONNECTED) { WiFiClient client; HTTPClient http; http.begin(client, url.c_str()); int httpResponseCode = http.GET(); Serial.print("HTTP Status Code: "); Serial.println(httpResponseCode); String payload = http.getString(); Serial.println(payload); http.end(); } }
Auf der seriellen Schnittstelle sehen wir nun neben dem Antwortcode vom Shelly (HTTP Status Code) noch zusätzlich den JSON Respond mit den gewünschten Daten.
Schritt 3.3 – Parsen des JSON Respond
Um an die Daten im JSON Respond vom Shelly zu gelangen, müssen wir diesen jetzt parsen. Dafür benötigen wir die Bibliothek ArduinoJson.
#include <ArduinoJson.h> StaticJsonDocument<200> json; char jsonResponse[1500] = ""; String relais = ""; String energieverbrauch = ""; String stromaufnahme = ""; String spannung = ""; String frequenz = ""; bool sendHttpRequest(String url) { if (WiFi.status() == WL_CONNECTED) { WiFiClient client; HTTPClient http; http.begin(client, url.c_str()); int httpResponseCode = http.GET(); Serial.print("HTTP Status Code: "); Serial.println(httpResponseCode); String payload = http.getString(); Serial.println(payload); payload.toCharArray(jsonResponse, sizeof(jsonResponse)); http.end(); return httpResponseCode == 200; } return false; } void printData(String text, String value, int index) { Serial.print(text); Serial.println(value); } void readData() { if (sendHttpRequest(shellyServerAdress + shellyGetStatus)) { DeserializationError error = deserializeJson(json, jsonResponse); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; } Serial.println(); energieverbrauch = json["apower"] + " W"; stromaufnahme = json["current"] + " A"; spannung = json["voltage"] + " V"; frequenz = json["freq"] + " Hz"; relais = json["output"] == true ? "AN" : "AUS"; printData("Relais: ", relais, 0); printData("Energieverbrauch: ", energieverbrauch, 1); printData("Stromaufnahme: ", stromaufnahme, 2); printData("Spannung: ", spannung, 3); printData("Frequenz: ", frequenz, 4); } }
Die Antwort vom Shelly (im JSON-Format) haben wir nun im Zugriff und können dort recht einfach auf die Daten zugreifen.
Aufbau der Verbindung zu: FRITZBox7590GI24
.......
Mit FRITZBox7590GI24 erfolgreich verbunden!
Server gestartet
Adresse : http://192.168.178.68
HTTP Status Code: 200
{"id":0, "source":"switch", "output":true, "apower":14.5, "voltage":227.5, "freq":50.0, "current":0.112, "aenergy":{"total":2.884,"by_minute":[206.027,206.027,206.027],"minute_ts":1716113335}, "ret_aenergy":{"total":0.000,"by_minute":[0.000,0.000,0.000],"minute_ts":1716113335},"temperature":{"tC":55.5, "tF":131.9}}
{"id":0, "source":"switch", "output":true, "apower":14.5, "voltage":227.5, "freq":50.0, "current":0.112, "aenergy":{"total":2.884,"by_minute":[206.027,206.027,206.027],"minute_ts":1716113335}, "ret_aenergy":{"total":0.000,"by_minute":[0.000,0.000,0.000],"minute_ts":1716113335},"temperature":{"tC":55.5, "tF":131.9}}
Energieverbrauch: 14.500 W
Stromaufnahme: 0.112 A
Spannung: 227.500 V
Frequenz: 50.000 Hz
Schritt 4 – Anzeigen der Daten auf einem OLED Display
Da wir die Daten vom Shelly nun ausgelesen haben, möchte ich dir zeigen wie diese auf einem OLED Display angezeigt werden.
Für das ansteuern des OLED Displays am Wemos D1 Mini gibt es eine extra Bibliothek von Adafruit welche du bequem über den Bibliotheksverwalter installieren kannst.
Die Adresse des OLED Displays ist 0x3c, mit dem kleinen Programm aus dem Beitrag Arduino I2C-Scanner für ESP8266 & ESP32 anpassen: Eine Schritt-für-Schritt-Anleitung kannst du am ESP8266 nach geräten suchen.
An LOLIN(WEMOS) D1 mini Pro was recognized! The microcontroller has 1 I2C Interfaces! [0] SDA: 4, SCL: 5 Scanning... I2C device found at address 0x3c! End.
Ich würde dir empfehlen eine zuvor installierte Version der Adafruit_SSD1306 zu deinstallieren damit eventuelle Probleme minimiert werden.
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 0 // GPIO0 Adafruit_SSD1306 display(OLED_RESET); void setup() { Serial.begin(9600); initWifiModul(); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.setTextSize(1); display.setTextColor(WHITE); } void printData(String text, String value, int index) { Serial.print(text); Serial.println(value); display.setCursor(0, index * 10); display.println(value); } void loop() { display.clearDisplay(); readData(); display.display(); delay(2000); }
Die Daten werden nun nicht nur auf der seriellen Schnittstelle ausgegeben sondern auch auf dem OLED Display. Da das Display sehr klein ist, kann hier keine zusätzliche Bezeichnung hinzugefügt werden und es werden lediglich die Werte angezeigt.
Schritt 5 – Auslesen des Temperatursensors SHT30
Wie eigentlich ganz am Anfang erläutert soll das Relais temperaturabhängig gesteuert werden, dazu stecken wir nun das SHT30 Shield auf den freien Platz der Dual Base Plate.
Man könnte auch die die Shields untereinander auf einem Breadboard stecken. Jedoch strahlt jedes elektrische Gerät eine wärme ab wie auch der WiFi Chip des Wemos D1 Mini und wenn der Sensor zu nah an diesem ist, werden die Werte stark beeinflußt.
Technische Daten des SHT30 Sensors
Den SHT30 Sensor habe ich dir bereits im Beitrag Wemos D1 mini Shield: SHT30 Temperatur und Luftfeuchtigkeit Sensor vorgestellt und gezeigt wie dieser programmiert wird.
Hier nun die technischen Daten Sensors:
- Betriebsspannung: 3V bis 5,5V DC
- Betriebstemperatur -40 °C bis 125 °C
- Schnittstelle: I2C (0x44 Standard / 0x45 über Lötpunkte)
- Temperatur: -40 bis +125 °C (± 0,3 °C)
- relative Luftfeuchtigkeit : 0 % bis 100 % (± 2 %)
Bibliothek zum auslesen des Sensors
Für den Sensor gibt es von Wemos eine Bibliothek welche du dir vom GitHub Repository https://github.com/wemos/WEMOS_SHT3x_Arduino_Library als ZIP-Datei herunterladen kannst.
Wie du eine ZIP-Bibliothek in der Arduino IDE installierst, habe ich dir bereits im Beitrag Arduino IDE, Einbinden einer Bibliothek erläutert.
Auslesen des Sensors und ausgeben der Daten
Da wir bereits eine Funktion erstellt haben mit welcher wir Daten auf der seriellen Schnittstelle und auf dem OLED Display anzeigen können, verwenden wir diese und können somit unseren Code deutlich verschlanken.
#include <WEMOS_SHT3X.h> SHT3X sht30(0x45); String tempC = ""; String tempF = ""; String relLuftfeuchte = ""; void readSHT30Sensor() { if (sht30.get() == 0) { tempC = String(sht30.cTemp, 2) + " C"; tempF = String(sht30.fTemp, 2) + " F"; relLuftfeuchte = String(sht30.humidity, 2) + " %"; printData("Temperatur in Celsius : ", tempC, 0); printData("Temperatur in Fahrenheit : ", tempF, 1); printData("relative Luftfeuchtigkeit : ", relLuftfeuchte, 2); } else { Serial.println("Fehler beim auslesen des Sensors!"); } } void loop() { display.clearDisplay(); readData(); delay(1000); display.clearDisplay(); readSHT30Sensor(); display.display(); delay(2000); }
Auf der seriellen Schnittstelle werden nun nicht nur die Daten des Shellys sondern auch die Sensordaten des SHT30 ausgegeben.
Aufbau der Verbindung zu: FRITZBox7590GI24
...........
Mit FRITZBox7590GI24 erfolgreich verbunden!
Server gestartet
Adresse : http://192.168.178.68
HTTP Status Code: 200
{"id":0, "source":"switch", "output":false, "apower":0.0, "voltage":227.2, "freq":50.1, "current":0.000, "aenergy":{"total":4.000,"by_minute":[0.000,0.000,0.000],"minute_ts":1716195610}, "ret_aenergy":{"total":0.000,"by_minute":[0.000,0.000,0.000],"minute_ts":1716195610},"temperature":{"tC":46.6, "tF":115.8}}
Relais: AUS
Energieverbrauch: 0 W
Stromaufnahme: 0 A
Spannung: 227.2 V
Frequenz: 50.1 Hz
Temperatur in Celsius : 21.84 C
Temperatur in Fahrenheit : 71.32 F
relative Luftfeuchtigkeit : 68.98 %
Wenn wir nun den Wemos D1 Mini starten, dann wird
die Daten vom Shelly gelesen
- die Verbindung zum WiFi Netzwerk aufgebaut,
- die Daten vom Shelly gelesen und auf dem Display angezeigt,
- eine kleine Pause von 1 Sekunde eingelegt,
- die Daten vom SHT30 Sensor gelesen und auf dem Display angezeigt,
- eine Pause von 2 Sekunden eingelegt
Schritt 6 – Temperaturabhängige Steuerung des Shelly Mini mit dem SHT30 Sensor
Abschließend definieren wir einen Schwellwert an welchem das Relais des Shellys aktiviert / deaktiviert werden soll.
bool relaisActive = false; float valueRelaisActive = 24.00; float valueRelaisDeactive = 23.00; void readData() { ... relaisActive = json["output"]; ... } void readSHT30Sensor() { if (sht30.get() == 0) { tempC = String(sht30.cTemp, 2) + " C"; tempF = String(sht30.fTemp, 2) + " F"; relLuftfeuchte = String(sht30.humidity, 2) + " %"; printData("Temperatur in Celsius : ", tempC, 0); printData("Temperatur in Fahrenheit : ", tempF, 1); printData("relative Luftfeuchtigkeit : ", relLuftfeuchte, 2); String url = shellyServerAdress + shellySetRelais; if (sht30.cTemp >= valueRelaisActive && !relaisActive) { url += "true"; sendHttpRequest(url); } else if (sht30.cTemp <= valueRelaisDeactive && relaisActive) { url += "false"; sendHttpRequest(url); } } else { Serial.println("Fehler beim auslesen des Sensors!"); } }
Damit können wir nun den Shelly bzw. eher das Relay temperaturabhängig steuern.
Fazit zu – Temperaturabhängige Steuerung eines Shelly Mini
Die temperaturabhängige Steuerung eines Shelly Mini ist im Grunde genommen ziemlich simpel. Mit der Shelly API und dem einfachen Versenden von HTTP-Anfragen zum Ein- und Ausschalten des Relais lässt sich dies problemlos umsetzen. Falls du, wie ich, einen Shelly 1PM Mini nutzt, hast du zusätzlich die Möglichkeit, den Energieverbrauch anzuzeigen.
Verwendest du hingegen nur einen normalen Shelly 1 Mini (die blauen), dann kannst du sämtliche Daten auf einer einzigen Seite darstellen.