Kann ein ESP8266 einen Thermostat ersetzen?


#1

Beschäftige mich schon länger mit ESP8266 Thermostat Hygrometer.
Es schein, daß es noch kein ESP8266 Thermostat nur mit Wlan (ohne Display und ohne Webapp) gibt.
Das hier geht nicht mit Adruino IDE:
http://harizanov.com/wiki/wiki-home/three-channel-wifi-relaythermostat-board/
Diese Hier habe ich am laufen aber ohne Timer:


Under bei diesen geht keine Temperatureinstellung:
http://esp8266-server.de/Zeitschaltuhr.html
Hätte bei Bedarf Hardware (ESP9266, Breadboard, Hygrometer,Spannungsregler, Relay…) zum Testen.
Lg Thomas


#2

hab mich auch schon ein wenig mit dem ESP8266 beschäftigt, sehr cooler extrem billiger kleiner wifi chip mit rudimentärer in & output funktionalität - aber leider recht instabil. (aber gut, vielleicht hab ich auch nur ein ei erwischt bei meinen tests)


#3

Ich würde euch Micropython empfehlen für den ESP8266. Die Software ist da wirklich schnell entwickelt mit einem ESP8266. Ich hab sowas mit DHT11/DHT22 oder DS18B20 als reinen Sensor herumliegen (der logt dann nach Thingspeak oder in ein anderes Backend hinein), um Temperatur und Feuchtigkeit ein bisschen zu beobachten. Wenn wer die Software verwenden will, würd mich das freuen, ist aber nichts großartiges bisher, sollte ich ein bisschen aufräumen vermutlich (hier liegt sie eigentlich eh schon öffentlich herum fällt mir auf).
Als Thermostat würd ich das aber nicht einsetzen, dazu ist mir eine warme Wohnung zu wichtig… :slight_smile: Ich kämpf schon länger mit Abstürzen alle paar Wochen und ich weiß keinen Weg so etwas zu debuggen, wenn es nur alle paar Wochen auftritt.


#4

Klingt, als müssten wir demnächst einen ESP8266 Workshop veranstalten :wink:


#5

Wir können uns jederzeit gern im Metalab mal unvorbereitet zum herumhacken treffen. Es hat schon 1-2 gute ESP8266-Workshops auch gegeben von anderen.


#6

Innenstadt ist für manche Aussenbezirkler und Niederösterreicher etwas mühsam, wegen miserabler Öffi-Anbindung und Parkgebühren. Eventuell findet sich ein anderer Ort. Ich tu mir das nicht mehr an, wenn’s nicht sein muss.


#7

Ich hab mit den esp8266 Geräten schon länger zu tun, sie sind genial für Basteleien, jedoch waren einige Langzeittests teilweise enttäuschend. Ich persönlich kann die Variante Wemo D1 mini empfehlen, die nutze ich bei mehreren IoT Devices und sie laufen schon seit vielen Monaten sehr zuverlässig, auch was Wifi und Stromversorgung und Stabilität anbelangt.
Ich nutze den DHT 22 zur Messwerterfassung im Garten, sowie als Toröffner und dies funktioniert nun schon seit mehr als einem Jahr ohne Probleme.


#8

Langzeittests - Abstürze?


#9

Oben Recht Netzgerät 3,3V700mA oder 5V700mA mit AMS1117 (3,3V Spannungsregler)
Oben Links SRD Relay 5Volt 220V 10A
Relayspule an +3,3 und Diode 1N4148 an Katode.
Relayspule an Transistor BC548 Kolektor und Diode 1N4148 Anode.
Transistor BC548 Emitter an GND.
Transistor BC548 Basis mit 2,2kOHM an GPIO04 (ESP-12)

Mitte Links ESP8266 ESP-12E
ESP EN an +3,3V
ESP VCC an +3,3V
ESP GPIO15 an GND
ESP GND an GND

Mitte Links schwarzer Kabel zum BME280
BME280 VCC an +3,3
BME280 GND an GND
BME280 SCK/SCL an GPIO13
BME280 SDA/SDI an GPIO12
BME280 SCB an GPIO14
BME280 SDO an GPIO16

Materialkosten ca. 6 Eur.

Wemo D1 war mir zu groß und zu teuer.

Konfiguration Arduino IDE:
http://randomnerdtutorials.com/how-to-install-esp8266-board-arduino-ide/

Thermostat Code:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <FS.h>
#include <Adafruit_BME280.h>
#define BME_SCK 13
#define BME_MOSI 12
#define BME1_CS 14
#define BME_MISO 16
#define SEALEVELPRESSURE_HPA (1013.25)
#define RELAYPIN 4
Adafruit_BME280 bme1(BME1_CS, BME_MOSI, BME_MISO, BME_SCK);
//Adafruit_BME280 bme2(BME2_CS, BME_MOSI, BME_MISO, BME_SCK);
unsigned long delayTime;
const char* ssid = “…”;
const char* password = “…”;
float heatOn = 18.0;
float heatOff = 19;
String relayState = “OFF”;
const static String fName = “prop.txt”;
const static String dfName = “data.txt”;
int dataLines = 0;
int maxFileData = 20;
ESP8266WebServer server(80);
float humidity, temp_f;
String webString = “”;
String webMessage = “”;
unsigned long previousMillis = 0;
long interval = 200000;
void gettemperature() {
humidity = bme1.readHumidity() + 5.0; //Eichung
temp_f = bme1.readTemperature() - 3.0; //Eichung
if (isnan(humidity) || isnan(temp_f)) {
Serial.println(“Failed to read from sensor!”);
return;
}
if (temp_f <= heatOn)
{
digitalWrite(RELAYPIN, HIGH);
relayState = “ON”;
}
else if (temp_f >= heatOff)
{
digitalWrite(RELAYPIN, LOW);
relayState = “OFF”;
}
}
void clearDataFile()
{
File f = SPIFFS.open(dfName, “w”);
if (!f) {
Serial.println(“data file open to clear failed”);
}
else
{
Serial.println("-- Data file cleared =========");
f.close();
}
}
void removeFileLine(String fi)
{
File original = SPIFFS.open(fi, “r”);
if (!original) {
Serial.println(“original data file open failed”);
}
File temp = SPIFFS.open(“tempfile.txt”, “w”);
if (!temp) {
Serial.println(“temp data file open failed”);
}
Serial.println("------ Removing Data Lines ------");
//Lets read line by line from the file
for (int i = 0; i < maxFileData; i++) {
String str = original.readStringUntil(’\n’); // read a line
if (i > 0) { // skip writing first line to the temp file
temp.println(str);
}
}
int origSize = original.size();
int tempSize = temp.size();
temp.close();
original.close();
Serial.print(“size orig: “); Serial.print(origSize); Serial.println(” bytes”);
Serial.print(“size temp: “); Serial.print(tempSize); Serial.println(” bytes”);
if (! SPIFFS.remove(dfName))
Serial.println(“Remove file failed”);
if (! SPIFFS.rename(“tempfile.txt”, dfName))
Serial.println(“Rename file failed”);
}
void updateDataFile()
{
Serial.println(“dataLines: “);
Serial.println(dataLines);
if (dataLines >= maxFileData)
{
removeFileLine(dfName);
}
File f = SPIFFS.open(dfName, “a”);
if (!f) {
Serial.println(“data file open failed”);
}
else
{
Serial.println(”====== Writing to data file =========”);
f.print(relayState); f.print(":");
f.print(temp_f); f.print( “,”); f.println(humidity);
Serial.println(“Data file updated”);
f.close();
}
Serial.print(“millis: “);
Serial.println(millis());
}
String readDataFile()
{
String returnStr = “”;
File f = SPIFFS.open(dfName, “r”);
if (!f)
{
Serial.println(“Data File Open for read failed.”);
}
else
{
Serial.println(”----Reading Data File-----”);
dataLines = 0;
while (f.available()) {
//Lets read line by line from the file
dataLines++;
String str = f.readStringUntil(’\n’);
String switchState = str.substring(0, str.indexOf(":") );
returnStr += switchState + " " + str.substring(str.indexOf(":") + 1) + “
”;
}
f.close();
}
return returnStr;
}
void setHTML()
{
webString = “\n”;
webString += “\n”;
webString += “<form action=“http://” + WiFi.localIP().toString() + “/submit” method=“POST”>”;
webString += “<a href=“http://” + WiFi.localIP().toString() + “”>Refresh”;
webString += “<div style=“color:red”>” + webMessage + “\n”;
webString += String(temp_f, 2) + “*C
\n”;
webString += String((int)humidity) + “%
\n”;
if (digitalRead(RELAYPIN) == LOW)
webString += “OFF
\n”;
else
webString += “ON
\n”;
webString += "Heat On: " + String((float)heatOn) + “” + “
\n”;
webString += "Heat Off : " + String((float)heatOff) + “” + “
\n”;
webString += "Sample Rate: " + String(interval / 1000) + “s " + “” + “
\n”;
webString += “Data Lines: " + String((int)dataLines) + “” + “
\n”;
webString += “
\n”;
webString += readDataFile() + “\n”;
webString += “<a href=”/clear”>Clear Data\n”;
webString += “”;
}
boolean isValidNumber(String str) {
for (byte i = 0; i < str.length(); i++)
{
if (isDigit(str.charAt(i))) return true;
}
return false;
}

void handle_submit() {
webMessage = “”;
float tempON = 0;
float tempOFF = 0;
long sRate = 0;
int maxData = 0;
if (server.args() > 0 ) {
for ( uint8_t i = 0; i < server.args(); i++ ) {
if (server.argName(i) == “heatOn”) {
if (server.arg(i) != “”)
{
if (isValidNumber(server.arg(i)) )
tempON = server.arg(i).toInt();
else
webMessage += “Heat On must be a number
”;
}
else
webMessage += “Heat On is required
”;
}
if (server.argName(i) == “heatOff”) {
if (server.arg(i) != “”)
{
if (isValidNumber(server.arg(i)) )
tempOFF = server.arg(i).toInt();
else
webMessage += “Heat Off must be a number
”;
}
else
webMessage += “Heat Off is required
”;
}
if (server.argName(i) == “sRate”) {
if (server.arg(i) != “”)
{
if (isValidNumber(server.arg(i)) )
sRate = server.arg(i).toInt();
else
webMessage += “Sample Rate must be a number
”;
}
else
webMessage += “Sample Rate is required
”;
}
if (server.argName(i) == “maxData”) {
if (server.arg(i) != “”)
{
if (isValidNumber(server.arg(i)) )
maxData = server.arg(i).toInt();
else
webMessage += “Max Chart Data must be a number
”;
}
else
webMessage += “Max Chart Data is required
”;
}
}
if (tempOFF <= tempON)
webMessage += “Heat On must be lower than Heat Off
”;
if (sRate < 10)
webMessage += “Sample Rate must be greater than or equal to 10
”;
if (maxData < 10 || maxData > 300)
webMessage += “Max Chart Data must be between 10 and 300
”;
if (webMessage == “”)
{
heatOn = tempON;
heatOff = tempOFF;
interval = sRate * 1000;
maxFileData = maxData;
File f = SPIFFS.open(fName, “w”);
if (!f) {
Serial.println(“file open for properties failed”);
}
else
{
Serial.println("====== Writing to config file =========");
f.print(heatOn); f.print( “,”); f.print(heatOff);
f.print("~"); f.print(sRate);
f.print(":"); f.println(maxData);
Serial.println(“Properties file updated”);
f.close();
}
}
}
if (webMessage == “”) {
webMessage = “Settings Updated”;
}
gettemperature();
setHTML();
server.send(200, “text/html”, webString);
delay(100);
}
void handle_root() {
gettemperature();
webMessage = “”;
setHTML();
server.send(200, “text/html”, webString);
delay(100);
}

void setup(void)
{
Serial.begin(115200);
bool status;
status = bme1.begin();
if (!status) {
Serial.println(“Could not find a valid BME280 sensor 1 , check wiring!”);
}
/*
status = bme2.begin();
if (!status) {
Serial.println(“Could not find a valid BME280 sensor 2 , check wiring!”);
}
*/
Serial.println("-- Default Test --");
delayTime = 5000;
Serial.println();
pinMode(RELAYPIN, OUTPUT);
digitalWrite(RELAYPIN, LOW);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("\n\r \n\rWorking to connect");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println(“Server”);
Serial.print(“Connected to “);
Serial.println(ssid);
Serial.print(“IP address: “);
Serial.println(WiFi.localIP());
delay(10);
ArduinoOTA.begin();
SPIFFS.begin();
delay(10);
// SPIFFS.format(); // uncomment to completely clear data
File f = SPIFFS.open(fName, “r”);
if (!f) {
Serial.println(“Please wait 30 secs for SPIFFS to be formatted”);
SPIFFS.format();
Serial.println(“Spiffs formatted”);
f = SPIFFS.open(fName, “w”);
if (!f) {
Serial.println(“properties file open failed”);
}
else
{
Serial.println(”====== Writing to properties file =========”);
f.print(heatOn); f.print( “,”); f.print(heatOff);
f.print(”~”); f.print(interval / 1000);
f.print(":"); f.println(maxFileData);
Serial.println(“Properties file created”);
dataLines = 1;
f.close();
}
}
else
{
Serial.println(“Properties file exists. Reading.”);
while (f.available()) {
String str = f.readStringUntil(’\n’);
String loSet = str.substring(0, str.indexOf(",") );
String hiSet = str.substring(str.indexOf(",") + 1, str.indexOf("~") );
String sampleRate = str.substring(str.indexOf("~") + 1, str.indexOf(":") );
String maxData = str.substring(str.indexOf(":") + 1 );
Serial.println(loSet);
Serial.println(hiSet);
Serial.println(sampleRate);
Serial.println(maxData);
heatOn = loSet.toInt();
heatOff = hiSet.toInt();
interval = sampleRate.toInt() * 1000;
maxFileData = maxData.toInt();
}
f.close();
}
readDataFile();
gettemperature();
updateDataFile();
server.on("/", handle_root);
server.on("/submit", handle_submit);
server.on("/clear", {
clearDataFile();
webMessage = “Data Cleared”;
gettemperature();
updateDataFile();
setHTML();
server.send(200, “text/html”, webString);
delay(100);
});
server.begin();
Serial.println(“HTTP server started”);
}
void loop(void)
{
ArduinoOTA.handle();
delay(delayTime);
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval )
{
previousMillis = currentMillis;
gettemperature();
Serial.print("Temp: ");
Serial.println(temp_f);
Serial.print("Humidity: ");
Serial.println(humidity);
updateDataFile();
readDataFile();
}
server.handleClient();
}


#10

@ThomasM vielen Dank für die Detailierte Doku!

Ich versuch’ mal 'ne Einkaufsliste zusammenzustellen, vielleicht kannst du mal drüberschaun ob du Verbesserungsvorschläge hättest oder ich was falsch interpretiert habe:

$1.25 Netzteil:
https://www.aliexpress.com/item/AC-DC-110V-220V-to-3-3V-700mA-2-3W-Switching-Switch-Power-Supply-Buck-Converter/32829978591.html

$0.57 Relay:
https://www.aliexpress.com/item/1-Channel-Relay-Module-Interface-Board-Shield-For-Arduino-5V-Low-Level-Trigger-One-PIC-AVR/32803347739.html

$0.48 Transistor 30 Stück
https://www.aliexpress.com/item/30Pcs-BC548-TO-92-NPN-30V-0-1A-Transistor/32658045588.html

$2.85 Temperatur, Luftdruck & Luftfeuchte Sensor GY-BME280
https://www.aliexpress.com/item/3In1-BME280-GY-BME280-Digital-Sensor-SPI-I2C-Humidity-Temperature-and-Barometric-Pressure-Sensor-Module-1/32847825408.html

$1.70 ESP8266 ESP-12E
https://www.aliexpress.com/item/Free-Shipping-1pcs-lot-ESP8266-serial-WIFI-model-ESP-12-ESP-12E-ESP12E-ESP12-Authenticity-Guaranteed/32647614807.html

Macht in Summe $6.85 (1.25+0.57+0.48+2.85+1.70) also ca. €5.70
220V Drähte und Dünne Litzen für die 3.3V Seite hab ich noch rumliegen, wobei den ESP8266 hab ich vielleicht auch noch einen wenn ich ihn finde :wink:

@ThomasM könnt das so klappen? Grade mit dem Relay bin ich mir unsicher ob das stimmt.


#11

Ja das geht gut. Habe die Teile um ca. 4,80 Eur pro Steckerleiste bekommen. Die Steckerleiste ist vom Hornbach um 1,85 Eur.

0,69 Eur
https://www.aliexpress.com/item/5V700mA-3-5W-Isolated-Switch-Power-Supply-Module-AC-DC-Buck-Step-down-Module-220V-Turn/32856166624.html

0,023 Eur/Stück
https://www.aliexpress.com/item/Free-Shipping-10Pcs-Original-AMS1117-3-3-AMS1117-3-3V-AMS1117-LM1117-1117-Voltage-Regulator-We/32520903460.html

0,24 Eur/Stück
https://www.aliexpress.com/item/Free-shipping-5PCS-Relays-SRD-03VDC-SL-C-SRD-05VDC-SL-C-SRD-06VDC-SL-C/32841645760.html

Dioden sind aus alten Geräten/Computer ausgelötet. Sonst 0,01 Eur.

BC548 und 2,2kOhm Wiederstände bekommst von mir.

2,38 Eur
https://www.aliexpress.com/item/ShenzhenMaker-GY-BME280-3-3-BME280-Atmospheric-Pressure-Sensor-Module/32861487175.html

1,45 Eur
https://www.aliexpress.com/item/Free-Shipping-2pcs-lot-ESP8266-remote-serial-Port-WIFI-wireless-module-through-walls-Wang-ESP-12/32256161821.html


#12

Könntest du mir eine Schaltung zeichen wie ich die diversen Bauteile mit den Dioden verbinden soll?
Bzw. wenn dir das zu aufwändig ist kann ich auch probieren deine textuelle Beschreibung in einen Schaltplan zu verwandeln und du sagst dann einfach ob ich’s richtig verstanden hab.


#13

Anbei eine Skitze.


#14

Ich hab jetzt doch noch nachdem ich mir mit den einzelnen konkreten Pins der Bauteile nicht alzu sicher bin einen Schaltplan für Dummies gezeichnet. Kannst du mal drüberschaun ob das so passt?

UPDATE: Was mir gerade auffällt (könnt auch Blödsinn sein) -> Muss in den Spulenkreislauf des Relays nicht noch irgendwo ein Widerstand rein? Sonst ist das ja wenn der Controller den Transistor aufmacht ein Kurzschluss von 3.3V auf GND, oder? Oder ham diese Relays nen ausreichend hohen Widerstand eingebaut?

UPDATE2: noch ne andere Frage: Im Chat wird gerade über Smarte Steckdosen die Stromverbrauch messen und aufzeichnen können diskutiert. (z.B. https://smartplugs.de/energie/edimax-sp-2110w/ oder TP-Link HS110) Denkst du könnte man sowas mit nem ESP8266 auch umsetzen und die Software dahinter selber basteln?


#15

Das ist ein super Schaltplan. Vielen Dank.

UPDATE
Die Relayspule hat ca. 200 Ohm (Spule mit langen dünnen Draht) - Ohmischen Wiederstand. Also ca. 30mA.
Beim Enschalten haben induktive Bauteile eine fast unendlichen Wiederstand.
Beim Außschalten wird durch die Änderung des Magnetfeldes eine negative Spannung/Energie erzeugt die den Transistor zerstören könnte. Deshalb wird eine Diode verbaut die die negative Spannung ableitet.

UPDATE2
Ja geht mit ACS709 oder Shunt-Wierderstand und Spannunswandler.


#16

Bitte, gerne :slight_smile: Heißt das, der Schaltplan stimmt so?

Add. Stromverbrauch messen mit ESP8266 als Controller:
Könntest du das konkreter ausformulieren wie das gehn könnte?

ACS709 klingt eleganter & weniger nach Heizung.
Hab hier den Chip um 2$ pro Stück gefunden, und hier gäbs ihn auf einer Platine um €13.09.

UPDATE: Danke @ThomasM für den Link: https://blog.thesen.eu/genaue-strommessung-mit-dem-arduino-und-dem-acs712-hall-sensor-mittels-oversampling/
Sieht also so aus als ob das etwas komplizierter wäre, ich werd mal versuchen deinen Thermostat nachzubauen, wenn das mal klappt kann ich ja weiter Pläne spinnen :wink:

UPDATE2: Eigentlich muss bei einem Transistor der Arbeitsstrom und der Basisstrom ja nicht die gleiche Spannung haben. Also könnte man hinter dem Transistor auch wenn der ESP8266 nur 3.3V hergibt trotzdem eines der weiter verbreiteten und damit billigeren 5V Relays verwenden. Weiters habe ich entdeckt, dass der AMS1117 auf seiner Ausgangsseite eienn 22µF Kondensator braucht. Also so:

Hier eine aktualisierte Einkaufsliste:

$0.86 1Stk. 5V 700mA power supply
https://www.aliexpress.com/item/Free-shipping-AC-DC-5V-700mA-3-5W-Power-Supply-Buck-Converter-Step-Down-Module-for/32529942015.html

$0.28 10Stk. 5V zu 3.3V
https://www.aliexpress.com/item/Free-Shipping-10Pcs-Original-AMS1117-3-3-AMS1117-3-3V-AMS1117-LM1117-1117-Voltage-Regulator-We/32520903460.html

$1.24 5Stk. 5V Relays
https://www.aliexpress.com/item/5PCS-lot-Relays-SRD-03VDC-SL-C-SRD-05VDC-SL-C-SRD-12VDC-SL-C-3V/32857311016.html
alternativ:
$0.39 1Stk. 5V Relay
https://www.aliexpress.com/item/Free-shipping-5V-DC-SONGLE-Power-Relay-T73-5V-SRD-05VDC-SL-C-PCB-Type-In/32728068614.html

$0.48 30Stk. Transistoren
https://www.aliexpress.com/item/30Pcs-BC548-TO-92-NPN-30V-0-1A-Transistor/32658045588.html

$0.59 100Stk. 2.2kΩ Widerstände
https://www.aliexpress.com/item/Free-Shipping-100pcs-2-2k-ohm-1-4W-2-2k-Metal-Film-Resistor-2-2kohm-0/32479947935.html

$0.60 20Stk. 22µF Kondensatoren
https://www.aliexpress.com/item/20pcs-lot-AC07-50V22UF-aluminum-electrolytic-capacitor-size-5-11-22UF/32830057405.html

$0.15 10Stk. Dioden
https://www.aliexpress.com/item/10pcs-lot-New-Original-IN4007-1N4007-4007-1A-1000V-DO-41-DO-41-Rectifier-Diode-Free/32480274160.html

$2.73 1Stk. 3in1 Sensor
https://www.aliexpress.com/item/1PCS-GY-BME280-3-3-precision-altimeter-atmospheric-pressure-BME280-sensor-module/32862421810.html

$1.70 ESP8266 ESP-12E
https://www.aliexpress.com/item/Free-Shipping-1pcs-lot-ESP8266-serial-WIFI-model-ESP-12-ESP-12E-ESP12E-ESP12-Authenticity-Guaranteed/32647614807.html

€1.85 3-Fach Steckdosenleiste mit 1,4m Kabel
https://www.hornbach.at/shop/Steckdosenleiste-3-fach-3G1-5-weiss-1-4-m/3882929/artikel.html
alternativ:
€3.60 3-Fach Steckdosenleiste mit Schalter & 1.5m Kabel
https://www.hornbach.at/shop/Steckdosenleiste-3-fach-mit-Schalter-3G1-5-weiss-1-5-m/3147964/artikel.html
alternativ:
€4.95 3-Fach Steckdosenleiste mit Schalter & 5m Kabel
https://www.hornbach.at/shop/Steckdosenleiste-mit-Schalter-3-fach-weiss-5-m/8204327/artikel.html

Also für die Elektronik-Komponenten macht das insgesamt $7.78 (Wobei vieles überbleibt weil man’s aufgrund des niedrigen Stückpreises gar nicht einzeln kaufen kann oder es keinen Sinn machen würde)
Und dann noch ein paar € je nach gewählter Steckdosenleiste.

@ThomasM: Könnte man diese kompaktere Version des 3in1 Sensors auch verwenden? Hab leider nirgends die Belegung dieser 3 kleinen Pads die bei der Version nicht mehr als richtige Pins vorliegen gefunden.
https://www.aliexpress.com/item/BME280-Digital-Sensor-Temperature-Humidity-Barometric-Pressure-Sensor-Module-I2C-SPI-1-8-5V-GY-BME280/32850070226.html

UPDATE3:
Vielleicht wärs noch sinnvoll, nachdem diese Relays “nur” 10A schaffen (und typische Sicherungen im Sicherungskasten 16A haben) und generell nachdem ja auch das 5V Netzteil ein Problem haben könnte ne Sicherung einzubauen:

$0.86 20Stk. 8A Sicherungen
https://www.aliexpress.com/item/20pcs-lot-Fast-Quick-Blow-Glass-Tube-Fuse-5x20mm-250V-5A-F5AL250V/32621878368.html

$1.50 10Stk. Sicherungshalter mit Deckel
https://www.aliexpress.com/item/10pcs-Panel-Mount-PCB-for-5-20mm-Glass-Tube-Fuse-Holder-Case-Cover-5x20mm-Casing-Mount/32863565504.html