community italiana di domotica personale
 
Le API Shelly di seconda generazione: una panoramica tecnica

Le API Shelly di seconda generazione: una panoramica tecnica

NOTA IMPORTANTE: l’articolo che segue prevede una certa preparazione tecnica. Chi non la possedesse tenga presente la reale possibilità di non comprendere certi concetti – che comunque possono essere chiariti facendosi una cultura anche usufruendo del nostro forum e della chat Telegram.

Shelly Logo

Come abbiamo accennato anche nella recensione del primo prodotto di seconda generazione che abbiamo testato, lo Shelly 1 Plus, il produttore Allterco ha completamente rivisto per questo nuovo corso la parte legata all’interoperabilità, migrando all’utilizzo del protocollo RPC (più precisamente, JSON-RPC 2.0). Si tratta di un protocollo client-server (request-response) sincrono.

Shelly 1 Plus

Questo, come vedremo, ha concesso ad Allterco di standardizzare le interfacce e rendere il tutto molto più strutturato. In precedenza, con i device di prima generazione, potevamo controllare o recuperare informazioni dal device in maniera diversa a seconda del protocollo che volevamo utilizzare; ora invece, indipendentemente dalla modalità di comunicazione scelta tra quelle messe a disposizione potremo fare sempre le stesse identiche cose.

Secondo quanto previsto dall’implementazione di questo protocollo, ogni “azione” che effettuiamo – sia essa per monitorare che per controllare un device – corrisponde ad un “metodo” che prevede in input un oggetto in notazione JSON e che restituisce, quando evocato, un altro oggetto JSON quale risultato. Questi metodi sono raggruppati per “namespace”. Per fare un esempio, il namespace “Switch” che riguarderà appunto gli switch, accorperà n metodi per l’interazione, come ad esempio quello per recuperare la configurazione “Getconfig”, quello per impostare uno stato “Set”, eccetera.

Esempio:

Switch.Getconfig
Switch.Set

Ma come funziona effettivamente la comunicazione tra il client (l’utente) ed il device ? La comunicazione avviene tramite l’invio/ricezione dei tre cosiddetti “frame”, che sono sostanzialmente degli oggetti JSON:

  • request frame
  • response frame
  • notification frame

Prendendo come spunto il namespace “Switch” appena menzionato, ammettiamo di voler impartire un comando per far cambiare stato allo switch esposto su uno Shelly.

Vetrina - Offerte del giorno

REQUEST FRAME

Il client (nel nostro caso l’utente/il nostro hub) invierà il request frame composto dai seguenti attributi:

  • id (obbligatorio): identificativo della request. E’ obbligatorio se si vuole ricevere il response frame;
  • src (obbligatorio): identificativo di chi ha inviato la request (nel nostro caso abbiamo impostato la stringa “homeassistant” ipotizzando di integrare lo Shelly sul noto HUB personale);
  • method (obbligatorio): è una stringa che rappresenta il metodo da invocare;
  • params (opzionale): è un oggetto JSON con i parametri eventualmente previsti dal metodo invocato.

Ecco un esempio di request frame:

{
   "id":1,
   "src":"homeassistant",
   "method":"Switch.Set",
   "params":{
      "id":0,
      "on":true
   }
}

RESPONSE FRAME

Il server (nel nostro caso lo Shelly), se indicato tramite l’id del request frame, invierà in risposta il response frame che sarà composto dai seguenti attributi:

  • id: identificativo corrispondente a quello della request;
  • src: identificativo di chi ha inviato il frame (nel nostro caso lo Shelly);
  • dst: identificativo del destinatario del response frame che corrisponderà al “src” presente nel request frame;
  • result: è un oggetto JSON con i parametri restituiti dal server.

Ecco un esempio di response frame:

{
   "id":1,
   "src":"shellyplus1-a8032abdcb2c",
   "dst":"homeassistant",
   "result":{
      "was_on":false
   }
}

Se ci fosse stato un errore, al posto di result avremmo avuto error. Di seguito un esempio:

{
   "id":1,
   "src":"shellyplus1-a8032abdcb2c",
   "dst": "homeassistant",
   "error": {
      "code": -105,
      "message": "Bad id=12"
   }
}

NOTIFICATION FRAME

Ultimo step. Il server (sempre lo Shelly) invierà il notification frame al cui interno ci saranno le informazioni relative ad un cambio stato: si precisa questo perché nel caso in cui inviassimo un request frame per passare in stato “on” quando lo switch è già in stato “on”, non verrebbe inviato alcun notification frame.

Il notification frame ad ogni modo è molto simile ad un request frame, ma in questo caso ovviamente il giro è chiuso e non si aspetta a sua volta un response frame.

È composto dai seguenti attributi:

  • src: l’identificativo di chi invia il response frame;
  • dst: l’identificativo del destinatario del notification frame;
  • method: il metodo invocato (che è in questo caso è NotifyStatus);
  • params: è un JSON object contenente i parametri relativi alla telemetria:
{
   "src":"shellyplus1-a8032abdcb2c",
   "dst":"shellyplus1-a8032abdcb2c/events",
   "method":"NotifyStatus",
   "params":{
      "ts":1633816032.14,
      "switch:0":{
         "id":0,
         "output":true,
         "source":"MQTT"
      }
   }

Piccola nota sull’attributo dst, il quale potrebbe confondere le idee. Immaginiamo che ci si possa aspettare “dst”:”homeassistant”. Come ragionamento è corretto, ma in questo caso, per questo esempio, come è possibile notare anche dall’ultimo JSON di notifica, il test è stato effettuato via MQTT ed in questo caso l’identificativo del destinatario non è “homeassistant” da cui è partita la prima publish, ma il topic apposito per i frame di notifica “shellydevicemodel-XXXXXXXXXXXX/events/rpc“, ecco perché troviamo “shellyplus1-a8032abdcb2c/events“.

Se avessimo fatto una prova utilizzando ad esempio websocket (usando wscat) il dst nel notification frame sarebbe stato effettivamente diverso:

$ wscat -c ws://http://192.168.1.8/rpc
Connected (press CTRL+C to quit)
> {"id":2, "src":"homeassistant", "method":"Switch.Set", "params":{"id":0, "on":true}}
< {"id":2,"src":"shellyplus1-a8032abdcb2c","dst":"homeassistant","result":{"was_on":false}}
< {"src":"shellyplus1-a8032abdcb2c","dst":"homeassistant","method":"NotifyStatus","params":{"ts":1633817170.00,"switch:0":{"id":0,"output":true,"source":"WS_in"}}}

Proprio da questo ultimo aspetto, come accennato anche all’inizio, possiamo notare come effettivamente sia possiible fare le stesse cose ma con strumenti e protocolli completamente diversi, anche detti RPC Channels. Nel momento in cui stiamo scrivendo questo articolo quelli supportati sono:

  • HTTP
  • Websocket
  • MQTT
  • UDP

Tutto ciò che possiamo fare è possibile farlo grazie ai metodi che abbiamo accennato essere raggruppati per namespace.
Questi namespace a loro volta li possiamo dividere a livello logico in n categorie.

Tenendo sempre in considerazione che la lista dei namespace e dei metodi è in continua evoluzione lato Shelly, per darvi un’idea di ciò che è possibile fare, è possibile fare un salto sul sito di documentazione ufficiale per censirli tutti.

Alcuni namespace sono:

  • Shelly: controllo del device (es. recupero configurazioni, aggiornamento firmware, Reboot, etc.);
  • Schedule: gestione temporizzazioni lato device;
  • Webhook: gestione webhook sul device;
  • HTTP: gestione request HTTP/S in GET e POST dal device.

Esiste poi la categoria “Components” che a sua volta si suddivide nelle seguenti sottocategorie:

  • System components:
    • System: permette di recuperare gli attributi a livello di sistema come uptime, ram, mac address, disponibilità aggiornamenti, eccetera;
    • Ethernet: restituisce i parametri relativi alla connessione via cavo come ad esempio ip, netmask, gw);
    • WiFi: come il precedente, ma relativa ovviamente al Wi-Fi restituendo anche parametri quali SSID, RSSI, stato, IP, eccetera;
    • BLE: restituisce solo lo stato del bluetooth (attivo/non attivo);
    • Cloud: come per il precedente, ma ovviamente riferito allo stato della connettività verso il cloud Shelly;
    • MQTT: restituisce lo stato della connettività verso il broker MQTT.
  • Functional components:
    • Input: controllo e configurazione degli input collegati allo Shelly;
    • Switch: controllo e configurazione del relè;
  • Notifications: i metodi delle notifiche di eventi di cambio stato e non. Non verranno mai utilizzati lato client in quanto si tratta dei metodi utilizzati per l’invio delle notifiche da parte del device;
  • Script: permette di controllare gli script (creare, cancellare, avviare, interrompere), una delle grosse novità dei device di seconda generazione.


Questa pagina è redatta, manutenuta e aggiornata dallo staff di inDomus, un gruppo di persone molto diverse tra loro che trovi, per domande e supporto, sul forum e sulla chat del sito. Alcuni link sono taggati in qualità di affiliati Amazon e riceviamo un compenso dagli acquisti idonei, utile al sostenimento del sito, ma le nostre recensioni sono tutte indipendenti e non sponsorizzate. Se ti sei perso, a tua disposizione c'è la mappa.