1. Prima di iniziare
Le integrazioni per la smart home consentono all'Assistente Google di controllare i dispositivi connessi nelle case degli utenti. Per creare un'integrazione cloud-to-cloud, devi fornire un endpoint webhook cloud in grado di gestire gli intent per la smart home. Ad esempio, quando un utente dice "Hey Google, accendi le luci", l'assistente invia il comando al tuo cloud fulfillment per aggiornare lo stato del dispositivo.
L'SDK Local Home migliora l'integrazione della tua smart home aggiungendo un percorso locale per instradare gli intent della smart home direttamente a un dispositivo Google Home, il che migliora l'affidabilità e riduce la latenza nell'elaborazione dei comandi degli utenti. Ti consente di scrivere ed eseguire il deployment di un'app di evasione degli ordini locale in TypeScript o JavaScript che identifica i dispositivi ed esegue i comandi su qualsiasi smart speaker Google Home o smart display Google Nest. L'app comunica quindi direttamente con gli smart device esistenti degli utenti tramite la rete locale utilizzando i protocolli standard esistenti per eseguire i comandi.
Il debug delle integrazioni cloud-to-cloud è un passaggio fondamentale per creare integrazioni con qualità di produzione, ma è impegnativo e richiede tempo se non si dispone di strumenti di risoluzione dei problemi e di test informativi e facili da usare. Per semplificare il debug delle integrazioni cloud-to-cloud, sono disponibili Metriche e Logging di Google Cloud (GCP) e la Suite di test per la smart home per aiutarti a identificare e risolvere i problemi delle integrazioni.
Prerequisiti
- Guida per gli sviluppatori su come creare un'integrazione cloud-to-cloud
- Esegui il codelab Attivare l'evasione degli ordini locali per le integrazioni cloud-to-cloud
Cosa creerai
In questo codelab, creerai un'implementazione locale per le integrazioni cloud-to-cloud e la collegherai all'assistente, quindi eseguirai il debug dell'app Home locale tramite la suite di test per le metriche e i log della smart home e della piattaforma Google Cloud (Google Cloud).
Obiettivi didattici
- Come utilizzare le metriche e la registrazione di Google Cloud per identificare e risolvere i problemi di produzione.
- Come utilizzare la Test Suite per identificare i problemi relativi alle API e al funzionamento.
- Come utilizzare gli Strumenti per sviluppatori di Chrome durante lo sviluppo dell'app Local Home.
Che cosa ti serve
- L'ultima versione di Google Chrome
- Un dispositivo iOS o Android con l'app Google Home
- Uno speaker smart Google Home o un display smart Google Nest
- Node.js versione 10.16 o successive
- Un Account Google
- Un account di fatturazione Google Cloud.
2. Esegui l'app della lavatrice
Ottieni il codice sorgente
Fai clic sul seguente link per scaricare il Sample per questo codelab sulla tua macchina di sviluppo:
In alternativa, puoi clonare il repository GitHub dalla riga di comando:
$ git clone https://github.com/google-home/smarthome-debug-local.git
Informazioni sul progetto
L'app di avvio contiene sottodirectory e funzioni cloud simili a quelle del codelab Abilita il completamento locale per le integrazioni cloud-to-cloud. Ma qui, invece di app-start
, abbiamo app-faulty
. Inizieremo con un'app Home locale che funziona, ma non benissimo.
Connettersi a Firebase
Utilizzeremo lo stesso progetto che hai creato nel codelab Attivare l'evasione degli ordini locale per le integrazioni cloud-to-cloud, ma eseguiremo il deployment dei file scaricati in questo codelab.
Vai alla directory app-faulty
, quindi configura l'interfaccia a riga di comando Firebase con il progetto di integrazione creato nel codelab Abilita l'evasione degli ordini locale per le integrazioni cloud-to-cloud:
$ cd app-faulty $ firebase use <project-id>
Esegui il deployment in Firebase
Vai alla cartella app-faulty/functions
e installa tutte le dipendenze necessarie utilizzando npm
:
$ cd functions $ npm install
Nota:se vedi il messaggio riportato di seguito, puoi ignorarlo e procedere. L'avviso è dovuto ad alcune dipendenze precedenti e puoi trovare ulteriori dettagli qui.
found 5 high severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
Vai alla directory app-faulty/local/
ed esegui i comandi seguenti per scaricare il compilatore TypeScript e compilare l'app:
$ cd ../local $ npm install $ npm run build
Verrà compilato il codice sorgente index.ts
(TypeScript) e i seguenti contenuti verranno inseriti nella directory app-faulty/public/local-home/
:
bundle.js
: output JavaScript compilato contenente l'app locale e le dipendenze.index.html
: pagina di hosting locale utilizzata per pubblicare l'app per i test sul dispositivo.
Ora che hai installato le dipendenze e configurato il progetto, puoi eseguire l'app per la prima volta.
$ firebase deploy
Questo è l'output della console che dovresti vedere:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<projectcd -id>.web.app
Questo comando esegue il deployment di un'app web e di diverse funzioni Cloud per Firebase.
Aggiornare HomeGraph
Apri l'URL di hosting nel browser (https://<project-id>.web.app
) per visualizzare l'app web. Nell'interfaccia utente web, fai clic sul pulsante Aggiorna per aggiornare HomeGraph tramite Richiedi sincronizzazione con i metadati del dispositivo più recenti dell'app della lavatrice difettosa:
Apri l'app Google Home e verifica di poter vedere la lavatrice con un nuovo nome "Lavatrice difettosa". Ricordati di assegnare il dispositivo a una stanza in cui è presente un dispositivo Nest.
3. Avvia la lavatrice smart
Se hai eseguito il codelab Attivare l'evasione degli ordini locali per le integrazioni cloud-to-cloud, dovresti aver già avviato la lavatrice smart virtuale. Se è fermo, ricordati di riavviare il dispositivo virtuale.
Avvia il dispositivo
Vai alla directory virtual-device/
ed esegui lo script del dispositivo, passando i parametri di configurazione come argomenti:
$ cd ../../virtual-device $ npm install $ npm start -- \ --deviceId=deviceid123 --projectId=<project-id> \ --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK
Verifica che lo script del dispositivo venga eseguito con i parametri previsti:
(...): UDP Server listening on 3311 (...): Device listening on port 3388 (...): Report State successful
4. Testare l'app Home locale
Invia comandi al tuo dispositivo tramite comandi vocali al dispositivo Google Home, ad esempio:
"Hey Google, accendi la lavatrice."
"Hey Google, avvia la lavatrice."
"Hey Google, forza locale."
"Hey Google, interrompi la lavatrice."
Quando provi a controllare la lavatrice dopo "force local", l'Assistente Google risponderà con "Mi dispiace, sembra che la lavatrice con problemi non sia disponibile al momento".
Ciò significa che il dispositivo non è raggiungibile tramite un percorso locale. Funzionava prima di emettere "Hey Google, forza locale" perché torneremo a utilizzare il percorso sul cloud quando il dispositivo non è raggiungibile tramite un percorso locale. Tuttavia, dopo "force local", l'opzione di ripristino del percorso cloud è disattivata.
Per scoprire qual è il problema, utilizziamo gli strumenti a nostra disposizione: Metriche e Logging della piattaforma Google Cloud (GCP) e gli Strumenti per sviluppatori di Chrome.
5. Eseguire il debug dell'app Home locale
Nella sezione seguente, utilizzerai gli strumenti forniti da Google per scoprire perché il dispositivo non è raggiungibile tramite il percorso locale. Puoi utilizzare gli strumenti per sviluppatori di Google Chrome per connetterti al dispositivo Google Home, visualizzare i log della console ed eseguire il debug dell'app Home locale. Puoi anche inviare log personalizzati a Cloud Logging per essere a conoscenza degli errori principali rilevati dagli utenti nell'app Home locale.
Collegare gli Strumenti per sviluppatori di Chrome
Per collegare il debugger all'app di evasione degli ordini locale:
- Assicurati di aver collegato il tuo dispositivo Google Home a un utente con l'autorizzazione ad accedere al progetto Developer Console.
- Riavvia il dispositivo Google Home, in modo che possa recuperare l'URL del codice HTML e la configurazione della scansione inserita in Play Console.
- Avvia Chrome sulla tua macchina di sviluppo.
- Apri una nuova scheda di Chrome e inserisci
chrome://inspect
nel campo dell'indirizzo per avviare l'ispezione.
Nella pagina dovresti vedere un elenco di dispositivi e l'URL dell'app dovrebbe essere visualizzato sotto il nome del dispositivo Google Home.
Avvia lo strumento di controllo
Fai clic su Controlla sotto l'URL dell'app per avviare gli Strumenti per sviluppatori di Chrome. Seleziona la scheda Console e verifica di poter vedere i contenuti dell'intent IDENTIFY
stampati dall'app TypeScript.
Questo output indica che l'handler IDENTIFY è stato attivato correttamente, ma il valore verificationId
restituito in IdentifyResponse
non corrisponde a nessuno dei dispositivi nel tuo HomeGraph. Aggiungiamo alcuni log personalizzati per scoprire il motivo.
Aggiungere log personalizzati
Sebbene l'SDK Local Home stampi un errore DEVICE_VERIFICATION_FAILED
, questo non aiuta molto a trovare la causa principale. Aggiungiamo alcuni log personalizzati per assicurarci di leggere ed elaborare correttamente i dati della scansione e tieni presente che, se rifiutiamo la promessa con un errore, il messaggio di errore viene inviato anche a Cloud Logging.
local/index.ts
identifyHandler(request: IntentFlow.IdentifyRequest):
Promise<IntentFlow.IdentifyResponse> {
console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));
const scanData = request.inputs[0].payload.device.udpScanData;
if (!scanData) {
const err = new IntentFlow.HandlerError(request.requestId,
'invalid_request', 'Invalid scan data');
return Promise.reject(err);
}
// In this codelab, the scan data contains only local device id.
// Is there something wrong here?
const localDeviceId = Buffer.from(scanData.data);
console.log(`IDENTIFY handler: received local device id
${localDeviceId}`);
// Add custom logs
if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
const err = new IntentFlow.HandlerError(request.requestId,
'invalid_device', 'Invalid device id from scan data ' +
localDeviceId);
return Promise.reject(err);
}
const response: IntentFlow.IdentifyResponse = {
intent: Intents.IDENTIFY,
requestId: request.requestId,
payload: {
device: {
id: 'washer',
verificationId: localDeviceId.toString(),
}
}
};
console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));
return Promise.resolve(response);
}
Inoltre, modifica la versione locale dell'app Home in modo che possiamo identificare se stiamo utilizzando la versione corretta.
local/index.ts
const localHomeSdk = new App('1.0.1');
Dopo aver aggiunto i log personalizzati, devi compilare di nuovo l'app e re-eseguirne il deployment in Firebase.
$ cd ../app-faulty/local $ npm run build $ firebase deploy --only hosting
Ora riavvia il dispositivo Google Home in modo che possa caricare l'app Home locale aggiornata. Puoi vedere se il dispositivo Google Home utilizza la versione prevista controllando i log della console in Strumenti per sviluppatori di Chrome.
Accedere a Cloud Logging
Vediamo come utilizzare Cloud Logging per trovare gli errori. Per accedere a Cloud Logging per il tuo progetto:
- Nella console della piattaforma Cloud, vai alla pagina Progetti.
- Seleziona il tuo progetto per la smart home.
- In Operazioni, seleziona Logging > Esplora log.
L'accesso ai dati di logging viene gestito tramite Identity and Access Management (IAM) per gli utenti del progetto di integrazione. Per ulteriori dettagli su ruoli e autorizzazioni per la registrazione dei dati, consulta il controllo dell'accesso di Cloud Logging.
Utilizzare i filtri avanzati
Sappiamo che si verificano errori nell'intent IDENTIFY
, in quanto il percorso locale non funziona perché non è possibile identificare il dispositivo locale. Tuttavia, vogliamo sapere esattamente qual è il problema, quindi eliminiamo prima gli errori che si verificano nell'handler IDENTIFY
.
Fai clic sul pulsante di attivazione/disattivazione Mostra query, che dovrebbe trasformarsi in una casella Query Builder. Inserisci jsonPayload.intent="IDENTIFY"
nella casella Query Builder e fai clic sul pulsante Esegui query.
Di conseguenza, vengono visualizzati tutti i log degli errori generati nell'handler IDENTIFY
. Poi, espandi l'ultimo errore. Troverai errorCode
e debugString
che hai appena impostato quando rifiuti la promessa nel gestore IDENTIFY
.
Da debugString
, possiamo dire che l'ID dispositivo locale non è nel formato previsto. L'app Home locale si aspetta di ricevere l'ID dispositivo locale come stringa che inizia con deviceid
seguita da 3 cifre, ma l'ID dispositivo locale qui è una stringa esadecimale.
Correggi l'errore
Tornando al codice sorgente in cui analizziamo l'ID dispositivo locale dai dati di scansione, notiamo che non abbiamo fornito la codifica durante la conversione della stringa in byte. I dati della scansione vengono ricevuti come stringa esadecimale, quindi passa hex
come codifica dei caratteri quando chiami Buffer.from()
.
local/index.ts
identifyHandler(request: IntentFlow.IdentifyRequest):
Promise<IntentFlow.IdentifyResponse> {
console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));
const scanData = request.inputs[0].payload.device.udpScanData;
if (!scanData) {
const err = new IntentFlow.HandlerError(request.requestId,
'invalid_request', 'Invalid scan data');
return Promise.reject(err);
}
// In this codelab, the scan data contains only local device id.
const localDeviceId = Buffer.from(scanData.data, 'hex');
console.log(`IDENTIFY handler: received local device id
${localDeviceId}`);
if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
const err = new IntentFlow.HandlerError(request.requestId,
'invalid_device', 'Invalid device id from scan data ' +
localDeviceId);
return Promise.reject(err);
}
const response: IntentFlow.IdentifyResponse = {
intent: Intents.IDENTIFY,
requestId: request.requestId,
payload: {
device: {
id: 'washer',
verificationId: localDeviceId.toString(),
}
}
};
console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));
return Promise.resolve(response);
}
Inoltre, modifica la versione locale dell'app Home in modo che possiamo identificare se stiamo utilizzando la versione corretta.
local/index.ts
const localHomeSdk = new App('1.0.2');
Dopo aver corretto l'errore, compila l'app e esegui nuovamente il deployment in Firebase. In app-faulty/local
, esegui:
$ npm run build $ firebase deploy --only hosting
Testa la correzione
Dopo il deployment, riavvia il dispositivo Google Home in modo che possa caricare l'app Home locale aggiornata. Assicurati che la versione dell'app Home locale sia 1.0.2 e, questa volta, non dovresti visualizzare errori nella Console degli strumenti per sviluppatori di Chrome.
Ora puoi provare a inviare di nuovo i comandi al dispositivo.
"Hey Google, forza locale."
"Hey Google, interrompi la lavatrice."
"Hey Google, accendi la lavatrice."
…
"Hey Google, forza predefinito."
6. Esegui la suite di test per la smart home
Dopo aver verificato il dispositivo utilizzando i controlli touch nell'app Google Home o tramite i comandi vocali, puoi utilizzare la Suite di test automatica per la smart home per convalidare i casi d'uso in base ai tipi di dispositivi e alle caratteristiche associate all'integrazione. La suite di test esegue una serie di test per rilevare i problemi nell'integrazione e mostra messaggi informativi per i casi di test non riusciti per velocizzare il debug prima di esaminare i log degli eventi.
Esegui la suite di test per la smart home
Segui queste istruzioni per testare l'integrazione cloud-to-cloud tramite Test Suite:
- Nel browser web, apri la Suite di test per la smart home.
- Accedi a Google utilizzando il pulsante nell'angolo in alto a destra. In questo modo, la suite di test può inviare i comandi direttamente all'Assistente Google.
- Nel campo ID progetto, inserisci l'ID progetto dell'integrazione cloud-to-cloud. Poi fai clic su AVANTI per continuare.
- Nel passaggio Test Settings (Impostazioni test), dovresti vedere la lavatrice difettosa nella sezione Devices and Trais (Dispositivi e tratti).
- Disattiva l'opzione Testa la sincronizzazione delle richieste poiché l'app della lavatrice di esempio non ha un'interfaccia utente per aggiungere / rimuovere / rinominare la lavatrice. In un sistema di produzione, devi attivare Richiedi sincronizzazione ogni volta che l'utente aggiunge / rimuove / rinomina i dispositivi.
- Lascia attiva l'opzione SDK della casa locale perché testeremo i percorsi locali e cloud.
- Fai clic su Avanti: ambiente di test per iniziare a eseguire il test.
Al termine dei test, noterai che i test di pausa/ripristino nel percorso locale non vanno a buon fine, mentre quelli nel percorso cloud vanno a buon fine.
Analizzare il messaggio di errore
Esamina più da vicino i messaggi di errore nei casi di test non riusciti. Ti indicano lo stato previsto per il test e lo stato effettivo. In questo caso, per "Metti in pausa la lavatrice", lo stato previsto è isPaused: true
, ma lo stato effettivo è isPaused: false
. Analogamente, per "Metti in pausa la lavatrice", lo stato previsto è isPaused: true
, ma lo stato effettivo è isPaused: false
.
Dai messaggi di errore sembra che nel percorso locale stiamo impostando lo stato isPaused
in modo inverso.
Identifica e correggi l'errore
Cerchiamo il codice sorgente in cui l'app Home locale invia il comando di esecuzione al dispositivo. getDataCommand()
è la funzione chiamata da executeHandler()
per impostare payload
nel comando di esecuzione inviato al dispositivo.
local/index.ts
getDataForCommand(command: string, params: IWasherParams): unknown {
switch (command) {
case 'action.devices.commands.OnOff':
return {
on: params.on ? true : false
};
case 'action.devices.commands.StartStop':
return {
isRunning: params.start ? true : false
};
case 'action.devices.commands.PauseUnpause':
return {
// Is there something wrong here?
isPaused: params.pause ? false : true
};
default:
console.error('Unknown command', command);
return {};
}
}
Stiamo impostando isPause
nello stato opposto, deve essere impostato su true
quando params.pause
è true
e su false
in caso contrario. Risolviamo il problema.
local/index.ts
getDataForCommand(command: string, params: IWasherParams): unknown {
switch (command) {
case 'action.devices.commands.OnOff':
return {
on: params.on ? true : false
};
case 'action.devices.commands.StartStop':
return {
isRunning: params.start ? true : false
};
case 'action.devices.commands.PauseUnpause':
return {
isPaused: params.pause ? true : false
};
default:
console.error('Unknown command', command);
return {};
}
}
Modifica la versione locale dell'app Home, in modo che possiamo identificare se stiamo utilizzando la versione corretta.
local/index.ts
const localHomeSdk = new App('1.0.3');
Ricorda di compilare di nuovo l'app e di eseguirne il nuovo deployment su Firebase. In app-faulty/local
, esegui:
$ npm run build $ firebase deploy --only hosting
Ora riavvia il dispositivo Google Home in modo che possa caricare l'app Home locale aggiornata. Assicurati che la versione dell'app Home locale sia 1.0.3.
Testa la correzione
Ora esegui di nuovo la suite di test per la smart home con le stesse configurazioni e vedrai che tutti i casi di test sono stati superati.
7. Complimenti
Complimenti! Hai imparato a risolvere i problemi di un'app Home locale tramite la suite di test per la smart home e Cloud Logging.
Scopri di più
Ecco alcune altre cose che puoi provare a fare:
- Aggiungi altri attributi supportati al tuo dispositivo e testa con Test Suite.
- Aggiungi altri log personalizzati in ciascuno degli handler intent e visualizzali in Cloud Logging.
- Crea dashboard, configura avvisi e accedi ai dati delle metriche in modo programmatico per ottenere metriche di utilizzo utili sulla tua integrazione.
Puoi anche scoprire di più su come testare e inviare un'integrazione per la revisione, inclusa la procedura di certificazione per pubblicare l'integrazione per gli utenti.