1. Prima di iniziare
Le azioni della smart home utilizzano i tipi di dispositivi per comunicare all'Assistente Google quale grammatica utilizzare con un dispositivo. I trait dei dispositivi definiscono le funzionalità di un tipo di dispositivo. Un dispositivo eredita gli stati di ogni trait del dispositivo aggiunto a un'Azione.
Puoi collegare qualsiasi trait supportato al tipo di dispositivo scelto per personalizzare la funzionalità dei dispositivi degli utenti. Se vuoi implementare nelle tue azioni tratti personalizzati che non sono attualmente disponibili nello schema del dispositivo, i trait Modalità e Attivazioni consentono un controllo delle impostazioni specifiche con un nome personalizzato definito da te.
Oltre alla funzionalità di controllo di base fornita dai tipi e dai trait, l'API Smart Home offre funzionalità aggiuntive per migliorare l'esperienza utente. Quando gli intent non hanno esito positivo, le risposte di errore forniscono un feedback dettagliato sugli utenti. La verifica utente secondaria estende queste risposte e rafforza la sicurezza del tratto dispositivo che scegli. Inviando risposte di errore specifiche ai blocchi di verifica emessi dall'Assistente, l'Azione per la smart home può richiedere un'autorizzazione aggiuntiva per completare un comando.
Prerequisiti
- Guida per gli sviluppatori Create a Smart home Action (Crea un'azione per la smart home)
- Codelab per lavatrici smart home
- Guida per gli sviluppatori Tipi di dispositivi e trait
Cosa creerai
In questo codelab, eseguirai il deployment di un'integrazione predefinita della smart home con Firebase, quindi imparerai ad aggiungere tratti non standard alla lavaggio smart home per dimensioni di carico e modalità turbo. Implementerai anche la segnalazione di errori ed eccezioni e imparerai a imporre una conferma verbale per accendere la lavatrice utilizzando la verifica utente secondaria.
Cosa imparerai a fare
- Come aggiungere i tratti delle modalità e dei pulsanti di attivazione/disattivazione all'azione
- 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 su cui è installata l'app Google Home.
- Node.js 10.16 o versioni successive
- Un Account Google
- Un account di fatturazione Google Cloud.
2. Per iniziare
Attivare la Gestione attività
Per utilizzare l'Assistente Google, devi condividere con Google determinati dati relativi alle attività. 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à relativa all'Account Google che vuoi usare con l'assistente.
Assicurati che le seguenti opzioni di attivazione/disattivazione siano abilitate:
- Attività web e app: 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 del dispositivo
- Attività vocale e audio
Creare un progetto Actions
- Vai alla Play Console per gli sviluppatori di Actions on Google.
- Fai clic su Nuovo progetto, inserisci un nome per il progetto e fai clic su CREA PROGETTO.
Seleziona l'app Smart home
Nella schermata Panoramica della console Actions, seleziona Smart home.
Scegli la scheda dell'esperienza Smart home, fai clic su Inizia a costruire e si aprirà la console del tuo progetto.
Installa l'interfaccia a riga di comando di Firebase
L'interfaccia a riga di comando (CLI) di Firebase ti consente di pubblicare le tue app web localmente ed eseguire il deployment dell'app web su Firebase Host.
Per installare l'interfaccia a riga di comando, esegui questo comando npm dal terminale:
npm install -g firebase-tools
Per verificare che l'interfaccia a riga di comando sia stata installata correttamente, esegui:
firebase --version
Autorizza l'interfaccia a riga di comando di Firebase con il tuo Account Google eseguendo:
firebase login
Abilita l'API HomeGraph
L'API HomeGraph consente l'archiviazione e l'esecuzione di query sui dispositivi e sui loro 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 che corrisponde alle tue azioni <project-id>.
. Quindi, nella schermata della libreria 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.
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-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 smartwash con Cloud Functions for Firebase e Firebase Realtime Database.
Il fulfillment Cloud fornito include le seguenti funzioni in index.js
:
fakeauth
: endpoint di autorizzazione per il collegamento dell'accountfaketoken
: endpoint token per il collegamento dell'accountsmarthome
: endpoint di fulfillment dell'intent per la smart homereportstate
: richiama l'API Home Graph in caso di modifiche dello stato del dispositivorequestsync
: abilita gli aggiornamenti dei dispositivi degli utenti senza dover ricollegare l'account
Connettersi a Firebase
Vai alla directory washer-start
, quindi configura l'interfaccia a riga di comando di Firebase con il tuo progetto Actions:
cd washer-start firebase use <project-id>
Configura progetto Firebase
Inizializzare un progetto Firebase.
firebase init
Seleziona le funzionalità dell'interfaccia a riga di comando, Realtime Database, Funzioni 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
Questa operazione inizializza le API e le funzionalità necessarie per il tuo progetto.
Quando richiesto, inizializza Realtime Database. Puoi utilizzare la località predefinita per l'istanza di 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 un 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 del 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
Infine, configura la configurazione di Hosting in modo che utilizzi la directory public
nel codice del progetto e 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, esistono due metodi per disabilitarlo:
- Utilizzando la GUI, vai alla cartella
../functions
del progetto, seleziona il file nascosto.eslintrc.js
ed eliminalo. Non scambiarlo con il nome simile.eslintrc.json
. - Utilizzo della riga di comando:
cd functions rm .eslintrc.js
Eseguire 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 e di diverse Cloud Functions for Firebase.
Apri l'URL di hosting nel tuo browser (https://<project-id>.web.app
) per visualizzare l'app web. Vedrai l'interfaccia seguente:
Questa UI web rappresenta una piattaforma di terze parti per visualizzare o modificare gli stati dei dispositivi. Per iniziare a completare il database con le informazioni del dispositivo, fai clic su AGGIORNA. Non vedrai alcuna modifica sulla pagina, ma lo stato attuale della lavatrice verrà memorizzato nel database.
Ora è il momento di connettere il servizio cloud di cui hai eseguito il deployment all'Assistente Google utilizzando la console di Actions.
Configura il progetto della console Actions
In Panoramica > Crea la tua azione, seleziona Aggiungi azioni. Inserisci l'URL della funzione Cloud Functions che fornisce il fulfillment per gli intent della smart home e fai clic su Salva.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Nella scheda Sviluppa > Chiamata, aggiungi un Nome visualizzato per l'azione e fai clic su Salva. Questo nome verrà visualizzato nell'app Google Home.
Per attivare il collegamento degli account, seleziona l'opzione Sviluppo > Collegamento dell'account nel pannello di navigazione a sinistra. Utilizza queste impostazioni di collegamento dell'account:
ID client |
|
Client secret |
|
URL autorizzazione |
|
URL token |
|
Fai clic su Salva per salvare la configurazione del collegamento dell'account e poi su Test per attivare i test sul progetto.
Verrà eseguito il reindirizzamento al Simulatore. Se non vedi "Test ora abilitato", fai clic su Reimposta test per verificare che i test siano attivati.
Eseguire il collegamento all'Assistente Google
Per testare l'Azione per la smart home, devi collegare il tuo progetto a un Account Google. In questo modo è possibile eseguire test tramite le piattaforme dell'Assistente Google e l'app Google Home su cui è stato eseguito l'accesso allo stesso account.
- Sullo smartphone, apri le impostazioni dell'Assistente Google. Tieni presente che devi aver eseguito l'accesso con lo stesso account utilizzato nella console.
- Vai a Assistente Google > Impostazioni > Controllo della casa (sotto Assistente).
- Fai clic sull'icona di ricerca in alto a destra.
- Cerca l'app di test utilizzando il prefisso [test] per trovare l'app di test specifica.
- Seleziona l'elemento. L'Assistente Google eseguirà quindi l'autenticazione con il tuo servizio e invierà una richiesta
SYNC
, chiedendo al servizio di fornire un elenco di dispositivi per l'utente.
Apri l'app Google Home e verifica che sia visibile il dispositivo della lavatrice.
Verifica di poter controllare la lavatrice utilizzando i comandi vocali nell'app Google Home. Dovresti anche vedere lo stato del dispositivo cambiare nell'interfaccia utente web di frontend del tuo Cloud fulfillment.
Ora che hai implementato una lavatrice di base, puoi personalizzare le modalità disponibili sul tuo dispositivo.
4. Aggiungi modalità
Il trait action.devices.traits.Modes
consente a un dispositivo di avere un numero arbitrario di impostazioni per una modalità, di cui è possibile impostare solo una alla volta. Aggiungerai una modalità alla lavatrice per definire le dimensioni del carico del bucato: piccolo, medio o grande.
Aggiorna risposta SYNC
Devi aggiungere informazioni sul nuovo trait alla tua risposta SYNC
in functions/index.js
. Questi dati vengono visualizzati nell'array traits
e nell'oggetto attributes
come mostrato nello snippet di codice riportato di seguito.
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,
}],
},
}],
},
};
});
Aggiungi nuovi comandi per intent EXECUTE
Nell'intent EXECUTE
, aggiungi il comando action.devices.commands.SetModes
come mostrato nello snippet di codice riportato di seguito.
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;
}
Aggiorna la risposta QUERY
Quindi, aggiorna la risposta QUERY
per segnalare lo stato attuale della lavatrice.
Aggiungi le modifiche aggiornate alle funzioni queryFirebase
e queryDevice
per ottenere lo stato archiviato nel 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 segnalare l'attuale impostazione di carico 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,
},
},
},
},
},
};
Eseguire il deployment in Firebase
Esegui questo comando per eseguire il deployment dell'azione aggiornata:
firebase deploy --only functions
Al termine del deployment, vai all'interfaccia utente web e fai clic sul pulsante Aggiorna nella barra degli strumenti. Questa operazione attiva una sincronizzazione delle richieste in modo che l'assistente riceva i dati aggiornati della risposta di SYNC
.
Ora puoi dare un comando per impostare la modalità della lavatrice, ad esempio:
"Hey Google, imposta il carico della lavatrice su grande."
Puoi anche fare domande sulla lavatrice, ad esempio:
"Hey Google, qual è il carico della lavatrice?"
5. Aggiungi pulsanti di attivazione/disattivazione
Il trait action.devices.traits.Toggles
rappresenta gli aspetti denominati di un dispositivo con uno stato vero o falso, ad esempio se la lavatrice è in modalità turbo.
Aggiorna risposta SYNC
Nella risposta SYNC
, devi aggiungere informazioni sul nuovo trait del dispositivo. Verrà visualizzato nell'array traits
e nell'oggetto attributes
come mostrato nello snippet di codice che segue.
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 per intent EXECUTE
Nell'intent EXECUTE
, aggiungi il comando action.devices.commands.SetToggles
come mostrato nello snippet di codice riportato di seguito.
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;
}
Aggiorna 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 di attivazione/disattivazione così come archiviato nel 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 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,
},
},
},
},
},
};
Eseguire il deployment in Firebase
Esegui questo comando per eseguire il deployment delle funzioni aggiornate:
firebase deploy --only functions
Fai clic sul pulsante Aggiorna nell'interfaccia utente web per attivare una sincronizzazione delle richieste al completamento del deployment.
Ora puoi dare un comando per impostare la modalità turbo della lavatrice dicendo:
"Hey Google, attiva il turbo per la lavatrice."
Puoi anche controllare se la lavatrice è già in modalità turbo chiedendo:
"Hey Google, la lavatrice è in modalità turbo?"
6. Segnalare errori ed eccezioni
La gestione degli errori nell'Azione per la smart home ti consente di segnalare agli utenti quando dei problemi causano la mancata riuscita delle risposte di EXECUTE
e QUERY
. Le notifiche creano un'esperienza più positiva per i tuoi utenti quando interagiscono con il tuo smart device e l'Azione.
Ogni volta che una richiesta EXECUTE
o QUERY
non va a buon fine, l'Azione dovrebbe 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 dicendo:
"Il coperchio della lavatrice è aperto. Chiudi 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 corretta. Un'eccezione può fornire informazioni correlate utilizzando il trait StatusReport
, ad esempio il livello della batteria o una modifica recente dello stato. I codici di eccezione che non bloccano la migrazione vengono restituiti insieme allo stato SUCCESS
, mentre i codici di eccezione di blocco vengono restituiti con lo stato EXCEPTIONS
.
Un esempio di risposta con un'eccezione è lo snippet di codice seguente:
{
"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 i report sugli errori per la lavatrice, apri functions/index.js
e aggiungi la definizione della classe di errore come illustrato 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 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( ... )
//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 segnalato. Vedrai un esempio specifico nella sezione successiva.
7. Aggiungi verifica utente secondaria
L'utente dovrebbe implementare la verifica dell'utente secondario nell'Azione se dispone di modalità che devono essere protette o che devono essere limitate a un gruppo specifico di utenti autorizzati, ad esempio un aggiornamento del software o la disattivazione di un blocco.
Puoi implementare la verifica utente secondaria su tutti i tipi e i tratti di dispositivo, personalizzando se la verifica di sicurezza si verifica ogni volta o se è necessario soddisfare criteri specifici.
Esistono tre tipi di sfida supportati:
No
challenge
: una richiesta e una risposta che non utilizza una verifica di autenticazione (comportamento predefinito).ackNeeded
: una verifica utente secondaria che richiede una conferma esplicita (sì o no)pinNeeded
: una verifica 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 ha esito negativo.
Apri functions/index.js
e aggiungi una definizione della classe di errore che restituisca il codice di errore e il tipo di verifica, come indicato 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( ... )
.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 la conferma esplicita dell'accensione o dello spegnimento della 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);
};
Eseguire 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, nel seguente modo:
Tu: "Hey Google, accendi la lavatrice."
L'assistente: "Confermi di voler 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à di Azioni per la smart home tramite i trait Modes
e Toggles
e ne hai protetto l'esecuzione tramite la verifica utente secondaria.
Scopri di più
Ecco alcune idee che puoi implementare per approfondire:
- Aggiungi funzionalità di esecuzione locale ai tuoi dispositivi.
- Utilizza un tipo di verifica utente secondaria diverso per modificare lo stato del dispositivo.
- Aggiorna la risposta QUERY del trait
RunCycle
in modo che venga aggiornata in modo dinamico. - Esplora questo esempio di GitHub.