1. Prima di iniziare
Le integrazioni cloud-to-cloud utilizzano i tipi di dispositivi per comunicare all'Assistente Google quale grammatica deve essere utilizzata con un dispositivo. I trait del dispositivo definiscono le funzionalità di un tipo di dispositivo. Un dispositivo eredita gli stati di ogni caratteristica del dispositivo aggiunta a un'integrazione.
Puoi collegare qualsiasi tratto supportato al tipo di dispositivo scelto per personalizzare la funzionalità dei dispositivi dei tuoi utenti. Se vuoi implementare caratteristiche personalizzate nelle tue Azioni che non sono attualmente disponibili nello schema del dispositivo, le caratteristiche Modalità e Attivazioni/disattivazioni consentono il controllo di impostazioni specifiche con un nome personalizzato che definisci.
Oltre alla funzionalità di controllo di base fornita da tipi e tratti, l'API Smart Home dispone di funzionalità aggiuntive per migliorare l'esperienza utente. Le risposte di errore forniscono un feedback dettagliato agli utenti 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. Inviando 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
- Crea un'integrazione cloud-to-cloud Guida per gli sviluppatori
- Codelab Smart Home Washer
- Guida per gli sviluppatori Tipi di dispositivi e caratteristiche
Cosa creerai
In questo codelab, eseguirai il deployment di un'integrazione per la smart home predefinita con Firebase, poi imparerai ad aggiungere caratteristiche non standard alla lavatrice smart home per le dimensioni del carico e la modalità Turbo. Implementerai anche la segnalazione di errori ed eccezioni e imparerai a richiedere una conferma verbale per accendere la lavatrice utilizzando la verifica secondaria dell'utente.
Obiettivi didattici
- Come aggiungere le caratteristiche Modalità e Toggle all'integrazione
- Come segnalare errori ed eccezioni
- Come applicare la verifica utente secondaria
Che cosa ti serve
- Un browser web, ad esempio Google Chrome
- Un dispositivo iOS o Android con l'app Google Home installata
- Node.js versione 10.16 o successive
- Un Account Google
- Un account di fatturazione Google Cloud.
2. Per iniziare
Attivare Gestione attività
Per utilizzare l'Assistente Google, devi condividere determinati dati sulle attività con Google. L'Assistente Google ha bisogno di questi dati per funzionare correttamente; tuttavia, il requisito di condivisione dei dati non è specifico dell'SDK. Per condividere questi dati, crea un Account Google se non ne hai già uno. Puoi utilizzare qualsiasi Account Google, non è necessario che sia il tuo account sviluppatore.
Apri la pagina Gestione attività dell'Account Google che vuoi utilizzare con l'assistente.
Assicurati che i seguenti pulsanti di attivazione/disattivazione siano abilitati:
- 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
Crea un progetto di integrazione cloud-to-cloud
- Vai a Google Play Console.
- Fai clic su Crea progetto, inserisci un nome per il progetto e fai clic su Crea progetto.
Seleziona l'integrazione da cloud a cloud
Nella Home page del progetto nella Developer Console, seleziona Aggiungi integrazione cloud-to-cloud in Cloud-to-cloud.
Installa l'interfaccia a riga di comando di Firebase
L'interfaccia a riga di comando (CLI) di Firebase ti consentirà di pubblicare le tue app web in locale e di eseguirne il deployment su Firebase Hosting.
Per installare la CLI, esegui questo comando npm dal terminale:
npm install -g firebase-tools
Per verificare che la CLI sia stata installata correttamente, esegui:
firebase --version
Autorizza la CLI Firebase con il tuo Account Google eseguendo:
firebase login
Aggiungere Firebase al progetto della console per gli sviluppatori di Google Home
Metodo 1: tramite la console Firebase
- Vai a Firebase.
- Fai clic su Crea un progetto Firebase.
- Nella schermata Crea un progetto, fai clic su Aggiungi Firebase al progetto Google Cloud.
- Nella schermata Inizia, seleziona il progetto Google Cloud che hai appena creato nella console Google Home Developer e poi fai clic su Continua.
Metodo 2: tramite l'interfaccia a riga di comando di Firebase
firebase projects:addfirebase
Seleziona il progetto della console per gli sviluppatori Google Home che hai appena creato per aggiungere Firebase.
Quando Firebase viene aggiunto al progetto Google Home Developer Console, viene visualizzato nella console Firebase. L'ID progetto Firebase corrisponderà all'ID progetto della console per gli sviluppatori Google Home.
Abilita l'API HomeGraph
L'API HomeGraph consente di archiviare ed 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 attivare l'API HomeGraph.
Nella console Google Cloud, assicurati di selezionare il progetto corrispondente alle tue azioni <firebase-project-id>.
. Poi, nella schermata della libreria di API per l'API HomeGraph, fai clic su Abilita.
3. Esegui l'app di base
Ora che hai configurato l'ambiente di sviluppo, puoi eseguire il deployment del progetto iniziale per verificare che tutto sia configurato correttamente.
Recupera 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-traits.git
Decomprimi 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 accountfaketoken
: endpoint token per il collegamento degli accountsmarthome
: Endpoint di evasione dell'intent per la smart homereportstate
: richiama l'API HomeGraph in caso di modifiche dello stato del dispositivorequestsync
: consente gli aggiornamenti dei dispositivi degli utenti senza richiedere il collegamento di nuovo dell'account
Connessione a Firebase
Vai alla directory washer-start
, quindi configura l'interfaccia a riga di comando di Firebase con il tuo progetto di integrazione:
cd washer-start firebase use <project-id>
Configura il progetto Firebase
Inizializza un progetto Firebase.
firebase init
Seleziona le funzionalità della CLI, Realtime Database e Functions.
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed) >( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore ( ) Genkit: Setup a new Genkit project with Firebase (*) Functions: Configure a Cloud Functions directory and its files ( ) App Hosting: Configure an apphosting.yaml file for App Hosting ( ) Hosting: Configure files for Firebase Hosting and (optionally) 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 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance ( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore
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 del 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 codebase.
? 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 nell'esempio di progetto.
? 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
Se ESLint è stato attivato per errore, esistono due metodi per disattivarlo:
- 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. - 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/<project-id>/overview Hosting URL: https://<project-id>.web.app
Questo comando esegue il deployment di un'app web, insieme a diverse Cloud Functions for Firebase.
Apri l'URL di hosting nel browser (https://<firebase-project-id>.web.app
) per visualizzare l'app web. Vedrai la seguente interfaccia:
Questa UI web rappresenta una piattaforma di terze parti per visualizzare o modificare gli stati dei dispositivi. Per iniziare a compilare il database con le informazioni sul 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 connettere il servizio cloud che hai implementato all'Assistente Google utilizzando la Developer Console.
Configura il progetto Developer Console
Nella scheda Sviluppa, aggiungi un Nome visualizzato per l'interazione. Questo nome verrà visualizzato nell'app Google Home.
In Branding dell'app, carica un file png
per l'icona dell'app, di dimensioni 144 x 144 px e denominato
.
Per attivare il collegamento degli account, utilizza queste impostazioni:
ID client |
|
Client secret |
|
URL autorizzazione |
|
URL del token |
|
In URL di Cloud Fulfillment, inserisci l'URL della tua funzione Cloud Functions che fornisce il fulfillment per gli intent per la smart home.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Fai clic su Salva per salvare la configurazione del progetto, poi fai clic su Avanti: test per attivare i test sul progetto.
Ora puoi iniziare a implementare i webhook necessari per connettere lo stato del dispositivo all'assistente.
Collegamento all'Assistente Google
Per testare l'integrazione cloud-to-cloud, devi collegare il tuo progetto a un Account Google. Ciò consente di eseguire test tramite le piattaforme dell'Assistente Google e l'app Google Home in cui è stato eseguito l'accesso allo stesso account.
- Apri le impostazioni dell'Assistente Google sullo smartphone. Tieni presente che devi aver eseguito l'accesso con lo stesso account della console.
- Vai a Assistente Google > Impostazioni > Controllo della casa (in Assistente).
- Fai clic sull'icona di ricerca in alto a destra.
- Cerca la tua app di test utilizzando il prefisso [test] per trovare l'app di test specifica.
- Seleziona l'elemento. L'Assistente Google si autenticherà con il tuo servizio e invierà 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 tua lavatrice.
Verifica di poter controllare la lavatrice utilizzando i comandi vocali nell'app Google Home. Dovresti anche vedere lo stato del dispositivo cambiare nella UI web frontend dell'evasione cloud.
Ora che hai distribuito una lavatrice di base, puoi personalizzare le modalità disponibili sul tuo dispositivo.
4. Aggiungere modalità
Il tratto action.devices.traits.Modes
consente a un dispositivo di avere un numero arbitrario di impostazioni per una modalità, di cui solo una può essere impostata alla volta. Aggiungi una modalità alla lavatrice per definire le dimensioni del carico di bucato: piccolo, medio o grande.
Aggiorna la risposta SYNC
Devi aggiungere informazioni sulla nuova caratteristica 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 di 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 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 in Realtime Database.
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 comunicare l'impostazione di carico attuale della lavatrice a Home Graph.
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 questo comando 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 nella barra degli strumenti. Viene attivata una richiesta di sincronizzazione in modo che l'assistente riceva i dati di risposta aggiornati di
SYNC
.
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 tua lavatrice, ad esempio:
"Hey Google, qual è il carico della lavatrice?"
5. Aggiungere pulsanti di attivazione/disattivazione
La caratteristica action.devices.traits.Toggles
rappresenta aspetti denominati di un dispositivo che hanno uno stato vero o falso, 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 di intent 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 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 memorizzato in Realtime Database.
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 comunicare a Home Graph se la lavatrice è impostata sulla modalità 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 comando seguente per eseguire il deployment delle funzioni aggiornate:
firebase deploy --only functions
Fai clic sul pulsante Aggiorna nell'interfaccia utente web per attivare una richiesta di sincronizzazione al termine del deployment.
Ora puoi dare un comando per impostare la lavatrice in modalità Turbo dicendo:
"Hey Google, imposta la lavatrice sulla modalità turbo."
Puoi anche verificare se la lavatrice è già in modalità Turbo chiedendo:
"Hey Google, la mia lavatrice è in modalità turbo?"
6. Segnalazione di errori ed eccezioni
La gestione degli errori nell'integrazione da cloud a cloud consente di segnalare agli utenti quando i problemi causano l'esito negativo delle risposte EXECUTE
e QUERY
. Le notifiche creano un'esperienza utente più positiva quando gli utenti interagiscono con il tuo dispositivo smart e la tua integrazione.
Ogni volta che una richiesta EXECUTE
o QUERY
non va a buon fine, l'integrazione deve restituire un codice di errore. Se, ad esempio, 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:
"Il coperchio della lavatrice è aperto. Chiudilo e riprova."
Le eccezioni sono simili agli errori, ma indicano quando un avviso è associato a un comando, che potrebbe o meno bloccare l'esecuzione. Un'eccezione può fornire informazioni correlate utilizzando la caratteristica StatusReport
, ad esempio il livello della batteria o la recente modifica dello stato. I codici di eccezione non bloccanti vengono restituiti con 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 di 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;
}
})
);
}
}
}
L'assistente ora 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 nella tua integrazione se il tuo dispositivo ha modalità che devono essere protette o limitate a un particolare gruppo di utenti autorizzati, ad esempio un aggiornamento software o lo sblocco della serratura.
Puoi implementare la verifica secondaria dell'utente su tutti i tipi e le caratteristiche dei dispositivi, personalizzando se la sfida 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 richiesta di autenticazione (questo è il comportamento predefinito)ackNeeded
: una verifica utente secondaria che richiede un riconoscimento esplicito (sì o no)pinNeeded
: una verifica secondaria dell'utente che richiede un PIN (Personal Identification Number)
Per questo codelab, aggiungi una sfida ackNeeded
al comando per accendere la lavatrice e la funzionalità per restituire un errore se la sfida di 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 sfida, come mostrato nel seguente snippet di codice:
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
nel seguente modo:
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
per 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 questo comando 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 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.
8. Complimenti
Complimenti! Hai esteso le funzionalità delle integrazioni cloud-to-cloud tramite i tratti Modes
e Toggles
e ne hai protetto l'esecuzione tramite la verifica secondaria dell'utente.
Scopri di più
Ecco alcune idee che puoi implementare per approfondire l'argomento:
- Aggiungi funzionalità di esecuzione locale ai tuoi dispositivi.
- Utilizza un tipo di verifica utente secondario diverso per modificare lo stato del dispositivo.
- Aggiorna la risposta QUERY del tratto
RunCycle
in modo dinamico. - Esplora questo esempio di GitHub.