Eseguire il debug della home page locale

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 all'esecuzione cloud per aggiornare lo stato del dispositivo.

L'SDK Local Home migliora l'integrazione della tua smart home aggiungendo un percorso locale per il routing degli 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 e implementare un'app di adempimento 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.

72ffb320986092c.png

Il debug delle integrazioni cloud-to-cloud è un passaggio fondamentale per creare integrazioni di qualità di produzione, ma è difficile e richiede molto tempo senza strumenti di test e risoluzione dei problemi informativi e facili da usare. Per facilitare il debug delle integrazioni cloud-to-cloud, sono disponibili le metriche e il logging di Google Cloud Platform (GCP) e la suite di test per la smart home per aiutarti a identificare e risolvere i problemi delle tue integrazioni.

Prerequisiti

Cosa creerai

In questo codelab creerai un fulfillment locale per le integrazioni da cloud a cloud e lo connetterai all'assistente, quindi eseguirai il debug dell'app Local Home tramite la suite di test per smart home e le metriche e la registrazione di Google Cloud (GCP).

Obiettivi didattici

  • Come utilizzare le metriche e la registrazione di GCP per identificare e risolvere i problemi di produzione.
  • Come utilizzare Test Suite per identificare problemi funzionali e relativi alle API.
  • Come utilizzare gli Strumenti per sviluppatori di Chrome durante lo sviluppo dell'app Local Home.

Che cosa ti serve

2. Esegui l'app della lavatrice

Recuperare il codice sorgente

Fai clic sul seguente link per scaricare l'esempio per questo codelab sul tuo computer di sviluppo:

...oppure 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 iniziale contiene sottodirectory e funzioni cloud simili a quelle del codelab Attiva il fulfillment locale per le integrazioni cloud-to-cloud. Ma anziché app-start, qui abbiamo app-faulty. Inizieremo con un'app per la casa locale che funziona, ma non benissimo.

Connessione a Firebase

Utilizzeremo lo stesso progetto che hai creato nel codelab Attivare l'evasione locale per le integrazioni cloud-to-cloud, ma implementeremo i file scaricati in questo codelab.

Vai alla directory app-faulty, quindi configura la CLI Firebase con il progetto di integrazione creato nel codelab Abilita l'evasione locale per le integrazioni da cloud a 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 visualizzi il messaggio riportato di seguito, puoi ignorarlo e procedere. L'avviso è dovuto ad alcune dipendenze precedenti e puoi trovare maggiori 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 seguenti comandi per scaricare il compilatore TypeScript e compilare l'app:

$ cd ../local
$ npm install
$ npm run build

In questo modo viene compilata l'origine index.ts (TypeScript) e i seguenti contenuti vengono 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, insieme a diverse Cloud Functions for Firebase.

Aggiorna 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 Aggiornaae8d3b25777a5e30.png per aggiornare HomeGraph con i metadati del dispositivo più recenti dall'app della lavatrice difettosa utilizzando Richiedi sincronizzazione.

fa3c47f293cfe0b7.png

Apri l'app Google Home e verifica di poter vedere la lavatrice con il nuovo nome "Lavatrice difettosa". Ricordati di assegnare il dispositivo a una stanza in cui è presente un dispositivo Nest.

2a082ee11d47ad1a.png

3. Avvia la lavatrice smart

Se hai eseguito il codelab Attiva l'evasione locale per le integrazioni da cloud a cloud, dovresti aver già avviato la lavatrice smart virtuale. Se è stato interrotto, ricordati di riavviare il dispositivo virtuale.

Avviare 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 Local Home

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, ferma la lavatrice."

Noterai che l'Assistente Google risponde con "Mi dispiace, sembra che la lavatrice difettosa non sia disponibile al momento" quando provi a controllarla dopo aver utilizzato il comando "force local".

Ciò significa che il dispositivo non è raggiungibile tramite un percorso locale. Funzionava prima di pronunciare "Hey Google, forza locale" perché torneremo a utilizzare il percorso cloud quando il dispositivo non è raggiungibile tramite un percorso locale. Tuttavia, dopo "force local", l'opzione di fallback al percorso cloud viene disattivata.

Per scoprire qual è il problema, utilizziamo gli strumenti a nostra disposizione: metriche e registrazione di Google Cloud Platform (GCP) e Chrome DevTools.

5. Eseguire il debug dell'app Local Home

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 Local Home. Puoi anche inviare log personalizzati a Cloud Logging per conoscere gli errori più comuni riscontrati dagli utenti nell'app Local Home.

Connettere gli Strumenti per sviluppatori di Chrome

Per connettere il debugger all'app di evasione locale:

  1. Assicurati di aver collegato il tuo dispositivo Google Home a un utente autorizzato ad accedere al progetto Developer Console.
  2. Riavvia il dispositivo Google Home, in modo che possa ottenere l'URL del tuo HTML e la configurazione della scansione che hai inserito nella Developer Console.
  3. Avvia Chrome sulla macchina di sviluppo.
  4. Apri una nuova scheda di Chrome e inserisci chrome://inspect nel campo dell'indirizzo per avviare lo strumento di ispezione.

Dovresti vedere un elenco di dispositivi nella pagina e l'URL della tua app dovrebbe essere visualizzato sotto il nome del tuo dispositivo Google Home.

567f97789a7d8846.png

Avviare lo strumento di controllo

Fai clic su Ispeziona sotto l'URL dell'app per avviare gli Strumenti per sviluppatori di Chrome. Seleziona la scheda Console e verifica di poter visualizzare i contenuti dell'intent IDENTIFY stampati dall'app TypeScript.

774c460c59f9f84a.png

Questo output indica che il gestore IDENTIFY è stato attivato correttamente, ma il valore verificationId restituito in IdentifyResponse non corrisponde a nessuno dei dispositivi in HomeGraph. Aggiungiamo alcuni log personalizzati per scoprire il motivo.

Aggiungere log personalizzati

Sebbene l'SDK Local Home stampi un errore DEVICE_VERIFICATION_FAILED, non è molto utile per trovare la causa principale. Aggiungiamo alcuni log personalizzati per assicurarci di leggere ed elaborare correttamente i dati della scansione. 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 dell'app per la casa locale, in modo da poter 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 ed eseguirne nuovamente il deployment su 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 per la casa locale aggiornata. Puoi verificare se il dispositivo Google Home utilizza la versione prevista esaminando i log della console in Chrome DevTools.

ecc56508ebcf9ab.png

Accedere a Cloud Logging

Vediamo come utilizzare Cloud Logging per trovare gli errori. Per accedere a Cloud Logging per il tuo progetto:

  1. Nella console Cloud Platform, vai alla pagina Progetti.
  2. Seleziona il progetto di smart home.
  3. 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 saperne di più su ruoli e autorizzazioni per i dati di logging, consulta la sezione Controllo dell'accesso di Cloud Logging.

Utilizzare i filtri avanzati

Sappiamo che si verificano errori nell'intent IDENTIFY, poiché il percorso locale non funziona perché non è possibile identificare il dispositivo locale. Tuttavia, vogliamo sapere esattamente qual è il problema, quindi filtriamo prima gli errori che si verificano nel gestore 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.

4c0b9d2828ee2447.png

Di conseguenza, ricevi tutti i log degli errori generati nel gestore IDENTIFY. Poi, espandi l'ultimo errore. Troverai errorCode e debugString che hai appena impostato quando rifiuti la promessa nel gestore IDENTIFY.

71f2f156c6887496.png

Dal debugString, possiamo notare che l'ID dispositivo locale non è nel formato previsto. L'app Local Home prevede di ricevere l'ID dispositivo locale come stringa che inizia con deviceid seguito da tre cifre, ma l'ID dispositivo locale qui è una stringa esadecimale.

Correggere 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 dell'app per la casa locale, in modo da poter 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 ed esegui di nuovo il deployment su Firebase. In app-faulty/local, esegui:

$ npm run build
$ firebase deploy --only hosting

Testare la correzione

Dopo il deployment, riavvia il dispositivo Google Home in modo che possa caricare l'app per la casa locale aggiornata. Assicurati che la versione dell'app per la casa locale sia 1.0.2 e questa volta non dovresti visualizzare errori nella console degli strumenti per sviluppatori Chrome.

c8456f7b5f77f894.png

Ora puoi provare di nuovo a inviare comandi al dispositivo.

"Hey Google, forza locale."

"Hey Google, ferma la lavatrice."

"Hey Google, accendi la lavatrice."

"Hey Google, forza predefinito."

6. Eseguire Test Suite per la smart home

Dopo aver verificato il dispositivo utilizzando i controlli touch nell'app Google Home o tramite comandi vocali, puoi utilizzare la suite di test per la smart home automatizzata per convalidare gli scenari 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 problemi nell'integrazione e mostra messaggi informativi per i casi di test non riusciti per accelerare il debug prima di esaminare i log eventi.

Eseguire Test Suite per la smart home

Segui queste istruzioni per testare l'integrazione da cloud a cloud tramite Test Suite:

  1. Nel browser web, apri la Test Suite per la smart home.
  2. Accedi a Google utilizzando il pulsante nell'angolo in alto a destra. Ciò consente alla suite di test di inviare i comandi direttamente all'Assistente Google.
  3. Nel campo ID progetto, inserisci l'ID progetto dell'integrazione cloud-to-cloud. e poi fai clic su AVANTI per continuare.
  4. Nel passaggio Impostazioni test, dovresti vedere la lavatrice difettosa nella sezione Dispositivi e percorsi.
  5. Disattiva l'opzione Sincronizzazione richiesta di test poiché l'app di esempio per la lavatrice non ha un'interfaccia utente per aggiungere, rimuovere o rinominare la lavatrice. In un sistema di produzione, devi attivare Richiedi sincronizzazione ogni volta che l'utente aggiunge, rimuove o rinomina i dispositivi.
  6. Lascia abilitata l'opzione SDK della casa locale, poiché testeremo sia i percorsi locali che quelli cloud.
  7. Fai clic su Avanti: ambiente di test per iniziare a eseguire il test.

67433d9190fa770e.png

Al termine dei test, noterai che i test di pausa/ripresa nel percorso locale non vanno a buon fine, mentre quelli nel percorso cloud vengono superati.

d1ebd5cfae2a2a47.png

Analizzare il messaggio di errore

Esamina più da vicino i messaggi di errore negli scenari 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 nello stato effettivo abbiamo ottenuto isPaused: false. Allo stesso modo, per "Metti in pausa la lavatrice", lo stato previsto è isPaused: true, ma nello stato effettivo abbiamo ottenuto isPaused: false.

6bfd3acef9c16b84.png

Dai messaggi di errore, sembra che nel percorso locale stiamo impostando lo stato isPaused in modo inverso.

Identificare e correggere l'errore

Troviamo il codice sorgente in cui l'app Local Home 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 inverso, deve essere impostato su true quando params.pause è true e false altrimenti. 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 dell'app Home locale, in modo da poter 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 nuovamente il 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 per la casa locale aggiornata. Assicurati che la versione dell'app per la casa locale sia 1.0.3.

Testare la correzione

Ora, esegui di nuovo la suite di test per la smart home con le stesse configurazioni e vedrai che tutti gli scenari di test sono stati superati.

b7fc8c5d3c727d8d.png

7. Complimenti

764dbc83b95782a.png

Complimenti! Hai imparato a risolvere i problemi di un'app Local Home utilizzando Test Suite per la smart home e Cloud Logging.

Scopri di più

Ecco alcune altre cose che puoi provare a fare:

Puoi anche scoprire di più su come testare e inviare un'integrazione per la revisione, incluso il processo di certificazione per pubblicarla per gli utenti.