Migliora e metti al sicuro le tue integrazioni cloud-to-cloud

Informazioni su questo codelab
schedule50 minuti
subjectUltimo aggiornamento: 20 novembre 2024
account_circleScritto da un Googler

1. Prima di iniziare

Le integrazioni cloud-to-cloud utilizzano i tipi di dispositivi per comunicare all'Assistente Google la grammatica da utilizzare con un dispositivo. I trait del dispositivo definiscono le funzionalità di un tipo di dispositivo. Un dispositivo eredita gli stati di ogni tratto del dispositivo aggiunto a un'integrazione.

dc8dce0dea87cd5c.png

Puoi collegare qualsiasi tratto supportato al tipo di dispositivo scelto per personalizzare la funzionalità dei dispositivi degli utenti. Se vuoi implementare nelle tue azioni attributi personalizzati non attualmente disponibili nello schema del dispositivo, gli attributi Modalità e Attiva/Disattiva consentono il controllo di impostazioni specifiche con un nome personalizzato definito da te.

Oltre alle funzionalità di controllo di base fornite da tipi e tratti, l'API Smart Home offre funzionalità aggiuntive per migliorare l'esperienza utente. Le risposte di errore forniscono un feedback dettagliato all'utente quando gli intent non vanno a buon fine. La verifica dell'utente secondario estende queste risposte e aggiunge ulteriore sicurezza alla caratteristica del dispositivo che preferisci. Se invii risposte di errore specifiche ai blocchi di verifica emessi dall'assistente, l'integrazione cloud-to-cloud può richiedere un'autorizzazione aggiuntiva per completare un comando.

Prerequisiti

Cosa creerai

In questo codelab, eseguirai il deployment di un'integrazione della smart home predefinita con Firebase, quindi imparerai ad aggiungere attributi non standard alla lavatrice per la smart home per le dimensioni del carico e la modalità turbo. Implementerai inoltre la generazione di report su errori ed eccezioni e imparerai a imporre un riconoscimento verbale per accendere la lavatrice utilizzando la verifica dell'utente secondario.

Obiettivi didattici

  • Come aggiungere le modalità e gli attributi di attivazione/disattivazione all'integrazione
  • Come segnalare errori ed eccezioni
  • Come applicare la verifica utente secondaria

Che cosa ti serve

2. Per iniziare

Abilitare Gestione attività

Per utilizzare l'Assistente Google, devi condividere determinati dati sulle tue attività con Google. L'Assistente Google ha bisogno di questi dati per funzionare correttamente, ma il requisito di condivisione dei dati non è specifico per l'SDK. Per condividere questi dati, crea un Account Google, se non ne hai già uno. Puoi utilizzare qualsiasi Account Google, non deve essere il tuo account sviluppatore.

Apri la pagina Gestione attività per l'Account Google che vuoi utilizzare con l'assistente.

Assicurati che i seguenti pulsanti di attivazione/disattivazione siano attivati:

  • Attività web e app: inoltre, assicurati di selezionare la casella di controllo Includi la cronologia di Chrome e le attività svolte su siti, app e dispositivi che usano i servizi Google.
  • Informazioni sul dispositivo
  • Attività vocale e audio

Creare un progetto di integrazione cloud-to-cloud

  1. Vai a Developer Console.
  2. Fai clic su Crea progetto, inserisci un nome per il progetto e fai clic su Crea progetto.

Assegna un nome al progetto

Seleziona l'integrazione cloud-to-cloud

Nella home page del progetto nella Console per gli sviluppatori, seleziona Aggiungi integrazione cloud-to-cloud in Cloud-to-cloud.

Aggiungi l'integrazione cloud-to-cloud

Installa l'interfaccia a riga di comando di Firebase

L'interfaccia a riga di comando (CLI) di Firebase ti consente di pubblicare le app web localmente e di eseguire il deployment delle app web su Firebase Hosting.

Per installare l'interfaccia a riga di comando, esegui il seguente comando npm dal terminale:

npm install -g firebase-tools

Per verificare che la CLI sia stata installata correttamente, esegui:

firebase --version

Autorizza l'interfaccia a riga di comando di Firebase con il tuo Account Google eseguendo:

firebase login

Crea un progetto Firebase

  1. Vai a Firebase.
  2. Fai clic su Crea un progetto e inserisci il nome del progetto.
  3. Seleziona la casella di controllo del contratto e fai clic su Continua. Se non è presente la casella di controllo del contratto, puoi saltare questo passaggio.
    Crea un progetto Firebase
  4. Una volta creato il progetto Firebase, individua l'ID progetto. Vai a Panoramica del progetto e fai clic sull'icona delle impostazioni > Impostazioni progetto.
    Apri le impostazioni del progetto
  5. Il progetto è elencato nella scheda Generali.
    Impostazioni generali del progetto

Abilita l'API HomeGraph

L'API HomeGraph consente di archiviare e eseguire query sui dispositivi e sui relativi stati all'interno di Home Graph di un utente. Per utilizzare questa API, devi prima aprire la console Google Cloud e abilitare l'API HomeGraph.

Nella console Google Cloud, assicurati di selezionare il progetto corrispondente alle tue azioni <firebase-project-id>.. Quindi, nella schermata Libreria API per l'API HomeGraph, fai clic su Attiva.

ee198858a6eac112.png

3. Esegui l'app di avvio

Ora che hai configurato l'ambiente di sviluppo, puoi eseguire il deployment del progetto iniziale per verificare che tutto sia configurato correttamente.

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-traits.git

Estrai il file ZIP scaricato.

Informazioni sul progetto

Il progetto iniziale contiene le seguenti sottodirectory:

  • public: Un'interfaccia utente frontend per controllare e monitorare facilmente lo stato della lavatrice smart.
  • functions: Un servizio cloud completamente implementato che gestisce la lavatrice smart con Cloud Functions per Firebase e Firebase Realtime Database.

Il fulfillment cloud fornito include le seguenti funzioni in index.js:

  • fakeauth: endpoint di autorizzazione per il collegamento degli account
  • faketoken: endpoint token per il collegamento degli account
  • smarthome: endpoint di adempimento dell'intent per la smart home
  • reportstate: invoca l'API HomeGraph in caso di modifiche dello stato del dispositivo
  • requestsync: consente gli aggiornamenti del dispositivo dell'utente senza richiedere il ricoinvolgimento dell'account

Connettersi a Firebase

Vai alla directory washer-start, quindi configura l'interfaccia a riga di comando di Firebase con il progetto di integrazione:

cd washer-start
firebase use <firebase-project-id>

Configura il progetto Firebase

Inizializza un progetto Firebase.

firebase init

Seleziona le funzionalità dell'interfaccia a riga di comando, Realtime Database, Functions e la funzionalità Hosting che include Firebase Hosting.

? Which Firebase CLI features do you want to set up for this directory? Press Space to select features, then
 Enter to confirm your choices.
❯◉ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Configure security rules and indexes files for Firestore
 ◉ Functions: Configure a Cloud Functions directory and its files
 ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
 ◯ Storage: Configure a security rules file for Cloud Storage
 ◯ Emulators: Set up local emulators for Firebase products
 ◯ Remote Config: Configure a template file for Remote Config
 ◯ Extensions: Set up an empty Extensions manifest

Verranno inizializzate le API e le funzionalità necessarie per il progetto.

Quando richiesto, inizializza Realtime Database. Puoi utilizzare la posizione predefinita per l'istanza del database.

? It seems like you haven't initialized Realtime Database in your project yet. Do you want to set it up?
Yes

? Please choose the location for your default Realtime Database instance:
us-central1

Poiché utilizzi il codice del progetto iniziale, scegli il file predefinito per le regole di sicurezza e assicurati di non sovrascrivere il file delle regole di database esistente.

? File database.rules.json already exists. Do you want to overwrite it with the Realtime Database Security Rules for <project-ID>-default-rtdb from the Firebase Console?
No

Se stai reinizializzando il progetto, seleziona Sovrascrivi quando ti viene chiesto se vuoi inizializzare o sovrascrivere una base di codice.

? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

Quando configuri le funzioni, devi utilizzare i file predefiniti e assicurarti di non sovrascrivere i file index.js e package.json esistenti nel progetto di esempio.

? What language would you like to use to write Cloud Functions?
JavaScript

? Do you want to use ESLint to catch probable bugs and enforce style?
No

? File functions/package.json already exists. Overwrite?
No

? File functions/index.js already exists. Overwrite?
No

Se stai reinizializzando il progetto, seleziona No quando ti viene chiesto se vuoi inizializzare o sovrascrivere functions/.gitignore.

? File functions/.gitignore already exists. Overwrite?
No
? Do you want to install dependencies with npm now?
Yes

Infine, configura la configurazione di Hosting in modo da utilizzare la directory public nel codice del progetto e utilizza il file index.html esistente. Seleziona No quando ti viene chiesto di utilizzare ESLint.

? What do you want to use as your public directory?
public

? Configure as a single-page app (rewrite all urls to /index.html)?
Yes

? Set up automatic builds and deploys with GitHub?
No

? File public/index.html already exists. Overwrite?
 No

Se ESLint è stato attivato per errore, sono disponibili due metodi per disattivarlo:

  1. Utilizzando la GUI, vai alla cartella ../functions nel progetto, seleziona il file nascosto .eslintrc.js ed eliminalo. Non confonderlo con .eslintrc.json, che ha un nome simile.
  2. Utilizzo della riga di comando:
    cd functions
    rm .eslintrc.js
    

Esegui il deployment in Firebase

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/<firebase-project-id>/overview
Hosting URL: https://<firebase-project-id>.web.app

Questo comando esegue il deployment di un'app web e di diverse funzioni Cloud per Firebase.

Apri l'URL di hosting nel browser (https://<firebase-project-id>.web.app) per visualizzare l'app web. Vedrai la seguente interfaccia:

5845443e94705557.png

Questa UI web rappresenta una piattaforma di terze parti per visualizzare o modificare gli stati del dispositivo. Per iniziare a compilare il database con le informazioni del dispositivo, fai clic su AGGIORNA. Non vedrai alcuna modifica nella pagina, ma lo stato attuale della lavatrice verrà memorizzato nel database.

Ora è il momento di collegare il servizio cloud di cui hai eseguito il deployment all'Assistente Google utilizzando la Console per gli sviluppatori.

Configurare il progetto Developers Console

Nella scheda Sviluppa, aggiungi un Nome visualizzato per l'interazione. Questo nome verrà visualizzato nell'app Google Home.

Aggiungere un nome visualizzato

In Branding dell'app, carica un file png per l'icona dell'app, di dimensioni 144 x 144 px e denominato .png.

Aggiungere un&#39;icona dell&#39;app

Per attivare il collegamento dell'account, utilizza queste impostazioni:

ID client

ABC123

Client secret

DEF456

URL autorizzazione

https://us-central1-
.cloudfunctions.net/fakeauth

URL token

https://us-central1-
.cloudfunctions.net/faketoken

Aggiornare gli URL di collegamento dell&#39;account

In URL di adempimento cloud, inserisci l'URL della funzione cloud che fornisce l'adempimento per gli intent per la smart home.

https://us-central1--cloudfunctions.net/smarthome

Aggiungi l&#39;URL della funzione cloud

Fai clic su Salva per salvare la configurazione del progetto, poi fai clic su Avanti: test per attivare i test nel progetto.

Testa l&#39;integrazione cloud-to-cloud

Ora puoi iniziare a implementare gli webhook necessari per collegare lo stato del dispositivo all'assistente.

Per testare l'integrazione cloud-to-cloud, devi collegare il tuo progetto a un Account Google. In questo modo puoi eseguire test tramite le piattaforme dell'Assistente Google e l'app Google Home su cui hai eseguito l'accesso allo stesso account.

  1. Apri le impostazioni dell'Assistente Google sullo smartphone. Tieni presente che devi aver eseguito l'accesso con lo stesso account utilizzato nella console.
  2. Vai ad Assistente Google > Impostazioni > Controllo della casa (nella sezione Assistente).
  3. Fai clic sull'icona di ricerca in alto a destra.
  4. Cerca l'app di test utilizzando il prefisso [test] per trovare l'app di test specifica.
  5. Seleziona l'elemento. L'Assistente Google si autentica quindi con il tuo servizio e invia una richiesta SYNC chiedendo al tuo servizio di fornire un elenco di dispositivi per l'utente.

Apri l'app Google Home e verifica di poter vedere la lavatrice.

ae252220753726f6.png

Verifica di poter controllare la lavatrice utilizzando i comandi vocali nell'app Google Home. Dovresti anche vedere la modifica dello stato del dispositivo nell'interfaccia utente web frontend del tuo cloud fulfillment.

Ora che hai implementato una lavatrice di base, puoi personalizzare le modalità disponibili sul tuo dispositivo.

4. Aggiungere modalità

L'attributo action.devices.traits.Modes consente a un dispositivo di avere un numero arbitrario di impostazioni per una modalità, di cui è possibile impostarne una alla volta. Aggiungi una modalità alla lavatrice per definire le dimensioni del carico di biancheria: piccolo, medio o grande.

Aggiorna la risposta SYNC

Devi aggiungere informazioni sul nuovo tratto alla risposta SYNC in functions/index.js. Questi dati vengono visualizzati nell'array traits e nell'oggetto attributes, come mostrato nello snippet di codice seguente.

index.js

app.onSync(body => {
 
return {
    requestId
: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
    payload
: {
      agentUserId
: USER_ID,
      devices
: [{
        id
: 'washer',
        type
: 'action.devices.types.WASHER',
        traits
: [
         
'action.devices.traits.OnOff',
         
'action.devices.traits.StartStop',
         
'action.devices.traits.RunCycle',
         
// Add Modes trait
         
'action.devices.traits.Modes',
       
],
        name
: { ... },
        deviceInfo
: { ... },
        attributes
: {
          pausable
: true,
         
//Add availableModes
          availableModes
: [{
            name
: 'load',
            name_values
: [{
              name_synonym
: ['load'],
              lang
: 'en',
           
}],
            settings
: [{
              setting_name
: 'small',
              setting_values
: [{
                setting_synonym
: ['small'],
                lang
: 'en',
             
}]
           
}, {
              setting_name
: 'medium',
              setting_values
: [{
                setting_synonym
: ['medium'],
                lang
: 'en',
             
}]
           
}, {
              setting_name
: 'large',
              setting_values
: [{
                setting_synonym
: ['large'],
                lang
: 'en',
             
}]
           
}],
            ordered
: true,
         
}],
       
},
     
}],
   
},
 
};
});

Aggiungere nuovi comandi dell'intent EXECUTE

Nell'intent EXECUTE, aggiungi il comando action.devices.commands.SetModes come mostrato nello snippet di codice seguente.

index.js

const updateDevice = async (execution,deviceId) => {
 
const {params,command} = execution;
  let state
, ref;
 
switch (command) {
   
case 'action.devices.commands.OnOff':
      state
= {on: params.on};
     
ref = firebaseRef.child(deviceId).child('OnOff');
     
break;
   
case 'action.devices.commands.StartStop':
      state
= {isRunning: params.start};
     
ref = firebaseRef.child(deviceId).child('StartStop');
     
break;
   
case 'action.devices.commands.PauseUnpause':
      state
= {isPaused: params.pause};
     
ref = firebaseRef.child(deviceId).child('StartStop');
     
Break;
   
// Add SetModes command
   
case 'action.devices.commands.SetModes':
      state
= {load: params.updateModeSettings.load};
     
ref = firebaseRef.child(deviceId).child('Modes');
     
break;
}

Aggiornare la risposta della query

Poi, aggiorna la risposta QUERY per segnalare lo stato attuale della lavatrice.

Aggiungi le modifiche aggiornate alle funzioni queryFirebase e queryDevice per ottenere lo stato memorizzato nel database in tempo reale.

index.js

const queryFirebase = async (deviceId) => {
 
const snapshot = await firebaseRef.child(deviceId).once('value');
 
const snapshotVal = snapshot.val();
 
return {
    on
: snapshotVal.OnOff.on,
    isPaused
: snapshotVal.StartStop.isPaused,
    isRunning
: snapshotVal.StartStop.isRunning,
   
// Add Modes snapshot
    load
: snapshotVal.Modes.load,
 
};
}

const queryDevice = async (deviceId) => {
 
const data = await queryFirebase(deviceId);
 
return {
    on
: data.on,
    isPaused
: data.isPaused,
    isRunning
: data.isRunning,
    currentRunCycle
: [{ ... }],
    currentTotalRemainingTime
: 1212,
    currentCycleRemainingTime
: 301,
   
// Add currentModeSettings
    currentModeSettings
: {
      load
: data.load,
   
},
 
};
};

Aggiorna stato report

Infine, aggiorna la funzione reportstate per segnalare a Home Graph l'impostazione di carico corrente della lavatrice.

index.js

const requestBody = {
  requestId
: 'ff36a3cc', /* Any unique ID */
  agentUserId
: USER_ID,
  payload
: {
    devices
: {
      states
: {
       
/* Report the current state of your washer */
       
[context.params.deviceId]: {
          on
: snapshot.OnOff.on,
          isPaused
: snapshot.StartStop.isPaused,
          isRunning
: snapshot.StartStop.isRunning,
         
// Add currentModeSettings
          currentModeSettings
: {
            load
: snapshot.Modes.load,
         
},
       
},
     
},
   
},
 
},
};

Esegui il deployment in Firebase

Esegui il comando seguente per eseguire il deployment dell'integrazione aggiornata:

firebase deploy --only functions

Al termine del deployment, vai all'interfaccia utente web e fai clic sul pulsante Aggiorna ae8d3b25777a5e30.png nella barra degli strumenti. Viene attivata una sincronizzazione della richiesta in modo che l'assistente riceva i dati aggiornati della risposta di SYNC.

bf4f6a866160a982.png

Ora puoi dare un comando per impostare la modalità della lavatrice, ad esempio:

"Hey Google, imposta il carico della lavatrice su grande."

Inoltre, puoi porre domande sulla lavatrice, ad esempio:

"Hey Google, qual è il carico della lavatrice?"

5. Aggiungere pulsanti di attivazione/disattivazione

L'attributo action.devices.traits.Toggles rappresenta aspetti denominati di un dispositivo che hanno uno stato true o false, ad esempio se la lavatrice è in modalità turbo.

Aggiorna la risposta SYNC

Nella risposta SYNC, devi aggiungere informazioni sulla nuova caratteristica del dispositivo. Verrà visualizzato nell'array traits e nell'oggetto attributes, come mostrato nello snippet di codice seguente.

index.js

app.onSync(body => {
 
return {
    requestId
: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
    payload
: {
      agentUserId
: USER_ID,
      devices
: [{
        id
: 'washer',
        type
: 'action.devices.types.WASHER',
        traits
: [
         
'action.devices.traits.OnOff',
         
'action.devices.traits.StartStop',
         
'action.devices.traits.RunCycle',
         
'action.devices.traits.Modes',
         
// Add Toggles trait
         
'action.devices.traits.Toggles',
       
],
        name
: { ... },
        deviceInfo
: { ... },
        attributes
: {
          pausable
: true,
          availableModes
: [{
            name
: 'load',
            name_values
: [{
              name_synonym
: ['load'],
              lang
: 'en'
           
}],
            settings
: [{ ... }],
            ordered
: true,
         
}],
         
//Add availableToggles
          availableToggles
: [{
            name
: 'Turbo',
            name_values
: [{
              name_synonym
: ['turbo'],
              lang
: 'en',
           
}],
         
}],
       
},
     
}],
   
},
 
};
});

Aggiungere nuovi comandi dell'intenzione EXECUTE

Nell'intent EXECUTE, aggiungi il comando action.devices.commands.SetToggles come mostrato nello snippet di codice seguente.

index.js

const updateDevice = async (execution,deviceId) => {
 
const {params,command} = execution;
  let state
, ref;
 
switch (command) {
   
case 'action.devices.commands.OnOff':
      state
= {on: params.on};
     
ref = firebaseRef.child(deviceId).child('OnOff');
     
break;
   
case 'action.devices.commands.StartStop':
      state
= {isRunning: params.start};
     
ref = firebaseRef.child(deviceId).child('StartStop');
     
break;
   
case 'action.devices.commands.PauseUnpause':
      state
= {isPaused: params.pause};
     
ref = firebaseRef.child(deviceId).child('StartStop');
     
break;
   
case 'action.devices.commands.SetModes':
      state
= {load: params.updateModeSettings.load};
     
ref = firebaseRef.child(deviceId).child('Modes');
     
break;
   
// Add SetToggles command
   
case 'action.devices.commands.SetToggles':
      state
= {Turbo: params.updateToggleSettings.Turbo};
     
ref = firebaseRef.child(deviceId).child('Toggles');
     
break;
 
}

Aggiornare la risposta della query

Infine, devi aggiornare la risposta QUERY per segnalare la modalità turbo della lavatrice. Aggiungi le modifiche aggiornate alle funzioni queryFirebase e queryDevice per ottenere lo stato del pulsante di attivazione/disattivazione come memorizzato nel database in tempo reale.

index.js

const queryFirebase = async (deviceId) => {
 
const snapshot = await firebaseRef.child(deviceId).once('value');
 
const snapshotVal = snapshot.val();
 
return {
    on
: snapshotVal.OnOff.on,
    isPaused
: snapshotVal.StartStop.isPaused,
    isRunning
: snapshotVal.StartStop.isRunning,
    load
: snapshotVal.Modes.load,
   
// Add Toggles snapshot
   
Turbo: snapshotVal.Toggles.Turbo,
 
};
}

const queryDevice = async (deviceId) => {
 
const data = queryFirebase(deviceId);
 
return {
    on
: data.on,
    isPaused
: data.isPaused,
    isRunning
: data.isRunning,
    currentRunCycle
: [{ ... }],
    currentTotalRemainingTime
: 1212,
    currentCycleRemainingTime
: 301,
    currentModeSettings
: {
      load
: data.load,
   
},
   
// Add currentToggleSettings
    currentToggleSettings
: {
     
Turbo: data.Turbo,
   
},
 
};
};

Aggiorna stato report

Infine, aggiorna la funzione reportstate per segnalare a Home Graph se la lavatrice è impostata su turbo.

index.js

const requestBody = {
  requestId
: 'ff36a3cc', /* Any unique ID */
  agentUserId
: USER_ID,
  payload
: {
    devices
: {
      states
: {
       
/* Report the current state of your washer */
       
[context.params.deviceId]: {
          on
: snapshot.OnOff.on,
          isPaused
: snapshot.StartStop.isPaused,
          isRunning
: snapshot.StartStop.isRunning,
          currentModeSettings
: {
            load
: snapshot.Modes.load,
         
},
         
// Add currentToggleSettings
          currentToggleSettings
: {
           
Turbo: snapshot.Toggles.Turbo,
         
},
       
},
     
},
   
},
 
},
};

Esegui il deployment in Firebase

Esegui il seguente comando per eseguire il deployment delle funzioni aggiornate:

firebase deploy --only functions

Fai clic sul pulsante Aggiorna ae8d3b25777a5e30.png nell'interfaccia utente web per attivare una sincronizzazione delle richieste al termine del deployment.

Ora puoi dare un comando per impostare la lavatrice in modalità turbo dicendo:

"Hey Google, attiva la modalità turbo per la lavatrice."

Puoi anche verificare se la lavatrice è già in modalità turbo chiedendo:

"Hey Google, la mia lavatrice è in modalità turbo?"

6. Errori e eccezioni di segnalazione

La gestione degli errori nell'integrazione cloud-to-cloud ti consente di segnalare agli utenti i problemi che causano l'errore delle risposte EXECUTE e QUERY. Le notifiche creano un'esperienza utente più positiva quando gli utenti interagiscono con lo smart device e l'integrazione.

Ogni volta che una richiesta EXECUTE o QUERY non va a buon fine, l'integrazione deve restituire un codice di errore. Ad esempio, se vuoi generare un errore quando un utente tenta di avviare la lavatrice con il coperchio aperto, la risposta EXECUTE sarà simile al seguente snippet di codice:

{
 
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
 
"payload": {
   
"commands": [
     
{
       
"ids": [
         
"456"
       
],
       
"status": "ERROR",
       
"errorCode": "deviceLidOpen"
     
}
   
]
 
}
}

Ora, quando un utente chiede di avviare la lavatrice, l'assistente risponde dicendo:

"Il coperchio della lavatrice è aperto. Chiudilo e riprova".

Le eccezioni sono simili agli errori, ma indicano quando un avviso è associato a un comando, il che può o meno bloccare l'esecuzione. Un'eccezione può fornire informazioni correlate utilizzando l'attributo StatusReport, ad esempio il livello della batteria o la modifica dello stato recente. I codici di eccezione non bloccanti vengono restituiti insieme a uno stato SUCCESS, mentre i codici di eccezione bloccanti vengono restituiti con uno stato EXCEPTIONS.

Un esempio di risposta con un'eccezione è riportato nel seguente snippet di codice:

{
 
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
 
"payload": {
   
"commands": [{
     
"ids": ["123"],
     
"status": "SUCCESS",
     
"states": {
       
"online": true,
       
"isPaused": false,
       
"isRunning": false,
       
"exceptionCode": "runCycleFinished"
     
}
   
}]
 
}
}

L'assistente risponde dicendo:

"La lavatrice ha finito."

Per aggiungere la segnalazione degli errori per la lavatrice, apri functions/index.js e aggiungi la definizione della classe di errore come mostrato nel seguente snippet di codice:

index.js

app.onQuery(async (body) => {...});

// Add SmartHome error handling
class SmartHomeError extends Error {
  constructor
(errorCode, message) {
   
super(message);
   
this.name = this.constructor.name;
   
this.errorCode = errorCode;
 
}
}

Aggiorna la risposta all'esecuzione per restituire il codice di errore e lo stato di errore:

index.js

const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
 
for (const device of command.devices) {
   
for (const execution of command.execution) {
      executePromises
.push(
        updateDevice
(execution, device.id)
       
.then((data) => {
         
...
       
})
       
//Add error response handling
       
.catch((error) => {
          functions
.logger.error('EXECUTE', device.id, error);
          result
.ids.push(device.id);
         
if (error instanceof SmartHomeError) {
            result
.status = 'ERROR';
            result
.errorCode = error.errorCode;
         
}
       
})
     
);
   
}
 
}
}

Ora l'assistente può comunicare agli utenti qualsiasi codice di errore che segnali. Nella sezione successiva vedrai un esempio specifico.

7. Aggiungere la verifica utente secondaria

Devi implementare la verifica dell'utente secondario nell'integrazione se il tuo dispositivo ha modalità che devono essere protette o limitate a un determinato gruppo di utenti autorizzati, ad esempio un aggiornamento software o lo sblocco della serratura.

Puoi implementare la verifica utente secondaria su tutti i tipi e le caratteristiche di dispositivo, personalizzando se la verifica di sicurezza si verifica ogni volta o se devono essere soddisfatti criteri specifici.

Esistono tre tipi di verifica supportati:

  • No challenge: una richiesta e una risposta che non utilizzano una verifica dell'autenticazione (questo è il comportamento predefinito)
  • ackNeeded: una verifica utente secondaria che richiede l'accettazione esplicita (sì o no)
  • pinNeeded: una verifica dell'utente secondaria che richiede un PIN (Personal Identification Number)

Per questo codelab, aggiungi una verifica ackNeeded al comando per accendere la lavatrice e la funzionalità per restituire un errore se la verifica secondaria non va a buon fine.

Apri functions/index.js e aggiungi una definizione di classe di errore che restituisca il codice di errore e il tipo di verifica, come mostrato nello snippet di codice seguente:

index.js

class SmartHomeError extends Error { ... }

// Add secondary user verification error handling
class ChallengeNeededError extends SmartHomeError {
 
/**
   * Create a new ChallengeNeededError
   * @param {string} suvType secondary user verification challenge type
   */

  constructor
(suvType) {
   
super('challengeNeeded', suvType);
   
this.suvType = suvType;
 
}
}

Devi anche aggiornare la risposta di esecuzione per restituire l'errore challengeNeeded come segue:

index.js

const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
 
for (const device of command.devices) {
   
for (const execution of command.execution) {
      executePromises
.push(

        updateDevice
(execution, device.id)
       
.then((data) => {
         
...
       
})
       
.catch((error) => {
          functions
.logger.error('EXECUTE', device.id, error);
          result
.ids.push(device.id);
         
if (error instanceof SmartHomeError) {
            result
.status = 'ERROR';
            result
.errorCode = error.errorCode;
           
//Add error response handling
           
if (error instanceof ChallengeNeededError) {
              result
.challengeNeeded = {
                type
: error.suvType
             
};
           
}
         
}
       
})
     
);
   
}
 
}
}

Infine, modifica updateDevice in modo da richiedere il riconoscimento esplicito per accendere o spegnere la lavatrice.

index.js

const updateDevice = async (execution,deviceId) => {
 
const {challenge,params,command} = execution; //Add secondary user challenge
  let state
, ref;
 
switch (command) {
   
case 'action.devices.commands.OnOff':
     
//Add secondary user verification challenge
     
if (!challenge || !challenge.ack) {
       
throw new ChallengeNeededError('ackNeeded');
     
}
      state
= {on: params.on};
     
ref = firebaseRef.child(deviceId).child('OnOff');
     
break;
   
...
 
}

 
return ref.update(state)
     
.then(() => state);
};

Esegui il deployment in Firebase

Esegui il comando seguente per eseguire il deployment della funzione aggiornata:

firebase deploy --only functions

Dopo aver eseguito il deployment del codice aggiornato, devi confermare verbalmente l'azione quando chiedi all'assistente di accendere o spegnere la lavatrice, ad esempio:

Tu: "Hey Google, accendi la lavatrice."

L'assistente: "Vuoi davvero accendere la lavatrice?"

Tu: "Sì."

Puoi anche visualizzare una risposta dettagliata per ogni passaggio del flusso di verifica dell'utente secondario aprendo i log di Firebase.

289dbe48f4bb8106.png

8. Complimenti

674c4f4392e98c1.png

Complimenti! Hai esteso le funzionalità delle integrazioni cloud-to-cloud tramite gli attributi Modes e Toggles e ne hai garantito l'esecuzione tramite la verifica secondaria dell'utente.

Scopri di più

Ecco alcune idee che puoi implementare per approfondire:

  • Aggiungi funzionalità di esecuzione locale ai tuoi dispositivi.
  • Utilizza un altro tipo di verifica utente secondaria per modificare lo stato del dispositivo.
  • Aggiorna la risposta alla QUERY del tratto RunCycle in modo che venga aggiornata dinamicamente.
  • Consulta questo esempio GitHub.