Shelley Plus 1 kommuniziert mit eine ESP32

1. Grundidee

Der Shelly Plus 1 kann über seine lokale Web-API angesprochen werden. Für einfache Projekte ist die Kommunikation über HTTP/RPC am übersichtlichsten.

ESP32 ----- WLAN ----- Router ----- WLAN ----- Shelly Plus 1 IP: 192.168.178.55

Ein einfacher HTTP-Aufruf zum Einschalten des Relais sieht so aus:

http://192.168.178.55/rpc/Switch.Set?id=0&on=true
Merke: Beim Shelly Plus 1 ist das Relais normalerweise switch:0. Die wichtigsten RPC-Befehle sind Switch.Set, Switch.Toggle, Switch.GetStatus und Shelly.GetStatus.

2. Browser-Test vor dem Programmieren

Bevor der ESP32 ins Spiel kommt, sollten die Befehle im Browser getestet werden. Das vermeidet viele kleine Fehler mit großer Wirkung.

http://SHELLY-IP/rpc/Shelly.GetStatus
http://SHELLY-IP/rpc/Switch.Set?id=0&on=true
http://SHELLY-IP/rpc/Switch.Set?id=0&on=false
http://SHELLY-IP/rpc/Switch.Toggle?id=0
http://SHELLY-IP/rpc/Switch.GetStatus?id=0

3. ESP32 schaltet Shelly ein

import network
import urequests
import time

WIFI_SSID = "DEIN_WLAN"
WIFI_PASS = "DEIN_PASSWORT"

SHELLY_IP = "192.168.178.55"

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASS)

while not wlan.isconnected():
    print("Verbinde mit WLAN...")
    time.sleep(0.5)

print("Verbunden:", wlan.ifconfig())

url = "http://{}/rpc/Switch.Set?id=0&on=true".format(SHELLY_IP)

response = urequests.get(url)
print(response.text)
response.close()

4. ESP32 schaltet Shelly aus

import urequests

SHELLY_IP = "192.168.178.55"

url = "http://{}/rpc/Switch.Set?id=0&on=false".format(SHELLY_IP)

response = urequests.get(url)
print(response.text)
response.close()

5. Shelly umschalten - Toggle

Dieser Befehl ist besonders praktisch für Taster: Jeder Aufruf wechselt den Schaltzustand.

import urequests

SHELLY_IP = "192.168.178.55"

url = "http://{}/rpc/Switch.Toggle?id=0".format(SHELLY_IP)

response = urequests.get(url)
print(response.text)
response.close()

6. Zustand des Shelly abfragen

Mit Shelly.GetStatus kann man den Gesamtstatus des Shelly abrufen.

import urequests
import json

SHELLY_IP = "192.168.178.55"

url = "http://{}/rpc/Shelly.GetStatus".format(SHELLY_IP)

response = urequests.get(url)
data = response.json()
response.close()

print(data)

# Relaiszustand auslesen
relais_an = data["switch:0"]["output"]

print("Relais ist an:", relais_an)

Typischer Ausschnitt aus der Antwort:

{
  "switch:0": {
    "id": 0,
    "output": true
  },
  "input:0": {
    "id": 0,
    "state": false
  }
}

7. Nur Relaisstatus abfragen

import urequests

SHELLY_IP = "192.168.178.55"

url = "http://{}/rpc/Switch.GetStatus?id=0".format(SHELLY_IP)

response = urequests.get(url)
data = response.json()
response.close()

print("Antwort:", data)
print("Relais an:", data["output"])

8. ESP32-Taster schaltet Shelly

Schülerfreundliches Beispiel: Ein Taster am ESP32 löst einen HTTP-Request aus, der das Shelly-Relais umschaltet.

import network
import urequests
import time
from machine import Pin

WIFI_SSID = "DEIN_WLAN"
WIFI_PASS = "DEIN_PASSWORT"

SHELLY_IP = "192.168.178.55"

button = Pin(14, Pin.IN, Pin.PULL_UP)

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASS)

while not wlan.isconnected():
    print("Verbinde mit WLAN...")
    time.sleep(0.5)

print("ESP32 verbunden:", wlan.ifconfig())

alter_zustand = 1

while True:
    zustand = button.value()

    # Taster gedrückt: Wechsel von 1 nach 0
    if alter_zustand == 1 and zustand == 0:
        print("Taster gedrückt - Shelly wird umgeschaltet")

        try:
            url = "http://{}/rpc/Switch.Toggle?id=0".format(SHELLY_IP)
            response = urequests.get(url)
            print(response.text)
            response.close()
        except Exception as e:
            print("Fehler:", e)

        time.sleep(0.3)   # Entprellen

    alter_zustand = zustand
    time.sleep(0.05)

9. Shelly schaltet ESP32 per HTTP

Die Kommunikation kann auch umgekehrt laufen: Der Shelly ruft eine Adresse auf dem ESP32 auf.

Shelly Plus 1 ----- HTTP-Request -----> ESP32-Webserver

ESP32 als einfacher Webserver

import network
import socket
from machine import Pin
import time

WIFI_SSID = "DEIN_WLAN"
WIFI_PASS = "DEIN_PASSWORT"

led = Pin(2, Pin.OUT)

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASS)

while not wlan.isconnected():
    print("Verbinde mit WLAN...")
    time.sleep(0.5)

print("ESP32 IP:", wlan.ifconfig()[0])

addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)

print("Webserver läuft...")

while True:
    cl, addr = s.accept()
    request = cl.recv(1024).decode()
    print(request)

    if "/led/on" in request:
        led.on()
        antwort = "LED eingeschaltet"
    elif "/led/off" in request:
        led.off()
        antwort = "LED ausgeschaltet"
    else:
        antwort = "ESP32 bereit"

    cl.send("HTTP/1.1 200 OK\r\n")
    cl.send("Content-Type: text/plain\r\n")
    cl.send("Connection: close\r\n\r\n")
    cl.send(antwort)
    cl.close()

Test im Browser, wenn der ESP32 zum Beispiel die IP 192.168.178.60 hat:

http://192.168.178.60/led/on
http://192.168.178.60/led/off

Im Shelly kann dann eine Action beziehungsweise ein Webhook eingerichtet werden, der diese URL aufruft.

10. ESP32 fragt Shelly regelmäßig ab

Damit kann der ESP32 zum Beispiel mit einer LED anzeigen, ob das Shelly-Relais gerade eingeschaltet ist.

import network
import urequests
import time

WIFI_SSID = "DEIN_WLAN"
WIFI_PASS = "DEIN_PASSWORT"

SHELLY_IP = "192.168.178.55"

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASS)

while not wlan.isconnected():
    print("Verbinde...")
    time.sleep(0.5)

while True:
    try:
        url = "http://{}/rpc/Switch.GetStatus?id=0".format(SHELLY_IP)
        response = urequests.get(url)
        data = response.json()
        response.close()

        print("Shelly Relais:", data["output"])

    except Exception as e:
        print("Fehler bei Abfrage:", e)

    time.sleep(5)

11. Sicheres Einschalten mit Auto-Aus

Für Pumpen, Magnetventile oder Experimente ist ein automatisches Ausschalten sinnvoll.

import urequests

SHELLY_IP = "192.168.178.55"

url = "http://{}/rpc/Switch.Set?id=0&on=true&toggle_after=10".format(SHELLY_IP)

response = urequests.get(url)
print(response.text)
response.close()
Wichtig: Bei 230-V-Schaltungen nur mit sicherem Aufbau, geeigneten Gehäusen und klarer Trennung zwischen Niederspannung und Netzspannung arbeiten. Für Schülerprojekte empfiehlt sich zuerst ein ungefährlicher Testaufbau ohne Netzspannung.

12. Didaktische Reihenfolge für die AG

  1. Browser-Test: Shelly-IP herausfinden und RPC-Befehle im Browser testen.
  2. ESP32 sendet HTTP-Requests: ESP32 steuert den Shelly.
  3. Tasterprojekt: Taster am ESP32 schaltet Shelly-Relais.
  4. Statusabfrage: ESP32 liest den Relaiszustand aus.
  5. Rückrichtung: Shelly ruft ESP32-Webserver per HTTP auf.
  6. Sicherheitslogik: Automatisches Ausschalten mit toggle_after.

13. Merksatz

Der Shelly Plus 1 ist nicht nur ein Relais. Er ist ein kleines WLAN-Gerät mit Web-API. Der ESP32 kann diese Web-API mit HTTP-Requests benutzen.

14. Quellen und Dokumentation