Améliorer et sécuriser vos actions pour la maison connectée

Les actions pour la maison connectée 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 action.

dc8dce0dea87cd5c.png

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. L'authentification à deux facteurs 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 action pour la maison connectée peut exiger une autorisation supplémentaire pour mettre en œuvre une commande.

Conditions préalables

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 l'authentification à deux facteurs.

Ce que vous allez apprendre

  • Ajouter des caractéristiques Modes et Activation/Désactivation dans votre action
  • Signaler des erreurs et des exceptions
  • Appliquer l'authentification à deux facteurs

Ce dont vous avez besoin

Activer les commandes relatives à l'activité

Activez ces commandes relatives à l'activité dans le compte Google que vous souhaitez utiliser avec l'Assistant :

  • Activité sur le Web et les applications
  • Informations provenant des appareils
  • Activité vocale et audio

Créer un projet Actions

  1. Accédez à la console pour les développeurs Actions on Google.
  2. Cliquez sur New Project (Nouveau projet), saisissez un nom pour le projet, puis cliquez sur CREATE PROJECT (Créer un projet).

AWXw5E1m9zVgvVeyeL3uxwCX6DtWOCK6LRSLmOATFzjMbmE5cSWBdSVhJZDFpEFH2azZTK2eMs6OYYdMJYiGb5bKqFEzxaLyRUYuwVGBlSjXzTyy8Z9CvwpXvRwP7xdycklETzFc7Q

Sélectionner l'application Smart Home

Sous l'onglet Overview (Aperçu) de la console Actions, sélectionnez Smart Home (Maison connectée).

36RsBUWBgbgsa5xZ7MJVMm1sIg07nXbfjv0mWCxXViaC5SlbL2gMigw9hgXsZQhNMHLLFOfiKdZsSTNXONFB1i47gksw3SBNpkVYl492WeryOlgxKjpVrLAvg-5cZqu1DI-s5kxM3g

Sélectionnez la fiche d'expérience Smart Home (Maison connectée) pour accéder à la console de votre projet.

pzgHPsmc2LvLoeUvJfkjKQqD_BvO4v8JOPlcrxsmyptFkkjL4PP6LqrM9r5tNvEIfT9HmK-UKw3GWFPXTjqo4nUrhD2o5shUKHBE31OT8iIA69JZCev7_0_nh-lnL2oJHoxGfqqZ4w

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

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 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.

5SVCzM8IZLi_9DV8M0nEklv16NXkpvM0bIzQK2hSyKyvnFHBxPOz90rbr72ayxzmxd5aNROOqC_Cp4outbdlwJdObDs0DIE_8vYzw6dovoVrP9IZWlWsZxDS7UHOi1jiRbDMG8MqUA

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 :

Télécharger le code source

Vous pouvez également cloner le dépôt GitHub à partir de la ligne de commande :

git clone https://github.com/googlecodelabs/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 du compte
  • faketoken : point de terminaison du jeton pour l'association du compte
  • smarthome : point de terminaison du traitement des intents de maison connectée
  • reportstate : appelle l'API HomeGraph en cas de modification de l'état de l'appareil
  • requestsync : 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 Actions :

cd washer-start
firebase use <project-id>

Effectuer le déploiement 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.

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 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 :

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

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 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 des actions). Saisissez l'URL de la fonction Cloud qui fournit le traitement nécessaire pour les intents de la maison connectée, puis cliquez sur Save (Enregistrer).

https://us-central1-<project-id>.cloudfunctions.net/smarthome

Uso-o00XQXBHvOR9vQq9tmpYDYQJKsFEstsgRFnxPAJf7zJ2FxwhISiodo3dB1Tz49Okd6ivi66fjpo7rarS_GZelglGWCT1r9FzDGUl1r67ddIcIbQrxqN8jG9F9GAKOpk0Ckc-eA

Dans l'onglet Develop > Invocation (Développer > Appel), donnez un nom à votre action dans la section Display name (Nom à afficher), puis cliquez sur Save (Enregistrer). Ce nom sera affiché dans l'application Google Home.

gvC-TvmKDy-D-xjwkeCjNt__9ErA7DL8hZWa1oH1yPJ9SpYOepDYjxx6WnJ56IG-t37fJ65kmHISQdh72Ot2G-0tu6Flxf4gom5kvx_3hlvFeMqYuFgXr_85pfWWn7VLFHtS55p1zw

s4yc1kOW4XtKUQN1EYegiDLU5oTqmxQ2PNbeaujm26OQmYKKpjug7j5FYmutLSAZ1zBd-ZkcZlL7zyTZqw4bge3_oOeWvJTsqJ-A08vfZwImYQrKiquLskLuTpmMqXEZD1xchhCWGQ

Pour activer l'association du compte, sélectionnez l'option Develop > Account linking (Développer > Association du compte) dans le panneau de navigation de gauche. Utilisez les paramètres suivants pour l'association du compte :

Client ID (ID client)

ABC123

Client secret (Code secret du client)

DEF456

Authorization URL (URL de l'autorisation)

https://us-central1-.cloudfunctions.net/fakeauth

Token URL (URL du jeton)

https://us-central1-.cloudfunctions.net/faketoken

rRyZTiBSTuPk3YtJtXjDK1pPftUxsaEhs9jzpvFtbHTD6bEwYxM8jV4MWxiljKA1bKVZrIRoO9O3jtBefLKf_OyMpukPjwIj8zGvyU3UwASzMrnRskl-hVAfAmQVi4sC_zAwgYwRXw

Cliquez sur Save (Enregistrer) pour enregistrer la configuration de l'association du compte, puis sur Test pour activer les tests sur votre projet.

OgUvpQfXioygkRwPcaJpzjyNQDZy6enidUC8YMPaCOrZi0YeWCFsCJV9Gqg-_UfsqTnn4KEg--uE3Ymr0QuamDonF4RyYHtRKcULXABDuaEnj2hq8i20LYj1SrGP_1lQ_UsUB90pGw

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 soCeBB1CkSIEqsBmDc8Cth6EjgcXUnrOHeOpLNlvMiiXM73Rmh8iBK1ZFLFd47kycYqIMq3Fm49ryAGUt79BXVPDyEB1IU3W0fgiL49iqTAVrpRszL10mmxzq_AQTJZVrXor-vne2w (tests sur l'appareil).

2zbfeYpG-wEd2SFP07Wc4mJzHakLX7YvrNw3IV0_0Kd-TonfsKIvvjKWlwvrmTm5jLj3XPWqCtcDd5J2z6gwn9fnchpYVraw1j_mE4M0LVppAl5WY5cK7g0uZyhZ3VFFS25yPmyksg

Afin de tester votre action pour 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.

  1. 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.
  2. Accédez à Assistant Google > Paramètres > Contrôle de la maison (sous "Assistant").
  3. Sélectionnez l'icône plus (+) dans l'angle inférieur droit.
  4. Vous devriez voir votre application de test, désignée par le nom à afficher que vous avez défini précédé de [test].
  5. 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é.

XcWmBVamBZtPfOFqtsr5I38stPWTqDcMfQwbBjetBgxt0FCjEs285pa9K3QXSASptw0KYN2G8yfkT0-xg664V4PjqMreDDs-HPegHjOc4EVtReYPu-WKZyygq9Xmkf8X8z9177nBjQ

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.

La caractéristique a``ction.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,
          },
        },
      },
    },
  },
};

Effectuer le déploiement sur Firebase

Exécutez la commande suivante pour déployer l'action mise à jour :

firebase deploy --only functions

Une fois le déploiement terminé, accédez à l'interface utilisateur Web et cliquez sur le bouton Actualiser ae8d3b25777a5e30.png 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.

bf4f6a866160a982.png

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 ?"

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 ae8d3b25777a5e30.png 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 ?"

La gestion des erreurs dans votre action pour la maison connectée 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 action.

Chaque fois qu'une requête EXECUTE ou QUERY échoue, votre action 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( ... )
          //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.

Vous devez mettre en œuvre une authentification à deux facteurs dans votre action 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 l'authentification à deux facteurs 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 : autorisation à deux facteurs qui nécessite une confirmation explicite ("Oui" ou "Non")
  • pinNeeded : authentification à deux facteurs 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 l'authentification à deux facteurs.

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 2FA error handling
class ChallengeNeededError extends SmartHomeError {
  constructor(tfaType) {
    super('challengeNeeded', tfaType);
    this.tfaType = tfaType;
  }
}

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( ... )
          .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 2FA error handling
              if(error instanceof ChallengeNeededError) {
                result.challengeNeeded = {
                  type: error.tfaType
                };
              }
            }
          })
      );
    }
  }
}

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 2FA challenge
  let state, ref;
  switch (command) {
    case 'action.devices.commands.OnOff':
      //Add 2FA 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 d'authentification à deux facteurs en ouvrant vos journaux Firebase.

289dbe48f4bb8106.png

674c4f4392e98c1.png

Félicitations ! Vous avez étendu les fonctionnalités des actions pour la maison connectée grâce aux caractéristiques Modes (Modes) et Activation/Désactivation (Toggles). Vous avez également sécurisé leur exécution via l'authentification à deux facteurs.

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 d'authentification à deux facteurs 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.