Los eventos son asíncronos y los administra Google Cloud Pub/Sub, en un solo tema por Project. Los eventos proporcionan actualizaciones para todos los dispositivos y estructuras, y la recepción de eventos está garantizada, siempre y cuando el usuario no revoque el token de acceso y los mensajes del evento no hayan vencido.
Habilitar eventos
Los eventos son una función opcional de la API de SDM. Consulta Habilita eventos para obtener información sobre cómo habilitarlos en tu Project.
Google Cloud Pub/Sub
Consulta la documentación de Google Cloud Pub/Sub para obtener más información sobre cómo funciona Pub/Sub. En particular:
- Aprende los conceptos básicos de Pub/Sub con sus guías prácticas.
- Comprende cómo funciona Authentication.
- Elige una biblioteca cliente proporcionada o escribe la tuya propia y usa las superficies de la API de REST/HTTP o gRPC.
Suscripción al evento
Cuando se habiliten los eventos para tu Project, se te proporcionará un tema específico para ese ID de Project , en el siguiente formato:
projects/sdm-prod/topics/enterprise-project-id
Para recibir eventos, crea una suscripción de extracción o envío a ese tema, según tu caso de uso. Se admiten varias suscripciones al tema de SDM. Consulta Cómo administrar suscripciones para obtener más información.
Cómo iniciar eventos
Para iniciar eventos por primera vez una vez que se haya creado la suscripción a Pub/Sub, realiza una
llamada a la API de devices.list
como activador único. Los eventos de todas las estructuras y dispositivos se publicarán después de esta
llamada.
Para ver un ejemplo, consulta la página Autorizar en la Guía de inicio rápido.
Orden de eventos
Pub/Sub no garantiza la entrega ordenada de eventos, y es posible que el orden de recepción de los eventos no
corresponda al orden en el que ocurrieron. Usa el campo timestamp
para facilitar la conciliación del orden de los eventos. Los eventos también pueden llegar de forma individual o combinados en un solo mensaje de evento.
Para obtener más información, consulta Ordena mensajes.
IDs de usuario
Si tu implementación se basa en los usuarios (en lugar de la estructura o el dispositivo), usa el campo userID
de la carga útil del evento para correlacionar recursos y eventos. Este campo es un ID ofuscado que representa a un usuario específico.
El userID
también está disponible en el encabezado de respuesta HTTP de cada llamada a la API.
Eventos de relación
Los eventos de relación representan una actualización relacional de un recurso. Por ejemplo, cuando se agrega un dispositivo a una estructura o cuando se borra un dispositivo de una estructura.
Existen tres tipos de eventos de relación:
- CREATED
- ELIMINADO
- ACTUALIZADA
La carga útil de un evento de relación es la siguiente:
Carga útil
{ "eventId" : "d5c0f0bd-de65-44fd-ac60-686c302e56eb", "timestamp" : "2019-01-01T00:00:01Z", "relationUpdate" : { "type" : "CREATED", "subject" : "enterprises/project-id/structures/structure-id", "object" : "enterprises/project-id/devices/device-id" }, "userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" }
En un evento de relación, object
es el recurso que activó el evento y subject
es el recurso con el que object
ahora tiene una relación. En el
ejemplo anterior, un user le otorgó acceso a este dispositivo específico a un
developer, y el dispositivo autorizado de userahora está relacionado con su estructura
autorizada, lo que activa el evento.
Un subject
solo puede ser una sala o una estructura. Si a developer no tiene permiso para ver la estructura de user, subject
siempre estará vacía.
Campos
Campo | Descripción | Tipo de datos |
---|---|---|
eventId |
Es el identificador único del evento. | string Ejemplo: "64b87b46-1aec-42a4-8c01-997a407814df" |
timestamp |
La hora en que ocurrió el evento. | string Ejemplo: “2019-01-01T00:00:01Z” |
relationUpdate |
Es un objeto que detalla información sobre la actualización de la relación. | object |
userId |
Un identificador único y ofuscado que representa al usuario. | string Ejemplo: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
Consulta Eventos para obtener más información sobre los diferentes tipos de eventos y cómo funcionan.
Ejemplos
Las cargas útiles de los eventos difieren para cada tipo de evento de relación:
CREATED
Se creó la estructura
"relationUpdate" : { "type" : "CREATED", "subject" : "", "object" : "enterprises/project-id/structures/structure-id" }
Se creó el dispositivo
"relationUpdate" : { "type" : "CREATED", "subject" : "enterprises/project-id/structures/structure-id", "object" : "enterprises/project-id/devices/device-id" }
Se creó el dispositivo
"relationUpdate" : { "type" : "CREATED", "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id", "object" : "enterprises/project-id/devices/device-id" }
ACTUALIZADA
Se movió el dispositivo
"relationUpdate" : { "type" : "UPDATED", "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id", "object" : "enterprises/project-id/devices/device-id" }
ELIMINADO
Se borró la estructura
"relationUpdate" : { "type" : "DELETED", "subject" : "", "object" : "enterprises/project-id/structures/structure-id" }
Se borró el dispositivo
"relationUpdate" : { "type" : "DELETED", "subject" : "enterprises/project-id/structures/structure-id", "object" : "enterprises/project-id/devices/device-id" }
Se borró el dispositivo
"relationUpdate" : { "type" : "DELETED", "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id", "object" : "enterprises/project-id/devices/device-id" }
Los eventos de relación no se envían en los siguientes casos:
- Se borra una sala
Eventos de recursos
Un evento de recurso representa una actualización específica de un recurso. Puede ser en respuesta a un cambio en el valor de un campo de atributo, como cambiar el modo de un termostato. También puede representar una acción del dispositivo que no cambia un campo de rasgo, como presionar un botón del dispositivo.
Un evento generado en respuesta a un cambio en el valor del campo de rasgo contiene un objeto traits
, similar a una llamada GET del dispositivo:
Carga útil
{
"eventId" : "a88bc884-d2b8-42d6-adba-b7be92c232a3",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"traits" : {
"sdm.devices.traits.ThermostatMode
" : {
"mode" : "COOL"
}
}
},
"userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}
Usa la documentación de los rasgos individuales para comprender el formato de la carga útil de cualquier evento de recurso de cambio de campo de rasgo.
Un evento generado en respuesta a una acción del dispositivo que no cambia un campo de atributo también tiene una carga útil con un objeto resourceUpdate
, pero con un objeto events
en lugar de un objeto traits
:
Carga útil
{ "eventId" : "4f80de08-1b77-42a4-b33e-40876a2a1865",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "MWJ253hZMPAsJZJWbrGM4ThsKM...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
Estos tipos de eventos de recursos se definen en atributos específicos. Por ejemplo, el evento de movimiento se define en el rasgo CameraMotion . Consulta la documentación de cada atributo para comprender el formato de la carga útil de estos tipos de eventos de recursos.
Campos
Campo | Descripción | Tipo de datos |
---|---|---|
eventId |
Es el identificador único del evento. | string Ejemplo: "4f80de08-1b77-42a4-b33e-40876a2a1865" |
timestamp |
La hora en que ocurrió el evento. | string Ejemplo: “2019-01-01T00:00:01Z” |
resourceUpdate |
Es un objeto que detalla la información sobre la actualización del recurso. | object |
userId |
Un identificador único y ofuscado que representa al usuario. | string Ejemplo: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
eventThreadId |
Es el identificador único del subproceso del evento. | string Ejemplo: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59" |
eventThreadState |
Es el estado del subproceso del evento. | string Valores: "STARTED", "UPDATED", "ENDED" |
resourceGroup |
Es un objeto que indica los recursos que podrían tener actualizaciones similares a este evento. El recurso del evento en sí (del objeto resourceUpdate ) siempre estará presente en este objeto. |
object |
Consulta Eventos para obtener más información sobre los diferentes tipos de eventos y cómo funcionan.
Notificaciones actualizables
Las notificaciones basadas en eventos de recursos se pueden implementar en una app, como para Android o iOS. Para reducir la cantidad de notificaciones enviadas, se puede implementar una función llamada notificaciones actualizables, en la que las notificaciones existentes se actualizan con información nueva según los eventos posteriores en el mismo subproceso de eventos.Algunos eventos admiten notificaciones actualizables y se etiquetan como
Actualizable eventThreadId
en sus cargas útiles. Usa este campo para vincular eventos individuales con el fin de actualizar una notificación existente que se mostró a un usuario.
Un subproceso de evento no es lo mismo que una sesión de evento. El subproceso de eventos identifica un estado actualizado para un evento anterior en el mismo subproceso. La sesión de eventos identifica eventos independientes que se relacionan entre sí, y puede haber varios subprocesos de eventos para una sesión de eventos determinada.
A los efectos de las notificaciones, los diferentes tipos de eventos se agrupan en diferentes subprocesos.
Google controla esta lógica de agrupación y sincronización de subprocesos, que está sujeta a cambios en cualquier momento. A developer debe actualizar las notificaciones en función de los subprocesos y las sesiones de eventos que proporciona la API de SDM.
Estado de subprocesos
Los eventos que admiten notificaciones actualizables también tienen un campo eventThreadState
que indica el estado del subproceso del evento en ese momento. Este campo tiene los siguientes valores:
- STARTED: Es el primer evento de un subproceso de evento.
- ACTUALIZADO: Es un evento en un subproceso de eventos en curso. Puede haber cero o más eventos con este estado en un solo subproceso.
- ENDED: Es el último evento de un subproceso de eventos, que puede ser un duplicado del último evento de UPDATED, según el tipo de subproceso.
Este campo se puede usar para hacer un seguimiento del progreso de un subproceso de evento y cuándo finalizó.
Filtrado de eventos
En algunos casos, es posible que los eventos detectados por un dispositivo no se publiquen en un tema de Pub/Sub de SDM. Este comportamiento se denomina filtrado de eventos. El propósito del filtrado de eventos es evitar publicar demasiados mensajes de eventos similares en un período breve.
Por ejemplo, un mensaje puede publicarse en un tema de SDM para un evento de movimiento inicial. Los demás mensajes de Motion después de ese momento se filtrarán de la publicación hasta que transcurra un período determinado. Una vez que transcurra ese período, es posible que se vuelva a publicar un mensaje de evento para ese tipo de evento.
En la app de Google Home (GHA), los eventos que se filtraron se seguirán mostrando en el historial de eventos de user. Sin embargo, esos eventos no generan una notificación de la app (incluso si ese tipo de notificación está habilitado).
Cada tipo de evento tiene su propia lógica de filtrado de eventos, que define Google y está sujeta a cambios en cualquier momento. Esta lógica de filtrado de eventos es independiente del subproceso de eventos y la lógica de la sesión.
Cuentas de servicio
Se recomiendan las cuentas de servicio para administrar las suscripciones a la API de SDM y los mensajes de eventos. Una aplicación o una máquina virtual, no una persona, usa una cuenta de servicio y tiene su propia clave de cuenta única.
La autorización de la cuenta de servicio para la API de Pub/Sub usa OAuth de dos pasos (2LO).
En el flujo de autorización de 2LO:
- developer solicita un token de acceso con una clave de servicio.
- developer usa el token de acceso con llamadas a la API.
Para obtener más información sobre la autenticación de 2 pasos de Google y cómo configurarla, consulta Cómo usar OAuth 2.0 para aplicaciones de servidor a servidor.
Autorización
La cuenta de servicio debe estar autorizada para usarla con la API de Pub/Sub:
- Habilita la API de Cloud Pub/Sub en Google Cloud.
- Crea una cuenta de servicio y una clave de cuenta de servicio como se describe en Cómo crear una cuenta de servicio. Te recomendamos que solo le otorgues el rol de Suscriptor de Pub/Sub. Asegúrate de descargar la clave de la cuenta de servicio en la máquina que usará la API de Pub/Sub.
- Proporciona tus credenciales de autenticación (clave de la cuenta de servicio) al código de la aplicación. Para ello, sigue las instrucciones de la página del paso anterior o obtén un token de acceso de forma manual con
oauth2l
si deseas probar rápidamente el acceso a la API. - Usa las credenciales de la cuenta de servicio o el token de acceso con la API de
project.subscriptions
de Pub/Sub para extraer y confirmar mensajes.
oauth2l
Google oauth2l
es una herramienta de línea de comandos para OAuth escrita en Go. Instálala en Mac o Linux con Go.
- Si no tienes Go en tu sistema, descárgalo e instálalo primero.
- Una vez que Go esté instalado, instala
oauth2l
y agrega su ubicación a tu variable de entornoPATH
:go install github.com/google/oauth2l@latest
export PATH=$PATH:~/go/bin
- Usa
oauth2l
para obtener un token de acceso para la API con los permisos de OAuth adecuados:
Por ejemplo, si tu clave de servicio se encuentra enoauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
~/myServiceKey-eb0a5f900ee3.json
:oauth2l fetch --credentials ~/myServiceKey-eb0a5f900ee3.json --scope https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
ya29.c.Elo4BmHXK5...
Consulta el archivo oauth2l
README para obtener más información sobre el uso.
Bibliotecas cliente de la API de Google
Hay varias bibliotecas cliente disponibles para las APIs de Google que usan OAuth 2.0. Consulta Bibliotecas cliente de la API de Google para obtener más información sobre el lenguaje que elijas.
Cuando uses estas bibliotecas con Pub/Sub API, usa las siguientes cadenas de alcance:
https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
Errores
Es posible que se muestren los siguientes códigos de error en relación con esta guía:
Mensaje de error | RPC | Solución de problemas |
---|---|---|
La imagen de la cámara ya no está disponible para descargarla. | DEADLINE_EXCEEDED |
Las imágenes de los eventos vencen 30 segundos después de que se publican. Asegúrate de descargar la imagen antes de que venza. |
El ID del evento no pertenece a la cámara. | FAILED_PRECONDITION |
Usa el eventID correcto que muestra el evento de la cámara. |
Consulta la referencia de códigos de error de la API para obtener la lista completa de los códigos de error de la API.