En tant que développeur de solutions IoT (Internet des objets), vous pouvez créer des Actions pour la maison connectée qui permettent aux utilisateurs de contrôler leurs appareils à l'aide de commandes tactiles dans l'application Google Home et de commandes vocales via l'Assistant.
Home Graph est utilisé par les Actions pour la maison connectée afin de fournir des données contextuelles sur la maison et les appareils associés, créant ainsi une carte logique de la maison. Ce contexte permet à l'Assistant de mieux comprendre les demandes formulées par l'utilisateur en fonction de sa position dans la maison. Par exemple, Home Graph peut stocker le concept d'une salle de séjour contenant plusieurs types d'appareils de différents fabricants, comme un thermostat, une lampe, un ventilateur ou encore un aspirateur.
Conditions préalables
- Guide du développeur Créer une Action pour la maison connectée
Objectifs de l'atelier
Dans cet atelier de programmation, vous allez publier un service cloud qui gère une machine à laver connectée virtuelle, puis créer une Action pour la maison connectée et la connecter à l'Assistant.
Points abordés
- Déployer un service cloud pour la maison connectée
- Connecter le service à l'Assistant
- Publier les changements d'état de l'appareil sur Google
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 de facturation Google Cloud
Activer les commandes relatives à l'activité
Activez les commandes relatives à l'activité suivantes dans le compte Google que vous prévoyez d'utiliser avec l'Assistant :
- Activité sur le Web et les applications
- Informations provenant des appareils
- Activité vocale et audio
Créer un projet Actions
- Accédez à la console Actions on Google pour les développeurs.
- Cliquez sur New Project (Nouveau projet), saisissez un nom pour le projet, puis cliquez sur CREATE PROJECT (CRÉER UN PROJET).
Sélectionner l'application Smart Home
Sur l'écran d'aperçu de la console Actions, sélectionnez Smart Home.
Sélectionnez la fiche d'expérience Smart Home pour accéder à la console de votre projet.
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
Maintenant que vous avez configuré votre environnement de développement, vous pouvez déployer le projet de démarrage pour vous assurer que la configuration est correcte.
Obtenir le code source
Cliquez sur le lien suivant pour télécharger l'exemple de 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/googlecodelabs/smarthome-washer.git
À 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.
Se connecter à Firebase
Accédez au répertoire washer-start
, puis configurez la CLI Firebase avec votre projet Actions :
cd washer-start firebase use <project-id>
Déployer le code sur Firebase
Accédez au dossier functions
et installez toutes les dépendances nécessaires à l'aide de npm.
cd functions npm install
Maintenant que vous avez installé les dépendances et configuré votre projet, vous êtes prêt à exécuter l'application pour la première fois.
firebase deploy
La console doit afficher le résultat suivant :
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.firebaseapp.com
Cette commande déploie une application Web, ainsi que plusieurs fonctions cloud (Cloud Functions for Firebase).
Ouvrez l'URL d'hébergement dans votre navigateur (https://<project-id>.firebaseapp.com
) 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 les états de l'appareil. Pour commencer à renseigner des informations provenant de l'appareil 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 Actions.
Configurer le projet de la console Actions
Sous Overview > Build your Action (Aperçu > Créer votre Action), sélectionnez Add Action(s) (Ajouter une ou plusieurs Actions). Saisissez l'URL de la fonction Cloud qui fournit le traitement nécessaire pour les intents de maison connectée, puis cliquez sur Save (Enregistrer).
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Dans l'onglet Develop > Invocation (Développer > Appel), attribuez un nom à afficher à votre Action dans la section Display name, puis cliquez sur Save (Enregistrer). Ce nom sera affiché dans l'application Google Home.
Pour activer l'association de comptes, sélectionnez l'option Develop > Account linking (Développer > Association de comptes) dans le panneau de navigation de gauche. Utilisez les paramètres d'association de comptes suivants :
Client ID (ID client) |
|
Client secret (Code secret du client) |
|
Authorization URL (URL d'autorisation) |
|
Token URL (URL du jeton) |
|
Cliquez sur Save (Enregistrer) pour enregistrer la configuration de l'association de comptes, puis sur Test pour activer les tests sur votre projet.
Vous accédez alors au Simulateur. Vérifiez que les tests ont bien été activés pour votre projet en passant la souris sur l'icône (Tests sur l'appareil).
Vous pouvez maintenant commencer à implémenter les webhooks nécessaires pour associer l'état de l'appareil à l'Assistant.
Maintenant que vous avez configuré votre Action, vous pouvez ajouter des appareils et envoyer des données. Votre service cloud doit gérer les intents suivants :
- Un intent
SYNC
se produit lorsque l'Assistant souhaite connaître les appareils que l'utilisateur a connectés. Cet intent est envoyé à votre service lorsque l'utilisateur associe un compte. En réponse, vous devez fournir une charge utile JSON avec tous les appareils de l'utilisateur, ainsi que leurs fonctionnalités. - Un intent
QUERY
se produit lorsque l'Assistant souhaite connaître l'état ou le statut actuel d'un appareil. En réponse, vous devez fournir une charge utile JSON avec l'état de chaque appareil demandé. - Un intent
EXECUTE
se produit lorsque l'Assistant souhaite contrôler un appareil pour le compte d'un utilisateur. En réponse, vous devez fournir une charge utile JSON avec le statut d'exécution de chaque appareil demandé. - Un intent
DISCONNECT
se produit lorsque l'utilisateur dissocie son compte de l'Assistant. Vous devez cesser d'envoyer des événements concernant les appareils de cet utilisateur à l'Assistant.
Vous allez mettre à jour les fonctions que vous avez déployées précédemment pour gérer ces intents dans les sections suivantes.
Mettre à jour la réponse SYNC
Ouvrez le fichier functions/index.js
qui contient le code permettant de répondre aux requêtes de l'Assistant.
Vous devrez gérer un intent SYNC
en renvoyant les métadonnées et les fonctionnalités de l'appareil. Mettez à jour le fichier JSON dans le tableau onSync
afin d'inclure les informations provenant des appareils ainsi que les caractéristiques recommandées pour un lave-linge.
index.js
app.onSync((body) => {
return {
requestId: body.requestId,
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',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer'],
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1',
},
willReportState: true,
attributes: {
pausable: true,
},
}],
},
};
});
Déployer le code sur Firebase
Déployez le traitement cloud mis à jour à l'aide de la CLI Firebase :
firebase deploy --only functions
Associer le projet à l'Assistant Google
Afin de tester votre Action pour la maison connectée, 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 vous devez ê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").
- Sélectionnez l'icône plus (+) dans l'angle inférieur droit.
- Vous devriez voir votre application de test avec le préfixe [test] et le nom à afficher que vous avez défini.
- Sélectionnez cet élément. 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 bien affiché.
Maintenant que votre service cloud signale correctement le lave-linge à Google, vous devez lui permettre de demander l'état de l'appareil et d'envoyer des commandes.
Gérer l'intent QUERY
Un intent QUERY
inclut un ensemble d'appareils. Pour chaque appareil, vous devez renvoyer l'état actuel.
Dans functions/index.js
, modifiez le gestionnaire QUERY
de manière à traiter la liste des appareils cibles figurant dans la requête d'intent.
index.js
app.onQuery(async (body) => {
const {requestId} = body;
const payload = {
devices: {},
};
const queryPromises = [];
const intent = body.inputs[0];
for (const device of intent.payload.devices) {
const deviceId = device.id;
queryPromises.push(queryDevice(deviceId)
.then((data) => {
// Add response to device payload
payload.devices[deviceId] = data;
}
));
}
// Wait for all promises to resolve
await Promise.all(queryPromises);
return {
requestId: requestId,
payload: payload,
};
});
Pour chaque appareil figurant dans la requête, renvoyez l'état actuel stocké dans Realtime Database. Mettez à jour les fonctions queryFirebase
et queryDevice
pour qu'elles renvoient les données d'état du lave-linge.
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,
};
};
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
};
};
Gérer l'intent EXECUTE
L'intent EXECUTE
gère les commandes de mise à jour de l'état de l'appareil. La réponse renvoie le statut de chaque commande (SUCCESS
, ERROR
ou PENDING
, par exemple) ainsi que le nouvel état de l'appareil.
Dans functions/index.js
, modifiez le gestionnaire EXECUTE
pour traiter la liste des caractéristiques qui doivent être mises à jour et l'ensemble des appareils cibles pour chaque commande :
index.js
app.onExecute(async (body) => {
const {requestId} = body;
// Execution results are grouped by status
const result = {
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
};
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) => {
result.ids.push(device.id);
Object.assign(result.states, data);
})
.catch(() => functions.logger.error('EXECUTE', device.id)));
}
}
}
await Promise.all(executePromises);
return {
requestId: requestId,
payload: {
commands: [result],
},
};
});
Pour chaque commande et appareil cible, mettez à jour les valeurs de Realtime Database qui correspondent à la caractéristique demandée. Modifiez la fonction updateDevice
de manière à mettre à jour la référence Firebase appropriée et à renvoyer l'état de l'appareil mis à jour.
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let 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;
}
return ref.update(state)
.then(() => state);
};
Après avoir implémenté les trois intents, vous pouvez vérifier que votre Action contrôle bien le lave-linge.
Déployer le code sur Firebase
Déployez le traitement cloud mis à jour à l'aide de la CLI Firebase :
firebase deploy --only functions
Tester le lave-linge
Comme vous pouvez maintenant le constater, la valeur change lorsque vous énoncez l'une des commandes vocales suivantes à l'aide de votre téléphone :
"Hey Google, allume mon lave-linge."
"Hey Google, mets mon lave-linge en pause."
"Hey Google, arrête mon lave-linge."
Vous pouvez également poser des questions pour connaître l'état actuel de votre lave-linge.
"Hey Google, est-ce que mon lave-linge est allumé ?"
"Hey Google, est-ce que mon lave-linge est en marche ?"
"Hey Google, quel est le cycle défini sur mon lave-linge ?"
Vous pouvez également afficher ces requêtes et commandes dans les journaux de votre console Firebase en cliquant sur Develop (Développer) > Functions (Fonctions) > Logs (Journaux) dans le menu de navigation.
Votre service cloud est maintenant complètement intégré aux intents de maison connectée, ce qui permet aux utilisateurs de contrôler leurs appareils et d'en connaître l'état actuel. Toutefois, cette implémentation ne permet toujours pas au service d'envoyer, de manière proactive, des informations sur les événements (tels que des changements d'état ou de présence sur l'appareil) à l'Assistant.
La fonction Request Sync vous permet de déclencher une nouvelle demande de synchronisation lorsque des utilisateurs ajoutent ou suppriment des appareils, ou en cas de modification des fonctionnalités de leurs appareils. La fonction Report State permet à votre service cloud d'envoyer, de manière proactive, l'état d'un appareil à Home Graph lorsque des utilisateurs le modifient physiquement (en activant un interrupteur, par exemple) ou à l'aide d'un autre service.
Dans cette section, vous allez ajouter du code afin d'appeler ces méthodes à partir de l'interface de l'application Web.
Activer l'API HomeGraph
L'API HomeGraph permet de stocker et d'interroger les appareils, ainsi que leurs états, dans le Home Graph d'un utilisateur. Pour utiliser cette API, vous devez d'abord ouvrir Google Cloud Console et activer l'API HomeGraph.
Dans Google Cloud Console, veillez à sélectionner le projet correspondant à vos Actions <project-id>.
Ensuite, sur l'écran "Bibliothèque d'API" de l'API HomeGraph, cliquez sur Activer.
Activer Report State
Lorsque des données sont écrites dans Realtime Database, la fonction reportstate
est déclenchée dans le projet de démarrage. Mettez à jour la fonction reportstate
dans functions/index.js
pour capturer les données écrites dans la base de données et les publier sur Home Graph par le biais de la fonction Report State.
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
functions.logger.info('Firebase write event triggered Report State');
const snapshot = change.after.val();
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
},
},
},
},
};
const res = await homegraph.devices.reportStateAndNotification({
requestBody,
});
functions.logger.info('Report state response:', res.status, res.data);
});
Activer Request Sync
La fonction requestsync
est déclenchée dans le projet de démarrage lors de l'actualisation de l'icône dans l'interface utilisateur Web. Implémentez la fonction requestsync
dans functions/index.js
pour appeler l'API HomeGraph.
index.js
exports.requestsync = functions.https.onRequest(async (request, response) => {
response.set('Access-Control-Allow-Origin', '*');
functions.logger.info(`Request SYNC for user ${USER_ID}`);
try {
const res = await homegraph.devices.requestSync({
requestBody: {
agentUserId: USER_ID,
},
});
functions.logger.info('Request sync response:', res.status, res.data);
response.json(res.data);
} catch (err) {
functions.logger.error(err);
response.status(500).send(`Error requesting sync: ${err}`);
}
});
Déployer le code sur Firebase
Déployez le code mis à jour à l'aide de la CLI Firebase :
firebase deploy --only functions
Tester l'implémentation
Cliquez sur le bouton Actualiser dans l'interface utilisateur Web et vérifiez qu'une demande de synchronisation est répertoriée dans le journal de la console Firebase.
Modifiez ensuite les attributs du lave-linge dans l'interface utilisateur Web, puis cliquez sur Mettre à jour. Vérifiez que le changement d'état signalé à Google figure bien dans les journaux de votre console Firebase.
Félicitations ! Vous avez intégré l'Assistant à un service cloud d'appareil en utilisant des Actions pour la maison connectée.
En savoir plus
Voici quelques idées que vous pouvez mettre en pratique pour approfondir le sujet :
- Ajouter des modes et des bascules à votre appareil
- Ajouter d'autres caractéristiques compatibles à votre appareil.
- Explorer l'exécution locale pour la maison connectée.
- Consulter notre exemple GitHub pour en savoir plus.
Vous pouvez également en apprendre davantage sur le test et l'envoi d'une Action pour examen, y compris le processus de certification permettant de publier votre Action auprès des utilisateurs.