Déboguer la page d'accueil locale

1. Avant de commencer

Lorsque l'Assistant Google est intégré à la maison connectée, il peut contrôler les appareils dont les utilisateurs sont équipés. Pour créer une intégration cloud à cloud, vous devez fournir un point de terminaison de webhook cloud capable de gérer les intents de maison connectée. Par exemple, lorsqu'un utilisateur dit "Hey Google, allume la lumière", l'Assistant envoie la commande à votre traitement cloud pour actualiser l'état de l'appareil.

Le SDK Local Home améliore l'intégration en vous permettant d'ajouter un chemin d'accès local qui route ces intents directement vers Google Home. Le traitement des commandes des utilisateurs est ainsi plus fiable et plus rapide. Il permet de créer et de déployer une application de traitement local en TypeScript ou JavaScript, capable d'identifier les appareils et d'exécuter des commandes sur n'importe quels enceinte intelligente Google Home ou écran connecté Google Nest. Votre application communique ensuite directement avec les appareils connectés des utilisateurs, via le réseau local, en utilisant les protocoles standards existants pour traiter les commandes.

72ffb320986092c.png

Le débogage des intégrations cloud à cloud est une étape essentielle pour créer des intégrations de qualité de production. Toutefois, il est difficile et chronophage sans outils de dépannage et de test informatifs et faciles à utiliser. Pour faciliter le débogage des intégrations cloud à cloud, les métriques et la journalisation de Google Cloud Platform (GCP), ainsi que la suite de tests pour la maison connectée, sont disponibles pour vous aider à identifier et à résoudre les problèmes liés à vos intégrations.

Prérequis

Ce que vous allez faire

Dans cet atelier de programmation, vous allez créer un traitement local pour les intégrations cloud à cloud et le connecter à l'Assistant, puis déboguer l'application Local Home à l'aide de la suite de tests pour la maison connectée et des métriques et journaux Google Cloud Platform (GCP).

Points abordés

  • Découvrez comment utiliser les métriques et la journalisation GCP pour identifier et résoudre les problèmes de production.
  • Utiliser la suite de tests pour identifier les problèmes fonctionnels et d'API
  • Découvrez comment utiliser les outils pour les développeurs Chrome lors du développement de votre application Local Home.

Prérequis

2. Exécuter l'application de la machine à laver

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-debug-local.git

À propos du projet

L'application de démarrage contient des sous-répertoires et des fonctions cloud semblables à ceux de l'atelier de programmation Activer l'exécution locale pour les intégrations cloud à cloud. Mais au lieu de app-start, nous avons app-faulty ici. Nous allons commencer par une application domotique locale qui fonctionne, mais pas très bien.

Se connecter à Firebase

Nous allons utiliser le même projet que celui que vous avez créé dans l'atelier de programmation Activer l'exécution locale pour les intégrations cloud à cloud, mais nous allons déployer les fichiers téléchargés dans cet atelier de programmation.

Accédez au répertoire app-faulty, puis configurez la CLI Firebase avec votre projet d'intégration créé dans l'atelier de programmation Activer le traitement local pour les intégrations cloud à cloud :

$ cd app-faulty
$ firebase use <project-id>

Déployer sur Firebase

Accédez au dossier app-faulty/functions et installez toutes les dépendances nécessaires à l'aide de npm :

$ cd functions
$ npm install

Remarque : Si le message ci-dessous s'affiche, vous pouvez l'ignorer et continuer. Cet avertissement est dû à certaines dépendances plus anciennes. Pour en savoir plus, cliquez ici.

found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Accédez au répertoire app-faulty/local/ et exécutez les commandes suivantes pour télécharger le compilateur TypeScript et compiler l'application :

$ cd ../local
$ npm install
$ npm run build

Cette opération compile la source index.ts (TypeScript) et place le contenu suivant dans le répertoire app-faulty/public/local-home/ :

  • bundle.js : sortie JavaScript compilée contenant l'application locale et les dépendances
  • index.html : page d'hébergement local utilisée pour diffuser l'application en vue d'un test sur l'appareil

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://<projectcd -id>.web.app

Cette commande déploie une application Web, ainsi que plusieurs fonctions Cloud Functions for Firebase.

Mettre à jour HomeGraph

Ouvrez l'URL d'hébergement dans votre navigateur (https://<project-id>.web.app) pour afficher l'application Web. Dans l'interface utilisateur Web, cliquez sur le bouton Actualiserae8d3b25777a5e30.png pour mettre à jour HomeGraph avec les dernières métadonnées de l'appareil à partir de l'application de la machine à laver défectueuse à l'aide de Synchroniser la requête.

fa3c47f293cfe0b7.png

Ouvrez l'application Google Home et vérifiez que votre lave-linge est affiché sous le nouveau nom "Lave-linge défectueux". N'oubliez pas d'attribuer l'appareil à une pièce contenant un appareil Nest.

2a082ee11d47ad1a.png

3. Démarrer le lave-linge connecté

Si vous avez effectué l'atelier de programmation Activer l'exécution locale pour les intégrations cloud à cloud, vous devriez déjà avoir démarré le lave-linge intelligent virtuel. Si elle est arrêtée, n'oubliez pas de redémarrer l'appareil virtuel.

Démarrer l'appareil

Accédez au répertoire virtual-device/ et exécutez le script de l'appareil en transmettant les paramètres de configuration en tant qu'arguments :

$ cd ../../virtual-device
$ npm install
$ npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

Vérifiez que le script de l'appareil s'exécute avec les paramètres attendus :

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

4. Tester l'application Local Home

Envoyez des ordres à votre appareil à l'aide des commandes vocales adressées à l'appareil Google Home. Par exemple :

"Hey Google, allume mon lave-linge."

"Hey Google, démarre mon lave-linge."

"Hey Google, force local."

"Hey Google, arrête mon lave-linge."

Vous remarquerez que l'Assistant Google répond "Désolé, il semble que la machine à laver défectueuse ne soit pas disponible pour le moment" lorsque vous essayez de contrôler la machine à laver après avoir forcé le contrôle local.

Cela signifie que l'appareil n'est pas accessible via un chemin d'accès local. Cela fonctionnait avant d'émettre la commande "Hey Google, force local", car nous revenons à l'utilisation du chemin d'accès au cloud lorsque l'appareil n'est pas accessible via un chemin d'accès local. Toutefois, après l'option "Forcer le local", la possibilité de revenir au chemin d'accès au cloud est désactivée.

Pour identifier le problème, utilisons les outils à notre disposition : les métriques et la journalisation de Google Cloud Platform (GCP), ainsi que les outils de développement Chrome.

5. Déboguer l'application Local Home

Dans la section suivante, vous allez utiliser les outils fournis par Google pour déterminer pourquoi l'appareil n'est pas accessible via le chemin local. Vous pouvez utiliser les Outils pour les développeurs Google Chrome pour vous connecter à l'appareil Google Home, consulter les journaux de la console et déboguer l'application Local Home. Vous pouvez également envoyer des journaux personnalisés à Cloud Logging pour identifier les principales erreurs rencontrées par vos utilisateurs dans votre application Local Home.

Connecter les Outils pour les développeurs Chrome

Pour connecter le débogueur à votre application de traitement en local :

  1. Assurez-vous d'avoir associé votre appareil Google Home à un utilisateur autorisé à accéder au projet de la console Développeur.
  2. Redémarrez votre appareil Google Home pour lui permettre d'obtenir l'URL de votre code HTML, ainsi que la configuration de recherche définie dans la console pour les développeurs.
  3. Lancez Chrome sur votre ordinateur de développement.
  4. Ouvrez un nouvel onglet Chrome, puis saisissez chrome://inspect dans le champ d'adresse pour lancer l'outil d'inspection.

Une liste d'appareils devrait s'afficher sur la page, et l'URL de votre application devrait figurer sous le nom de votre appareil Google Home.

567f97789a7d8846.png

Lancer l'outil d'inspection

Cliquez sur Inspect (Inspecter) sous l'URL de votre application pour ouvrir les Outils pour les développeurs Chrome. Sélectionnez l'onglet Console et vérifiez que le contenu de l'intent IDENTIFY produit par votre application TypeScript apparaît correctement.

774c460c59f9f84a.png

Cette sortie signifie que le gestionnaire IDENTIFY a été déclenché avec succès, mais que le verificationId renvoyé dans le IdentifyResponse ne correspond à aucun des appareils de votre HomeGraph. Ajoutons des journaux personnalisés pour en savoir plus.

Ajouter des journaux personnalisés

Bien que le SDK Local Home affiche une erreur DEVICE_VERIFICATION_FAILED, cela ne vous aide pas beaucoup à trouver la cause première. Ajoutons des journaux personnalisés pour nous assurer que nous lisons et traitons correctement les données d'analyse. Notez que si nous rejetons la promesse avec une erreur, le message d'erreur est également envoyé à Cloud Logging.

local/index.ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device id.
  // Is there something wrong here?
  const localDeviceId = Buffer.from(scanData.data);
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  // Add custom logs
  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_device', 'Invalid device id from scan data ' +
        localDeviceId);
    return Promise.reject(err);
  }

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

Modifiez également la version locale de l'application Home pour que nous puissions identifier si nous utilisons la bonne version.

local/index.ts

const localHomeSdk = new App('1.0.1');

Après avoir ajouté les journaux personnalisés, vous devez recompiler l'application et la redéployer sur Firebase.

$ cd ../app-faulty/local
$ npm run build
$ firebase deploy --only hosting

Redémarrez maintenant votre appareil Google Home pour qu'il puisse charger l'application Local Home mise à jour. Vous pouvez vérifier si l'appareil Google Home utilise la version attendue en consultant les journaux de la console dans les outils pour les développeurs Chrome.

ecc56508ebcf9ab.png

Accéder à Cloud Logging

Voyons comment utiliser Cloud Logging pour trouver vos erreurs. Pour accéder à Cloud Logging pour votre projet :

  1. Dans la console Cloud Platform, accédez à la page Projets.
  2. Sélectionnez votre projet de maison connectée.
  3. Sous Opérations, sélectionnez Journalisation > Explorateur de journaux.

L'accès aux données de journalisation est géré par le biais d'Identity and Access Management (IAM) pour les utilisateurs de votre projet d'intégrations. Pour en savoir plus sur les rôles et les autorisations pour les données de journaux, consultez la page Contrôle des accès de Cloud Logging.

Utiliser des filtres avancés

Nous savons que des erreurs se produisent dans l'intention IDENTIFY, car le chemin d'accès local ne fonctionne pas, car l'appareil local n'a pas pu être identifié. Cependant, nous voulons connaître exactement le problème. Filtrons donc d'abord les erreurs qui se produisent dans le gestionnaire IDENTIFY.

Cliquez sur le bouton Afficher la requête. Il devrait se transformer en zone de texte Générateur de requêtes. Saisissez jsonPayload.intent="IDENTIFY" dans la zone Générateur de requêtes, puis cliquez sur le bouton Exécuter la requête.

4c0b9d2828ee2447.png

Par conséquent, vous obtenez tous les journaux d'erreurs générés dans le gestionnaire IDENTIFY. Ensuite, développez la dernière erreur. Vous trouverez les errorCode et debugString que vous venez de définir lors du rejet de la promesse dans le gestionnaire IDENTIFY.

71f2f156c6887496.png

À partir de debugString, nous pouvons voir que l'ID de l'appareil local n'est pas au format attendu. L'application Local Home s'attend à recevoir l'ID de l'appareil local sous forme de chaîne commençant par deviceid, suivi de trois chiffres, mais l'ID de l'appareil local est ici une chaîne hexadécimale.

Corriger l'erreur

En revenant au code source où nous analysons l'ID de l'appareil local à partir des données d'analyse, nous remarquons que nous n'avons pas fourni l'encodage lors de la conversion de la chaîne en octets. Les données d'analyse sont reçues sous forme de chaîne hexadécimale. Par conséquent, transmettez hex comme encodage de caractères lorsque vous appelez Buffer.from().

local/index.ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device id.
  const localDeviceId = Buffer.from(scanData.data, 'hex');
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
      'invalid_device', 'Invalid device id from scan data ' +
      localDeviceId);
    return Promise.reject(err);
  }

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

Modifiez également la version locale de l'application Home pour que nous puissions identifier si nous utilisons la bonne version.

local/index.ts

const localHomeSdk = new App('1.0.2');

Après avoir corrigé l'erreur, compilez l'application et redéployez-la sur Firebase. Dans l'outil app-faulty/local, exécutez :

$ npm run build
$ firebase deploy --only hosting

Tester votre correction

Après le déploiement, redémarrez votre appareil Google Home pour qu'il puisse charger l'application Local Home mise à jour. Assurez-vous que la version de l'application Local Home est la 1.0.2. Cette fois, vous ne devriez voir aucune erreur dans la console des outils pour les développeurs Chrome.

c8456f7b5f77f894.png

Vous pouvez maintenant réessayer d'envoyer des commandes à votre appareil.

"Hey Google, force local."

"Hey Google, arrête mon lave-linge."

"Hey Google, allume mon lave-linge."

"Hey Google, force le paramètre par défaut."

6. Exécuter la suite de tests pour la maison connectée

Après avoir validé votre appareil à l'aide des commandes tactiles de l'application Google Home ou des commandes vocales, vous pouvez utiliser la suite de tests automatisée pour la maison connectée afin de valider les cas d'utilisation en fonction des types d'appareils et des caractéristiques associés à votre intégration. La suite de tests exécute une série de tests pour détecter les problèmes dans votre intégration et affiche des messages informatifs pour les cas de test ayant échoué afin d'accélérer le débogage avant d'examiner les journaux d'événements.

Exécuter la suite de tests pour la maison connectée

Suivez ces instructions pour tester votre intégration cloud à cloud à l'aide de la suite de tests :

  1. Dans votre navigateur Web, ouvrez la suite de tests pour la maison connectée.
  2. Connectez-vous à Google à l'aide du bouton en haut à droite. Cela permet à la suite de tests d'envoyer les commandes directement à l'Assistant Google.
  3. Dans le champ ID du projet, saisissez l'ID du projet de votre intégration cloud à cloud. Cliquez ensuite sur SUIVANT pour continuer.
  4. À l'étape Paramètres de test, vous devriez voir votre lave-linge défectueux dans la section Appareils et traits.
  5. Désactivez l'option Synchronisation des demandes de test, car l'application de machine à laver exemple ne dispose pas d'interface utilisateur permettant d'ajouter, de supprimer ou de renommer la machine à laver. Dans un système de production, vous devez déclencher Request Sync chaque fois que l'utilisateur ajoute, supprime ou renomme des appareils.
  6. Laissez l'option SDK Local Home activée, car nous allons tester les chemins locaux et cloud.
  7. Cliquez sur Suivant : environnement de test pour lancer le test.

67433d9190fa770e.png

Une fois les tests terminés, vous remarquerez que les tests de mise en pause/reprise dans le chemin d'accès local échouent, tandis que ceux dans le chemin d'accès cloud réussissent.

d1ebd5cfae2a2a47.png

Analyser le message d'erreur

Examinez de plus près les messages d'erreur dans les scénarios de test ayant échoué. Elles vous indiquent l'état attendu pour ce test et l'état réel. Dans ce cas, pour "Mettre en pause la machine à laver", l'état attendu est isPaused: true, mais l'état réel est isPaused: false. De même, pour "Mettre en pause le lave-linge", l'état attendu est isPaused: true, mais l'état réel est isPaused: false.

6bfd3acef9c16b84.png

D'après les messages d'erreur, il semble que nous définissions l'état isPaused de manière inverse dans le chemin local.

Identifier et corriger l'erreur

Recherchons le code source où l'application Local Home envoie la commande d'exécution à l'appareil. getDataCommand() est la fonction appelée par executeHandler() pour définir payload dans la commande d'exécution envoyée à l'appareil.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                // Is there something wrong here?
                isPaused: params.pause ? false : true
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

En effet, nous définissons isPause dans l'état inverse. Il doit être défini sur true lorsque params.pause est true et sur false dans le cas contraire. Alors, corrigeons cela.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                isPaused: params.pause ? true : false
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

Modifiez la version locale de l'application Home pour que nous puissions identifier si nous utilisons la bonne version.

local/index.ts

const localHomeSdk = new App('1.0.3');

N'oubliez pas de compiler à nouveau l'application et de la redéployer sur Firebase. Dans l'outil app-faulty/local, exécutez :

$ npm run build
$ firebase deploy --only hosting

Redémarrez ensuite votre appareil Google Home pour qu'il puisse charger l'application Local Home mise à jour. Assurez-vous que la version de l'application Local Home est la 1.0.3.

Tester votre correction

Maintenant, réexécutez la suite de tests pour la maison connectée avec les mêmes configurations. Vous constaterez que tous les cas de test ont réussi.

b7fc8c5d3c727d8d.png

7. Félicitations

764dbc83b95782a.png

Félicitations ! Vous avez appris à résoudre les problèmes d'une application Local Home à l'aide de la suite de tests pour la maison connectée et de Cloud Logging.

En savoir plus

Voici quelques pistes à explorer :

Vous pouvez également en savoir plus sur le test et l'envoi d'une intégration pour examen, y compris le processus de certification permettant de publier votre intégration auprès des utilisateurs.