TapHome

Shelly Motion 2

Packet Parser → MQTT
Eingereicht von
Zuletzt aktualisiert: 03. 2026
Shelly Motion 2

Der Shelly Motion 2 (SHMOS-02) ist ein batteriebetriebener (Li-ion 6500 mAh, über USB-C aufladbar) Wi-Fi PIR-Bewegungssensor. TapHome kommuniziert mit dem Gerät über MQTT — das empfohlene Protokoll für batteriebetriebene Shelly-Geräte, da der Sensor die meiste Zeit schläft und Daten nur bei Aufwachereignissen veröffentlicht (Bewegungserkennung oder periodischer Timer).

Im Gegensatz zu Relais-basierten Gen1 Shelly-Geräten, die individuelle Zustandstopics veröffentlichen, veröffentlicht der Motion 2 seinen vollständigen Status über einen einzelnen /info JSON-Payload beim Aufwachen. Das TapHome-Listener-Skript parst dieses JSON, um Bewegungsstatus, Helligkeit, Temperatur, Batteriestand und Diagnoseattribute zu extrahieren.

Die Vorlage unterstützt bis zu 5 Shelly Motion 2 Sensoren pro Modul. Jede Sensorinstanz wird durch eine Custom-Variable sensorN_topic unterschieden, die auf die MQTT Client ID des Geräts verweist.

Konfiguration

Device ID

Jeder Shelly Motion 2 hat eine eindeutige MQTT Device ID im Format shellymotion2-<MAC>, wobei <MAC> die vollständige 12-stellige MAC-Adresse in hexadezimaler Großschreibung ist (z.B. shellymotion2-AABBCCDDEEFF).

Die Device ID finden Sie:

  • Auf dem Gerätelabel (MAC-Adresse)
  • In der Shelly Web-UI: SettingsDevice Info
  • Über API: GET http://<device-ip>/settings → Feld device.hostname
Vorlageneinrichtung

Nach dem Import der Vorlage in TapHome:

  1. Öffnen Sie das Modul Shelly Motion 2 MQTT
  2. Setzen Sie die MQTT Broker IP und den Port (Standard 1883)
  3. Setzen Sie für jede Sensorinstanz die Custom-Variable sensorN_topic auf die Device ID des entsprechenden Shelly Motion 2 (z.B. shellymotion2-AABBCCDDEEFF)

Das Modul abonniert shellies/# und die Listener-Skripte filtern Nachrichten nach dem konfigurierten Topic-Präfix.

Konfigurieren Sie nur die Sensorslots, die Sie tatsächlich verwenden. Nicht konfigurierte Slots (mit dem Standardwert shellymotion2-deviceid) zeigen eine Fehlermeldung an, die zur Einstellung des korrekten Topics auffordert.

Bewegungssensor-Einstellungen

Der Shelly Motion 2 hat mehrere konfigurierbare Parameter, die das Erkennungsverhalten beeinflussen. Diese werden direkt am Gerät über seine Web-Oberfläche (http://<device-ip>/) konfiguriert, nicht über TapHome:

ParameterBereichBeschreibung
Empfindlichkeit1–256Empfindlichkeit der Bewegungserkennung (niedriger = empfindlicher)
Blindzeit1–1440 minMinuten, in denen Bewegung nach einer Erkennung ignoriert wird
Impulszahl1–4Aufeinanderfolgende Bewegungen zur Bestätigung
BetriebsmodusANY / DARK / TWILIGHT / BRIGHTWann die Erkennung basierend auf Umgebungslicht aktiv ist
Schlafzeit0–86400 sPeriodisches Aufwachintervall in Sekunden

Kürzere Schlafzeiten erhöhen die Datenaktualität, reduzieren aber die Batterielebensdauer. Das Standard-Aufwachintervall ist für die meisten Anwendungsfälle ausreichend. Bewegungsereignisse lösen immer ein sofortiges Aufwachen aus, unabhängig vom Schlaftimer.

Gerätefähigkeiten

Bewegungserkennung

Jede Sensorinstanz wird als Reed-Contact-Gerät mit „Security"-Fähigkeit in TapHome abgebildet. Der Bewegungsstatus wird aus dem Topic shellies/<id>/info geparst — konkret das Feld $.sensor.motion im JSON-Payload:

  • trueAlarm (Bewegung erkannt)
  • falseOK (keine Bewegung)

Der Sensor wacht auf und veröffentlicht seinen Status bei Bewegungserkennung (abhängig von Empfindlichkeit, Blindzeit und Impulszahl) sowie während periodischer Aufwachintervalle.

Serviceattribute

Jede Sensorinstanz stellt 14 Serviceattribute auf Geräteebene bereit, alle geparst aus dem /info JSON-Payload:

AttributQuellfeldBeschreibung
IP-Adresse$.wifi_sta.ipWi-Fi IP-Adresse des Sensors
MAC-Adresse$.macHardware-MAC-Adresse
Batterie$.bat.voltage, $.bat.valueBatteriespannung und Prozentsatz (z.B. 3,83V (97%))
Signal$.wifi_sta.rssiWi-Fi Signalstärke in dB
Cloud aktiviert$.cloud.enabledOb Shelly Cloud aktiviert ist
Cloud verbunden$.cloud.connectedOb das Gerät mit Shelly Cloud verbunden ist
Gerätezeit$.timeAktuelle Zeit auf dem Gerät
Helligkeit$.lux.valueUmgebungslichtniveau in Lux
Temperatur$.tmp.value, $.tmp.unitsInternes Temperaturmesswert
Betriebszeit$.uptimeZeit seit dem letzten Neustart
FW-Version$.fw_info.fwAktuelle Firmwareversion
FW-Update$.update.has_updateOb ein Firmware-Update verfügbar ist
Freier RAM$.ram_total, $.ram_freeVerfügbarer Arbeitsspeicher
Freier FS-Speicher$.fs_size, $.fs_freeVerfügbarer Dateisystemspeicher

Eine Warnung bei niedrigem Batteriestand wird automatisch ausgelöst, wenn der Batteriestand unter 20 % fällt.

Weitere Fähigkeiten (nicht implementiert)

Der Shelly Motion 2 veröffentlicht auch Vibrations-/Manipulationserkennung ($.sensor.vibration, konfigurierbare Empfindlichkeit 0–80), Beleuchtungskategorie ($.lux.illumination — dark/twilight/bright) und USB-Ladestatus ($.charger) über den /info JSON-Payload. Ein Online/Offline-Status ist über das LWT-Topic (shellies/<id>/online) verfügbar. Diese Fähigkeiten sind im MQTT-Ausgang des Geräts verfügbar, werden aber in der aktuellen TapHome-Vorlage nicht abgebildet. Sie können in einer zukünftigen Vorlagenaktualisierung hinzugefügt werden.

Fehlerbehebung

Sensor meldet keine Daten
  1. Überprüfen Sie, dass der Shelly Motion 2 mit Wi-Fi verbunden ist und MQTT in den Geräteeinstellungen aktiviert ist
  2. Prüfen Sie, dass die Custom-Variable sensorN_topic exakt mit der Device ID übereinstimmt (z.B. shellymotion2-AABBCCDDEEFF)
  3. Verwenden Sie einen MQTT-Client (z.B. MQTT Explorer) zum Abonnieren von shellies/# und überprüfen Sie, ob der Sensor Nachrichten beim Aufwachen veröffentlicht
  4. Der Motion 2 ist batteriebetrieben und veröffentlicht Daten nur beim Aufwachen — lösen Sie ein Bewegungsereignis aus, um ein Aufwachen zu erzwingen
Bewegungsstatus aktualisiert sich nicht
  1. Überprüfen Sie, dass die PIR-Sensorlinse nicht verdeckt ist und der Sensor in der empfohlenen Höhe (1,8–2,5 m) montiert ist
  2. Wenn der Sensor kürzlich installiert wurde, überprüfen Sie die Einstellungen für Empfindlichkeit und Blindzeit in der Web-Oberfläche des Geräts — eine hohe Blindzeit bedeutet, dass der Sensor Bewegung nach jeder Erkennung länger ignoriert
  3. Passen Sie die Impulszahl an, wenn der Sensor zu selten auslöst (niedriger = weniger aufeinanderfolgende Bewegungen erforderlich)
  4. Überprüfen Sie in TapHome den Status des Reed-Contact-Geräts — 1 = Bewegung erkannt (Alarm), 0 = keine Bewegung (OK)
Batterie entlädt sich schnell
  1. Der Shelly Motion 2 verwendet einen eingebauten aufladbaren Li-ion-Akku (6500 mAh), der über USB-C geladen wird, mit typischer aktiver Lebensdauer von 12–18 Monaten
  2. Häufiges Aufwachen durch hohe Bewegungsaktivität oder kurze Schlafintervalle entladen die Batterie schneller
  3. Die Aktivierung von SSL bei MQTT reduziert die Batterielebensdauer erheblich — verwenden Sie plain MQTT (Port 1883) in einem vertrauenswürdigen lokalen Netzwerk
  4. Sorgen Sie für ein starkes Wi-Fi-Signal am Standort des Sensors — ein schwaches Signal bedeutet längere Verbindungszeiten bei jedem Aufwachen

Gen1 Shelly-Geräte unterstützen MQTT über TLS nicht ohne erhebliche Auswirkungen auf die Batterie. Die Kommunikation zwischen Sensor und MQTT-Broker ist typischerweise unverschlüsselt (plain MQTT, Port 1883). Stellen Sie sicher, dass sich der MQTT-Broker in einem vertrauenswürdigen lokalen Netzwerk befindet.

Die Aktivierung von MQTT auf Gen1 Shelly-Geräten deaktiviert die Cloud-Konnektivität. MQTT und Cloud können nicht auf demselben Gerät koexistieren.

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 Motion 2 MQTT Modul
Benutzerdefinierte Variablen
sensor1_topic (string) = shellymotion2-deviceidMQTT-Geräte-ID des Bewegungssensors 1 — Format: 'shellymotion2-DEVICEID' (in der Shelly Web-UI → Settings → Device Info)
Open http://shellyIpAddress → Settings → Device info → copy Device ID. Format: shellymotion2-<last6MAC>
sensor2_topic (string) = shellymotion2-deviceidMQTT-Geräte-ID des Bewegungssensors 2
sensor3_topic (string) = shellymotion2-deviceidMQTT-Geräte-ID des Bewegungssensors 3
sensor4_topic (string) = shellymotion2-deviceidMQTT-Geräte-ID des Bewegungssensors 4
sensor5_topic (string) = shellymotion2-deviceidMQTT-Geräte-ID des Bewegungssensors 5
Bewegungsmelder 1 Reed-Kontakt Nur lesen

PIR-Bewegungserkennung — meldet Alarm bei Bewegungserkennung, OK ohne Bewegung; parst $.sensor.motion aus /info JSON-Payload

boolean
Serviceattribute
IP-Adresse
MAC-Adresse
Batterie
Signal
Cloud aktiviert
Cloud verbunden
Gerätezeit
Beleuchtungsstärke
Temperatur
Betriebszeit
FW-Version
FW-Update
Freier RAM
Freier FS-Speicher

Bewegungsmelder 1

Listener
IF (INDEXOF(sensor1_topic, "shellymotion2-deviceid") = 0)
    ADDERROR("Set correct 'sensor1_topic' value in module variables. Topic format is 'shellymotion2-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

VAR topicPrefix := "shellies/" + sensor1_topic;

IF (INDEXOF(RECEIVEDMSG.TOPIC, topicPrefix + "/info") = 0)
    BOOL status := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.sensor.motion", 1);
    
    IF ISNULL(status)
        Rc := NaN;
    ELSE
        Rc := status;
    END
    
    VAR battery := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.bat.value");
    IF battery < 20
        ADDWARNING("Battery low (" + battery + "%)");
    END
END
Serviceattribute
IP Address
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.ip"));
END
MAC Address
IF(LENGTH(infoJson) = 0, "-", PARSEJSON(infoJson, "$.mac"));

IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.mac"));
END
Battery
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR voltage := PARSEJSON(infoJson, "$.bat.voltage");
    VAR percentage := PARSEJSON(infoJson, "$.bat.value");

    RETURN(voltage + "V (" + percentage + "%)");
END
Signal
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.rssi", 1) + "db");
END
Cloud enabled
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.enabled"));
END
Cloud connected
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.connected"));
END
Device time
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.time"));
END
Luminance
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.lux.value", 1) + "lux");
END
Temperature
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.tmp.value", 1) + PARSEJSON(infoJson, "$.tmp.units", 1));
END
Uptime
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR upTimeSeconds := PARSEJSON(infoJson, "$.uptime", 1);
    VAR days := FLOOR(upTimeSeconds/86400, 1);
    uptimeSeconds := MOD(upTimeSeconds, 86400);
    var hours := FLOOR(upTimeSeconds/3600, 1);
    uptimeSeconds := MOD(upTimeSeconds, 3600);
    var minutes := FLOOR(upTimeSeconds/60, 1);
    RETURN(days + "day(s) " + hours + "h " + minutes + "m");
END
FW version
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.fw_info.fw"));
END
FW update
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.update.has_update", 1));
END
Free RAM
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.ram_total");
    VAR free := PARSEJSON(infoJson, "$.ram_free");
    RETURN(free + "/" + total + "(B)");
END
Free FS space
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.fs_size");
    VAR free := PARSEJSON(infoJson, "$.fs_free");
    RETURN(free + "/" + total + "(B)");
END
Bewegungsmelder 2 Reed-Kontakt Nur lesen

PIR-Bewegungserkennung — meldet Alarm bei Bewegungserkennung, OK ohne Bewegung; parst $.sensor.motion aus /info JSON-Payload

boolean
Serviceattribute
IP-Adresse
MAC-Adresse
Batterie
Signal
Cloud aktiviert
Cloud verbunden
Gerätezeit
Beleuchtungsstärke
Temperatur
Betriebszeit
FW-Version
FW-Update
Freier RAM
Freier FS-Speicher

Bewegungsmelder 2

Listener
IF (INDEXOF(sensor2_topic, "shellymotion2-deviceid") = 0)
    ADDERROR("Set correct 'sensor2_topic' value in module variables. Topic format is 'shellymotion2-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

VAR topicPrefix := "shellies/" + sensor2_topic;

IF (INDEXOF(RECEIVEDMSG.TOPIC, topicPrefix + "/info") = 0)
    BOOL status := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.sensor.motion", 1);
    
    IF ISNULL(status)
        Rc := NaN;
    ELSE
        Rc := status;
    END
    
    VAR battery := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.bat.value");
    IF battery < 20
        ADDWARNING("Battery low (" + battery + "%)");
    END
END
Serviceattribute
IP Address
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.ip"));
END
MAC Address
IF(LENGTH(infoJson) = 0, "-", PARSEJSON(infoJson, "$.mac"));

IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.mac"));
END
Battery
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR voltage := PARSEJSON(infoJson, "$.bat.voltage");
    VAR percentage := PARSEJSON(infoJson, "$.bat.value");

    RETURN(voltage + "V (" + percentage + "%)");
END
Signal
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.rssi", 1) + "db");
END
Cloud enabled
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.enabled"));
END
Cloud connected
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.connected"));
END
Device time
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.time"));
END
Luminance
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.lux.value", 1) + "lux");
END
Temperature
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.tmp.value", 1) + PARSEJSON(infoJson, "$.tmp.units", 1));
END
Uptime
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR upTimeSeconds := PARSEJSON(infoJson, "$.uptime", 1);
    VAR days := FLOOR(upTimeSeconds/86400, 1);
    uptimeSeconds := MOD(upTimeSeconds, 86400);
    var hours := FLOOR(upTimeSeconds/3600, 1);
    uptimeSeconds := MOD(upTimeSeconds, 3600);
    var minutes := FLOOR(upTimeSeconds/60, 1);
    RETURN(days + "day(s) " + hours + "h " + minutes + "m");
END
FW version
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.fw_info.fw"));
END
FW update
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.update.has_update", 1));
END
Free RAM
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.ram_total");
    VAR free := PARSEJSON(infoJson, "$.ram_free");
    RETURN(free + "/" + total + "(B)");
END
Free FS space
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.fs_size");
    VAR free := PARSEJSON(infoJson, "$.fs_free");
    RETURN(free + "/" + total + "(B)");
END
Bewegungsmelder 3 Reed-Kontakt Nur lesen

PIR-Bewegungserkennung — meldet Alarm bei Bewegungserkennung, OK ohne Bewegung; parst $.sensor.motion aus /info JSON-Payload

boolean
Serviceattribute
IP-Adresse
MAC-Adresse
Batterie
Signal
Cloud aktiviert
Cloud verbunden
Gerätezeit
Beleuchtungsstärke
Temperatur
Betriebszeit
FW-Version
FW-Update
Freier RAM
Freier FS-Speicher

Bewegungsmelder 3

Listener
IF (INDEXOF(sensor3_topic, "shellymotion2-deviceid") = 0)
    ADDERROR("Set correct 'sensor3_topic' value in module variables. Topic format is 'shellymotion2-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

VAR topicPrefix := "shellies/" + sensor3_topic;

IF (INDEXOF(RECEIVEDMSG.TOPIC, topicPrefix + "/info") = 0)
    BOOL status := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.sensor.motion", 1);
    
    IF ISNULL(status)
        Rc := NaN;
    ELSE
        Rc := status;
    END
    
    VAR battery := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.bat.value");
    IF battery < 20
        ADDWARNING("Battery low (" + battery + "%)");
    END
END
Serviceattribute
IP Address
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.ip"));
END
MAC Address
IF(LENGTH(infoJson) = 0, "-", PARSEJSON(infoJson, "$.mac"));

IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.mac"));
END
Battery
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR voltage := PARSEJSON(infoJson, "$.bat.voltage");
    VAR percentage := PARSEJSON(infoJson, "$.bat.value");

    RETURN(voltage + "V (" + percentage + "%)");
END
Signal
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.rssi", 1) + "db");
END
Cloud enabled
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.enabled"));
END
Cloud connected
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.connected"));
END
Device time
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.time"));
END
Luminance
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.lux.value", 1) + "lux");
END
Temperature
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.tmp.value", 1) + PARSEJSON(infoJson, "$.tmp.units", 1));
END
Uptime
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR upTimeSeconds := PARSEJSON(infoJson, "$.uptime", 1);
    VAR days := FLOOR(upTimeSeconds/86400, 1);
    uptimeSeconds := MOD(upTimeSeconds, 86400);
    var hours := FLOOR(upTimeSeconds/3600, 1);
    uptimeSeconds := MOD(upTimeSeconds, 3600);
    var minutes := FLOOR(upTimeSeconds/60, 1);
    RETURN(days + "day(s) " + hours + "h " + minutes + "m");
END
FW version
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.fw_info.fw"));
END
FW update
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.update.has_update", 1));
END
Free RAM
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.ram_total");
    VAR free := PARSEJSON(infoJson, "$.ram_free");
    RETURN(free + "/" + total + "(B)");
END
Free FS space
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.fs_size");
    VAR free := PARSEJSON(infoJson, "$.fs_free");
    RETURN(free + "/" + total + "(B)");
END
Bewegungsmelder 4 Reed-Kontakt Nur lesen

PIR-Bewegungserkennung — meldet Alarm bei Bewegungserkennung, OK ohne Bewegung; parst $.sensor.motion aus /info JSON-Payload

boolean
Serviceattribute
IP-Adresse
MAC-Adresse
Batterie
Signal
Cloud aktiviert
Cloud verbunden
Gerätezeit
Beleuchtungsstärke
Temperatur
Betriebszeit
FW-Version
FW-Update
Freier RAM
Freier FS-Speicher

Bewegungsmelder 4

Listener
IF (INDEXOF(sensor4_topic, "shellymotion2-deviceid") = 0)
    ADDERROR("Set correct 'sensor4_topic' value in module variables. Topic format is 'shellymotion2-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

VAR topicPrefix := "shellies/" + sensor4_topic;

IF (INDEXOF(RECEIVEDMSG.TOPIC, topicPrefix + "/info") = 0)
    BOOL status := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.sensor.motion", 1);
    
    IF ISNULL(status)
        Rc := NaN;
    ELSE
        Rc := status;
    END
    
    VAR battery := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.bat.value");
    IF battery < 20
        ADDWARNING("Battery low (" + battery + "%)");
    END
END
Serviceattribute
IP Address
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.ip"));
END
MAC Address
IF(LENGTH(infoJson) = 0, "-", PARSEJSON(infoJson, "$.mac"));

IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.mac"));
END
Battery
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR voltage := PARSEJSON(infoJson, "$.bat.voltage");
    VAR percentage := PARSEJSON(infoJson, "$.bat.value");

    RETURN(voltage + "V (" + percentage + "%)");
END
Signal
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.rssi", 1) + "db");
END
Cloud enabled
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.enabled"));
END
Cloud connected
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.connected"));
END
Device time
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.time"));
END
Luminance
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.lux.value", 1) + "lux");
END
Temperature
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.tmp.value", 1) + PARSEJSON(infoJson, "$.tmp.units", 1));
END
Uptime
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR upTimeSeconds := PARSEJSON(infoJson, "$.uptime", 1);
    VAR days := FLOOR(upTimeSeconds/86400, 1);
    uptimeSeconds := MOD(upTimeSeconds, 86400);
    var hours := FLOOR(upTimeSeconds/3600, 1);
    uptimeSeconds := MOD(upTimeSeconds, 3600);
    var minutes := FLOOR(upTimeSeconds/60, 1);
    RETURN(days + "day(s) " + hours + "h " + minutes + "m");
END
FW version
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.fw_info.fw"));
END
FW update
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.update.has_update", 1));
END
Free RAM
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.ram_total");
    VAR free := PARSEJSON(infoJson, "$.ram_free");
    RETURN(free + "/" + total + "(B)");
END
Free FS space
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.fs_size");
    VAR free := PARSEJSON(infoJson, "$.fs_free");
    RETURN(free + "/" + total + "(B)");
END
Bewegungsmelder 5 Reed-Kontakt Nur lesen

PIR-Bewegungserkennung — meldet Alarm bei Bewegungserkennung, OK ohne Bewegung; parst $.sensor.motion aus /info JSON-Payload

boolean
Serviceattribute
IP-Adresse
MAC-Adresse
Batterie
Signal
Cloud aktiviert
Cloud verbunden
Gerätezeit
Beleuchtungsstärke
Temperatur
Betriebszeit
FW-Version
FW-Update
Freier RAM
Freier FS-Speicher

Bewegungsmelder 5

Listener
IF (INDEXOF(sensor5_topic, "shellymotion2-deviceid") = 0)
    ADDERROR("Set correct 'sensor5_topic' value in module variables. Topic format is 'shellymotion2-<deviceid>'. The Device ID can be found by opening url 'http://shellyIpAddress', in Settings -> Device info.");
    RETURN(-1);
END

VAR topicPrefix := "shellies/" + sensor5_topic;

IF (INDEXOF(RECEIVEDMSG.TOPIC, topicPrefix + "/info") = 0)
    BOOL status := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.sensor.motion", 1);
    
    IF ISNULL(status)
        Rc := NaN;
    ELSE
        Rc := status;
    END
    
    VAR battery := PARSEJSON(RECEIVEDMSG.PAYLOAD, "$.bat.value");
    IF battery < 20
        ADDWARNING("Battery low (" + battery + "%)");
    END
END
Serviceattribute
IP Address
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.ip"));
END
MAC Address
IF(LENGTH(infoJson) = 0, "-", PARSEJSON(infoJson, "$.mac"));

IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.mac"));
END
Battery
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR voltage := PARSEJSON(infoJson, "$.bat.voltage");
    VAR percentage := PARSEJSON(infoJson, "$.bat.value");

    RETURN(voltage + "V (" + percentage + "%)");
END
Signal
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.wifi_sta.rssi", 1) + "db");
END
Cloud enabled
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.enabled"));
END
Cloud connected
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.cloud.connected"));
END
Device time
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.time"));
END
Luminance
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.lux.value", 1) + "lux");
END
Temperature
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.tmp.value", 1) + PARSEJSON(infoJson, "$.tmp.units", 1));
END
Uptime
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR upTimeSeconds := PARSEJSON(infoJson, "$.uptime", 1);
    VAR days := FLOOR(upTimeSeconds/86400, 1);
    uptimeSeconds := MOD(upTimeSeconds, 86400);
    var hours := FLOOR(upTimeSeconds/3600, 1);
    uptimeSeconds := MOD(upTimeSeconds, 3600);
    var minutes := FLOOR(upTimeSeconds/60, 1);
    RETURN(days + "day(s) " + hours + "h " + minutes + "m");
END
FW version
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.fw_info.fw"));
END
FW update
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    RETURN(PARSEJSON(infoJson, "$.update.has_update", 1));
END
Free RAM
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.ram_total");
    VAR free := PARSEJSON(infoJson, "$.ram_free");
    RETURN(free + "/" + total + "(B)");
END
Free FS space
IF LENGTH(infoJson) = 0
    RETURN("-");
ELSE
    VAR total := PARSEJSON(infoJson, "$.fs_size");
    VAR free := PARSEJSON(infoJson, "$.fs_free");
    RETURN(free + "/" + total + "(B)");
END
Verbindung: Packet Parser → MQTT
Mögliche Verbesserungen (4)
  • Vibration / Tamper Detection — Vibration/tamper detection (bool). Available in the /info JSON but not parsed by the listener script. Configurable sensitivity 0-80.
  • Illumination Category — Light category string — dark/twilight/bright. Available in /info but only numeric lux is parsed via service attributes.
  • USB Charger Connected — Whether USB-C charger is plugged in. Available in /info JSON.
  • Connection Status — LWT topic — true on connect, false on disconnect. Could detect offline sensors.

Quellen