События асинхронны и управляются Google Cloud Pub/Sub в одной теме на Project. События предоставляют обновления для всех устройств и структур, и получение событий гарантируется до тех пор, пока токен доступа не будет отозван пользователем и срок действия сообщений о событиях не истечет.
Информация о мероприятиях
События – это необязательная функция SDM API. Подробнее о том, как включить события для Project, читайте в разделе Как включить события .
Google Cloud Pub/Sub
Подробную информацию о работе Pub/Sub можно найти в документации Google Cloud Pub/Sub. В их числе:
- Ознакомьтесь с основами работы с Pub/Sub в практических руководствах.
- Узнайте, как работает аутентификация.
- Выберите одну из доступных клиентских библиотек или напишите собственную и используйте REST/HTTP или gRPC API.
Подписка на события
До января 2025 г., если для вашего Projectбыли включены события, вы получали размещенную в Google тему, связанную с этим Project , в следующем формате:
projects/sdm-prod/topics/enterprise-project-id
Теперь все проекты должны самостоятельно размещать свои темы издатель-подписчик в собственном облачном проекте Google Cloud (обязательно для новых проектов с января 2025 года и для всех существующих проектов до 30 ноября 2026 года) в следующем формате:
projects/gcp-project-name/subscriptions/topic-id
Если в вашем project уже используется тема, размещенная в вашем облачном проекте Google Cloud, никаких действий не требуется. Перенос конфигурации темы Pub/Sub не аннулирует существующие токены доступа пользователей или разрешения OAuth. Для тем и подписок, размещенных на собственном сервере, действуют стандартные тарифы Google Cloud Pub/Sub (включая бесплатный план с 10 ГБ в месяц). Подробнее о том, как создать тему…
Чтобы получать события, создайте подписку на эту тему с запросом или отправкой в зависимости от вашего варианта использования. Поддерживается несколько подписок на тему SDM. Подробнее об управлении подписками…
Инициировать события
Чтобы инициировать события в первый раз после создания подписки издатель-подписчик, выполните вызов API
devices.list в качестве однократного триггера. После этого вызова будут публиковаться события для всех структур и устройств.
Пример можно найти на странице Авторизация в кратком руководстве.
Порядок событий
Pub/Sub не гарантирует упорядоченную доставку событий, и порядок получения событий может не соответствовать порядку, в котором они произошли. Используйте поле timestamp, чтобы сопоставить порядок событий. События могут поступать по отдельности или в виде единого сообщения.
Подробнее о порядке сообщений…
идентификаторы пользователей;
Если ваша реализация основана на пользователях (а не на структуре или устройстве), используйте поле userID из полезной нагрузки события, чтобы сопоставить ресурсы и события. Это поле содержит замаскированный идентификатор, представляющий определенного пользователя.
Значение userID также доступно в заголовке HTTP-ответа каждого вызова API.
События, связанные с отношениями
События отношений представляют собой обновление отношений для ресурса. Например, когда устройство добавляется в структуру или удаляется из нее.
Существует три типа событий, связанных с отношениями:
- CREATED
- УДАЛЕНО
- ОБНОВЛЕНО
Полезная нагрузка для события связи выглядит следующим образом:
Полезная нагрузка
{
"eventId" : "78b596bf-84ac-46ff-898e-608519a3cec2",
"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"
}В событии связи object – это ресурс, который активировал событие, а subject – ресурс, с которым теперь связан object. В примере выше user предоставил доступ к определенному устройству developer, и авторизованное устройство userтеперь связано с авторизованной структурой, что запускает событие.
subject может быть только комнатой или строением. Если у a developer нет разрешения на просмотр структуры user, то subject всегда будет пустым.
Поля
| Поле | Описание | Тип данных |
|---|---|---|
eventId |
Уникальный идентификатор события. | stringПример: "27fe1a5b-2427-46dc-aa40-9da7fa9cea0a". |
timestamp |
Время, когда произошло событие. | stringПример: "2019-01-01T00:00:01Z". |
relationUpdate |
Объект, содержащий подробную информацию об обновлении связи. | object |
userId |
Уникальный замаскированный идентификатор пользователя. | stringПример: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi". |
Подробнее о событиях…
Примеры
Полезная нагрузка события зависит от его типа:
ВРЕМЯ СОЗДАНИЯ
Структура создана
"relationUpdate" : {
"type" : "CREATED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Устройство создано.
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Устройство создано.
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}ОБНОВЛЕНО
Устройство перемещено
"relationUpdate" : {
"type" : "UPDATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}УДАЛЕНО
Дом удален
"relationUpdate" : {
"type" : "DELETED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Устройство удалено.
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Устройство удалено.
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}События, связанные с отношениями, не отправляются, если:
- Комната удалена.
События, связанные с ресурсами
Событие ресурса представляет собой обновление, относящееся к ресурсу. Например, это может быть реакция на изменение значения поля характеристики, такое как изменение режима термостата. Оно также может представлять действие устройства, которое не меняет поле характеристики, например нажатие кнопки устройства.
Событие, созданное в ответ на изменение значения поля типажа, содержит объект traits, аналогичный вызову GET устройства:
Полезная нагрузка
{
"eventId" : "5f7b7bd4-c014-4303-9fdc-9f4a103f07fb",
"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"
]
}Чтобы узнать, как выглядит полезная нагрузка для события ресурса, связанного с изменением поля признака, ознакомьтесь с документацией по отдельным признакам.
Событие, сгенерированное в ответ на действие устройства, которое не меняет поле признака, также имеет полезную нагрузку с объектом resourceUpdate, но с объектом events вместо объекта traits:
Полезная нагрузка
{
"eventId" : "36a8de1e-ee94-4eea-814b-464c98fe57c8",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "VhzVySCwWUvB-PIcOaBnub4xS1...",
}
}
}
"userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}Эти типы событий ресурсов определены в определенных признаках. Например, событие Motion определено в типаже CameraMotion . Чтобы узнать, в каком формате передаются данные о событиях, связанных с ресурсами, ознакомьтесь с документацией по каждому свойству.
Поля
| Поле | Описание | Тип данных |
|---|---|---|
eventId |
Уникальный идентификатор события. | stringПример: "36a8de1e-ee94-4eea-814b-464c98fe57c8". |
timestamp |
Время, когда произошло событие. | stringПример: "2019-01-01T00:00:01Z". |
resourceUpdate |
Объект, содержащий подробную информацию об обновлении ресурса. | object |
userId |
Уникальный замаскированный идентификатор пользователя. | stringПример: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi". |
eventThreadId |
Уникальный идентификатор цепочки событий. | stringПример: d67cd3f7-86a7-425e-8bb3-462f92ec9f59. |
eventThreadState |
Состояние цепочки событий. | stringЗначения: STARTED, UPDATED, ENDED. |
resourceGroup |
Объект, указывающий на ресурсы, которые могут иметь аналогичные обновления для этого события. Ресурс самого события (из объекта resourceUpdate) всегда будет присутствовать в этом объекте. |
object |
Подробнее о событиях…
Обновляемые уведомления
Уведомления о событиях ресурсов можно реализовать в приложении, например для Android или iOS. Чтобы уменьшить количество отправляемых уведомлений, можно реализовать функцию обновляемых уведомлений, когда существующие уведомления обновляются новой информацией на основе последующих событий в той же цепочке событий.Некоторые события поддерживают обновляемые уведомления и помечены в документации как Updateable eventThreadId. Используйте это поле, чтобы связать отдельные события и обновить существующее уведомление, которое было показано пользователю.
Цепочка мероприятия – это не то же самое, что сеанс мероприятия. Цепочка событий определяет обновленный статус предыдущего события в той же цепочке. Сеанс событий идентифицирует отдельные события, связанные друг с другом. В рамках одного сеанса может быть несколько цепочек событий.
Для удобства уведомления о разных типах событий группируются в цепочки.
Логика группировки и времени отправки сообщений определяется Google и может быть изменена в любой момент. developer должно обновлять уведомления на основе цепочек событий и сеансов, предоставляемых SDM API.
Состояние цепочки
События, поддерживающие обновляемые уведомления, также имеют поле eventThreadState, которое указывает на состояние цепочки событий в данный момент времени. Это поле может принимать следующие значения:
- STARTED – первое событие в цепочке.
- UPDATED – событие в текущей цепочке событий. В одной цепочке может быть несколько событий с таким статусом или не быть ни одного.
- ENDED – последнее событие в цепочке, которое может быть копией последнего события UPDATED в зависимости от типа цепочки.
Это поле можно использовать для отслеживания хода выполнения цепочки событий и момента ее завершения.
Фильтрация событий
В некоторых случаях события, обнаруженные устройством, могут быть отфильтрованы и не опубликованы в теме издатель-подписчик SDM. Такое поведение называется фильтрацией событий. Фильтрация событий позволяет избежать публикации слишком большого количества похожих сообщений о событиях за короткий промежуток времени.
Например, сообщение может быть опубликовано в теме SDM для начального события движения. Другие сообщения для Motion после этого будут отфильтрованы и не будут опубликованы, пока не пройдет определенный период времени. По истечении этого времени сообщение о событии этого типа может быть опубликовано снова.
В приложении Google Home отфильтрованные события по-прежнему будут показываться в истории событий user. Однако такие события не генерируют уведомления в приложении (даже если этот тип уведомлений включен).
Для каждого типа событий используется своя логика фильтрации, которая определяется Google и может быть изменена в любой момент. Эта логика фильтрации событий не зависит от логики цепочки событий и сеанса.
Сервисные аккаунты
Для управления подписками SDM API и сообщениями о событиях рекомендуется использовать сервисные аккаунты. Сервисный аккаунт используется приложением или виртуальной машиной, а не человеком, и имеет собственный уникальный ключ.
Для авторизации сервисного аккаунта в Pub/Sub API используется двусторонняя аутентификация OAuth (2LO).
В процессе авторизации 2LO:
- developer запрашивает токен доступа, используя ключ сервиса.
- developer использует токен доступа при вызовах API.
Подробнее о том, как использовать OAuth 2.0 для серверных приложений…
Авторизация
Сервисный аккаунт должен быть авторизован для использования с Pub/Sub API:
- Включите Cloud Pub/Sub API в Google Cloud.
- Создайте сервисный аккаунт и ключ для него, как описано в статье Создание сервисного аккаунта. Рекомендуем назначить ему только роль Подписчик Pub/Sub. Скачайте ключ сервисного аккаунта на компьютер, который будет использовать Pub/Sub API.
- Предоставьте учетные данные для аутентификации (ключ сервисного аккаунта) коду приложения, следуя инструкциям на странице, указанной на предыдущем шаге, или получите токен доступа вручную с помощью
oauth2l, если вы хотите быстро протестировать доступ к API. - Используйте учетные данные сервисного аккаунта или токен доступа с Pub/Sub
project.subscriptionsAPI, чтобы извлекать и подтверждать сообщения.
oauth2l
Google oauth2l – это инструмент командной строки для OAuth, написанный на языке Go. Установите его для Mac или Linux с помощью Go.
- Если у вас нет Go, скачайте и установите его.
- После установки Go установите
oauth2lи добавьте его местоположение в переменную средыPATH:go install github.com/google/oauth2l@latestexport PATH=$PATH:~/go/bin - Используйте
oauth2l, чтобы получить токен доступа для API, используя соответствующие области действия OAuth: Например, если ключ сервиса находится в папкеoauth2l 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...
Дополнительную информацию можно найти в файле README для oauth2l.
Клиентские библиотеки Google API
Для API Google, использующих OAuth 2.0, доступно несколько клиентских библиотек. Дополнительную информацию о выбранном языке можно найти в статье Клиентские библиотеки Google API.
При использовании этих библиотек с Pub/Sub APIукажите следующие строки области действия:
https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
Ошибки
В связи с этим руководством могут возвращаться следующие коды ошибок:
| Сообщение об ошибке | Доход от клика | Устранение неполадок |
|---|---|---|
| Изображение с камеры больше недоступно для скачивания. | DEADLINE_EXCEEDED |
Изображения событий становятся недействительными через 30 секунд после публикации события. Скачайте изображение до истечения срока действия. |
| Идентификатор события не принадлежит камере. | FAILED_PRECONDITION |
Используйте правильное значение eventID, возвращенное событием камеры. |
Полный список кодов ошибок API приведен в справочнике.