TapHome

Shelly Plus i4

Packet Parser → MQTT
Eingereicht von
Zuletzt aktualisiert: 03. 2026
Shelly Plus i4

Der Shelly Plus i4 ist ein kompaktes WLAN-4-Kanal-Digitaleingangsmodul. Er verfügt über keine Relais oder Ausgänge — er funktioniert ausschließlich als Eingangsgerät, das Tastendruck und Schalterzustände an vier unabhängigen Klemmen (SW1–SW4) erkennt. Er passt hinter einen Standard-Wandschalter (37 x 42 x 16 mm) und wird mit 110–240 VAC versorgt. TapHome kommuniziert mit dem Gerät über MQTT mittels Gen2+ JSON-RPC 2.0-Benachrichtigungen im lokalen Netzwerk — keine Cloud-Verbindung erforderlich.

Jeder der vier Eingänge kann unabhängig als Tastermodus (erkennt Einzeldruck, Doppeldruck, langen Druck) oder Schaltermodus (erkennt offen/geschlossen-Zustand) konfiguriert werden. Die TapHome-Vorlage erstellt für jeden Eingang sowohl ein Taster- als auch ein Reedkontakt-Gerät — Sie verwenden dasjenige, das der Konfiguration des Eingangs in der Shelly-Weboberfläche entspricht.

Konfiguration

MQTT-Broker-Einrichtung

Der Shelly Plus i4 kommuniziert über MQTT. Sie benötigen einen MQTT-Broker in Ihrem Netzwerk (z. B. Mosquitto). Gehen Sie in der Shelly-Weboberfläche (http://{geraete-ip}) zu Einstellungen → MQTT und aktivieren Sie MQTT, indem Sie die IP-Adresse und den Port des Brokers eingeben.

Parameter des Vorlagenimports

Beim Vorlagenimport in TapHome geben Sie drei Parameter ein:

ParameterBeschreibungBeispiel
MQTT Broker IPIP-Adresse des MQTT-Brokers192.168.1.10
MQTT Broker PortBroker-Port (Standard 1883)1883
Shelly IDMQTT-Client-ID aus der Shelly-Weboberfläche → Einstellungen → MQTTshellyplusi4-xxxxxxxxxxxx
Eingangsmodus-Konfiguration

Konfigurieren Sie nach dem Vorlagenimport jeden Eingang in der Shelly-Weboberfläche (http://{geraete-ip}) → Eingänge:

  • Tastermodus — für Impulstaster. Verwenden Sie das entsprechende Gerät Taster 1–4 in TapHome.
  • Schaltermodus — für Kippschalter oder Reedkontakte. Verwenden Sie das entsprechende Gerät Schalter 1–4 in TapHome.

Jeder physische Eingang kann gleichzeitig nur einen Typ haben. Wenn ein Eingang auf Schaltermodus eingestellt ist, TapHome aber ein Taster-Ereignis empfängt (oder umgekehrt), meldet das Listener-Skript einen Fehler wegen der Nichtübereinstimmung.

Gerätefunktionen

Tastendruck-Erkennung (Taster 1–4)

Vier Tastergeräte lauschen auf MQTT-NotifyEvent-Nachrichten im Topic {device_id}/events/rpc. Jeder Taster erkennt drei Druckarten und ordnet sie numerischen Werten zu:

DruckartWert
Einzeldruck1
Langer Druck2
Doppeldruck3

Die Tastergeräte sind schreibgeschützt — sie melden das zuletzt erkannte Ereignis. Jeder Taster lauscht auf Ereignisse seiner entsprechenden Eingangskomponente (input:0 bis input:3).

Schalter-/Reedkontakt-Erkennung (Schalter 1–4)

Vier Reedkontakt-Geräte lauschen auf MQTT-NotifyStatus-Nachrichten. Jeder Schalter liest den binären Zustand seines entsprechenden Eingangs:

ZustandWert
Geschlossen (aktiv)1
Offen (inaktiv)0

Die Schaltergeräte sind schreibgeschützt mit einem Abfrageintervall von 2,5 Sekunden. Sie eignen sich für Kippschalter, magnetische Reedkontakte oder jeden beliebigen binären Ein/Aus-Sensor an den Eingangsklemmen.

Weitere Funktionen

Die Shelly Plus i4 API unterstützt auch Dreifachdruck-Erkennung, rohe Button-Down/Button-Up-Ereignisse und eine programmatische Input.Trigger-Methode (einzigartig für i4-Geräte), die Ereignisse ohne physischen Eingang auslösen kann. Systemdiagnose (Betriebszeit, MAC, WiFi-RSSI) ist über HTTP-RPC verfügbar, wird aber in dieser reinen MQTT-Vorlage nicht bereitgestellt. Diese Funktionen können in einem zukünftigen Vorlagenupdate hinzugefügt werden.

Fehlerbehebung

Tastendruck wird nicht erkannt
  1. Überprüfen Sie, dass der Eingang im Tastermodus in der Shelly-Weboberfläche → Eingänge konfiguriert ist
  2. Prüfen Sie, dass TapHome mit dem MQTT-Broker verbunden ist und die Shelly-ID mit der MQTT-Client-ID des Geräts übereinstimmt
  3. Wenn TapHome den Fehler “Device is set as switch” anzeigt, ist der Eingang im Schaltermodus — ändern Sie ihn in der Shelly-Weboberfläche auf Tastermodus oder verwenden Sie stattdessen das Gerät Schalter 1–4
Schalterzustand aktualisiert sich nicht
  1. Überprüfen Sie, dass der Eingang im Schaltermodus in der Shelly-Weboberfläche → Eingänge konfiguriert ist
  2. Wenn TapHome den Fehler “Device is set as button” anzeigt, ist der Eingang im Tastermodus — ändern Sie ihn auf Schaltermodus oder verwenden Sie stattdessen das Gerät Taster 1–4
  3. Betätigen Sie den physischen Schalter und prüfen Sie den MQTT-Broker auf NotifyStatus-Nachrichten im Topic shellyplusi4-{id}/events/rpc
Gerät nicht erreichbar
  1. Überprüfen Sie, dass der Shelly mit dem WLAN verbunden ist — die blaue LED sollte dauerhaft leuchten
  2. Bestätigen Sie, dass MQTT in der Shelly-Weboberfläche → Einstellungen → MQTT aktiviert ist und die Broker-Adresse korrekt ist
  3. Versuchen Sie den mDNS-Hostnamen (shellyplusi4-AABBCCDDEE.local) für den Zugriff auf die Shelly-Weboberfläche
  4. Prüfen Sie, dass der MQTT-Broker läuft und sowohl von TapHome Core als auch vom Shelly-Gerät erreichbar ist

Der Shelly Plus i4 hat ein MQTT-Ratelimit von 80 Benachrichtigungen pro 60-Sekunden-Fenster. Schnelles wiederholtes Drücken kann dieses Limit überschreiten und dazu führen, dass einige Ereignisse verloren gehen. Dies ist eine Firmware-Einschränkung.

Installation in TapHome

Voraussetzungen

  • Shelly-Gerät mit Wi-Fi verbunden (siehe HTTP-Verbindungsanleitung, falls noch nicht geschehen)
  • MQTT-Broker in Ihrem lokalen Netzwerk aktiv (z. B. Mosquitto, Home Assistant oder der integrierte TapHome-Broker)
  • TapHome CCU im selben Netzwerk wie der Broker

Auf Gen1-Geräten deaktiviert das Aktivieren von MQTT die Shelly Cloud. Beides kann nicht gleichzeitig betrieben werden. Auf Gen2/Plus-Geräten gilt diese Einschränkung nicht.

Schritt 1 — MQTT auf dem Shelly-Gerät aktivieren

Gen1-Geräte (Shelly 1, 1PM, 2.5, EM, 3EM, Plug S, RGBW2, Dimmer, TRV…)

  1. Öffnen Sie die Shelly-Weboberfläche: http://<device-ip>/
  2. Navigieren Sie zu Internet & SecurityAdvanced — MQTT
  3. Aktivieren Sie MQTT
  4. Setzen Sie MQTT Server: <broker-ip>:<port> (z. B. 192.168.1.10:1883)
  5. Optional setzen Sie MQTT User und MQTT Password, falls Ihr Broker eine Authentifizierung erfordert
  6. Klicken Sie auf Save — das Gerät startet neu und verbindet sich mit dem Broker

Gen2 / Plus-Geräte (Shelly Plus 1, Plus 1PM, Plus 2PM, Plus Plug S, Plus H&T, Pro 3EM…)

  1. Öffnen Sie die Shelly-Weboberfläche: http://<device-ip>/
  2. Navigieren Sie zu SettingsMQTT
  3. Aktivieren Sie MQTT
  4. Setzen Sie Server: <broker-ip>:<port> (z. B. 192.168.1.10:1883)
  5. Die Client ID ist mit der Geräte-ID vorausgefüllt (z. B. shellyplus1pm-AABBCCDDEE) — belassen Sie sie so, es sei denn, Sie haben einen bestimmten Grund zur Änderung
  6. Klicken Sie auf Save und starten Sie das Gerät neu

Um zu überprüfen, ob MQTT funktioniert, verwenden Sie einen MQTT-Client (z. B. MQTT Explorer) und abonnieren Sie shellies/# (Gen1) oder <device-id>/# (Gen2). Sie sollten Statusnachrichten vom Gerät sehen.

Schritt 2 — Device ID / MQTT Client ID ermitteln

Einige Vorlagen erfordern einen Parameter Device ID oder MQTT Client ID. Dies ist die eindeutige Kennung, die in MQTT-Topics verwendet wird.

  • Gen1: auf dem Etikett als MAC-Adresse zu finden (z. B. AABBCCDDEE). Device ID = shelly<model>-<mac>, z. B. shelly1pm-AABBCCDDEE
  • Gen2/Plus: in der Shelly-Weboberfläche unter SettingsDevice InfoDevice ID zu finden, oder auf dem Geräteetikett

Schritt 3 — Konfiguration in TapHome

  1. Fügen Sie in TapHome ein neues Modul Packet Parser (MQTT) hinzu
  2. IP Address: Geben Sie die IP-Adresse des MQTT-Brokers ein (z. B. 192.168.1.10)
  3. Port: 1883 (Standard; verwenden Sie 8883 für TLS)
  4. Device ID / MQTT Client ID: Geben Sie den Wert aus Schritt 2 ein (falls von der Vorlage benötigt)
  5. Importieren Sie die Vorlage — TapHome abonniert automatisch die Geräte-Topics

Verfügbare Geräte

Shelly Plus i4 Modul
Benutzerdefinierte Variablen
ID (string)
Taste 1 Taster Nur lesen

Taster an Eingang input:0 — erkennt Einzeldruck (1), Langdruck (2), Doppeldruck (3)

numeric JSON-RPC event
Variable: Button

Taste 1

Listener
Bp := 0;
#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0
    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF method = "NotifyEvent"
        VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
        VAR component := PARSEJSON(zero, "component");
        VAR event := PARSEJSON(zero, "event");
    
        if component = "input:0"
            Bp := SWITCH(event, "single_push", Bp := 1, "double_push", Bp :=3,  "long_push", Bp := 2, Bp := 0 );
            #RETURN(Bp);
        END
    elseif method = "NotifyStatus"
        IF( INDEXOF(params, "input:0") > -1, ADDERROR("Device is set as switch"));
    END
END
Taste 2 Taster Nur lesen

Taster an Eingang input:1 — erkennt Einzeldruck (1), Langdruck (2), Doppeldruck (3)

numeric JSON-RPC event

Taste 2

Listener
Bp := 0;

#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF method = "NotifyEvent"
        VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
        VAR component := PARSEJSON(zero, "component");
        VAR event := PARSEJSON(zero, "event");
    
        if component = "input:1"
            Bp := SWITCH(event, "single_push", Bp := 1, "double_push", Bp :=3,  "long_push", Bp := 2, Bp := 0 );
            #RETURN(Bp);
        END
    elseif method = "NotifyStatus"
        IF( INDEXOF(params, "input:0") > -1, ADDERROR("Device is set as switch"));
    END
END
Taste 3 Taster Nur lesen

Taster an Eingang input:2 — erkennt Einzeldruck (1), Langdruck (2), Doppeldruck (3)

numeric JSON-RPC event

Taste 3

Listener
Bp := 0;

#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF method = "NotifyEvent"
        VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
        VAR component := PARSEJSON(zero, "component");
        VAR event := PARSEJSON(zero, "event");
    
        if component = "input:2"
            Bp := SWITCH(event, "single_push", Bp := 1, "double_push", Bp :=3,  "long_push", Bp := 2, Bp := 0 );
            #RETURN(Bp);
        END
    elseif method = "NotifyStatus"
        IF( INDEXOF(params, "input:0") > -1, ADDERROR("Device is set as switch"));
    END
END
Taste 4 Taster Nur lesen

Taster an Eingang input:3 — erkennt Einzeldruck (1), Langdruck (2), Doppeldruck (3)

numeric JSON-RPC event

Taste 4

Listener
Bp := 0;

#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF method = "NotifyEvent"
        VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
        VAR component := PARSEJSON(zero, "component");
        VAR event := PARSEJSON(zero, "event");
    
        if component = "input:3"
            Bp := SWITCH(event, "single_push", Bp := 1, "double_push", Bp :=3,  "long_push", Bp := 2, Bp := 0 );
            #RETURN(Bp);
        END
    elseif method = "NotifyStatus"
        IF( INDEXOF(params, "input:0") > -1, ADDERROR("Device is set as switch"));
    END
END
Schalter 1 Reed-Kontakt Nur lesen

Reed-Kontakt an Eingang input:0 — geschlossen (1), offen (0)

boolean JSON-RPC status

Schalter 1

Listener
#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF(method ="NotifyEvent")
    VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
    VAR component := PARSEJSON(zero, "component");
    
    if component = "input:0"
    ADDERROR("Device is set as button");
    END
    
    IF(method = "NotifyStatus")
    IF( INDEXOF(params, "input:0") > -1)
        VAR input := PARSEJSON(params, "input:0");
        SWITCH(PARSEJSON(input, "state"), true, Rc := 1, Rc := 0);
    END  
    END
END
END
Schalter 2 Reed-Kontakt Nur lesen

Reed-Kontakt an Eingang input:1 — geschlossen (1), offen (0)

boolean JSON-RPC status

Schalter 2

Listener
#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF(method ="NotifyEvent")
    VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
    VAR component := PARSEJSON(zero, "component");
    
    if component = "input:1"
    ADDERROR("Device is set as button");
    END
    
    IF(method = "NotifyStatus")
    IF( INDEXOF(params, "input:1") > -1)
    VAR input := PARSEJSON(params, "input:1");
        SWITCH(PARSEJSON(input, "state"), true, Rc := 1, Rc := 0);
    END  
    END
END
END
Schalter 3 Reed-Kontakt Nur lesen

Reed-Kontakt an Eingang input:2 — geschlossen (1), offen (0)

boolean JSON-RPC status

Schalter 3

Listener
#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF(method ="NotifyEvent")
    VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
    VAR component := PARSEJSON(zero, "component");
    
    if component = "input:2"
    ADDERROR("Device is set as button");
    END
    
    IF(method = "NotifyStatus")
    IF( INDEXOF(params, "input:2") > -1)
    VAR input := PARSEJSON(params, "input:2");
        SWITCH(PARSEJSON(input, "state"), true, Rc := 1, Rc := 0);
    END  
    END
END
END
Schalter 4 Reed-Kontakt Nur lesen

Reed-Kontakt an Eingang input:3 — geschlossen (1), offen (0)

boolean JSON-RPC status

Schalter 4

Listener
#index of shelly
if INDEXOF(RECEIVEDMSG.TOPIC, ID) = 0

    VAR method := PARSEJSON(RECEIVEDMSG.PAYLOAD, "method", true);
    VAR params := PARSEJSON(RECEIVEDMSG.PAYLOAD, "params", true);

    IF(method ="NotifyEvent")
    VAR zero := PARSEJSON(PARSEJSON(params, "events"),"[0]");
    VAR component := PARSEJSON(zero, "component");
    
    if component = "input:3"
    ADDERROR("Device is set as button");
    END
    
    IF(method = "NotifyStatus")
    IF( INDEXOF(params, "input:3") > -1)
    VAR input := PARSEJSON(params, "input:3");
        SWITCH(PARSEJSON(input, "state"), true, Rc := 1, Rc := 0);
    END  
    END
END
END
Verbindung: Packet Parser → MQTT
Mögliche Verbesserungen (7)
  • Triple Push Detection — Input component supports triple_push events but template only maps single_push, double_push, long_push
  • Button Press/Release Events — Raw button-down and button-up events available via MQTT but not captured by template
  • Programmatic Input Trigger — Input.Trigger method allows emitting events without physical input — unique to i4/i4 Gen3 devices
  • System Status (uptime, RAM, MAC, time) — Available via HTTP /rpc/Sys.GetStatus but template uses MQTT only — no HTTP polling configured
  • WiFi Status (SSID, IP, RSSI) — Available via HTTP /rpc/WiFi.GetStatus but template uses MQTT only
  • Analog Input Mode — Input component supports analog mode (0-100%) but template does not implement it — Plus i4 hardware supports digital inputs only
  • Counter/Pulse Input Mode — Input component supports pulse counting mode but template does not implement it

Quellen