Depuración de la página principal local

1. Antes de comenzar

Las integraciones de casa inteligente permiten a Asistente de Google controlar los dispositivos conectados en los hogares de los usuarios. Para crear una integración de Cloud a Cloud, debes proporcionar un extremo de webhook de Cloud que pueda manejar intents de casa inteligente. Por ejemplo, cuando un usuario dice "Hey Google, enciende las luces", Asistente envía el comando a tu entrega de nube para actualizar el estado del dispositivo.

El SDK de Local Home mejora la integración de tu casa inteligente ya que agrega una ruta de acceso local para enrutar intents de casa inteligente directamente a un dispositivo Google Home, lo que mejora la confiabilidad y reduce la latencia al procesar comandos de los usuarios. Te permite implementar y escribir una app de entrega local en TypeScript o JavaScript que identifica dispositivos y ejecuta comandos en cualquier bocina inteligente de Google Home o en una pantalla inteligente Google Nest. Luego, tu app se comunica directamente con los dispositivos inteligentes existentes de los usuarios mediante la red de área local mediante protocolos estándar existentes para completar los comandos.

72ffb320986092c.png

La depuración de integraciones de nube a nube es un paso fundamental para compilar tus integraciones con calidad de producción, pero es un proceso desafiante y que requiere tiempo si no cuentas con herramientas de prueba y solución de problemas informativas y fáciles de usar. Para facilitar la depuración de integraciones de nube a nube, las métricas y el registro de Google Cloud Platform (GCP) y el Test Suite para la casa inteligente están disponibles para ayudarte a identificar y resolver problemas de tus integraciones.

Requisitos previos

Qué compilarás

En este codelab, compilarás una entrega local para integraciones de nube a nube y la conectarás al Asistente. Luego, depurarás la app de Local Home a través del paquete de pruebas para métricas y registros de casa inteligente y Google Cloud Platform (GCP).

Qué aprenderás

  • Cómo usar las métricas y el registro de GCP para identificar y resolver problemas de producción
  • Cómo usar el conjunto de pruebas para identificar problemas funcionales y de API
  • Cómo usar las herramientas para desarrolladores de Chrome mientras desarrollas tu app de Local Home

Requisitos

2. Ejecuta la app de la lavadora

Obtén el código fuente

Haz clic en el siguiente vínculo para descargar la muestra de este codelab en tu máquina de desarrollo:

O bien, puedes clonar el repositorio de GitHub desde la línea de comandos.

$ git clone https://github.com/google-home/smarthome-debug-local.git

Acerca del proyecto

La app de partida contiene subdirectorios y funciones en la nube similares a los del codelab Habilita la entrega local para integraciones de nube a nube. Pero, en lugar de app-start, tenemos app-faulty aquí. Comenzaremos con una app de inicio local que funciona, pero no muy bien.

Cómo conectarse a Firebase

Usaremos el mismo proyecto que creaste en el codelab Habilita la entrega local para integraciones de nube a nube, pero implementaremos los archivos que se descargaron en este codelab.

Navega al directorio app-faulty y configura Firebase CLI con el proyecto de integración que creaste en el codelab Habilita la entrega local para integraciones de nube a nube:

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

Cómo implementar en Firebase

Ve a la carpeta app-faulty/functions y, luego, instala todas las dependencias necesarias mediante npm:

$ cd functions
$ npm install

Nota: Si ves el siguiente mensaje, puedes ignorarlo y continuar. La advertencia se debe a algunas dependencias anteriores. Puedes encontrar más detalles aquí.

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

Navega al directorio app-faulty/local/ y ejecuta los siguientes comandos para descargar el compilador de TypeScript y compilar la app:

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

Esta acción, compila la fuente index.ts (TypeScript) y coloca el siguiente contenido en el directorio app-faulty/public/local-home/:

  • bundle.js: Salida de JavaScript compilada que contiene la app y las dependencias locales.
  • index.html: Página de hosting local que se usa para publicar la app a fin de realizar pruebas en el dispositivo.

Ahora que ya instalaste las dependencias y configuraste tu proyecto, tienes todo listo para ejecutar la app por primera vez.

$ firebase deploy

Este es el resultado que debería ver en la consola:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<projectcd -id>.web.app

Este comando implementa una app web, junto con varias Cloud Functions para Firebase.

Actualiza HomeGraph

Abre la URL de Hosting en tu navegador (https://<project-id>.web.app) para ver la app web. En la IU web, haz clic en el botón Actualizar ae8d3b25777a5e30.png para actualizar HomeGraph a través de Solicitar sincronización con los metadatos de dispositivos más recientes de la app de la lavadora defectuosa:

fa3c47f293cfe0b7.png

Abre la app de Google Home y verifica que puedas ver el dispositivo de la lavadora con el nombre "Lavadora defectuosa". Recuerda asignar el dispositivo a una habitación que tenga un dispositivo Nest.

2a082ee11d47ad1a.png

3. Inicia la lavadora inteligente

Si ejecutaste el codelab Habilita la entrega local para integraciones de nube a nube, ya deberías haber iniciado la lavadora inteligente virtual. Si se detuvo, recuerda reiniciar el dispositivo virtual.

Cómo iniciar el dispositivo

Ve al directorio virtual-device/ y ejecuta la secuencia de comandos del dispositivo. Para ello, pasa los parámetros de configuración como argumentos:

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

Verifica que la secuencia de comandos del dispositivo se ejecute con los parámetros esperados:

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

4. Prueba la app de Home local

Envía comandos al dispositivo mediante comandos por voz al dispositivo Google Home, como los siguientes:

"Hey Google, enciende la lavadora".

"Hey Google, inicia mi lavadora".

"Hey Google, fuerza la búsqueda local".

"Hey Google, detén la lavadora".

Notarás que Asistente de Google responde con "Lo siento, parece que la lavadora defectuosa no está disponible en este momento" cuando intentes controlarla después de "forzar la conexión local".

Esto significa que no se puede acceder al dispositivo a través de una ruta de acceso local. Funcionó antes de emitir "Hey Google, fuerza local" porque volveremos a usar la ruta de acceso a la nube cuando no se pueda acceder al dispositivo a través de una ruta de acceso local. Sin embargo, después de "forzar local", se inhabilita la opción de volver a la ruta de acceso a la nube.

Para averiguar cuál es el problema, usemos las herramientas que tenemos: las métricas y el registro de Google Cloud Platform (GCP) y las herramientas para desarrolladores de Chrome.

5. Cómo depurar la app de Home local

En la siguiente sección, usarás las herramientas que proporciona Google para averiguar por qué no se puede acceder al dispositivo a través de la ruta de acceso local. Puedes usar las Herramientas para desarrolladores de Google Chrome para conectarte al dispositivo Google Home, ver los registros de la consola y depurar la app de Local Home. También puedes enviar registros personalizados a Cloud Logging para conocer los errores principales que encuentran los usuarios en tu app de Local Home.

Cómo conectar las Herramientas para desarrolladores de Chrome

Para conectar el depurador a tu app de entrega local, sigue estos pasos:

  1. Asegúrate de haber vinculado tu dispositivo Google Home a un usuario con permiso para acceder al proyecto de Developer Console.
  2. Reinicia tu dispositivo Google Home, lo que te permite obtener la URL del código HTML y la configuración de análisis que se coloca en la Consola de Play.
  3. Inicia Chrome en tu máquina de desarrollo.
  4. Abre una nueva pestaña de Chrome e ingresa chrome://inspect en el campo de dirección a fin de iniciar el inspector.

Deberías ver una lista de dispositivos en la página y la URL de tu app debería aparecer debajo del nombre de tu dispositivo Google Home.

567f97789a7d8846.png

Cómo iniciar el inspector

Haz clic en Inspeccionar debajo de la URL de tu app para iniciar las Herramientas para desarrolladores de Chrome. Selecciona la pestaña Console y verifica que puedas ver el contenido del intent IDENTIFY impreso por tu app de TypeScript.

774c460c59f9f84a.png

Este resultado significa que el controlador IDENTIFY se activó correctamente, pero el verificationId que se muestra en IdentifyResponse no coincide con ninguno de los dispositivos de tu HomeGraph. Agreguemos algunos registros personalizados para averiguar por qué.

Agrega registros personalizados

Aunque el SDK de Local Home imprime un error DEVICE_VERIFICATION_FAILED, no ayuda mucho a encontrar la causa raíz. Agreguemos algunos registros personalizados para asegurarnos de leer y procesar los datos de análisis correctamente. Ten en cuenta que, si rechazamos la promesa con un error, el mensaje de error también se envía a 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);
}

Además, cambia la versión local de la app de Home para que podamos identificar si estamos usando la versión correcta.

local/index.ts

const localHomeSdk = new App('1.0.1');

Después de agregar los registros personalizados, debes volver a compilar la app y volver a implementarla en Firebase.

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

Ahora, reinicia el dispositivo Google Home para que pueda cargar la app de inicio local actualizada. Para ver si el dispositivo Google Home está usando la versión esperada, consulta los registros de Console en las herramientas para desarrolladores de Chrome.

ecc56508ebcf9ab.png

Accede a Cloud Logging

Veamos cómo usar Cloud Logging para encontrar tus errores. Para acceder a Cloud Logging en tu proyecto, sigue estos pasos:

  1. En la consola de Cloud Platform, ve a la página Proyectos.
  2. Selecciona tu proyecto de casa inteligente.
  3. En Operaciones, selecciona Registro > Explorador de registros.

El acceso a los datos de registro se administra a través de la administración de identidades y accesos (IAM) para los usuarios de tu proyecto de integraciones. Para obtener más detalles sobre los roles y los permisos de los datos de registro, consulta el control de acceso de Cloud Logging.

Usa filtros avanzados

Sabemos que se producen errores en el intent IDENTIFY, ya que la ruta de acceso local no funciona porque no se identifica el dispositivo local. Sin embargo, queremos saber exactamente cuál es el problema, así que primero filtremos los errores que ocurren en el controlador IDENTIFY.

Haz clic en el botón de activación Mostrar consulta, que debería convertirse en un cuadro Compilador de consultas. Ingresa jsonPayload.intent="IDENTIFY" en el cuadro Query builder y haz clic en el botón Run query.

4c0b9d2828ee2447.png

Como resultado, obtienes todos los registros de errores que se generan en el controlador IDENTIFY. A continuación, expande el último error. Encontrarás los errorCode y debugString que acabas de configurar cuando rechazas la promesa en el controlador IDENTIFY.

71f2f156c6887496.png

A partir de debugString, podemos saber que el ID de dispositivo local no tiene el formato esperado. La app de Local Home espera obtener el ID de dispositivo local como una cadena que comienza con deviceid seguida de 3 dígitos, pero el ID de dispositivo local aquí es una cadena hexadecimal.

Cómo corregir el error

Si volvemos al código fuente en el que analizamos el ID de dispositivo local a partir de los datos de análisis, notamos que no proporcionamos la codificación cuando convertimos la cadena en bytes. Los datos de análisis se reciben como una cadena hexadecimal, por lo que debes pasar hex como la codificación de caracteres cuando llames a 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);
}

Además, cambia la versión local de la app de Home para que podamos identificar si estamos usando la versión correcta.

local/index.ts

const localHomeSdk = new App('1.0.2');

Después de corregir el error, compila la app y vuelve a implementarla en Firebase. En la herramienta app-faulty/local, ejecuta el siguiente comando:

$ npm run build
$ firebase deploy --only hosting

Prueba la corrección

Después de la implementación, reinicia el dispositivo Google Home para que pueda cargar la app de Home local actualizada. Asegúrate de que la versión de la app de Home local sea 1.0.2 y, esta vez, no deberías ver errores en la consola de herramientas para desarrolladores de Chrome.

c8456f7b5f77f894.png

Ahora puedes volver a enviar comandos a tu dispositivo.

"Hey Google, fuerza la conexión local".

"Hey Google, detén la lavadora".

"Hey Google, enciende la lavadora".

"Hey Google, aplica la configuración predeterminada".

6. Ejecuta el paquete de pruebas para la casa inteligente

Después de verificar el dispositivo con los controles táctiles de la app de Google Home o con comandos por voz, puedes usar el Test Suite automatizado para la casa inteligente para validar los casos de uso según los tipos de dispositivos y las características asociadas con tu integración. El Test Suite ejecuta una serie de pruebas para detectar problemas en tu integración y muestra mensajes informativos para los casos de prueba que fallaron para acelerar la depuración antes de analizar los registros de eventos.

Ejecuta el paquete de pruebas para la casa inteligente

Sigue estas instrucciones para probar tu integración de nube a nube con Test Suite:

  1. En tu navegador web, abre Test Suite para casa inteligente.
  2. Accede a Google con el botón que se encuentra en la esquina superior derecha. Esto permite que el paquete de prueba envíe los comandos directamente a Asistente de Google.
  3. En el campo ID del proyecto, ingresa el ID del proyecto de tu integración de nube a nube. Luego, haz clic en SIGUIENTE (NEXT) para continuar.
  4. En el paso Test Settings, deberías ver la lavadora defectuosa en la sección Devices and Trais.
  5. Inhabilita la opción Test Request Sync, ya que la app de la lavadora de muestra no tiene una IU para agregar, quitar o cambiar el nombre de la lavadora. En un sistema de producción, debes activar Request Sync cada vez que el usuario agregue, quite o cambie el nombre de los dispositivos.
  6. Deja habilitada la opción Local Home SDK, ya que probaremos las rutas de acceso locales y en la nube.
  7. Haz clic en Siguiente: Entorno de prueba para comenzar a ejecutar la prueba.

67433d9190fa770e.png

Cuando se completen las pruebas, notarás que las pruebas de Pausa/Reanudación en la ruta de acceso local fallan, mientras que las pruebas de Pausa/Reanudación en la ruta de acceso a la nube se aprueban.

d1ebd5cfae2a2a47.png

Cómo analizar el mensaje de error

Observa con mayor detalle los mensajes de error en los casos de prueba que fallaron. Te indican cuál es el estado esperado para esa prueba y cuál es el estado real. En este caso, para "Pause the Washer", el estado esperado es isPaused: true, pero en el estado real obtuvimos isPaused: false. De manera similar, para "Pause the Washer", el estado esperado es isPaused: true, pero en el estado real obtuvimos isPaused: false.

6bfd3acef9c16b84.png

Según los mensajes de error, parece que en la ruta local, configuramos el estado isPaused de forma inversa.

Identifica y corrige el error

Busquemos el código fuente en el que la app de Local Home envía el comando de ejecución al dispositivo. getDataCommand() es la función a la que llama executeHandler() para establecer payload en el comando de ejecución que se envía al dispositivo.

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 {};
    }
}

De hecho, configuramos isPause en el estado inverso, debe establecerse en true cuando params.pause sea true y false de lo contrario. Entonces, vamos a solucionarlo.

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 {};
    }
}

Cambia la versión local de la app de Home para que podamos identificar si estamos usando la versión correcta.

local/index.ts

const localHomeSdk = new App('1.0.3');

Recuerda volver a compilar la app y volver a implementarla en Firebase. En la herramienta app-faulty/local, ejecuta el siguiente comando:

$ npm run build
$ firebase deploy --only hosting

Ahora, reinicia el dispositivo Google Home para que pueda cargar la app de Home local actualizada. Asegúrate de que la versión de la app de Home local sea 1.0.3.

Prueba la corrección

Ahora, vuelve a ejecutar el paquete de pruebas para la casa inteligente con las mismas configuraciones y verás que todos los casos de prueba se aprobaron.

b7fc8c5d3c727d8d.png

7. Felicitaciones

764dbc83b95782a.png

¡Felicitaciones! Aprendiste a solucionar problemas de una app de Local Home a través del Test Suite para la casa inteligente y Cloud Logging.

Más información

Puedes intentar hacer lo siguiente:

También puedes obtener más información sobre cómo probar una integración y enviarla a revisión, incluido el proceso de certificación para publicar tu integración a los usuarios.