Os eventos são assíncronos e gerenciados pelo Google Cloud Pub/Sub, em um único tópico por Project. Os eventos fornecem atualizações para todos os dispositivos e estruturas, e o recebimento deles é garantido enquanto o token de acesso não for revogado pelo usuário e as mensagens de evento não tiverem expirado.
Ativar eventos
Os eventos são um recurso opcional da API SDM. Consulte Ativar eventos para saber como ativá-los no seu Project.
Google Cloud Pub/Sub
Consulte a documentação do Google Cloud Pub/Sub para saber mais sobre como o Pub/Sub funciona. Especificamente:
- Aprenda os conceitos básicos do Pub/Sub com os guias de instruções.
- Entenda como a autenticação funciona.
- Escolha uma biblioteca de cliente ou escreva sua própria e use as plataformas de API REST/HTTP ou gRPC.
Inscrição em eventos
Antes de janeiro de 2025, se os eventos estivessem ativados para seu Project, você teria sido fornecido um tópico específico para esse Project ID, no formato de:
projects/gcp-project-name/subscriptions/topic-id
Para receber eventos, crie uma assinatura de pull ou push para esse tópico, dependendo do seu caso de uso. Várias assinaturas para o tópico SDM são aceitas. Consulte Gerenciar assinaturas para mais informações.
Iniciar eventos
Para iniciar eventos pela primeira vez depois que a assinatura do Pub/Sub for criada, faça uma
devices.list
chamada de API como um acionador único. Os eventos de todas as estruturas e dispositivos serão publicados após essa
chamada.
Para ver um exemplo, consulte a página Autorizar no Guia de início rápido.
Ordem dos eventos
O Pub/Sub não garante a entrega ordenada de eventos, e a ordem de recebimento dos eventos pode não
corresponder à ordem em que eles ocorreram. Use o campo timestamp
para ajudar na reconciliação da ordem dos eventos. Os eventos também podem chegar individualmente ou combinados
em uma única mensagem de evento.
Para mais informações, consulte Como ordenar mensagens.
IDs de usuários
Se a implementação for baseada em usuários (em vez de estrutura ou dispositivo), use o
userID campo do payload do evento para correlacionar recursos e eventos. Esse campo é
um ID ofuscado que representa um usuário específico.
O userID também está disponível no cabeçalho de resposta HTTP de cada chamada de API.
Eventos de relacionamento
Os eventos de relacionamento representam uma atualização relacional para um recurso. Por exemplo, quando um dispositivo é adicionado ou excluído de uma estrutura.
Há três tipos de eventos de relacionamento:
- CREATED
- EXCLUÍDO
- ATUALIZADO
O payload de um evento de relacionamento é o seguinte:
Payload
{
"eventId" : "6020f8dc-cf16-4070-9793-3a74e297b296",
"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"
}Em um evento de relacionamento, o object é o recurso que acionou o evento, e o
subject é o recurso com que o object agora tem uma relação. No
exemplo acima, um user concedeu acesso a esse dispositivo específico a um
developer, e o dispositivo autorizado do useragora está relacionado à estrutura autorizada, o que aciona o evento.
Um subject só pode ser um cômodo ou uma estrutura. Se a developer não tiver
permissão para visualizar a estrutura do user, o subject estará sempre
vazio.
Campos
| Campo | Descrição | Tipo de dados |
|---|---|---|
eventId |
O identificador exclusivo do evento. | stringExemplo: "808d1a1e-063f-4901-8ff8-2004c595cce4" |
timestamp |
A hora em que o evento ocorreu. | stringExemplo: "2019-01-01T00:00:01Z" |
relationUpdate |
Um objeto que detalha informações sobre a atualização da relação. | object |
userId |
Um identificador único e ofuscado que representa o usuário. | stringExemplo: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
Consulte Eventos para mais informações sobre os diferentes tipos de eventos e como eles funcionam.
Exemplos
Os payloads de eventos são diferentes para cada tipo de evento de relacionamento:
CREATED
Estrutura criada
"relationUpdate" : {
"type" : "CREATED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Dispositivo criado
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Dispositivo criado
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}ATUALIZADO
Dispositivo movido
"relationUpdate" : {
"type" : "UPDATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}EXCLUÍDO
Estrutura excluída
"relationUpdate" : {
"type" : "DELETED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Dispositivo excluído
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Dispositivo excluído
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}Os eventos de relacionamento não são enviados quando:
- Um cômodo é excluído
Eventos do recurso
Um evento de recurso representa uma atualização específica de um recurso. Ele pode ser em resposta a uma mudança no valor de um campo de característica, como mudar o modo de um termostato. Ele também pode representar uma ação do dispositivo que não muda um campo de característica, como pressionar um botão do dispositivo.
Um evento gerado em resposta a uma mudança no valor do campo de característica contém um
traits objeto, semelhante a uma chamada GET de dispositivo:
Payload
{
"eventId" : "c0f5f713-ec68-4aed-868d-85eaed6a26e7",
"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"
]
}Use a documentação de característica individual para entender o formato do payload de qualquer evento de recurso de mudança de campo de característica.
Um evento gerado em resposta a uma ação do dispositivo que não muda um campo de característica também tem um
payload com um resourceUpdate objeto, mas com um events objeto
em vez de um traits objeto:
Payload
{
"eventId" : "2af57608-415c-4c67-9f66-3edbdf82bf4a",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "_wHEvcpb2sPsNjtMCeDoJx7P1G...",
}
}
}
"userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}Esses tipos de eventos de recursos são definidos em características específicas. Por exemplo, o evento de movimento é definido na característica CameraMotion . Consulte a documentação de cada característica para entender o formato do payload desses tipos de eventos de recursos.
Campos
| Campo | Descrição | Tipo de dados |
|---|---|---|
eventId |
O identificador exclusivo do evento. | stringExemplo: "2af57608-415c-4c67-9f66-3edbdf82bf4a" |
timestamp |
A hora em que o evento ocorreu. | stringExemplo: "2019-01-01T00:00:01Z" |
resourceUpdate |
Um objeto que detalha informações sobre a atualização do recurso. | object |
userId |
Um identificador único e ofuscado que representa o usuário. | stringExemplo: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
eventThreadId |
O identificador exclusivo da linha de execução do evento. | stringExemplo: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59" |
eventThreadState |
O estado da linha de execução do evento. | stringValores: "STARTED", "UPDATED", "ENDED" |
resourceGroup |
Um objeto que indica recursos que podem ter atualizações semelhantes a esse evento. O recurso do evento em si (do objeto resourceUpdate) sempre estará presente nesse objeto. |
object |
Consulte Eventos para mais informações sobre os diferentes tipos de eventos e como eles funcionam.
Notificações atualizáveis
As notificações baseadas em eventos de recursos podem ser implementadas em um app, como para Android ou iOS. Para reduzir o número de notificações enviadas, um recurso chamado notificações atualizáveis pode ser implementado, em que as notificações atuais são atualizadas com novas informações com base em eventos subsequentes na mesma linha de execução de eventos.Selecione o recurso de eventos para notificações atualizáveis e marque-os como
Atualizáveis eventThreadId nos payloads. Use esse campo para vincular eventos individuais com o objetivo de atualizar uma notificação atual que foi exibida para um usuário.
Uma linha de execução de eventos não é a mesma coisa que uma sessão de eventos. A linha de execução de eventos identifica um status atualizado para um evento anterior na mesma linha. A sessão de eventos identifica eventos separados que se relacionam entre si, e pode haver várias linhas de execução de eventos para uma determinada sessão de eventos.
Para fins de notificação, diferentes tipos de eventos são agrupados em linhas de execução diferentes.
Essa lógica de agrupamento e tempo de linha de execução é processada pelo Google e está sujeita a mudanças a qualquer momento. A developer deve atualizar as notificações com base nas linhas de execução e sessões de eventos fornecidas pela API SDM.
Estado da linha de execução
Os eventos que oferecem suporte a notificações atualizáveis também têm um campo eventThreadState que indica o estado da linha de execução do evento naquele momento. Esse campo tem os seguintes valores:
- STARTED: o primeiro evento em uma linha de execução de eventos.
- UPDATED: um evento em uma linha de execução de eventos em andamento. Pode haver zero ou mais eventos com esse estado em uma única linha.
- ENDED: o último evento em uma linha de execução de eventos, que pode ser uma duplicata do último evento UPDATED, dependendo do tipo de linha.
Esse campo pode ser usado para acompanhar o progresso de uma linha de execução de eventos e quando ela terminou.
Filtragem de eventos
Em alguns casos, os eventos detectados por um dispositivo podem ser filtrados da publicação em um tópico do Pub/Sub SDM. Esse comportamento é chamado de filtragem de eventos. O objetivo da filtragem de eventos é evitar a publicação de muitas mensagens de eventos semelhantes em um curto período.
Por exemplo, uma mensagem pode ser publicada em um tópico SDM para um evento de movimento inicial. Outras mensagens de movimento depois disso serão filtradas da publicação até que um período definido seja concluído. Depois desse período, uma mensagem de evento para esse tipo de evento poderá ser publicada novamente.
No app Google Home (GHA), os eventos que foram filtrados ainda serão mostrados no user's histórico de eventos. No entanto, esses eventos não geram uma notificação do app (mesmo que esse tipo de notificação esteja ativado).
Cada tipo de evento tem a própria lógica de filtragem de eventos, que é definida por Google e está sujeita a mudanças a qualquer momento. Essa lógica de filtragem de eventos é independente da lógica de linha de execução e sessão de eventos.
Contas de serviço
As contas de serviço são recomendadas para gerenciar assinaturas da API SDM e mensagens de eventos. Uma conta de serviço é usada por um aplicativo ou máquina virtual, não por uma pessoa, e tem a própria chave de conta exclusiva.
A autorização da conta de serviço para a API Pub/Sub usa o OAuth de duas etapas (2LO).
No fluxo de autorização 2LO:
- O developer solicita um token de acesso usando uma chave de serviço.
- O developer usa o token de acesso com chamadas para a API.
Para saber mais sobre o 2LO do Google e como configurar, consulte Usar o OAuth 2.0 para aplicativos de servidor para servidor Applications.
Autorização
A conta de serviço precisa ser autorizada para uso com a API Pub/Sub:
- Ative a API Cloud Pub/Sub no Google Cloud.
- Crie uma conta de serviço e uma chave de conta de serviço conforme descrito em Criar uma conta de serviço. Recomendamos conceder apenas o papel de Assinante do Pub/Sub. Faça o download da chave da conta de serviço para a máquina que vai usar a API Pub/Sub.
- Forneça suas credenciais de autenticação (chave da conta de serviço) ao
código do aplicativo seguindo as instruções na página da etapa
anterior ou receba um token de acesso manualmente usando
oauth2l, se quiser testar rapidamente o acesso à API. - Use as credenciais da conta de serviço ou o token de acesso com a
API
project.subscriptionsdo Pub/Sub para extrair e confirmar mensagens.
oauth2l
O oauth2l do Google é uma ferramenta de linha de comando para OAuth escrita em Go. Instale-o para Mac ou Linux usando Go.
- Se você não tiver o Go no sistema, faça o download e instale-o primeiro.
- Depois que o Go for instalado, instale o
oauth2le adicione o local dele à variável de ambientePATH:go install github.com/google/oauth2l@latestexport PATH=$PATH:~/go/bin - Use
oauth2lpara receber um token de acesso para a API, usando os escopos OAuth apropriados: Por exemplo, se a chave de serviço estiver localizada emoauth2l 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-platformya29.c.Elo4BmHXK5...
Consulte o arquivo oauth2l README para mais informações sobre o uso.
Bibliotecas de cliente de APIs do Google
Há várias bibliotecas de cliente disponíveis para APIs do Google que utilizam o OAuth 2.0. Consulte Bibliotecas de cliente de APIs do Google para mais informações sobre o idioma de sua escolha.
Ao usar essas bibliotecas com o Pub/Sub API, use as seguintes strings de escopo:
https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
Erros
Os seguintes códigos de erro podem ser retornados em relação a este guia:
| Mensagem de erro | RPC | Solução de problemas |
|---|---|---|
| A imagem da câmera não está mais disponível para download. | DEADLINE_EXCEEDED |
As imagens de eventos expiram 30 segundos após a publicação do evento. Faça o download da imagem antes da expiração. |
| O ID do evento não pertence à câmera. | FAILED_PRECONDITION |
Use o eventID correto retornado pelo evento da câmera. |
Consulte a Referência de códigos de erro da API para conferir a lista completa de códigos de erro da API.