%20Using%20RPC.png?inst-v=8eb5b645-f616-454e-a1eb-47030b06b1ec)
Panoramica
Bluetooth Low Energy (BLE) è diventata una tecnologia fondamentale per la comunicazione wireless nei dispositivi smart moderni, offrendo connettività efficiente e a basso consumo energetico. I dispositivi Shelly, parte integrante degli ecosistemi smart home, sfruttano il BLE per facilitare una comunicazione e un controllo senza interruzioni. Un aspetto chiave della comunicazione BLE di Shelly è l'implementazione dei protocolli Remote Procedure Call (RPC) su BLE, che consente interazioni sofisticate tra dispositivi e controller. Questo articolo approfondisce le sfumature tecniche della comunicazione con dispositivi Shelly usando BLE, concentrandosi sul Generic Attribute Profile (GATT), gli handle e i meccanismi per eseguire operazioni di lettura e scrittura basate su RPC.
Prerequisiti
Prima di addentrarsi negli aspetti tecnici della comunicazione con dispositivi Shelly tramite BLE e RPC, è essenziale avere una comprensione di base dei seguenti concetti:
Bluetooth Low Energy (BLE): Una tecnologia di rete personale wireless progettata per basso consumo energetico e costi contenuti. BLE è ampiamente utilizzata nei dispositivi IoT per una comunicazione efficiente.
Generic Attribute Profile (GATT): Un protocollo BLE che definisce come i dati sono strutturati e scambiati tra dispositivi. GATT organizza i dati in servizi e caratteristiche.
Remote Procedure Call (RPC): Un protocollo che permette a un programma di eseguire una procedura (subroutine) su un dispositivo remoto come se fosse una chiamata locale.
JSON: Un formato leggero di scambio dati usato per strutturare richieste e risposte RPC.
Architettura BLE RPC di Shelly
Comunicare con dispositivi Shelly tramite BLE e RPC implica un'integrazione fluida di stabilire una connessione, interagire con specifici servizi e caratteristiche GATT, costruire e inviare richieste RPC, e ricevere e analizzare risposte. Questo flusso di lavoro unificato garantisce una comunicazione efficiente e affidabile con i dispositivi Shelly, permettendo integrazioni diverse attraverso vari sistemi e linguaggi di programmazione.
Componenti chiave GATT nei dispositivi Shelly
UUID del servizio GATT Shelly: Identifica il servizio principale responsabile della comunicazione RPC.
SHELLY_GATT_SERVICE_UUID = "5f6d4f53-5f52-5043-5f53-56435f49445f" UUID della caratteristica dati RPC: Gestisce la trasmissione dei dati di richiesta e risposta RPC.
RPC_CHAR_DATA_UUID = "5f6d4f53-5f52-5043-5f64-6174615f5f5f" UUID della caratteristica di controllo TX RPC: Gestisce il controllo della trasmissione, in particolare per inviare informazioni sulla lunghezza dei dati al dispositivo Shelly.
RPC_CHAR_TX_CTL_UUID = "5f6d4f53-5f52-5043-5f74-785f63746c5f" UUID della caratteristica di controllo RX RPC: Gestisce il controllo della ricezione, principalmente per ricevere informazioni sulla lunghezza dei dati dal dispositivo Shelly.
RPC_CHAR_RX_CTL_UUID = "5f6d4f53-5f52-5043-5f72-785f63746c5f" Nota: Questi UUID sono specifici per i dispositivi Shelly, fare riferimento alla documentazione ufficiale Shelly o utilizzare strumenti di scansione BLE per identificare gli UUID appropriati.
Aspetti chiave dell'RPC di Shelly su BLE
Protocollo JSON-RPC 2.0
I dispositivi Gen2+ di Shelly utilizzano il protocollo JSON-RPC 2.0 per il monitoraggio e il controllo delle funzionalità. Questo protocollo è simmetrico, permettendo a entrambi i peer—client e dispositivo—di invocare metodi e inviare notifiche reciprocamente. JSON-RPC 2.0 garantisce una comunicazione strutturata e standardizzata, facilitando interazioni affidabili tra l'applicazione client e il dispositivo Shelly.
Convenzioni di Namespace
Shelly organizza i suoi metodi RPC in namespace per categorizzare le funzionalità, migliorando chiarezza e manutenibilità. Di seguito alcuni namespace principali ed esempi di metodi:
-
Namespace Shelly: Gestisce la gestione del sistema, configurazione e stato.
Shelly.FactoryReset
Shelly.ResetWiFiConfig
Shelly.ListTimezones
-
Namespace Switch: Gestisce uscite di potenza discrete, tipicamente relè.
Switch.Set
Switch.GetConfig
Nota: I namespace e i metodi sopra indicati sono esempi illustrativi. L'implementazione RPC di Shelly include numerosi metodi aggiuntivi in vari namespace per supportare diverse funzionalità del dispositivo.
Tipi di frame
La comunicazione tra utente e dispositivo consiste in tre tipi di frame:
Frame di richiesta: Usato per inviare comandi ai dispositivi.
Frame di risposta: Usato per ricevere risposte dai dispositivi.
Frame di notifica: Usato per ricevere aggiornamenti non sollecitati dai dispositivi.
Strutture dei frame nel protocollo RPC di Shelly
Frame di richiesta
Il frame di richiesta è un oggetto JSON usato per invocare metodi sui dispositivi Shelly. Contiene i seguenti attributi:
jsonrpc (stringa): Specifica la versione di JSON-RPC usata, tipicamente "2.0". Questo campo può essere omesso.
id (numero o stringa): Identificatore della richiesta, usato per abbinare il frame di risposta. Obbligatorio.
src (stringa): Nome della sorgente della richiesta (es. "user_1"). Obbligatorio.
method (stringa): Nome della procedura da chiamare (es. "Shelly.GetDeviceInfo"). Obbligatorio.
params (oggetto): Parametri che il metodo accetta (es. {"id":1}). Opzionale.
Frame di risposta
Il frame di risposta è un oggetto JSON restituito dal dispositivo Shelly in risposta a un frame di richiesta. Contiene i seguenti attributi:
id (numero o stringa): Identificatore della comunicazione. Obbligatorio.
src (stringa): Nome della sorgente della risposta (tipicamente il dispositivo Shelly). Obbligatorio.
dst (stringa): Nome della destinazione (tipicamente il richiedente). Obbligatorio.
result (oggetto): Il risultato della procedura invocata se la richiesta ha avuto successo. Mutuamente esclusivo con error.
error (oggetto): Contiene la descrizione dell'errore occorso se la richiesta non ha avuto successo. Mutuamente esclusivo con result.
Frame di notifica
Il frame di notifica è un oggetto JSON inviato dal dispositivo Shelly per notificare al client certi eventi o cambiamenti di stato senza aspettarsi una risposta. Contiene i seguenti attributi:
src (stringa): Nome della sorgente della notifica (es. dispositivo Shelly). Obbligatorio.
dst (stringa): Nome della destinazione (es. "user_1"). Obbligatorio.
method (stringa): Il metodo invocato (es. "NotifyStatus"). Obbligatorio.
params (oggetto): I parametri della notifica contenenti dati rilevanti. Obbligatorio.
Guida passo-passo per comunicare con dispositivi Shelly
1. Stabilire una connessione BLE
Obiettivo: Connettersi al dispositivo Shelly usando il suo indirizzo BLE univoco.
Procedura:
Scoperta del dispositivo: Iniziare scansionando i dispositivi BLE nelle vicinanze per identificare il dispositivo Shelly. Questo può essere fatto usando strumenti di scansione BLE o librerie disponibili nell'ambiente di programmazione scelto. Il dispositivo Shelly può essere identificato dal nome o dall'indirizzo BLE.
Avviare la connessione: Una volta identificato, avviare una connessione al dispositivo Shelly usando il suo indirizzo BLE. Questa connessione costituisce la base per tutte le interazioni successive. Assicurarsi che l'hardware BLE del sistema sia funzionante e che il dispositivo Shelly sia in uno stato pronto ad accettare connessioni.
Considerazioni:
Timeout di connessione: Le connessioni BLE possono a volte essere instabili o richiedere più tempo del previsto. Implementare meccanismi di timeout per gestire scenari in cui il tentativo di connessione supera una durata ragionevole.
Logica di riconnessione: In caso di disconnessioni inaspettate, avere una strategia di riconnessione assicura che l'applicazione possa recuperare senza intervento manuale.
2. Interagire con servizi e caratteristiche GATT
Obiettivo: Accedere e utilizzare i servizi e le caratteristiche GATT specifici necessari per la comunicazione RPC.
Procedura:
Scoperta dei servizi: Una volta connessi, eseguire la scoperta dei servizi per recuperare la lista dei servizi GATT disponibili offerti dal dispositivo Shelly. Individuare il servizio GATT Shelly usando il suo UUID predefinito.
Scoperta delle caratteristiche: All'interno del servizio GATT Shelly, identificare le caratteristiche RPC Data, RPC TX Control e RPC RX Control usando i rispettivi UUID. Queste caratteristiche sono fondamentali per inviare richieste RPC e ricevere risposte. Fare riferimento a Componenti chiave GATT nei dispositivi Shelly.
Considerazioni:
Precisione degli UUID: Assicurarsi di usare gli UUID corretti per evitare errori di comunicazione. Usare UUID errati può causare fallimenti nella lettura o scrittura delle caratteristiche desiderate.
Disponibilità delle caratteristiche: Alcuni dispositivi Shelly potrebbero avere variazioni nei loro profili GATT in base al modello o alla versione del firmware. Implementare controlli per confermare la presenza di tutte le caratteristiche richieste prima di procedere.
3. Costruire richieste RPC
Obiettivo: Creare richieste RPC nel formato corretto per comunicare le azioni desiderate al dispositivo Shelly.
Procedura:
Struttura JSON: Le richieste RPC sono strutturate come oggetti JSON contenenti campi specifici:
id: Un identificatore unico per la richiesta, che garantisce che le risposte possano essere correlate alle rispettive richieste.
src: Identificatore della sorgente, come “user_1”, che indica l'origine della richiesta.
method: Il metodo RPC da invocare, per esempio, “Shelly.GetDeviceInfo”.
params: Parametri opzionali richiesti dal metodo RPC.
{ "id": 123456789, "src": "user_1", "method": "Shelly.GetDeviceInfo", "params": {} } Codifica: Convertire l'oggetto JSON in un array di byte codificato UTF-8. Questo array di byte sarà trasmesso via BLE al dispositivo Shelly.
Calcolo della lunghezza: Determinare la lunghezza in byte della richiesta RPC codificata. Questa informazione è cruciale per informare il dispositivo Shelly sulla dimensione dei dati in arrivo.
Impacchettamento della lunghezza: Convertire la lunghezza calcolata in un intero a 4 byte in formato big-endian. Questa lunghezza impacchettata viene scritta nella caratteristica RPC TX Control per segnalare la dimensione dei dati in arrivo.
Considerazioni:
ID unici per le richieste: Ogni richiesta RPC dovrebbe avere un id unico per abbinare correttamente le risposte alle richieste corrispondenti.
Validazione dei parametri: Assicurarsi che i parametri forniti al metodo RPC siano validi e aderiscano al formato previsto. Parametri non validi possono portare a richieste malformate ed errori dal dispositivo Shelly.
4. Inviare richieste RPC
Obiettivo: Trasmettere la richiesta RPC costruita al dispositivo Shelly tramite BLE.
Procedura:
Scrivere la lunghezza nella caratteristica di controllo TX: Iniziare scrivendo la lunghezza impacchettata della richiesta RPC nella caratteristica RPC TX Control. Questo informa il dispositivo Shelly sulla dimensione dei dati in arrivo, preparandolo a ricevere la richiesta RPC vera e propria.
Introdurre una breve pausa: Dopo aver scritto la lunghezza, introdurre una breve pausa (es. 1 secondo) per permettere al dispositivo Shelly di processare l'informazione sulla lunghezza. Questo assicura la sincronizzazione tra client e dispositivo prima di inviare i dati effettivi.
Scrivere la richiesta RPC nella caratteristica dati: Procedere a scrivere i byte della richiesta RPC codificata nella caratteristica RPC Data. Questa azione invia il comando o la query vera e propria al dispositivo Shelly, inducendolo a eseguire il metodo RPC specificato.
Considerazioni:
Operazioni di scrittura con risposta: Utilizzare operazioni di scrittura che prevedono una risposta (acknowledgment) dal dispositivo Shelly. Questo assicura che il dispositivo abbia ricevuto e processato correttamente la richiesta di scrittura.
Gestione degli errori: Implementare meccanismi per confermare che le operazioni di scrittura siano andate a buon fine. Gestire scenari in cui le scritture falliscono, possibilmente a causa di problemi di connessione o mancata risposta del dispositivo, riprovando o avvisando l'utente.
5. Ricevere e analizzare risposte RPC
Obiettivo: Ricevere la risposta dal dispositivo Shelly, garantendo integrità e correttezza dei dati.
Procedura:
Leggere la lunghezza della risposta dalla caratteristica di controllo RX: Iniziare leggendo la lunghezza della risposta dalla caratteristica RPC RX Control. Questa lunghezza indica la dimensione dei dati di risposta in arrivo, permettendo al client di sapere quanti byte aspettarsi.
Decodificare la lunghezza: Convertire l'intero a 4 byte big-endian ricevuto in un valore reale di lunghezza in byte. Questa lunghezza decodificata determina la dimensione totale dei dati di risposta da leggere.
Leggere i dati di risposta a pezzi: A causa delle limitazioni MTU (Maximum Transmission Unit) di BLE, leggere i dati di risposta dalla caratteristica RPC Data a pezzi gestibili (tipicamente 20 byte). Continuare a leggere finché l'intera risposta, come indicato dalla lunghezza, non è stata ricevuta.
Accumulare i dati di risposta: Man mano che ogni pezzo viene letto, aggiungerlo a un buffer o array di byte per ricostruire la risposta completa.
Decodificare e analizzare la risposta: Una volta ricevuti tutti i pezzi, decodificare i byte accumulati in una stringa UTF-8 e analizzare l'oggetto JSON. Questa risposta analizzata conterrà o il risultato della chiamata RPC o un campo errore che indica un fallimento.
Validare la risposta: Assicurarsi che l'id nella risposta corrisponda all'id della richiesta originale. Questa validazione conferma che la risposta corrisponde alla richiesta RPC corretta. Inoltre, verificare la presenza di un campo result per confermare l'esecuzione con successo o gestire eventuali messaggi di errore in modo appropriato.
Considerazioni:
Letture a pezzi: La dimensione MTU limitata di BLE richiede di leggere i dati a pezzi per evitare troncamenti o perdite di dati. Implementare logica per gestire letture parziali e accumulare dati finché la risposta completa non è ricevuta.
Timeout: Implementare timeout di lettura per evitare attese indefinite nel caso in cui il dispositivo Shelly non risponda o la connessione venga interrotta.
Integrità dei dati: Validare che l'intera risposta sia stata ricevuta e correttamente analizzata per garantire una comunicazione accurata e affidabile.
Gestione delle sfide comuni
Comunicare con dispositivi Shelly tramite BLE e RPC è un approccio potente, ma comporta alcune sfide. Affrontarle efficacemente garantisce integrazioni robuste e affidabili.
Gestione della dimensione MTU
Problema: L'unità massima di trasmissione (MTU) di BLE definisce la dimensione massima dei pacchetti dati che possono essere inviati in una singola trasmissione. Superare l'MTU può causare troncamenti o trasmissioni fallite.
Soluzione:
Letture/Scritture a pezzi: Implementare logica per suddividere grandi payload di dati in pezzi più piccoli che rispettino la dimensione MTU (tipicamente 20 byte). Questo assicura che i dati siano trasmessi in modo affidabile senza superare i limiti di BLE.
Approccio di esempio:
Determinare la lunghezza totale dei dati da inviare.
Dividere i dati in pezzi di 20 byte o meno.
Scrivere sequenzialmente ogni pezzo nella caratteristica appropriata.
Regolazione dinamica dell'MTU: Alcune librerie e dispositivi BLE supportano la negoziazione di un MTU più grande. Se supportato, regolare l'MTU per ottimizzare l'efficienza della trasmissione dati.
Considerazione di esempio:
Prima di iniziare la trasmissione dati, richiedere un MTU più grande se la libreria e il dispositivo lo supportano.
Gestire scenari in cui la negoziazione fallisce tornando alle dimensioni standard dei pezzi.
Buone pratiche:
Verificare la capacità MTU: Verificare se sia il dispositivo Shelly che il client BLE supportano MTU più grandi per massimizzare la velocità di trasmissione dati.
Implementare meccanismi di fallback: In caso di negoziazione MTU dinamica non riuscita, utilizzare dimensioni standard dei pezzi per mantenere la compatibilità.
Timeout e ritentativi
Problema: Le connessioni BLE possono essere instabili, causando timeout o comunicazioni interrotte, specialmente in ambienti con interferenze o molti dispositivi connessi.
Soluzione:
Implementare timeout: Impostare durate di timeout appropriate per tentativi di connessione, operazioni di lettura/scrittura e fasi di elaborazione dati. Questo evita che l'applicazione attenda indefinitamente risposte.
Approccio di esempio:
Definire tempi massimi di attesa per ogni operazione.
Se un'operazione supera il timeout, gestirla con un retry o notificando l'utente.
Logica di ritentativo: Incorporare meccanismi di ritentativo per fallimenti temporanei, come cadute di connessione o scritture fallite. Limitare il numero di ritentativi per evitare loop infiniti e consumo eccessivo di risorse.
Approccio di esempio:
Dopo un'operazione fallita, attendere un breve periodo prima di tentare un nuovo tentativo.
Implementare strategie di backoff esponenziale per ridurre la frequenza dei ritentativi nel tempo.
Buone pratiche:
Backoff esponenziale: Aumentare gradualmente il tempo di attesa tra i ritentativi per ridurre la probabilità di fallimenti ripetuti, specialmente in ambienti con alta interferenza.
Notifiche all'utente: Informare gli utenti di fallimenti persistenti dopo aver esaurito i tentativi, permettendo interventi manuali se necessario.
Gestione degli errori
Problema: Vari errori possono verificarsi durante la comunicazione BLE, inclusa la non disponibilità di caratteristiche, risposte malformate o errori specifici RPC.
Soluzione:
Gestione completa delle eccezioni: Implementare meccanismi robusti di cattura errori in ogni fase della comunicazione. Questo include la gestione di eccezioni legate a BLE, errori di parsing JSON e problemi specifici RPC.
Approccio di esempio:
Includere operazioni critiche in blocchi try-catch.
Registrare messaggi di errore dettagliati per facilitare il debug e la risoluzione dei problemi.
Controlli di validazione: Eseguire validazioni approfondite delle risposte per garantire l'integrità dei dati. Questo include il confronto degli ID di risposta con quelli delle richieste e la verifica della presenza di campi attesi come result o error.
Approccio di esempio:
Dopo aver ricevuto una risposta, verificare che l'id corrisponda alla richiesta originale.
Assicurarsi che la risposta contenga un campo result o error per determinare l'esito.
Buone pratiche:
Logging: Mantenere registri dettagliati di tutti i tentativi di comunicazione, successi e fallimenti. Questo aiuta nel troubleshooting e nella comprensione del comportamento del sistema in varie condizioni.
Degradazione graduale: In caso di errori non critici, permettere al sistema di continuare a funzionare gestendo i fallimenti in modo elegante senza crash o interruzioni di altre operazioni.
Conclusione
Comunicare con dispositivi Shelly tramite BLE e RPC offre una potente opportunità per creare integrazioni smart home sofisticate e soluzioni di automazione. Comprendendo l'architettura BLE, i servizi GATT e i meccanismi RPC, gli sviluppatori possono realizzare framework di comunicazione robusti ed efficienti su misura per le loro esigenze specifiche. Questa guida ha fornito una roadmap dettagliata per stabilire una comunicazione senza interruzioni, permettendoti di sfruttare appieno le capacità smart di Shelly su vari linguaggi di programmazione e piattaforme.
Apprezziamo il tuo feedback!
Grazie per aver dedicato del tempo a leggere il nostro articolo! Ti è stato utile o interessante?
I tuoi suggerimenti possono aiutarci a migliorare. Saremmo grati per qualsiasi feedback. Se hai un momento,
per favore condividilo con noi al seguente indirizzo email: