Im Bereich der Hausautomatisierung sind 433 MHz Funksteckdosen kaum wegzudenken. Ebenso der ESP8266 Microcontroller. Mit diesen beiden Komponenten zusammen lässt sich eine extrem einfache und kostengünstige Methode schaffen, eine ESP8266 433MHz Funksteckdosen-Steuerung zu bauen. Da die NodeMCU Boards noch einmal für weniger Geld als bspw. ein Raspberry Pi Zero zu haben und dazu Wifi-fähig sind, bieten sie das perfekte Werkzeug.
In diesem Tutorial bauen wir für wenige Euro eine per Smartphone und Web steuerbare Oberfläche, mit der wir unsere Steckdosen daheim schalten können.
Aus einer normalen 433 MHz Funksteckdose machen wir mittels dem ESP8266 eine WLAN-Steckdose bzw. Netzwerksteckdose und das für einen Bruchteil dessen, was jene Modelle einzeln kosten würden.
Zubehör
Einige haben vielleicht noch die Funksteckdosen aus der Raspberry Pi Schaltung zuhause. Diese lassen sich super einfach mit einem ESP8266 bedienen. Falls wir (noch) keine da haben, brauchen wir lediglich folgendes Zubehör, um die Steckdosen per 433 MHz Funk über eine Weboberfläche mit jedem internetfähigen Gerät fern zu steuern:
- NodeMCU ESP8266 (z.B. als Developer Board)
- 433 MHz Funksteckdosen (kein generischer Code)
- Sender Empfänger (433MHz Sender + Empfänger RF Set)
- Breadboard
- Jumperkabel (ebay)
Im Endeffekt brauchen wir nur einen GPIO, weshalb es egal ist, welches ESP Board du nutzt. Falls du einen ESP-01 hast, solltest du dir die Verkabelung in diesem Tutorial ansehen, da dieser anders als das ESP-12 Development Board keinen Micro USB Port hat, womit wir ihn einfach per USB anschließen können.
Wer die Anwendung möglichst klein halten will, kann den ESP8266 als normale / nicht Development Board Version nehmen und per USB flashen.
Aufbau & Verkabelung der 433 MHz Funksteckdosen am NodeMCU
Beginnen wir mit den Funksteckdosen. Diese müssen einen einstellbaren Hauscode haben, welchen wir zunächst setzen. Dazu muss die Rückseite geöffnet werden und der Code eingestellt werden. Details dazu findest du in diesem Tutorial.
Der Code ist dabei in zwei Teile aufgeteilt: Zunächst der eigentliche Hauscode, sowie die Belegung innerhalb (bei mir A bis E). Achte darauf, dass nur ein Buchstabe aktiviert (oben) sein darf!
Ebenso sollte die Fernbedienung eingestellt werden. Jedoch wird hier nur der eigentliche Code, ohne Nummerierung (A-E) angegeben, da diese über die Knöpfe ausgewählt werden.
Du kannst die Steckdosen nun wieder zu schrauben und per Fernbedienung testen. Sie sollten problemlos angehen.
Die Verbindung des Sendemoduls ist recht einfach: VCC kommt an den 3.3V Pin, GND an GND und DATA an einen freien GPIO (bspw. D6 in meinem Beispiel):
Vorbereitung – ESP8266 Firmware mit 433 MHz Bibliothek laden
Wir brauchen ein Custom-Build, welches die rfswitch Bibliothek bereits enthält. Dazu rufen wir nodemcu-build.com auf und wählen zusätzlich zu den standardmäßig ausgewählten „rfswitch“ aus (ggf. noch weitere, falls wir ein anderes Projekt ebenfalls laufen lassen wollen):
Anschließend bekommst du eine Mail mit dem Build innerhalb von wenigen Minuten. Lade diesen herunter und übertrage die Firmware wie in diesem Tutorial beschrieben mit dem ESP8266 Flasher auf das NodeMCU Board.
433 MHz Codes der Funksteckdosen auslesen
Wir haben erneut zwei Möglichkeiten. Entweder wir kennen die Codes zum An- und Ausschalten bereits (z.B. aus dem Raspberry Pi Tutorial oder aufgrund der Belegung) oder wir müssen sie erst herausfinden.
Leider ist es mit der Programmiersprache Lua nicht möglich die Codes auszulesen, weshalb man dies über die Arduino IDE machen müsste. Welcher GPIO genutzt wird ist dabei egal.
Ein einfaches Beispiel (für ESP8266 sowie Arduino) findet sich in der rfswitch Bibliothek auf Github.
Meine Codes für Steckdose „A“ mit Hauscode 00011 sind bspw. folgende:
- An: 5506385 (binär 10101000000010101010001)
- Aus: 5506388 (binär 10101000000010101010100)
Für gewöhnlich haben die Codes 24Bits.
Einfache ESP8266 433MHz Funksteckdosen-Steuerung
Sobald die Codes ausgelesen wurden und wir diese für jede 433 MHz Funksteckdose gespeichert haben, können wir mit einer Zeile den RF Transmitter bedienen. Dafür ist ein solcher Aufruf nötig:
1 |
rfswitch.send(protocol_id, pulse_length, repeat, pin, value, length) |
Die Parameter haben folgende Bedeutung:
- protocol_id: Wert zwischen 1 und 6, normalerweise 1.
- pulse_length: Pulslänge im Millisekunden, zwischen 100 und 650.
- repeat: Anzahl an Wiederholungen (sollte nicht zu groß sein)
- pin: I/O Pin (Pin 6 = GPIO12)
- value: Dezimalzahl, die gesendet werden soll (vorher ausgelesen).
- length: Bitlänge (3Byte = 24 Bit)
Mit folgendem Skript würde meine Steckdose sich also anschalten lassen:
1 |
rfswitch.send(1, 300, 5, 6, 5506385, 24) |
ESP8266 Weboberfläche für 433 MHz Funksteckdosen
Nun möchten wir ja auch einfach per Smartphone, Tablet und PC die Funksteckdosen an- und ausschalten. Deshalb entwerfen wir nun noch eine entsprechende GUI, welche dann über die lokale IP Adresse des ESP8266 über einen Browser aufrufbar ist.
Öffne deinen ESPlorer und erstelle eine neue Datei (remotecontrol433mhz.lua). Diese bekommt folgenden Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
-- Your Wifi connection data local SSID = "xxxxxxxxxxxxxxx" local SSID_PASSWORD = "xxxxxxxxxxxxxxx" SENDER_PIN = 6 OUTLETS = { {name="Test Steckdose 1", codeON=5506385, codeOFF=5506388, status="OFF"} --, --{name="Test Steckdose 2", codeON=5506373, codeOFF=5506376, status="OFF"}, --etc } function wait_for_wifi_conn ( ) tmr.alarm (1, 1000, 1, function ( ) if wifi.sta.getip ( ) == nil then print ("Waiting for Wifi connection") else tmr.stop (1) print ("ESP8266 mode is: " .. wifi.getmode ( )) print ("The module MAC address is: " .. wifi.ap.getmac ( )) print ("Config done, IP is " .. wifi.sta.getip ( )) end end) end function setOutlet(index, status) print(index,OUTLETS[index]) if OUTLETS[index] ~= nil then print("ok") if status == true then rfswitch.send(1, 300, 5, SENDER_PIN, OUTLETS[index]["codeON"], 24) OUTLETS[index]["status"] = "ON" elseif status == false then rfswitch.send(1, 300, 5, SENDER_PIN, OUTLETS[index]["codeOFF"], 24) OUTLETS[index]["status"] = "OFF" end end end function connect (conn, data) local data = "" local function outletHTML(index, outlet) local output = "" output = output .. "<div class='col-sm-4 col-xs-12'><h4 class ='text-left'>" .. outlet["name"] output = output .. "<span class='badge'>" .. outlet["status"] .. "</span></h4></div>" output = output .. "<div class='col-sm-4 col-xs-6'><form action='/' method='POST'><button type='button submit' name='" .. index .. "' value='1' class='btn btn-success btn-lg'>ON</button></form></div>" output = output .. "<div class='col-sm-4 col-xs-6'><form action='/' method='POST'><button type='button submit' name='" .. index .. "' value='0' class='btn btn-danger btn-lg'>OFF</button></form></div>" return output end conn:on ("receive", function (cn, req_data) if req_data:find('^POST / HTTP/1.1') ~= nil then -- POST data --print(req_data) local l = req_data:match(".*()\r\n") if l < string.len(req_data) then local d = string.sub(req_data, l) local nr, val = string.match(d, "(%d+)=(%d+)") nr = tonumber(nr) if nr ~= nil then if val == "0" then setOutlet(nr, false) elseif val == "1" then setOutlet(nr, true) end end end end data = data .. "<html><head><meta name='viewport' content='width=device-width, initial-scale=1'>" data = data .. "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'></script>" data = data .. "<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>" data = data .. "<title>ESP8266 433MHz Funksteckdosen Steuerung</title></head><body>" data = data .. "<div class='container'>" data = data .. "<div class='row'>" for i, outlet in pairs(OUTLETS) do data = data .. outletHTML(i, outlet) end data = data .. "</div>" data = data .. "</div>" data = data .. "</body></html>" --cn:send("HTTP/1.1 200 OK\r\nServer: NodeLuau\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n") cn:send(data) -- Close the connection for the request cn:on("sent",function(cn) cn:close() end) end) end -- Configure the ESP as a station (client) wifi.setmode(wifi.STATION) --wifi.sta.config(SSID, SSID_PASSWORD) wifi.sta.config {ssid=SSID, pwd=SSID_PASSWORD} wifi.sta.autoconnect(1) -- Hang out until we get a wifi connection before the httpd server is started. wait_for_wifi_conn() -- Create the httpd server svr = net.createServer(net.TCP, 30) -- Server listening on port 80, call connect function if a request is received svr:listen (80, connect) |
Zunächst müssen die WLAN Daten eingetragen werden. Ebenfalls musst du für jede zu steuernde Steckdose einen Eintrag bereit stellen. Dieser sollte neben dem Namen auch die ausgelesenen Codes für das An- und Ausschalten in dezimaler Schreibweise enthalten. Hast du mehrere Steckdosen, müssen die Einträge jeweils mit Komma getrennt werden (hinter dem letzten Eintrag kommt jedoch kein Komma!).
Hast du alles angepasst, kannst du die Datei bereits auf den NodeMCU übertragen und ausführen.
Zu guter letzt erstellen wir noch eine „init.lua“, die nichts weiter tut, als unser vorher erstelltes Skript aufzurufen. Dadurch ist gesichert, dass der ESP8266 Server auch nach einem Neustart noch ausgeführt und erreichbar ist:
1 |
dofile("remotecontrol433mhz.lua"); |
Nach dem übertragen kannst du den ESP8266 neu starten und solltest gleich die IP Adresse im rechten Fenster des ESPlorer angezeigt bekommen. In meinem Fall ist dies 192.168.1.53.
Öffnest du nun in deinem Heimnetzwerk einen beliebigen Browser (Smartphone, Tablet, PC) und gibst diese IP als URL ein, erscheint ein solches Layout:
Drücken der entsprechenden Buttons sendet die eingestellten Codes und schaltet die Steckdosen, sofern sie sich im Umkreis befinden. Der Status (AN/AUS) könnte theoretisch auch in Dateien gespeichert werden und somit auch erhalten bleiben, sofern der ESP8266 neugestartet wird. Ansonsten ist er initial immer auf „Aus“. Dazu muss allerdings noch gesagt werden, dass ggf. Statusänderungen per Funkfernbedienung nicht erfasst werden, sondern nur jene über das ESP8266 Webinterface / GUI.
PS: Die Bootstrap Javascript und CSS Dateien werden aus dem Internet geladen. Diejenigen die ein komplett lokales System aufbauen möchten, müssten eben jene beiden Dateien lokal speichern und daher laden.
PPS: Sofern du die Funksteckdosen auch von außerhalb deines Netzwerks nutzen willst (wovon ich aber abrate, solange nicht entsprechende Sicherheitsmaßnahmen getroffen wurden), brauchst du einen dDNS Service wie NoIP oder dynDNS. Moderne Router wie die FRITZ!Box unterstützen diese Services.
17 Kommentare
Klingt gut, obschon ich nur Pi Erfahrung habe und es mir zuerst schwer fiel, zu erkennen um was es ging:
per WLAN und Browser 433 Mhz Steckdosen schalten
Ich habe noch eine Dose über, mit der kann ich es versuchen, denn 3 x 433Mhz Funksender + Empfänger Sets hab ich auch noch, nur das arduino Teil fehlt. So komm ich wohl doch noch an arduino Erfahrung.
Danke schon mal
Hallo Wolf,
der NodeMCU ist kein Arduino.
Es ist ein eigenes opensource WLAN Entwicklungsboard.
Es ist Leistungsstärker und hat bereits WLAN integriert.
Hi,
danke für das super Tutorial! Habe es ausprobiert und nach kleineren Schwierigkeiten klappt es jetzt, wie es soll. Vielleicht spare ich dem ein oder anderen Zeit: Die Daten zur SSID und dem zugehörigen Passwort müssen im remotecontrol433mhz.lua script nur ganz oben eingetragen werden. Ich hatte sie zuerst auch noch weiter unten im script eingetragen. Falsch verstanden, viele Fehlermeldungen.
Grüße aus Münster!
Hallo Felix,
lässt sich die Webseite auch mit einem Passwort sichern?
Das wäre sicher für einige, auch für mich, sehr interessant.
Du könntest es einfach mit einer .htacces und .htpasswd probieren.
Hmm, zwei Fragen:
1. Wie komme ich ohne Empfänger an die Codes für Brennenstuhlsteckdosen? Für andere Sprachen/Systeme scheint es ja einfach Libarys zu geben, in die man nur den Hauscode und den Steckdosenbuchstaben über gibt. Es muss also doch irgendwo Tabellen geben oder Umrechnungsanleitungen oder?
2. Wie könnte man System erweitern, dass man die Steckdosen auch über Zeit steuern kann? Also eine Kombination aus beidem. Gerade jetzt, wo die Weihnachtszeit näher kommt, wäre das für die zahlreichen Licherterketten und Lichtbögen echte klasse, wenn man als Grundgerüst eine Zeitschaltung hätte und die dann bequem variieren kann.
1. Kann gut sein, dass es da Tabellen gibt, aber mir sind bisher keine bekannt.
2. Du meinst quasi über einen Cronjob? Beim Raspberry Pi ist das sehr einfach, beim NodeMCU müsstest du immer wieder warten und die Zeit abfragen – falls die Bedingung(en) erfüllt sind an bzw. ausschalten.
Ob man das über einen Cronjob löst oder anders ist ja eignetlich egal. Es reicht ja notfalls eine Schleife, in der kontrolliert wird, ob zu dieser Zeit die Steckdose an sein sollte oder nicht. Und die kontrolliert, ob die Steckdose schon dem gewünschten Zustand entspricht und bei Bedarf den Funkcode senden. Und sie muss kontrollieren, ob die Steckdose in dem Schaltzeitraum schon manuell geschaltet wurde, dann wird für diesen Zeitschaltraum die Automatik ignoriert.
Ehrlich gesagt habe ich keine Ahnung, wie man das programmiert. Bücher zum Lernen von Lua habe ich nirgendwo gefunden. Gibts da nichts?
Ja im Prinzip stimmt das, bis auf, dass du den Status nicht abfragen kannst. Du kannst lediglich die ganze Zeit alle Codes „mithören“. Wurde ein manueller Code zum An/Ausschalten erkannt, setzt du den Status (inkl. Zeit etc).
Bzgl. Lua gibt es schon einige Bücher, aber überwiegend im Englischen. Ansonsten hilft evtl noch die Lua Website.
Hallo!
Kann es sein, dass es eine Grenze bei 5 Steckdosen gibt? Wenn ich noch eine sechste mit dem script steuern möchte, gibt es eine Fehlermeldung („out of memory“). Reicht dafür der Arbeitsspeicher des ESP8266 nicht mehr aus? Gibt es da einen Trick, damit man noch mehr Steckdosen steuern kann?
Hallo,
ich würde gern die Steckdosen über ein http get/push (von openhab) ein und ausschalten, also ganz ohne WebGUI. Ist das auch möglich?
Das lua script müsste dann ja kleiner werden. Im get könnte man dann auch die codes mit übergeben dann ist man flexibler wenn neue Steckdosen hinzukommen.
Ist möglich und ein Tutorial zu OpenHAB im Bezug darauf kommt bald 🙂
Hallo Felix,
vielen Dank für das Tutorial, funktioniert wunderbar. Ich bin beim Experimentieren ebenfalls auf die maximale Anzahl von 5 Geräten gestoßen, worin liegt die Begrenzung?
Grüsse
Jeff
Hallo Felix,
bei mir läuft die Seite nur wenn ich Sie mit ESPlorer an den MCU send. Wenn ich die
remotecontrol433mhz.lua auf dem MCU speichere und mit init.lua nach neustert aufrufen lasse,
wird die Web Seite nicht aufgebaut.
Gruß Odinear
Hallo Felix!
Mal wieder ein Super Tutorial! Vielen Dank dafür!
Ich möchte etwas ganz ähnliches umsetzen, jedoch mit einer webGUI, über die ich hinterlegte IR-Commands senden kann. Mein Traum wäre es eine webGUI mit Senderlogos zu haben, die ich anklicken kann und daraufhin auf den jeweiligen Sender auf dem Fernseher umgeschaltet wird.
Es bereitet mir allerdings schon Schwierigkeiten, dass es bei nodemcu-build.com keine IR-Bibliothek zum Einbinden gibt. Ist das vielleicht schon in einem anderen Modul inkludiert? Online finde ich irgendwie auch nix, was mir hilft. Vielleicht auch, weil ich falsch suche 😀
Bin mit Python und raspberry mittlerweile ganz fit, allerdings bei Arfuino/NodeMCU noch blutiger Anfänger.
Hallo zusammen,
wenn ich die remotecontrol433mhz.lua aufrufe bekomme ich diese Fehlermeldung:
> dofile(‚remotecontrol433mhz.lua‘)
Lua error: remotecontrol433mhz.lua:13: attempt to call field ‚alarm‘ (a nil value)
stack traceback:
remotecontrol433mhz.lua:13: in function ‚wait_for_wifi_conn‘
remotecontrol433mhz.lua:102: in main chunk
[C]: in function ‚dofile‘
stdin:1: in main chunk
[C]: ?
[C]: ?
Der ESP meldet sich (trotzdem ?) im Heimnetz an (zumindest taucht er in der fritz.box auf) aber nach Eingabe der IP bekomme ich nur „Seiten-Ladefehler“.
Was mache ich falsch ?!
Hallo zusammen,
ist es möglich die über den ESP8266 empfangenen 433MHz-Signale über MQTT an einen Raspberry PI weiterzuleiten?
Würde mich über jede Idee und Tipp freuen. DANKE!!