Eseguire il debug della home page locale

1. Prima di iniziare

Le integrazioni della smart home consentono all'Assistente Google di controllare i dispositivi connessi nelle case degli utenti. Per creare un'azione per la smart home, devi fornire un endpoint webhook per il 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 a Cloud fulfillment per aggiornare lo stato del dispositivo.

L'SDK della casa locale migliora l'integrazione della tua smart home aggiungendo un percorso locale per indirizzare gli intent per la smart home direttamente a un dispositivo Google Home. Questa funzionalità aumenta l'affidabilità e riduce la latenza nell'elaborazione dei comandi degli utenti. Consente di scrivere e implementare un'app di distribuzione locale in TypeScript o JavaScript che identifica i dispositivi ed esegue comandi su qualsiasi smart speaker Google Home o smart display Google Nest. L'app comunica quindi direttamente con gli smart device esistenti degli utenti sulla local area network utilizzando i protocolli standard esistenti per eseguire i comandi.

72ffb320986092c.png

Il debug delle azioni per la smart home è un passaggio fondamentale per creare le tue azioni con qualità produttiva, ma è impegnativo e dispendioso in termini di tempo senza strumenti informativi e di facile utilizzo per la risoluzione dei problemi e i test. Per facilitare il debug delle Azioni per la smart home, sono disponibili le metriche, Logging e Test Suite per la smart home di Google Cloud Platform (GCP) che consentono di identificare e risolvere i problemi delle Azioni.

Prerequisiti

Cosa creerai

In questo codelab, creerai un fulfillment locale per le azioni della smart home e lo connetterai all'assistente, quindi eseguirai il debug dell'app Home locale tramite la Test Suite per la smart home, le metriche e il logging di Google Cloud Platform (GCP).

Cosa imparerai a fare

  • Come utilizzare le metriche e il logging di Google Cloud per identificare e risolvere i problemi di produzione.
  • Come utilizzare il Test Suite per identificare problemi funzionali e delle API.
  • Come usare Chrome Dev Tools durante lo sviluppo dell'app Local Home.

Che cosa ti serve

2. Esegui l'app della lavatrice

Ottieni il codice sorgente

Fai clic sul seguente link per scaricare l'esempio per questo codelab sulla tua macchina di sviluppo:

...oppure clona il repository GitHub dalla riga di comando:

$ git clone https://github.com/google-home/smarthome-debug-local.git

Informazioni sul progetto

L'app di base contiene sottodirectory e funzioni Cloud Functions simili a quelle del codelab Abilita il fulfillment locale per le azioni della smart home. Invece di app-start, abbiamo app-faulty. Inizieremo con un'app per la casa locale che funzioni, ma non molto bene.

Connettersi a Firebase

Utilizzeremo lo stesso progetto che hai creato nel codelab Abilita il fulfillment locale per le azioni per la smart home, ma eseguiremo il deployment dei file scaricati in questo codelab.

Vai alla directory app-faulty, quindi configura l'interfaccia a riga di comando di Firebase con il progetto Actions creato nel codelab relativo all'abilitazione del fulfillment locale per le azioni della smart home:

$ cd app-faulty
$ firebase use <project-id>

Eseguire il deployment in Firebase

Vai alla cartella app-faulty/functions e installa tutte le dipendenze necessarie utilizzando npm:

$ cd functions
$ npm install

Nota:se viene visualizzato il messaggio seguente, puoi ignorarlo e procedere. L'avviso è dovuto ad alcune dipendenze meno recenti. Puoi trovare ulteriori dettagli qui.

found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Passa alla directory app-faulty/local/ ed esegui questi comandi per scaricare il compilatore TypeScript e compilare l'app:

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

Questo comando compila l'origine index.ts (TypeScript) e inserisce i seguenti contenuti nella directory app-faulty/public/local-home/:

  • bundle.js: output JavaScript compilato contenente l'app e le dipendenze locali.
  • 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 Cloud Functions for Firebase.

Aggiorna Home Graph

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 ae8d3b25777a5e30.png per aggiornare Home Graph tramite Richiedi sincronizzazione con i metadati del dispositivo più recenti dall'app della lavatrice difettosa:

fa3c47f293cfe0b7.png

Apri l'app Google Home e verifica di vedere il nuovo nome della lavatrice difettosa. Ricordati di assegnare il dispositivo a una stanza in cui è inserito un dispositivo Nest.

2a082ee11d47ad1a.png

3. Avviare la lavatrice smart

Se hai eseguito il codelab Abilita il fulfillment locale per le azioni per la smart home, dovresti aver già avviato la smartwash virtuale. Se viene interrotto, 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. Testa l'app Local Home

Invia comandi al tuo dispositivo Google Home tramite comandi vocali, ad esempio:

"Hey Google, accendi la lavatrice."

"Hey Google, avvia la lavatrice."

"Hey Google, forza la localizzazione."

"Hey Google, interrompi la lavatrice."

Quando provi a controllare la lavatrice dopo aver eseguito l'operazione "forza locale", l'Assistente Google risponde con il messaggio "Spiacenti, sembra che la lavatrice difettosa non sia disponibile in questo momento".

Ciò significa che il dispositivo non è raggiungibile tramite un percorso locale. Ha funzionato prima di dire "Hey Google, forza locale", perché torneremo a utilizzare il percorso cloud quando il dispositivo non è raggiungibile attraverso un percorso locale. Tuttavia, dopo il comando "forza locale", l'opzione di tornare al percorso cloud è disabilitata.

Per scoprire qual è il problema, usiamo gli strumenti a nostra disposizione: Metriche della piattaforma Google Cloud (GCP), Logging e Strumenti per sviluppatori di Chrome.

5. Eseguire il debug dell'app Local Home

Nella sezione che segue, 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 in modo da essere a conoscenza degli errori principali riscontrati dagli utenti nell'app Local Home.

Collega gli Strumenti per sviluppatori di Chrome

Per connettere il debugger all'app di fulfillment locale, procedi nel seguente modo:

  1. Assicurati di aver collegato il tuo dispositivo Google Home a un utente con l'autorizzazione ad accedere al progetto della console di Actions.
  2. Riavvia il dispositivo Google Home; in questo modo potrai recuperare l'URL del codice HTML e la configurazione della scansione inserita nella console di Actions.
  3. Avvia Chrome sul tuo computer di sviluppo.
  4. Apri una nuova scheda di Chrome e inserisci chrome://inspect nel campo dell'indirizzo per avviare lo strumento di controllo.

Dovresti vedere un elenco di dispositivi nella pagina e l'URL dell'app dovrebbe apparire sotto il nome del dispositivo Google Home.

567f97789a7d8846.png

Avvia 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 nessun dispositivo in Home Graph. Aggiungiamo alcuni log personalizzati per capire il motivo.

Aggiungi log personalizzati

Anche se è presente un errore DEVICE_VERIFICATION_FAILED stampato dall'SDK Local Home, non è di grande aiuto 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 effettivamente 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 da poter capire se è in uso 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 eseguire nuovamente 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 Google Home aggiornata. Per verificare se il dispositivo Google Home utilizza la versione prevista, consulta i log della console in Strumenti per sviluppatori di Chrome.

ecc56508ebcf9ab.png

Accedi a Cloud Logging

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

  1. Nella console della piattaforma Cloud, vai alla pagina Progetti.
  2. Seleziona il progetto per la smart home.
  3. In Operazioni, seleziona Logging > Esplora log.

L'accesso ai dati di logging è gestito tramite Identity and Access Management (IAM) per gli utenti del progetto Actions. Per maggiori dettagli sui ruoli e sulle autorizzazioni per i dati di logging, vedi Controllo dell'accesso di Cloud Logging.

Utilizzare i filtri avanzati

Sappiamo che si verificano errori nell'intent IDENTIFY, perché il percorso locale non funziona perché non è possibile identificare il dispositivo locale. Tuttavia, vogliamo sapere esattamente di che problema si tratta, quindi filtra prima gli errori che si verificano nel gestore IDENTIFY.

Espandi la casella Anteprima 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, vengono restituiti tutti i log degli errori che vengono generati nel gestore IDENTIFY. Quindi, espandi l'ultimo errore. Troverai i errorCode e i debugString che hai appena impostato per il rifiuto della promessa nel gestore IDENTIFY.

71f2f156c6887496.png

Da debugString, risulta che l'ID dispositivo locale non è nel formato previsto. L'app Home locale prevede di ottenere l'ID dispositivo locale come stringa che inizia con deviceid seguito da 3 cifre, ma l'ID dispositivo locale in questo caso è una stringa esadecimale.

Correggi l'errore

Tornando al codice sorgente in cui analizziamo l'ID dispositivo locale dai dati dell'analisi, abbiamo notato che non abbiamo fornito la codifica per la conversione della stringa in byte. I dati di scansione vengono ricevuti come una 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 da poter capire se è in uso 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 in Firebase. In app-faulty/local, esegui:

$ npm run build
$ firebase deploy --only hosting

Verifica la correzione

Dopo l'implementazione, 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 vedere errori nella Console Strumenti per sviluppatori di Chrome.

c8456f7b5f77f894.png

Ora puoi provare a inviare di nuovo i comandi al tuo dispositivo.

"Hey Google, forza la localizzazione."

"Hey Google, interrompi la lavatrice."

"Hey Google, accendi la lavatrice."

...

"Hey Google, forza l'impostazione predefinita."

6. Esegui Test Suite per la smart home

Dopo aver verificato il dispositivo usando i controlli touch nell'app Google Home o tramite i comandi vocali, puoi utilizzare la Test Suite per la smart home automatizzata per convalidare i casi d'uso in base ai tipi di dispositivi e ai trait associati all'Azione. La Test Suite esegue una serie di test per rilevare problemi nell'Azione e mostra messaggi informativi sugli scenari di test non riusciti per accelerare il debug prima di analizzare i log eventi.

Esegui Test Suite per la smart home

Segui queste istruzioni per testare l'Azione per la smart home con Test Suite:

  1. Nel browser web, apri la Suite di test per la smart home.
  2. Accedi a Google utilizzando il pulsante nell'angolo in alto a destra. In questo modo il Test Suite può inviare i comandi direttamente all'Assistente Google.
  3. Nel campo ID progetto, inserisci l'ID progetto dell'azione per la smart home. Fai clic su AVANTI per continuare.
  4. Nel passaggio Impostazioni di test, dovresti vedere la tua lavatrice difettosa nella sezione Dispositivi e sistemi.
  5. Disattiva l'opzione Richiesta di sincronizzazione di test poiché l'app della lavatrice di esempio non ha una UI per l'aggiunta, la rimozione o il ridenominazione della lavatrice. In un sistema di produzione, devi attivare Richiedi sincronizzazione ogni volta che l'utente aggiunge / rimuove / rinomina i dispositivi.
  6. Lascia attivata l'opzione SDK Local Home perché testeremo sia i percorsi locali che quelli cloud.
  7. Fai clic su AVANTI per iniziare a eseguire il test.

67433d9190fa770e.png

Al termine dei test, noterai che i test Metti in pausa/Riprendi nel percorso locale non vanno a buon fine mentre vengono superati i test Metti in pausa/Riprendi nel percorso cloud.

d1ebd5cfae2a2a47.png

Analizza messaggio di errore

Esamina più da vicino i messaggi di errore negli scenari di test non riusciti. e ti indicano lo stato previsto per il test e quello 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 attuale abbiamo isPaused: false.

6bfd3acef9c16b84.png

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

Identifica e correggi l'errore

Troviamo 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 infatti impostando isPause sullo stato inverso, dovrebbe essere impostato su true quando params.pause è true e false negli altri casi. Quindi 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 {};
    }
}

Cambia la versione dell'app Home locale in modo da poter capire se è in uso la versione corretta.

local/index.ts

const localHomeSdk = new App('1.0.3');

Ricordati di compilare di nuovo l'app ed eseguire nuovamente il deployment in Firebase. In app-faulty/local, esegui:

$ npm run build
$ firebase deploy --only hosting

Ora riavvia il dispositivo Google Home affinché possa caricare l'app Home locale aggiornata. Assicurati che la versione dell'app Home locale sia 1.0.3.

Verifica la correzione

Ora, esegui di nuovo la Test Suite per la smart home con le stesse configurazioni: scoprirai 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 Home locale con la Test Suite per la smart home e Cloud Logging.

Scopri di più

Ecco alcune altre cose che puoi provare a fare:

Scopri di più su come testare e inviare un'Azione per la revisione, inclusa la procedura di certificazione per la pubblicazione dell'Azione per gli utenti.