TapHome

Shelly Motion 2

Packet Parser → MQTT
Inviato da
Ultimo aggiornamento: 03. 2026
Shelly Motion 2

Lo Shelly Motion 2 (SHMOS-02) è un sensore di movimento PIR Wi-Fi alimentato a batteria (Li-ion 6500 mAh, ricaricabile tramite USB-C). TapHome comunica con il dispositivo tramite MQTT — il protocollo consigliato per i dispositivi Shelly alimentati a batteria, poiché il sensore è in stato di sospensione per la maggior parte del tempo e pubblica dati solo in corrispondenza degli eventi di risveglio (rilevamento movimento o timer periodico).

A differenza dei dispositivi Gen1 Shelly di tipo relè che pubblicano topic di stato individuali, il Motion 2 pubblica il proprio stato completo tramite un singolo payload JSON /info al risveglio. Lo script listener di TapHome analizza questo JSON per estrarre lo stato del movimento, la luminosità, la temperatura, il livello della batteria e gli attributi diagnostici.

Il template supporta fino a 5 sensori Shelly Motion 2 per modulo. Ogni istanza del sensore è identificata da una variabile personalizzata sensorN_topic che punta all’MQTT Client ID del dispositivo.

Configurazione

Device ID

Ogni Shelly Motion 2 ha un MQTT Device ID univoco nel formato shellymotion2-<MAC>, dove <MAC> è l’indirizzo MAC completo a 12 caratteri in formato esadecimale maiuscolo (es. shellymotion2-AABBCCDDEEFF).

Il Device ID si trova:

  • Sull’etichetta del dispositivo (indirizzo MAC)
  • Nell’interfaccia web di Shelly: SettingsDevice Info
  • Tramite API: GET http://<device-ip>/settings → campo device.hostname
Configurazione del template

Dopo aver importato il template in TapHome:

  1. Apri il modulo Shelly Motion 2 MQTT
  2. Imposta l’MQTT Broker IP e la Porta (predefinita 1883)
  3. Per ogni istanza del sensore, imposta la variabile personalizzata sensorN_topic sul Device ID dello Shelly Motion 2 corrispondente (es. shellymotion2-AABBCCDDEEFF)

Il modulo si sottoscrive a shellies/# e gli script listener filtrano i messaggi in base al prefisso del topic configurato.

Configura solo gli slot dei sensori che utilizzi effettivamente. Gli slot non configurati (con il valore predefinito shellymotion2-deviceid) mostreranno un messaggio di errore che invita a impostare il topic corretto.

Impostazioni del sensore di movimento

Lo Shelly Motion 2 dispone di diversi parametri configurabili che influenzano il comportamento di rilevamento. Questi si configurano direttamente sul dispositivo tramite la sua interfaccia web (http://<device-ip>/), non tramite TapHome:

ParametroIntervalloDescrizione
Sensibilità1–256Sensibilità del rilevamento movimento (inferiore = più sensibile)
Tempo cieco1–1440 minMinuti di ignoramento del movimento dopo un rilevamento
Conteggio impulsi1–4Movimenti consecutivi necessari per confermare il movimento
Modalità operativaANY / DARK / TWILIGHT / BRIGHTQuando il rilevamento è attivo in base alla luce ambientale
Tempo di sospensione0–86400 sIntervallo di risveglio periodico in secondi

Tempi di sospensione più brevi aumentano la freschezza dei dati ma riducono la durata della batteria. L’intervallo di risveglio predefinito è sufficiente per la maggior parte dei casi d’uso. Gli eventi di movimento attivano sempre un risveglio immediato indipendentemente dal timer di sospensione.

Funzionalità del dispositivo

Rilevamento movimento

Ogni istanza del sensore è mappata come dispositivo Reed Contact con capacità “security” in TapHome. Lo stato del movimento viene analizzato dal topic shellies/<id>/info — in particolare il campo $.sensor.motion nel payload JSON:

  • trueAllarme (movimento rilevato)
  • falseOK (nessun movimento)

Il sensore si risveglia e pubblica il proprio stato quando viene rilevato un movimento (in base alle impostazioni di sensibilità, tempo cieco e conteggio impulsi), e anche durante gli intervalli di risveglio periodici.

Attributi di servizio

Ogni istanza del sensore espone 14 attributi di servizio a livello di dispositivo, tutti analizzati dal payload JSON /info:

AttributoCampo sorgenteDescrizione
Indirizzo IP$.wifi_sta.ipIndirizzo IP Wi-Fi del sensore
Indirizzo MAC$.macIndirizzo MAC hardware
Batteria$.bat.voltage, $.bat.valueTensione e percentuale batteria (es. 3,83V (97%))
Segnale$.wifi_sta.rssiPotenza del segnale Wi-Fi in dB
Cloud abilitato$.cloud.enabledSe Shelly Cloud è abilitato
Cloud connesso$.cloud.connectedSe il dispositivo è connesso a Shelly Cloud
Ora dispositivo$.timeOra corrente sul dispositivo
Luminosità$.lux.valueLivello di luce ambientale in lux
Temperatura$.tmp.value, $.tmp.unitsLettura della temperatura interna
Tempo di attività$.uptimeTempo dall’ultimo riavvio
Versione FW$.fw_info.fwVersione firmware corrente
Aggiornamento FW$.update.has_updateSe è disponibile un aggiornamento firmware
RAM libera$.ram_total, $.ram_freeMemoria disponibile
Spazio FS libero$.fs_size, $.fs_freeSpazio di archiviazione filesystem disponibile

Un avviso di batteria scarica viene attivato automaticamente quando il livello della batteria scende sotto il 20%.

Funzionalità aggiuntive (non implementate)

Lo Shelly Motion 2 pubblica anche il rilevamento vibrazioni/manomissione ($.sensor.vibration, sensibilità configurabile 0–80), la categoria di illuminazione ($.lux.illumination — dark/twilight/bright) e lo stato del caricatore USB ($.charger) tramite il payload JSON /info. Lo stato online/offline è disponibile tramite il topic LWT (shellies/<id>/online). Queste funzionalità sono disponibili nell’output MQTT del dispositivo ma non sono mappate nel template TapHome attuale. Possono essere aggiunte in un futuro aggiornamento del template.

Risoluzione dei problemi

Il sensore non segnala dati
  1. Verifica che lo Shelly Motion 2 sia connesso al Wi-Fi e che l’MQTT sia abilitato nelle impostazioni del dispositivo
  2. Controlla che la variabile personalizzata sensorN_topic corrisponda esattamente al Device ID (es. shellymotion2-AABBCCDDEEFF)
  3. Usa un client MQTT (es. MQTT Explorer) per sottoscriverti a shellies/# e verificare che il sensore pubblichi messaggi al risveglio
  4. Il Motion 2 è alimentato a batteria e pubblica dati solo al risveglio — attiva un evento di movimento per forzare un risveglio
Lo stato del movimento non si aggiorna
  1. Controlla che la lente del sensore PIR non sia ostruita e che il sensore sia montato all’altezza consigliata (1,8–2,5 m)
  2. Se il sensore è stato installato di recente, verifica le impostazioni di sensibilità e tempo cieco nell’interfaccia web del dispositivo — un tempo cieco elevato significa che il sensore ignora il movimento per periodi più lunghi dopo ogni rilevamento
  3. Regola il conteggio impulsi se il sensore si attiva troppo raramente (inferiore = meno movimenti consecutivi necessari)
  4. Controlla in TapHome lo stato del dispositivo Reed Contact — 1 = movimento rilevato (allarme), 0 = nessun movimento (OK)
La batteria si scarica rapidamente
  1. Lo Shelly Motion 2 utilizza una batteria Li-ion ricaricabile integrata (6500 mAh) caricata tramite USB-C, con una durata attiva tipica di 12–18 mesi
  2. Risvegli frequenti dovuti a elevata attività di movimento o brevi intervalli di sospensione scaricano la batteria più velocemente
  3. L’abilitazione di SSL su MQTT riduce significativamente la durata della batteria — usa MQTT semplice (porta 1883) su una rete locale affidabile
  4. Assicura un segnale Wi-Fi forte nella posizione del sensore — un segnale debole comporta tempi di connessione più lunghi ad ogni risveglio

I dispositivi Gen1 Shelly non supportano MQTT su TLS senza un impatto significativo sulla batteria. La comunicazione tra il sensore e il broker MQTT è tipicamente non crittografata (MQTT semplice, porta 1883). Assicurati che il broker MQTT si trovi su una rete locale affidabile.

L’abilitazione di MQTT sui dispositivi Gen1 Shelly disabilita la connettività Cloud. MQTT e Cloud non possono coesistere sullo stesso dispositivo.

Come installare in TapHome

Prerequisiti

  • Dispositivo Shelly connesso al Wi-Fi (vedi la guida alla connessione HTTP se non ancora fatto)
  • Broker MQTT attivo sulla rete locale (es. Mosquitto, Home Assistant o il broker integrato di TapHome)
  • TapHome CCU sulla stessa rete del broker

Sui dispositivi Gen1, l’attivazione di MQTT disabilita Shelly Cloud. Entrambi non possono funzionare contemporaneamente. Sui dispositivi Gen2/Plus questa limitazione non si applica.

Passaggio 1 — Abilitare MQTT sul dispositivo Shelly

Dispositivi Gen1 (Shelly 1, 1PM, 2.5, EM, 3EM, Plug S, RGBW2, Dimmer, TRV…)

  1. Apri l’interfaccia web Shelly: http://<device-ip>/
  2. Vai su Internet & SecurityAdvanced — MQTT
  3. Abilita MQTT
  4. Imposta MQTT Server: <broker-ip>:<port> (es. 192.168.1.10:1883)
  5. Opzionalmente imposta MQTT User e MQTT Password se il broker richiede l’autenticazione
  6. Clicca su Save — il dispositivo si riavvierà e si connetterà al broker

Dispositivi Gen2 / Plus (Shelly Plus 1, Plus 1PM, Plus 2PM, Plus Plug S, Plus H&T, Pro 3EM…)

  1. Apri l’interfaccia web Shelly: http://<device-ip>/
  2. Vai su SettingsMQTT
  3. Abilita MQTT
  4. Imposta Server: <broker-ip>:<port> (es. 192.168.1.10:1883)
  5. Il Client ID è precompilato con l’ID del dispositivo (es. shellyplus1pm-AABBCCDDEE) — lascialo così a meno che tu non abbia un motivo specifico per cambiarlo
  6. Clicca su Save e riavvia il dispositivo

Per verificare che MQTT funzioni, usa un client MQTT (es. MQTT Explorer) e sottoscrivi shellies/# (Gen1) o <device-id>/# (Gen2). Dovresti vedere i messaggi di stato dal dispositivo.

Passaggio 2 — Trovare il Device ID / MQTT Client ID

Alcuni template richiedono un parametro Device ID o MQTT Client ID. Questo è l’identificatore univoco utilizzato nei topic MQTT.

  • Gen1: si trova sull’etichetta come indirizzo MAC (es. AABBCCDDEE). Device ID = shelly<model>-<mac>, es. shelly1pm-AABBCCDDEE
  • Gen2/Plus: si trova nell’interfaccia web Shelly sotto SettingsDevice InfoDevice ID, oppure sull’etichetta del dispositivo

Passaggio 3 — Configurazione in TapHome

  1. In TapHome, aggiungi un nuovo modulo Packet Parser (MQTT)
  2. IP Address: inserisci l’IP del broker MQTT (es. 192.168.1.10)
  3. Port: 1883 (predefinito; usa 8883 per TLS)
  4. Device ID / MQTT Client ID: inserisci il valore dal passaggio 2 (se richiesto dal template)
  5. Importa il template — TapHome si sottoscriverà automaticamente ai topic del dispositivo

Dispositivi disponibili

Shelly Motion 2 MQTT Modulo
Variabili personalizzate
sensor1_topic (string) = shellymotion2-deviceidID dispositivo MQTT del sensore di movimento 1 — formato: 'shellymotion2-DEVICEID' (nell'interfaccia web Shelly → Settings → Device Info)
Open http://shellyIpAddress → Settings → Device info → copy Device ID. Format: shellymotion2-<last6MAC>
sensor2_topic (string) = shellymotion2-deviceidID dispositivo MQTT del sensore di movimento 2
sensor3_topic (string) = shellymotion2-deviceidID dispositivo MQTT del sensore di movimento 3
sensor4_topic (string) = shellymotion2-deviceidID dispositivo MQTT del sensore di movimento 4
sensor5_topic (string) = shellymotion2-deviceidID dispositivo MQTT del sensore di movimento 5
Rilevatore di movimento 1 Contatto reed Solo lettura

Rilevamento movimento PIR — segnala allarme quando rileva movimento, OK senza movimento; analizza $.sensor.motion dal payload JSON /info

boolean
Attributi di servizio
Indirizzo IP
Indirizzo MAC
Batteria
Segnale
Cloud abilitato
Cloud connesso
Ora dispositivo
Luminanza
Temperatura
Tempo di attività
Versione FW
Aggiornamento FW
RAM libera
Spazio FS libero

Rilevatore di movimento 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
Attributi di servizio
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
Rilevatore di movimento 2 Contatto reed Solo lettura

Rilevamento movimento PIR — segnala allarme quando rileva movimento, OK senza movimento; analizza $.sensor.motion dal payload JSON /info

boolean
Attributi di servizio
Indirizzo IP
Indirizzo MAC
Batteria
Segnale
Cloud abilitato
Cloud connesso
Ora dispositivo
Luminanza
Temperatura
Tempo di attività
Versione FW
Aggiornamento FW
RAM libera
Spazio FS libero

Rilevatore di movimento 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
Attributi di servizio
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
Rilevatore di movimento 3 Contatto reed Solo lettura

Rilevamento movimento PIR — segnala allarme quando rileva movimento, OK senza movimento; analizza $.sensor.motion dal payload JSON /info

boolean
Attributi di servizio
Indirizzo IP
Indirizzo MAC
Batteria
Segnale
Cloud abilitato
Cloud connesso
Ora dispositivo
Luminanza
Temperatura
Tempo di attività
Versione FW
Aggiornamento FW
RAM libera
Spazio FS libero

Rilevatore di movimento 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
Attributi di servizio
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
Rilevatore di movimento 4 Contatto reed Solo lettura

Rilevamento movimento PIR — segnala allarme quando rileva movimento, OK senza movimento; analizza $.sensor.motion dal payload JSON /info

boolean
Attributi di servizio
Indirizzo IP
Indirizzo MAC
Batteria
Segnale
Cloud abilitato
Cloud connesso
Ora dispositivo
Luminanza
Temperatura
Tempo di attività
Versione FW
Aggiornamento FW
RAM libera
Spazio FS libero

Rilevatore di movimento 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
Attributi di servizio
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
Rilevatore di movimento 5 Contatto reed Solo lettura

Rilevamento movimento PIR — segnala allarme quando rileva movimento, OK senza movimento; analizza $.sensor.motion dal payload JSON /info

boolean
Attributi di servizio
Indirizzo IP
Indirizzo MAC
Batteria
Segnale
Cloud abilitato
Cloud connesso
Ora dispositivo
Luminanza
Temperatura
Tempo di attività
Versione FW
Aggiornamento FW
RAM libera
Spazio FS libero

Rilevatore di movimento 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
Attributi di servizio
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
Connessione: Packet Parser → MQTT
Possibili miglioramenti (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.

Fonti