Shelly PLUS e PRO in Home Assistant tramite MQTT - Come fare!

Home Assistant

Scritto da Luigi Duchi

Con l'uscita della nuova generazione di dispositivi Shelly (PLUS e PRO) la modalità di comunicazione MQTT è stata completamente riscritta e di sicuro resa più complicata rispetto ai dispositivi della precedente generazione.

Complice anche l'integrazione locale nativa in Home Assistant, questo protocollo di comunicazione è andato un po' in disuso (per i dispositivi Shelly). Tuttavia questo non toglie che sia un ottimo protocollo di comunicazione che ci permetterà anche di leggere dei valori che con l'integrazione nativa non vengono rilevati.

Personalmente anche io mi sono fatto ammaliare dall'integrazione nativa specialmente con gli Shelly di nuova generazione, più che altro per pigrizia di studiare la nuova modalità di integrazione MQTT.

Ricorderete che non molto tempo fa ho recensito il nuovissimo Shelly Pro EM-50.

Ecco proprio in quell'occasione mi sono accorto che l'integrazione nativa non supportava i sensori del dispositivo.

Sapevo benissimo che l'integrazione sarebbe stata aggiornata donando il pieno supporto ai sensori necessari alle misurazioni.

In effetti Quando abbiamo pubblicato il video era già disponibile l'integrazione dei valori letti dallo Shelly EM-50 ma, come ben sapete, abbiamo dei tempi tecnici dal momento in cui giriamo un video a quando viene pubblicato.

In occasione di quel video vi avevo promesso che avrei approfondito l'integrazione tramite MQTT e i device di seconda generazione, ovviamente non potevo esimermi da onorare la mia promessa ed eccomi qui.

Prima di iniziare con la guida vi segnalo le nostre recensioni degli ultimi dispositivi Shelly nel caso ve li siate persi:

Il primo step da fare è quello di abilitare MQTT sul dispositivo.

Con l'avvento della nuova applicazione Shelly si può abilitare il protocollo MQTT anche dalla sua interfaccia, cosa che era invece preclusa nella vecchia applicazione che da non molto tempo è stata abbandonata e non verrà più aggiornata a vantaggio della nuova app. Ma un po' per abitudine un po' perché sono diventato cieco con l'età (dicono che succede quando si affronta la pubertà) preferisco sempre operare sull'interfaccia web dei dispositivi Shelly raggiungendola al proprio indirizzo IP da un browser.

Rechiamoci quindi all'indirizzo IP del dispositivo, nel mio caso 192.168.1.68

cliccate su Settings e successivamente su MQTT

Spuntate tutte le voci come nella foto sottostante e aggiungete l'indirizzo del vostro broker seguito dalla porta :1883

Nel mio caso il broker è installato su Home Assistant di conseguenza utilizzerò il suo indirizzo ip interno 192.168.1.67:1883

Inserite username e password utilizzate in fase di configurazione del broker e se volete potrete cambiare client id e mqtt prefix, io ho preferito lasciare quelli di default.

Salvate la configurazione e riavviate il dispositivo, fatelo con l'apposito pulsante che comparirà.

Per il momento non dovremo fare altro sull'interfaccia dello Shelly.

Per scoprire i topic che vengono comunicati dal device Shelly al broker MQTT, vi consiglio un software chiamato MQTT explorer.

Questo software è disponibile per MacOS, Windows e credo anche per Linux e permette di "esplorare" il traffico MQTT aiutandoci a capire come estrapolare i dati che ci servono.

Dovrete puntare all'indirizzo del vostro broker inserendo username e password e successivamente collegarvi.

Successivamente aprendolo noterete il traffico generato dallo Shelly, che nel mio caso è uno Shelly Pro EM 50

(Scusate purtroppo non sono riuscito a scattare uno screenshot dove si vede chiaramente, sicuramente nel video di fine articolo avrete una visuale migliore, la seconda foto è fatta con lo smarthpone magari si riesce a leggere meglio)

Come noterete, a differenza della vecchia generazione, i dispositivi più recenti non sono sotto il topic shellies ma generano un nome proprio che poi non è altro che il topic prefix che avete trovato nelle impostazioni MQTT del dispositivo.

Un altra cosa che salta all'occhio è che i valori dei sensori non sono espressi singolarmente ma sono espressi all'interno di un file JSON.

Il nostro obbiettivo sarà proprio quello di estrapolare tali dati creando dei sensori ad hoc.

Prima di procedere alla creazione di 3 sensori, che analizzeranno Volt, Watt e Ampere letti dalle due pinze amperometriche, voglio farvi notare che, tramite MQTT, si ricavano anche dei valori che non vengono esposti tramite l'integrazione nativa SHELLY.

Ad esempio l'indirizzo IP del dispositivo, la temperatura del dispositivo (quest'ultima la noterete dopo la voce switch:0) il Mac address e altri valori quali ram libera, occupata, ecc...

Inutile dire che potrete creare dei sensori che vanno ad estrapolare questi dati ma oggi ci concentreremo sulla creazione dei 3 sensori sopracitati e di uno switch che andrà ad attivare l'uscita dello Shelly Pro em-50

Come notate dalla foto di MQTT Explorer, le letture sono sotto le rispettive voci em1:0 e em1:1

Esse non sono altro che le letture derivanti dalle due pinze amperometriche, ovviamente nel caso utilizziate un altro tipo di dispositivo dovrete individuare, tramite MQTT Explorer, dove queste letture vengono indicate.

Nella sezione MQTT andremo a creare quindi 6 sensori di seguito il codice di esempio:

mqtt:
  sensor:
    - name: "test em watt1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.act_power }}"
      unit_of_measurement : "W"
      device_class: "power"
      
    - name: "test em volt1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.voltage }}"
      unit_of_measurement : "V"
      device_class: "power"   

    - name: "test em ampere1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.current }}"
      unit_of_measurement : "A"
      device_class: "power"   
      
    - name: "test em watt2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.act_power }}"
      unit_of_measurement : "W"
      device_class: "power"

    - name: "test em volt2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.voltage }}"
      unit_of_measurement : "V"
      device_class: "power"   

    - name: "test em ampere2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.current }}"
      unit_of_measurement : "A"
      device_class: "power"   

Come avrete notato i 6 sensori calcolano i Volt, i Watt e gli Ampere di entrambe le pinze, ovviamente dovrete avere cura di cambiare lo state topic con il topic che il vostro dispositivo.

Nel mio caso è state_topic: "shellyproem50-34987a47a7cc/status/em1:0" 

voi dovrete sostituire shellyproem50-34987a47a7cc con quello che è il vostro topic.

Analizzando lo state topic vediamo che lo stato del sensore verrà letto dal percorso

NOME_VOSTRO_SHELLY/status/em1:0 per la prima pinza amperometrica e 

NOME_VOSTRO_SHELLY/status/em1:1 per la seconda pinza.

Tuttavia ciò non basta ad identificare il valore richiesto perché come abbiamo visto tutte le letture sono si a quel percorso ma all'interno di un JSON.

Quindi dovremo appunto aggiungere la voce value_template.

Prendiamo come esempio il primo valore i watt ricavati dalla pinza 1 noterete che sul JSON letto su MQTT explorer il valore dei watt è espresso alla voce act_power.

Chiaramente quindi il nostro value_template dovrà estrapolare quel valore con la formula value_template: "{{ value_json.act_power }}" che avete letto nel codice sopra-scritto

Dato che gli altri valori sono inseriti nello stesso JSON, per ricavare Volt e Ampere, non dovrete far altro che cambiare il value_template.

value_template: "{{ value_json.voltage }}" per quanto riguarda i volt

value_template: "{{ value_json.current }}" per quanto riguarda gli ampere.

Dovrete replicare il tutto per la seconda pinza andando a cambiare lo state topic come abbiamo visto poco sopra.

Io ho estrapolato solo questi 6 sensori di esempio ma potrete estrapolare tutti i sensori presenti in quel JSON semplicemente cambiando il value_template.

In alternativa potrete estrapolare altri sensori cambiando lo state topic con quello del sensore che desiderate creare ad esempio, come si evince dalla foto della mia schermata di MQTT Explorer, per ricavare l'indirizzo ip del dispositivo avrei dovuto usare lo state_topic: "NOME_VOSTRO_SHELLY/status/eth" 

Ovviamente in quel caso dovrete cambiare il value_template con il seguente valore: value_template: "{{ value_json.ip }}"

Vediamo come estrapolare la temperatura del dispositivo:

La temperatura del dispositivo viene rilevata nello state topic dello switch:0 quindi dovrete utilizzare   state_topic: "NOME_VOSTRO_SHELLY/status/switch:0"

Il sensore di temperatura rileva sia i gradi Celsius che i gradi Fahrenheit di conseguenza ne value_template non sarà sufficiente inserire la voce temperature ma dovrete indicare quali gradi vorrete ottenere.

Nel caso di gradi Celsius il value template sarà cosi: value_template: "{{ value_json.temperature.tC }}"

Nel caso di gradi Fahrenheit cosi: value_template: "{{ value_json.temperature.tF }}"

Andiamo ad aggiungere i nuovi sensori creati assieme ai sei precedentemente inseriti.

mqtt:
  sensor:
    - name: "test em eth"
      state_topic: "NOME_VOSTRO_SHELLY/status/eth"
      value_template: "{{ value_json.ip }}"

    - name: "test em temperatura"
      state_topic: "NOME_VOSTRO_SHELLY/status/switch:0"
      value_template: "{{ value_json.temperature.tC }}"
      unit_of_measurement : "°C"

    - name: "test em watt1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.act_power }}"
      unit_of_measurement : "W"
      device_class: "power"
      
    - name: "test em volt1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.voltage }}"
      unit_of_measurement : "V"
      device_class: "power"   

    - name: "test em ampere1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.current }}"
      unit_of_measurement : "A"
      device_class: "power"   
      
    - name: "test em watt2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.act_power }}"
      unit_of_measurement : "W"
      device_class: "power"

    - name: "test em volt2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.voltage }}"
      unit_of_measurement : "V"
      device_class: "power"   

    - name: "test em ampere2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.current }}"
      unit_of_measurement : "A"
      device_class: "power"   

Per questi ultimi due sensori c'è da fare un piccolo appunto, tale appunto lo riprenderemo dopo aver parlato dello switch proprio perchè l'argomento è collegato.

Andiamo quindi ad aggiungere lo switch dello Shelly che, nel mio caso, dato che sto realizzando questa guida con uno Shelly pro em-50, altro non è che il contatto pulito dal carico massimo di 2 Ampere attivabile.

Questa configurazione ovviamente è utilizzabile con tutti gli Switch della nuova serie.

Aggiungiamolo ai nostri sensori precedentemente configurati e poi andiamo ad analizzarlo.

mqtt:
  switch:

    - name: "test em Switch"
      state_topic: "NOME_VOSTRO_SHELLY/status/switch:0"
      value_template: "{{ true if value_json.output == true else false }}"
      state_on: true
      state_off: false
      optimistic: false
      command_topic: 'NOME_VOSTRO_SHELLY/rpc'
      qos: 0
      payload_on: '{"id": 2,"src":"NOME_VOSTRO_SHELLY","method":"Switch.Set","params": {"id":0,"on":true}}'
      payload_off: '{"id": 2,"src":"NOME_VOSTRO_SHELLY","method":"Switch.Set","params": {"id":0,"on":false}}'

  sensor:
    - name: "test em eth"
      state_topic: "NOME_VOSTRO_SHELLY/status/eth"
      value_template: "{{ value_json.ip }}"

    - name: "test em temperatura"
      state_topic: "NOME_VOSTRO_SHELLY/status/switch:0"
      value_template: "{{ value_json.temperature.tC }}"
      unit_of_measurement : "°C"

    - name: "test em watt1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.act_power }}"
      unit_of_measurement : "W"
      device_class: "power"
      
    - name: "test em volt1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.voltage }}"
      unit_of_measurement : "V"
      device_class: "power"   

    - name: "test em ampere1"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:0"
      value_template: "{{ value_json.current }}"
      unit_of_measurement : "A"
      device_class: "power"   
      
    - name: "test em watt2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.act_power }}"
      unit_of_measurement : "W"
      device_class: "power"

    - name: "test em volt2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.voltage }}"
      unit_of_measurement : "V"
      device_class: "power"   

    - name: "test em ampere2"
      state_topic: "NOME_VOSTRO_SHELLY/status/em1:1"
      value_template: "{{ value_json.current }}"
      unit_of_measurement : "A"
      device_class: "power"   

La configurazione dello Switch è leggermente più complessa rispetto ai sensori ma nulla di impossibile

Come notate lo state topic è lo stesso del sensore di temperatura che abbiamo creato prima, questo perché, come potrete notare da MQTT Explorer, la temperatura viene inserita nello stesso topic che serve a comandare lo switch, in questo caso switch:0 

Il valore che dovremo prendere di riferimento da JSON di switch:0 è appunto output e quindi nel value template dovremo andare a definire che ci aspettiamo un valore true quando output è su true e false quando output e su false.

e lo andremo a definire con questo: value_template: "{{ true if value_json.output == true else false }}"

poi dobbiamo definire cosa ci aspettiamo quando il valore è true e quando e false e quindi indicheremo 

state_on: true state_off: false

Dove lo stato on è tale quando output è su true e off quando output è su false.

Infine dovremo definire il command_topic che altro non è che il topic dal quale si ppossono lanciare i comandi MQTT per l'accensione e lo spegnimento dello switch 

Il vostro command_topic sarà il seguente:

command_topic: 'NOME_VOSTRO_SHELLY/rpc'

Una volta inserito il command topic andiamo a lavorare sui comandi veri e propri per accendere e spegnere il dispositivo.

definiti payload_on e payload_off

payload_on: '{"id": 2,"src":"NOME_VOSTRO_SHELLY","method":"Switch.Set","params": {"id":0,"on":true}}' payload_off: '{"id": 2,"src":"NOME_VOSTRO_SHELLY","method":"Switch.Set","params": {"id":0,"on":false}}'

Queste ultime stringhe le potrete recuperare sempre da MQTT Explorer, in questo caso sotto la voce rpc.

Ricordate che, prima di parlare dello switch, vi avevo detto che per i due sensori creati ci sarebbe stato da fare un appunto?

Bene, è giunto il momento.

Il grosso problema dei dispositivi di nuova generazione è quello che non possiamo pubblicare un topic che ci permette di ricavare lo stato di connessione del dispositivo al broker come avveniva con availability_topic nei dispositivi di prima generazione.

Che cosa comporta questo?

Comporta che fino a che andiamo a riavviare lo Shelly una volta che tornerà online comunicherà i suoi parametri al broker ma se riavviamo ad esempio Home Assistant non ci sarà alcuna pubblicazione di topic per rivelare lo stato di connessione al broker (che abbiamo riavviato assieme ad Home Assistant dato che è installato al suo interno)

Quindi di fatto non vedremo lo stato dello switch fino a che non gli daremo un comando di accensione o spegnimento, certo da li in poi si visualizzerà perfettamente lo stato ma pensate al disagio ad ogni riavvio specialmente in presenza di molti dispositivi.

Anche i due sensori che abbiamo creato temperatura e indirizzo IP seguiranno la stessa sorte e di conseguenza al riavvio di Home Assistant non verranno riconosciuti e verranno descritti come sconosciuti.

Certo ci sarebbe la possibilità di creare delle automazioni con dei template all'avvio di Home Assistant, ma ciò andrebbe fatto per ogni dispositivo e sinceramente non mi piace l'idea che debba essere Home Assistant a dover interrogare il dispositivo per capirne lo stato, la logica mi porta a pensare che debba essere il dispositivo stesso a comunicare ad Home Assistant il suo stato.

Come risolvere questo problema?

Abbiamo visto nei nuovi dispositivi della famiglia PLUS e PRO la possibilità di utilizzare degli script.

Perché non sfruttare questa potenzialità?

In questo caso avremo bisogno di creare 2 script per far si che lo Shelly comunichi di continuo lo stato sia dello switch che del sensore di temperatura che del sensore che va a leggere l'indirizzo IP.

Perché 2 script e non 3? semplice perché come abbiamo visto precedentemente la temperatura è inserita nello stesso topic che serve alla gestione dello switch, ricordate? switch:0

Torniamo quindi nell'interfaccia web del nostro dispositivo Shelly sfruttando da un browser il suo indirizzo IP.

Andate alla voce script e aggiungetene uno, io per comodità l'ho chiamato annuncio MQTT

Questo script servirà a far comunicare ogni 10 secondi lo stato dello switch al broker ovviamente il tempo lo potrete decidere voi modificando il valore in millisecondi (che nel mio caso è 10000)



let MioTimer = Timer.set(
     10000,
     true,
     function() {
     
     let mqtt_prefix = Shelly.getComponentConfig("mqtt").topic_prefix;
     MQTT.publish(mqtt_prefix + "/status/switch:0", JSON.stringify(Shelly.getComponentStatus("switch:0")),0, false);

 }
 
 );

Salvate e avviate lo script

Il secondo script invece servirà a comunicare l'indirizzo IP ogni 10 secondi al broker

let MioTimer = Timer.set(
     10000,
     true,
     function() {
     
     let mqtt_prefix = Shelly.getComponentConfig("mqtt").topic_prefix;
     MQTT.publish(mqtt_prefix + "/status/eth", JSON.stringify(Shelly.getComponentStatus("eth")),0, false);

 }
 
 );

anche in questo caso salvate e avviate lo script dall'interfaccia web dello Shelly

Tutto pronto adesso ogni volta che riavvierete Home Assistant tutte le informazioni saranno subito disponibili e non dovrete più effettuare nessun intervento.

Vi lascio al video di fine articolo che vi aiuterà ad approfondire questi passaggi.

Produrre e aggiornare contenuti su vincenzocaputo.com richiede molto tempo e lavoro. Se il contenuto che hai appena letto è di tuo gradimento e vuoi supportarmi, clicca uno dei link qui sotto per fare una donazione.

Luigi Duchi

Nato a Grosseto il 24 Dicembre 1982 perito elettrotecnico che lavora nel mondo della domotica e installazione di impianti elettrici, impianti di allarmi, videosorveglianza e automazioni in genere. Appassionato da sempre di tecnologia e aperto alla conoscenza di nuove soluzioni.


Vai ai commenti