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 nube a nube, debes proporcionar un extremo de webhook de Cloud que pueda controlar 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 las integraciones de nube a nube es un paso fundamental para crear integraciones con calidad de producción, pero es un proceso difícil y que requiere mucho tiempo sin herramientas informativas y fáciles de usar para solucionar problemas y realizar pruebas. Para facilitar la depuración de las integraciones de nube a nube, Google Cloud Platform (GCP) ofrece métricas, registros y un paquete de pruebas para la casa inteligente que te ayudarán a identificar y resolver problemas de tus integraciones.

Requisitos previos

Qué compilarás

En este codelab, compilarás un cumplimiento local para las integraciones de nube a nube y lo conectarás a Asistente. Luego, depurarás la app de Local Home con el conjunto de pruebas para métricas y registros de casa inteligente y Google Cloud Platform (GCP).

Qué aprenderás

  • Cómo usar los registros y las métricas de GCP para identificar y resolver problemas de producción
  • Cómo usar el conjunto de pruebas para identificar problemas funcionales y de la API
  • Cómo usar las herramientas para desarrolladores de Chrome mientras desarrollas tu app para 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 inicio contiene subdirectorios y Cloud Functions similares a los del codelab Habilita el cumplimiento local para las integraciones de nube a nube. Pero, en lugar de app-start, tenemos app-faulty aquí. Comenzaremos con una app de casa local que funciona, pero no tan bien.

Cómo conectarse a Firebase

Usaremos el mismo proyecto que creaste en el codelab Habilita el cumplimiento local para las integraciones de nube a nube, pero implementaremos los archivos que descargaste en este codelab.

Navega al directorio app-faulty y, luego, configura Firebase CLI con tu proyecto de integración creado en el codelab Habilita la entrega local para las 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 con npm:

$ cd functions
$ npm install

Nota: Si ves el siguiente mensaje, puedes ignorarlo y continuar. La advertencia se debe a algunas dependencias anteriores, y 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 Actualizarae8d3b25777a5e30.png para actualizar HomeGraph con los metadatos de dispositivo más recientes de la app de la lavadora defectuosa con Request Sync.

fa3c47f293cfe0b7.png

Abre la app de Google Home y verifica que puedas ver el dispositivo de la lavadora con el nuevo 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 el cumplimiento local para las integraciones de nube a nube, ya deberías haber iniciado la lavadora inteligente virtual. Si se detuvo, recuerda reiniciar el dispositivo virtual.

Inicia 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. Cómo probar la app de Local Home

Envía comandos al dispositivo a través de 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 sentimos, parece que la lavadora defectuosa no está disponible en este momento" cuando intentes controlar la lavadora después de "force local".

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

Para descubrir 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. Depura la app de Local Home

En la siguiente sección, usarás las herramientas proporcionadas por Google para averiguar por qué no se puede acceder al dispositivo a través de la ruta 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 que conozcas los principales errores 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 la consola para desarrolladores.
  2. Reinicia tu dispositivo Google Home, lo que le permite obtener la URL de tu código HTML y la configuración de análisis que colocaste en la consola para desarrolladores.
  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 devolvió en el 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 de DEVICE_VERIFICATION_FAILED, no ayuda mucho a encontrar la causa raíz. Agreguemos algunos registros personalizados para asegurarnos de que leemos y procesamos los datos de la exploración correctamente, y 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 de la app de Local 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 tu dispositivo Google Home para que pueda cargar la app de casa local actualizada. Puedes ver si el dispositivo Google Home usa la versión esperada consultando los registros de la consola en las Herramientas para desarrolladores de Chrome.

ecc56508ebcf9ab.png

Accede a Cloud Logging

Veamos cómo usar Cloud Logging para encontrar tus errores. Sigue estos pasos para acceder a Cloud Logging de tu proyecto:

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

El acceso a los datos de registro se administra a través de Identity and Access Management (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.

Cómo usar filtros avanzados

Sabemos que se producen errores en la intención de IDENTIFY, ya que la ruta local no funciona porque no se puede identificar el dispositivo local. Sin embargo, queremos saber exactamente cuál es el problema, así que primero filtraremos 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 de Compilador de consultas. Ingresa jsonPayload.intent="IDENTIFY" en el cuadro Compilador de consultas y haz clic en el botón Ejecutar consulta.

4c0b9d2828ee2447.png

Como resultado, obtendrás todos los registros de errores que se generen en el controlador IDENTIFY. A continuación, expande el último error. Encontrarás los valores errorCode y debugString que acabas de establecer cuando rechaces la promesa en el controlador IDENTIFY.

71f2f156c6887496.png

En debugString, podemos ver que el ID del dispositivo local no tiene el formato esperado. La app de Local Home espera recibir el ID del dispositivo local como una cadena que comienza con deviceid seguido de 3 dígitos, pero el ID del dispositivo local aquí es una cadena hexadecimal.

Corrige el error

Si volvemos al código fuente en el que analizamos el ID del dispositivo local a partir de los datos de la exploración, notamos que no proporcionamos la codificación cuando convertimos la cadena en bytes. Los datos de la exploración 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 de la app de Local 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 Local Home actualizada. Asegúrate de que la versión de la app de Local Home sea 1.0.2 y, esta vez, no deberías ver ningún error en la consola de Herramientas para desarrolladores de Chrome.

c8456f7b5f77f894.png

Ahora puedes intentar enviar comandos a tu dispositivo nuevamente.

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

"Hey Google, detén la lavadora".

"Hey Google, enciende la lavadora".

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

6. Ejecuta el paquete de pruebas para casas inteligentes

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

Ejecuta el paquete de pruebas para casas inteligentes

Sigue estas instrucciones para probar tu integración de nube a nube con el paquete de pruebas:

  1. En tu navegador web, abre la Test Suite para casas inteligentes.
  2. Accede a Google con el botón de la esquina superior derecha. Esto permite que Test Suite 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 Cloud a Cloud. Luego, haz clic en SIGUIENTE para continuar.
  4. En el paso Configuración de la prueba, deberías ver la lavadora defectuosa en la sección Dispositivos y rutas.
  5. Inhabilita la opción Test Request Sync, ya que la app de ejemplo de la lavadora 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 dispositivos.
  6. Deja habilitada la opción SDK de Local Home, ya que probaremos las rutas 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 local fallan, mientras que las pruebas de pausa/reanudación en la ruta de Cloud se aprueban.

d1ebd5cfae2a2a47.png

Analiza el mensaje de error

Observa con más detalle los mensajes de error en los casos de prueba fallidos. Te indican cuál es el estado esperado para esa prueba y cuál fue el estado real. En este caso, para "Pausar la lavadora", el estado esperado es isPaused: true, pero en el estado real obtuvimos isPaused: false. Del mismo modo, para "Pausar la lavadora", 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, estamos configurando el estado de 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, estamos configurando isPause en el estado inverso. Se debe establecer en true cuando params.pause es true y en false en los demás casos. Así que 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 de la app de Local 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 tu dispositivo Google Home para que pueda cargar la app de Local Home actualizada. Asegúrate de que la versión de la app de Local Home sea la 1.0.3.

Prueba la corrección

Ahora, vuelve a ejecutar el paquete de pruebas para casas inteligentes con la misma configuración y verás que se aprobaron todos los casos de prueba.

b7fc8c5d3c727d8d.png

7. Felicitaciones

764dbc83b95782a.png

¡Felicitaciones! Aprendiste correctamente a solucionar problemas de una app de Local Home con la Test Suite para 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 poner tu integración a disposición de los usuarios.