1. Prima di iniziare
Le azioni per la smart home utilizzano tipi di dispositivi per comunicare all'Assistente Google le regole grammaticali 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'azione.
Puoi collegare qualsiasi trait supportato al tipo di dispositivo scelto per personalizzare la funzionalità dei tuoi utenti dispositivi mobili. Se vuoi implementare nelle tue Azioni dei trait personalizzati che non sono attualmente disponibili nello schema del dispositivo, i trait Modalità e Attivazione/disattivazione consentono impostazioni specifiche. con un nome personalizzato da te definito.
Oltre alla funzionalità di controllo di base offerta da tipi e caratteristiche, l'API Smart Home ha funzionalità aggiuntive per migliorare l'esperienza utente. Le risposte di errore forniscono un feedback dettagliato all'utente quando gli intent non hanno esito positivo. La verifica utente secondaria estende queste risposte e aggiunge ulteriore sicurezza al tratto del dispositivo che scegli. Inviando risposte di errore specifiche ai blocchi di verifica emessi dall'assistente, l'azione della tua smart home può richiedere un'autorizzazione aggiuntiva per completare un comando.
Prerequisiti
- Guida per gli sviluppatori Creare un'azione per la smart home
- Codelab Lavatrice smart home
- Guida per gli sviluppatori su tipi e trait di dispositivi
Cosa creerai
In questo codelab, eseguirai il deployment di un'integrazione predefinita per la smart home con Firebase, quindi imparerai ad aggiungere tratti non standard alla 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 attivare la lavatrice utilizzando la verifica utente secondaria.
Obiettivi didattici
- Come aggiungere le modalità e i trait 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 sia 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 Gestione attività
Per poter usare 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 attive:
- Web e Attività nelle app: assicurati inoltre 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
- Voce e Attività audio
Creare un progetto Actions
- Vai alla 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 creare. Si aprirà la console di progetto.
Installa l'interfaccia a riga di comando di Firebase
L'interfaccia a riga di comando di Firebase (CLI) ti consente di pubblicare le app web localmente ed eseguirne il deployment su Firebase Hosting.
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 di archiviare ed eseguire query sui dispositivi e sul relativo stato all'interno dell'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 iniziale
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 link seguente per scaricare l'esempio per questo codelab sul tuo computer di sviluppo:
...oppure clonare il repository GitHub dalla riga di comando:
git clone https://github.com/google-home/smarthome-traits.git
Apri il file ZIP scaricato.
Informazioni sul progetto
Il progetto iniziale contiene le seguenti sottodirectory:
public:
Una UI 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 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 evasione degli intent per la smart homereportstate
: richiama l'API Home Graph quando lo stato del dispositivo cambiarequestsync
: abilita gli aggiornamenti del dispositivo dell'utente senza richiedere il ricollegamento dell'account.
Connettersi a Firebase
Vai alla directory washer-start
, quindi configura l'interfaccia a riga di comando di Firebase con il progetto Actions:
cd washer-start firebase use <project-id>
Configura un progetto Firebase
Inizializza 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
Verranno inizializzate le API e le funzionalità necessarie per il 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 features/.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 abilitato 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 confonderlo con il nome simile.eslintrc.json
. - Tramite la 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, insieme a diverse Cloud Functions for Firebase.
Apri Hosting URL (URL di hosting) nel browser (https://<project-id>.web.app
) per visualizzare l'app web. Verrà visualizzata la seguente interfaccia:
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 nella 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 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 completamento per gli intent della smart home e fai clic su Salva.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Nella scheda Sviluppo > 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 dell'account, seleziona il menu Sviluppo > Collegamento dell'account nel riquadro 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, quindi fai clic su Test per attivare i test sul tuo progetto.
Il sistema ti reindirizzerà al Simulatore. Se non visualizzi "Test ora abilitato", fai clic su Reimposta test per verificare che i test siano attivati.
Collegare l'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.
- Apri le impostazioni dell'Assistente Google sullo smartphone. Tieni presente che devi aver eseguito l'accesso con lo stesso account della console.
- Vai su Assistente Google > Impostazioni > Controllo della casa (nella sezione Assistente).
- Fai clic sull'icona di ricerca in alto a destra.
- Cerca la tua app di test utilizzando il prefisso [test] per trovare la tua 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 di riuscire a vedere la lavatrice.
Verifica di poter controllare la lavatrice tramite i comandi vocali nell'app Google Home. La modifica dello stato del dispositivo dovrebbe essere visualizzata anche nella UI web frontend del tuo fulfillment Cloud.
Ora che hai 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 configurarne solo una alla volta. Aggiungerai una modalità alla lavatrice per definire le dimensioni del carico della biancheria: 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 nel seguente snippet di codice.
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
Nel tuo intent EXECUTE
, aggiungi il comando action.devices.commands.SetModes
come mostrato nel seguente snippet di codice.
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 di QUERY
Dopodiché, aggiorna la tua 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 del report
Infine, aggiorna la funzione reportstate
per segnalare l'impostazione di carico attuale della lavatrice in 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, accedi all'interfaccia utente web e fai clic sul pulsante Aggiorna nella barra degli strumenti. Questo attiva una sincronizzazione delle richieste in modo che l'assistente riceva i dati aggiornati per le risposte 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 tua lavatrice, ad esempio:
"Hey Google, qual è il carico della lavatrice?"
5. Aggiungi opzioni di attivazione/disattivazione
Il tratto action.devices.traits.Toggles
rappresenta aspetti denominati di un dispositivo in stato vero o falso, ad esempio se la lavatrice è in modalità turbo.
Aggiorna risposta SYNC
Nella risposta di SYNC
, devi aggiungere informazioni sul nuovo tratto dispositivo. Verrà visualizzato nell'array traits
e nell'oggetto attributes
come mostrato nel seguente snippet di codice.
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
Nel tuo intent EXECUTE
, aggiungi il comando action.devices.commands.SetToggles
come mostrato nel seguente snippet di codice.
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 di 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 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 del report
Infine, aggiorna la funzione reportstate
per segnalare a Home Graph se la lavatrice è impostata sulla 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 nella UI web per attivare una sincronizzazione della richiesta al termine del deployment.
Ora puoi dare un comando per impostare la lavatrice in modalità turbo dicendo:
"Hey Google, accendi il turbo della lavatrice."
Puoi anche controllare se la lavatrice è già in modalità turbo chiedendo:
"Hey Google, la mia lavatrice è in modalità turbo?"
6. Segnalare errori ed eccezioni
L'azione Gestione degli errori nell'azione per la smart home ti consente di segnalare agli utenti quando problemi impediscono le risposte di EXECUTE
e QUERY
. Le notifiche creano un'esperienza più positiva per gli 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 accendere la lavatrice, l'assistente risponde dicendo:
"Il coperchio della lavatrice è aperto. Chiudila e riprova."
Le Eccezioni sono simili agli errori, ma indicano quando un avviso è associato a un comando, il che può bloccare o meno l'esecuzione corretta. Un'eccezione può fornire informazioni correlate tramite il tratto StatusReport
, ad esempio il livello della batteria o una modifica recente dello stato. I codici di eccezione che non comportano il blocco vengono restituiti con lo stato SUCCESS
, mentre i codici di eccezione di blocco vengono restituiti con lo stato EXCEPTIONS
.
Un esempio di risposta con un'eccezione è il 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 non è più in funzione."
Per aggiungere report sugli errori per la tua lavatrice, apri functions/index.js
e aggiungi la definizione della classe di errore come visualizzata 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 in modo che restituisca 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ò informare gli utenti di qualsiasi codice di errore che segnali. Troverai un esempio specifico nella prossima sezione.
7. Aggiungere la verifica utente secondaria
Devi implementare la verifica dell'utente secondaria nell'Azione se il tuo dispositivo ha modalità che devono essere protette o devono essere limitate a un determinato gruppo di utenti autorizzati, ad esempio un aggiornamento 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 devono essere soddisfatti criteri specifici.
Esistono tre tipi di sfide supportati:
No
challenge
: richiesta e risposta che non utilizzano una verifica di autenticazione (questo è il comportamento predefinito)ackNeeded
: una verifica utente secondaria che richiede il riconoscimento esplicito (sì o no)pinNeeded
: una verifica secondaria dell'utente che richiede un PIN (Personal Identification Number)
Per questo codelab, aggiungi una verifica ackNeeded
al comando per attivare 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 della classe di errore che restituisca il codice di errore e il tipo di verifica, come illustrato 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( ... )
.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 che richieda il riconoscimento esplicito per attivare o disattivare 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);
};
Eseguire il deployment in Firebase
Esegui questo comando per eseguire il deployment della funzione aggiornata:
firebase deploy --only functions
Dopo aver implementato il codice aggiornato, devi confermare verbalmente l'operazione quando chiedi all'assistente di accendere o spegnere la lavatrice, nel seguente modo:
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 degli utenti secondario aprendo i log di Firebase.
8. Complimenti
Complimenti! Hai esteso le funzionalità delle Azioni per la smart home tramite i trait Modes
e Toggles
e ne hai protetto l'esecuzione tramite una verifica utente secondaria.
Scopri di più
Ecco alcune idee che puoi mettere in pratica per approfondire:
- Aggiungi funzionalità di esecuzione locale ai tuoi dispositivi.
- Utilizza un tipo di verifica dell'utente secondario diverso per modificare lo stato del dispositivo.
- Aggiorna la risposta QUERY del trait
RunCycle
per aggiornarla in modo dinamico. - Esplora questo esempio di GitHub.