1. Avant de commencer
Les intégrations cloud à cloud utilisent les types d'appareils pour indiquer à l'Assistant Google la grammaire à utiliser avec un appareil. Les caractéristiques d'appareil définissent les fonctionnalités d'un type d'appareil. Un appareil hérite des états de chaque caractéristique d'appareil ajoutée à une intégration.
Vous pouvez associer n'importe quelle caractéristique compatible au type d'appareil que vous avez choisi pour personnaliser les fonctionnalités des appareils de vos utilisateurs. Si vous souhaitez mettre en œuvre des caractéristiques personnalisées dans vos actions qui ne sont pas disponibles actuellement dans le schéma de l'appareil, les caractéristiques Modes et Activation/Désactivation permettent de définir des commandes de paramètres spécifiques avec un nom personnalisé.
En plus des commandes de base fournies par les types et les caractéristiques, l'API Smart Home offre des fonctionnalités supplémentaires pour améliorer l'expérience utilisateur. Les réponses d'erreur fournissent des commentaires d'utilisateurs détaillés lorsque les intents échouent. La validation de l'utilisateur secondaire renforce ces réponses et améliore la sécurité de la caractéristique d'appareil de votre choix. En envoyant des réponses d'erreur spécifiques aux ensembles de questions posées par l'Assistant, votre intégration cloud à cloud peut exiger une autorisation supplémentaire pour mettre en œuvre une commande.
Prérequis
- Guide du développeur sur la création d'une intégration cloud à cloud
- Atelier de programmation Lave-linge connecté
- Guide du développeur Types et caractéristiques d'appareils
Ce que vous allez faire
Dans cet atelier de programmation, vous allez déployer une intégration de maison connectée prédéfinie avec Firebase, puis apprendre à ajouter des caractéristiques non standards concernant la capacité et le mode rapide du lave-linge connecté. Vous allez également mettre en œuvre la création de rapports d'erreurs et d'exceptions, et apprendre à appliquer un accusé de réception verbal pour allumer le lave-linge à l'aide de la validation de l'utilisateur secondaire.
Points abordés
- Ajouter des caractéristiques Modes et Activation/Désactivation à votre intégration
- Signaler des erreurs et des exceptions
- Demander la validation secondaire de l'utilisateur
Prérequis
- Un navigateur Web, tel que Google Chrome
- Un appareil iOS ou Android sur lequel est installée l'application Google Home
- Node.js version 10.16 ou ultérieure
- Un compte Google
- un compte de facturation Google Cloud ;
2. Premiers pas
Activer les commandes relatives à l'activité
Pour utiliser l'Assistant Google, vous devez partager certaines données d'activité avec Google. L'Assistant Google a besoin de ces données pour fonctionner correctement. Toutefois, l'obligation de partager les données n'est pas spécifique au SDK. Pour partager ces données, créez un compte Google si vous n'en possédez pas. Vous pouvez utiliser n'importe quel compte Google. Il ne doit pas nécessairement s'agir de votre compte de développeur.
Ouvrez la page "Commandes relatives à l'activité" du compte Google que vous souhaitez utiliser avec l'Assistant.
Vérifiez que les boutons suivants sont activés :
- Activité sur le Web et les applications : veillez également à cocher la case Inclure l'historique Chrome et l'activité liée aux sites, aux applications et aux appareils qui utilisent les services Google.
- Informations provenant des appareils
- Activités vocales et audio
Créer un projet d'intégration cloud à cloud
- Accédez à la console pour les développeurs.
- Cliquez sur Créer un projet, saisissez un nom pour le projet, puis cliquez sur Créer un projet.
Sélectionner l'intégration cloud à cloud
Sur la page Project Home (Accueil du projet) de la console du développeur, sélectionnez Add cloud-to-cloud integration (Ajouter une intégration cloud à cloud) sous Cloud-to-cloud (Cloud à cloud).
Installer la CLI Firebase
L'interface de ligne de commande (CLI) Firebase vous permet de diffuser vos applications Web en local et de les déployer sur Firebase Hosting.
Pour installer la CLI, exécutez la commande npm suivante à partir du terminal :
npm install -g firebase-tools
Pour vérifier que la CLI a bien été installée, exécutez la commande suivante :
firebase --version
Autorisez la CLI Firebase avec votre compte Google en exécutant la commande suivante :
firebase login
Créer un projet Firebase
- Accédez à Firebase.
- Cliquez sur Créer un projet, puis saisissez le nom de votre projet.
- Cochez la case du contrat, puis cliquez sur Continuer. Si aucune case à cocher n'est disponible, vous pouvez ignorer cette étape.
- Une fois votre projet Firebase créé, recherchez son ID. Accédez à Vue d'ensemble du projet, puis cliquez sur l'icône des paramètres > Paramètres du projet.
- Votre projet est listé dans l'onglet Général.
Activer l'API HomeGraph
L'API HomeGraph permet de stocker les données des appareils et leur état, et de les interroger, depuis le Home Graph d'un utilisateur. Pour utiliser cette API, vous devez d'abord ouvrir la console Google Cloud et activer l'API HomeGraph.
Dans la console Google Cloud, veillez à sélectionner le projet correspondant à vos actions <firebase-project-id>.
Ensuite, sur l'écran "Bibliothèque d'API" de l'API HomeGraph, cliquez sur Activer.
3. Exécuter l'application de démarrage
Maintenant que vous avez configuré votre environnement de développement, vous pouvez déployer le projet d'initiation pour vous assurer que la configuration est correcte.
Obtenir le code source
Cliquez sur le lien suivant pour télécharger l'exemple utilisé dans cet atelier de programmation sur votre ordinateur de développement :
Vous pouvez également cloner le dépôt GitHub à partir de la ligne de commande :
git clone https://github.com/google-home/smarthome-traits.git
Décompressez le fichier ZIP téléchargé.
À propos du projet
Le projet de démarrage contient les sous-répertoires suivants :
public:
interface utilisateur permettant de contrôler et de surveiller facilement l'état du lave-linge connecté.functions:
service cloud entièrement implémenté qui gère le lave-linge connecté avec Cloud Functions for Firebase et Firebase Realtime Database.
Le traitement cloud fourni comprend les fonctions suivantes dans index.js
:
fakeauth
: point de terminaison de l'autorisation pour l'association de comptesfaketoken
: point de terminaison du jeton pour l'association de comptessmarthome
: point de terminaison du traitement des intents de maison connectéereportstate
:appelle l'API HomeGraph en cas de modification de l'état de l'appareilrequestsync
:active les mises à jour des appareils des utilisateurs sans nécessiter une nouvelle association de compte.
Se connecter à Firebase
Accédez au répertoire washer-start
, puis configurez la CLI Firebase avec votre projet d'intégration:
cd washer-start firebase use <firebase-project-id>
Configurer un projet Firebase
Initialisez un projet Firebase.
firebase init
Sélectionnez les fonctionnalités de la CLI, Realtime Database, Functions et la fonctionnalité Hosting qui inclut 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
Cette opération initialise les API et les fonctionnalités nécessaires pour votre projet.
Lorsque vous y êtes invité, initialisez Realtime Database. Vous pouvez utiliser l'emplacement par défaut pour l'instance de base de données.
? 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
Comme vous utilisez le code du projet d'initiation, choisissez le fichier par défaut pour les règles de sécurité, en veillant à ne pas écraser le fichier des règles de base de données existantes.
? 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
Si vous réinitialisez votre projet, sélectionnez Remplacer lorsque vous êtes invité à initialiser ou à remplacer un codebase.
? Would you like to initialize a new codebase, or overwrite an existing one? Overwrite
Lorsque vous configurez vos fonctions, vous devez utiliser les fichiers par défaut et veiller à ne pas écraser les fichiers index.js et package.json existants dans l'exemple de projet.
? 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
Si vous réinitialisez votre projet, sélectionnez Non lorsque vous êtes invité à initialiser ou à écraser functions/.gitignore.
? File functions/.gitignore already exists. Overwrite? No
? Do you want to install dependencies with npm now? Yes
Enfin, configurez votre configuration Hosting pour utiliser le répertoire public
dans le code du projet, et le fichier index.html existant. Sélectionnez Non lorsque vous êtes invité à utiliser 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
Si ESLint a été activé par erreur, vous pouvez le désactiver de deux manières:
- Dans l'IUG, accédez au dossier
../functions
sous le projet, sélectionnez le fichier masqué.eslintrc.js
, puis supprimez-le. Ne le confondez pas avec.eslintrc.json
, dont le nom est très similaire. - À l'aide de la ligne de commande:
cd functions rm .eslintrc.js
Déployer sur Firebase
Maintenant que vous avez installé les dépendances et configuré votre projet, vous êtes prêt à exécuter l'application.
firebase deploy
La console doit afficher le résultat suivant :
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<firebase-project-id>/overview Hosting URL: https://<firebase-project-id>.web.app
Cette commande déploie une application Web, ainsi que plusieurs fonctions Cloud Functions for Firebase.
Ouvrez l'URL d'hébergement dans votre navigateur (https://<firebase-project-id>.web.app
) pour afficher l'application Web. L'interface suivante s'affiche :
Cette interface utilisateur Web représente une plate-forme tierce permettant d'afficher ou de modifier l'état des appareils. Pour commencer à renseigner des informations provenant des appareils dans votre base de données, cliquez sur UPDATE (Mettre à jour). Aucune modification n'est affichée sur la page, mais l'état actuel de votre lave-linge est stocké dans la base de données.
Il est maintenant temps d'associer le service cloud que vous avez déployé à l'Assistant Google à l'aide de la console du développeur.
Configurer votre projet dans la console développeur
Dans l'onglet Develop (Développer), ajoutez un Display Name (Nom à afficher) à votre interaction. Ce nom sera affiché dans l'application Google Home.
Sous Identité visuelle de l'application, importez un fichier png
pour l'icône de l'application, de taille 144 x 144 px et nommé
.
Pour activer l'association de comptes, utilisez les paramètres suivants:
ID client |
|
Client secret (Code secret du client) |
|
Authorization URL (URL de l'autorisation) |
|
Token URL (URL du jeton) |
|
Sous URL de traitement cloud, saisissez l'URL de votre fonction cloud qui fournit le traitement nécessaire pour les intents de la maison connectée.
https://us-central1-
Cliquez sur Save (Enregistrer) pour enregistrer la configuration de votre projet, puis sur Next: Test (Suivant : Test) pour activer les tests sur votre projet.
Vous pouvez maintenant commencer à implémenter les webhooks nécessaires pour associer l'état de l'appareil à l'Assistant.
Associer le projet à l'Assistant Google
Pour tester votre intégration cloud à cloud, vous devez associer votre projet à un compte Google. Vous pourrez effectuer des tests via les surfaces de l'Assistant Google et l'application Google Home connectées au même compte.
- Sur votre téléphone, ouvrez les paramètres de l'Assistant Google. Notez que votre appareil doit être connecté avec le même compte que celui utilisé dans la console.
- Accédez à Assistant Google > Paramètres > Contrôle de la maison (sous "Assistant").
- Cliquez sur l'icône de recherche en haut à droite.
- Recherchez votre application de test à l'aide du préfixe [test] pour la trouver.
- Sélectionnez-la. L'Assistant Google s'authentifie alors auprès de votre service et envoie une requête
SYNC
pour lui demander de fournir une liste d'appareils pour l'utilisateur.
Ouvrez l'application Google Home et vérifiez que votre lave-linge est affiché.
Vérifiez que vous pouvez contrôler le lave-linge à l'aide de commandes vocales dans l'application Google Home. Vous devriez également observer la modification de l'état de l'appareil dans l'interface utilisateur Web de votre traitement cloud.
Maintenant que vous avez déployé un lave-linge de base, vous pouvez personnaliser les modes disponibles sur votre appareil.
4. Ajouter des modes
La caractéristique action.devices.traits.Modes
permet à un appareil d'avoir un nombre arbitraire de paramètres pour un mode (un seul pouvant être défini à la fois). Vous allez ajouter un mode au lave-linge afin de définir la capacité : petite, moyenne ou grande.
Mettre à jour la réponse SYNC
Vous devez ajouter des informations sur la nouvelle caractéristique à votre réponse SYNC
dans functions/index.js
. Ces données apparaissent dans le tableau traits
et dans l'objet attributes
, comme indiqué dans l'extrait de code suivant.
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,
}],
},
}],
},
};
});
Ajouter de nouvelles commandes d'intent EXECUTE
Dans votre intent EXECUTE
, ajoutez la commande action.devices.commands.SetModes
, comme indiqué dans l'extrait de code suivant.
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;
}
Mettre à jour la réponse QUERY
Ensuite, mettez à jour votre réponse QUERY
pour signaler l'état actuel du lave-linge.
Ajoutez les modifications aux fonctions queryFirebase
et queryDevice
pour obtenir l'état stocké dans 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,
},
};
};
Mettre à jour l'état du rapport
Enfin, mettez à jour votre fonction reportstate
pour signaler le paramètre de capacité actuel du lave-linge à 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,
},
},
},
},
},
};
Déployer sur Firebase
Exécutez la commande suivante pour déployer l'intégration mise à jour:
firebase deploy --only functions
Une fois le déploiement terminé, accédez à l'interface utilisateur Web et cliquez sur le bouton Actualiser dans la barre d'outils. Cela déclenchera une synchronisation des requêtes afin que l'Assistant reçoive les données de réponse
SYNC
actualisées.
Vous pouvez à présent énoncer une commande pour définir le mode du lave-linge, par exemple :
"Hey Google, règle le mode Grande capacité du lave-linge."
Vous pouvez également poser des questions sur votre lave-linge, comme :
"Hey Google, quelle est la capacité du lave-linge ?"
5. Ajouter des caractéristiques Activation/Désactivation
La caractéristique action.devices.traits.Toggles
représente les aspects nommés d'un appareil dont l'état est vrai ou faux, par exemple le mode rapide d'un lave-linge.
Mettre à jour la réponse SYNC
Dans votre réponse SYNC
, vous devez ajouter des informations sur la nouvelle caractéristique d'appareil. Elle apparaîtra dans le tableau traits
et dans l'objet attributes
, comme indiqué dans l'extrait de code suivant.
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',
}],
}],
},
}],
},
};
});
Ajouter de nouvelles commandes d'intent EXECUTE
Dans votre intent EXECUTE
, ajoutez la commande action.devices.commands.SetToggles
, comme indiqué dans l'extrait de code suivant.
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;
}
Mettre à jour la réponse QUERY
Enfin, vous devez mettre à jour votre réponse QUERY
pour signaler le mode rapide du lave-linge. Ajoutez les modifications aux fonctions queryFirebase
et queryDevice
pour obtenir l'état d'activation stocké dans 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,
},
};
};
Mettre à jour l'état du rapport
Enfin, mettez à jour votre fonction reportstate
pour signaler à Home Graph si le lave-linge est réglé sur le mode rapide.
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,
},
},
},
},
},
};
Effectuer le déploiement sur Firebase
Exécutez la commande suivante pour déployer les fonctions mises à jour :
firebase deploy --only functions
Cliquez sur le bouton Actualiser dans l'interface utilisateur Web pour déclencher une synchronisation des requêtes à la fin du déploiement.
Vous pouvez à présent énoncer la commande suivante pour activer le mode rapide du lave-linge :
"Hey Google, active le mode rapide du lave-linge."
Vous pouvez également vérifier si votre lave-linge est déjà en mode rapide en demandant :
"Hey Google, est-ce que mon lave-linge est en mode rapide ?"
6. Signaler des erreurs et des exceptions
La gestion des erreurs dans votre intégration cloud à cloud vous permet de signaler aux utilisateurs quand des problèmes entraînent l'échec des réponses EXECUTE
et QUERY
. Les notifications permettent d'offrir une expérience positive aux utilisateurs lorsqu'ils interagissent avec votre appareil connecté et votre intégration.
Chaque fois qu'une requête EXECUTE
ou QUERY
échoue, votre intégration doit renvoyer un code d'erreur. Si, par exemple, vous souhaitez générer une erreur lorsqu'un utilisateur tente de démarrer le lave-linge alors que le hublot est ouvert, votre réponse EXECUTE
devrait ressembler à l'extrait de code suivant :
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [
{
"ids": [
"456"
],
"status": "ERROR",
"errorCode": "deviceLidOpen"
}
]
}
}
Désormais, lorsqu'un utilisateur demande à lancer le lave-linge, l'Assistant répond en disant :
"Le hublot du lave-linge est ouvert. Veuillez le fermer et réessayer."
Les exceptions sont similaires aux erreurs, mais elles indiquent si une alerte est associée à une commande, qu'elle soit bloquante ou non pour l'exécution. Une exception peut fournir des informations associées à l'aide de la caractéristique StatusReport
, comme le niveau de batterie ou un changement d'état récent. Les codes d'exception non bloquants sont renvoyés avec l'état SUCCESS
, tandis que les codes d'exception bloquants sont renvoyés avec l'état EXCEPTIONS
.
Un exemple de réponse avec exception est présenté dans l'extrait de code suivant :
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [{
"ids": ["123"],
"status": "SUCCESS",
"states": {
"online": true,
"isPaused": false,
"isRunning": false,
"exceptionCode": "runCycleFinished"
}
}]
}
}
L'Assistant répond ce qui suit :
"Le cycle de lavage est terminé."
Si vous souhaitez signaler les erreurs liées à votre lave-linge, ouvrez functions/index.js
et ajoutez la définition de classe d'erreur, comme illustré dans l'extrait de code suivant :
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;
}
}
Mettez à jour la réponse d'exécution pour renvoyer le code d'erreur et l'état de l'erreur :
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'Assistant peut à présent transmettre tous les codes d'erreur que vous signalez à vos utilisateurs. Un exemple spécifique est présenté dans la section suivante.
7. Ajouter une validation secondaire de l'utilisateur
Vous devez mettre en œuvre une validation secondaire de l'utilisateur dans votre intégration si votre appareil comporte des modes devant être sécurisés ou limités à un groupe spécifique d'utilisateurs autorisés, comme une mise à jour de logiciel ou un déverrouillage.
Vous pouvez mettre en œuvre la validation secondaire des utilisateurs sur tous les types et caractéristiques d'appareils afin de déterminer si la question de sécurité doit être posée systématiquement ou uniquement lors de situations spécifiques.
Il existe trois types d'authentification:
No
challenge
: demande et réponse qui ne nécessitent pas de question de sécurité (comportement par défaut)ackNeeded
: validation secondaire de l'utilisateur qui nécessite une confirmation explicite ("Oui" ou "Non")pinNeeded
: validation secondaire de l'utilisateur qui nécessite un code secret
Pour les besoins de cet atelier de programmation, ajoutez l'authentification ackNeeded
à la commande permettant d'allumer le lave-linge ainsi qu'une fonctionnalité permettant de renvoyer une erreur en cas d'échec de la vérification secondaire.
Ouvrez functions/index.js
, puis ajoutez une définition de classe d'erreur qui renvoie le code d'erreur et le type d'authentification, comme indiqué dans l'extrait de code suivant :
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;
}
}
Vous devez également mettre à jour la réponse d'exécution pour renvoyer l'erreur challengeNeeded
comme suit :
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
};
}
}
})
);
}
}
}
Enfin, modifiez le paramètre updateDevice
de manière à exiger un accusé de réception explicite pour allumer ou éteindre le lave-linge.
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);
};
Effectuer le déploiement sur Firebase
Exécutez la commande suivante pour déployer la fonction mise à jour :
firebase deploy --only functions
Après avoir déployé le code mis à jour, vous devez confirmer l'action à voix haute lorsque vous demandez à l'Assistant d'allumer ou d'éteindre votre lave-linge, comme suit :
Vous : "Hey Google, allume le lave-linge."
Assistant : "Voulez-vous vraiment allumer le lave-linge ?"
Vous : "Oui."
Vous pouvez également obtenir une réponse détaillée pour chaque étape du parcours de validation de l'utilisateur secondaire en ouvrant vos journaux Firebase.
8. Félicitations
Félicitations ! Vous avez étendu les fonctionnalités des intégrations cloud à cloud grâce aux caractéristiques Modes
et Toggles
. Vous avez également sécurisé leur exécution via la validation secondaire des utilisateurs.
En savoir plus
Voici quelques idées que vous pouvez mettre en pratique pour approfondir le sujet :
- Ajoutez des fonctionnalités d'exécution locale à vos appareils.
- Utilisez un autre type de défi de validation secondaire de l'utilisateur pour modifier l'état de l'appareil.
- Mettez à jour la réponse QUERY de la caractéristique
RunCycle
pour qu'elle soit dynamique. - Explorez cet exemple GitHub.