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 Acción de casa inteligente, 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.
La depuración de Acciones de casa inteligente es un paso fundamental para desarrollar tus Acciones con calidad de producción. Sin embargo, es desafiante y requiere mucho tiempo sin herramientas informativas y de prueba y solución de problemas fáciles de usar. Para facilitar la depuración de Acciones de casa inteligente, las métricas y los registros de Google Cloud Platform (GCP), así como el paquete de pruebas para casas inteligentes, están disponibles para ayudarte a identificar y resolver los problemas de tus Acciones.
Requisitos previos
- Guía para desarrolladores sobre Cómo crear una Acción de casa inteligente
- Ejecuta el codelab Habilita la entrega local para acciones de casa inteligente.
Qué compilarás
En este codelab, compilarás una entrega local para Acciones de casa inteligente y la conectarás al Asistente. Luego, depurarás la app de Local Home con el paquete de pruebas para las métricas de casa inteligente y Google Cloud Platform (GCP) y Logging.
Qué aprenderás
- Cómo usar las métricas de GCP y Logging para identificar y resolver problemas de producción
- Cómo usar el paquete 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
- La versión más reciente de Google Chrome
- Un dispositivo iOS o Android con la app de Google Home instalada
- Una bocina inteligente Google Home o una pantalla inteligente Google Nest
- Node.js versión 10.16 o posterior
- Una Cuenta de Google
- Una cuenta de facturación de Google Cloud
2. Cómo ejecutar 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 Cloud Functions similares a los del codelab Habilita la entrega local para Acciones de casa inteligente. Sin embargo, en lugar de app-start
, tenemos app-faulty
aquí. Comenzaremos con una app de Home local que funciona, pero no tan bien.
Cómo conectarse a Firebase
Usaremos el mismo proyecto que creaste en el codelab Habilita la entrega local para acciones de casa inteligente, pero implementaremos los archivos descargados en este codelab.
Navega al directorio app-faulty
y configura Firebase CLI con tu proyecto de acciones creado en el codelab Habilita la entrega local para acciones de casa inteligente:
$ cd app-faulty $ firebase use <project-id>
Realiza la implementación en Firebase
Navega 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 antiguas. Puedes obtener 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ías 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 funciones de Cloud Functions para Firebase.
Actualiza HomeGraph
Abre la URL de Hosting en tu navegador (https://<project-id>.web.app
) para ver la aplicación web. En la IU web, haz clic en el botón Actualizar para actualizar HomeGraph mediante Request Sync con los metadatos más recientes del dispositivo de la app de la lavadora con errores:
Abre la app de Google Home y verifica que puedas ver el dispositivo de la lavadora con el nuevo nombre "Lavadora con errores". Recuerda asignar el dispositivo a una habitación que tenga un dispositivo Nest.
3. Inicia la lavadora inteligente
Si ejecutaste el codelab Habilita la entrega local para acciones de casa inteligente, ya deberías haber iniciado la lavadora virtual inteligente. Si se detiene, recuerda reiniciar el dispositivo virtual.
Enciende 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 Local Home
Envía comandos a tu dispositivo mediante comandos por voz al dispositivo Google Home, como los siguientes:
"Hey Google, enciende la lavadora".
"Hey Google, inicia la lavadora".
“Hey Google, fuerza local”.
"Hey Google, detén la lavadora".
Cuando intentes controlar la lavadora después de presionar "Force local", verás que Asistente de Google responde con el mensaje "Lo siento, parece que la lavadora con errores no está disponible en este momento".
Esto significa que no se puede acceder al dispositivo a través de una ruta local. Funcionó antes de emitir "Hey Google, forzar 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 local”, se inhabilita la opción de recurrir a la ruta de acceso a la nube.
Para descubrir cuál es el problema, usemos las herramientas disponibles: Métricas y Logging de Google Cloud Platform (GCP), y Herramientas para desarrolladores de Chrome.
5. Cómo depurar la app de Local Home
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 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 estar al tanto de 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:
- Asegúrate de haber vinculado tu dispositivo Google Home a un usuario con permiso para acceder al proyecto de la Consola de Actions.
- 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 Actions.
- Inicia Chrome en tu máquina de desarrollo.
- 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.
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.
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é.
Agregar registros personalizados
Aunque hay un error DEVICE_VERIFICATION_FAILED
impreso por el SDK de Local Home, no ayuda mucho a encontrar la causa raíz. Agreguemos algunos registros personalizados para asegurarnos de leer y procesar correctamente los datos del análisis y tener en cuenta que, si rechazamos la promesa con un error, el mensaje de error también se enviará 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 inicio local 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, tendrás que compilar la app nuevamente 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 inicio local actualizada. Si quieres saber si el dispositivo Google Home usa la versión esperada, consulta los registros de la consola en las Herramientas para desarrolladores de Chrome.
Accede a Cloud Logging
Veamos cómo usar Cloud Logging para encontrar tus errores. Sigue estos pasos para acceder a Cloud Logging en tu proyecto:
- En la consola de Cloud Platform, ve a la página Proyectos.
- Selecciona tu proyecto de casa inteligente.
- 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 Acciones. Si deseas obtener más detalles sobre las funciones y los permisos para registrar datos, consulta el control de acceso de Cloud Logging.
Cómo usar filtros avanzados
Sabemos que se producen errores en el intent 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 filtremos los errores que ocurren en el controlador IDENTIFY
.
Expande el cuadro Vista previa de la consulta, que debería convertirse en un cuadro del Compilador de consultas. Ingresa jsonPayload.intent="IDENTIFY"
en el cuadro Compilador de consultas y haz clic en el botón Ejecutar consulta.
Como resultado, obtienes todos los registros de errores que se arrojan en el controlador IDENTIFY
. A continuación, expande el último error. Encontrarás las errorCode
y la debugString
que acabas de configurar cuando rechazas la promesa en el controlador IDENTIFY
.
A partir de debugString
, podemos decir que el ID del dispositivo local no está en el formato esperado. La app de Local Home espera obtener el ID del dispositivo local como una cadena que comienza con deviceid
seguida de 3 dígitos, pero el ID del dispositivo local es una cadena hexadecimal.
Corrige el error
Volviendo al código fuente en el que analizamos el ID de dispositivo local de los datos analizados, notamos que no proporcionamos la codificación al convertir la cadena en bytes. Los datos de escaneo se reciben como una cadena hexadecimal, así que pasa hex
como la codificación de caracteres cuando llamas 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 inicio local 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 tu dispositivo Google Home para que pueda cargar la app de inicio local actualizada. Asegúrate de que la versión de la app de inicio local sea 1.0.2 y, esta vez, no deberías ver errores en la Consola de herramientas para desarrolladores de Chrome.
Ahora puedes intentar volver a enviar comandos a tu dispositivo.
"Hey Google, fuerza local".
"Hey Google, detén la lavadora".
"Hey Google, enciende la lavadora".
...
"Hey Google, forzar la configuración predeterminada".
6. Ejecuta el paquete de pruebas para casa inteligente
Después de verificar tu dispositivo con los controles de tacto en la app de Google Home o mediante comandos por voz, puedes usar el paquete de pruebas para casa inteligente automatizado para validar casos de uso según los tipos y las características de dispositivos asociados con tu Acción. El paquete de pruebas ejecuta una serie de pruebas para detectar problemas en tu Acción y muestra mensajes informativos sobre casos de prueba con errores para acelerar la depuración antes de sumergirte en los registros de eventos.
Ejecuta el paquete de pruebas para un hogar inteligente
Sigue estas instrucciones para probar la Acción por paquete de pruebas de tu casa inteligente:
- En el navegador web, abre el paquete de pruebas para la casa inteligente.
- Accede a Google con el botón de la esquina superior derecha. Esto permite que el paquete de pruebas envíe los comandos directamente a Asistente de Google.
- En el campo ID del proyecto, ingresa el ID del proyecto de tu Acción de casa inteligente. Y, luego, haz clic en SIGUIENTE para continuar.
- En el paso Configuración de la prueba, deberías ver la lavadora con errores en la sección Dispositivos y bandeja.
- 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 la opción Solicitar sincronización cada vez que el usuario agregue dispositivos, los quite o les cambie el nombre.
- Deja habilitada la opción SDK de Local Home, ya que vamos a probar las rutas de acceso local y en la nube.
- Haz clic en SIGUIENTE para comenzar a ejecutar la prueba.
Cuando se hayan completado las pruebas, notarás que las opciones de Pausar/reanudar pruebas en la ruta de acceso local fallan, mientras que las de Pausar o reanudar pruebas en la ruta de la nube están aprobadas.
Analizar mensaje de error
Examina con más detalle los mensajes de error en los casos de prueba fallidos. Indican cuál es el estado esperado para esa prueba y cuál fue el estado real. En este caso, para "Pause the Washer", 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
.
En los mensajes de error, parece que, en la ruta de acceso local, estamos configurando el estado isPaused
a la inversa.
Cómo identificar y corregir el error
Encontremos el código fuente donde la app de Local Home envía el comando de ejecución al dispositivo. getDataCommand()
es la función que llama executeHandler()
para establecer payload
en el comando de ejecución enviado 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 estableciendo isPause
en el estado inverso. Debe establecerse en true
cuando params.pause
es true
y, de lo contrario, false
. Entonces, corríjalo.
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 inicio local para que podamos identificar si estamos usando la versión correcta.
local/index.ts
const localHomeSdk = new App('1.0.3');
Recuerda compilar la app nuevamente 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 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 una casa inteligente con los mismos parámetros de configuración y verás que todos los casos de prueba fueron aprobados.
7. Felicitaciones
¡Felicitaciones! Aprendiste a solucionar problemas en una app de Local Home con éxito con el paquete de pruebas para casas inteligentes y Cloud Logging.
Más información
Puedes intentar hacer lo siguiente:
- Agrega más características compatibles a tu dispositivo y realiza pruebas con el paquete de pruebas.
- Agregar más registros personalizados en cada uno de los controladores de intents y visualizarlos en Cloud Logging.
- Crea paneles, configura alertas y accede a datos de métricas de manera programática para obtener métricas de uso útiles sobre tu Acción.
También puedes obtener más información sobre cómo probar una Acción y enviarla a revisión, incluido el proceso de certificación para publicar tu Acción para los usuarios.