События асинхронны и управляются 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" : "1a2e13bc-c23c-4bc4-8366-6b5669607f0e",
"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Пример: "a121b435-e3bb-4ba1-9dea-945686b7dabf". |
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" : "caec1000-1cab-43d3-946f-bc3c5f8615c9",
"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" : "0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "jOvQqNOSL76837k_JxTR4BJ6nw...",
}
}
}
"userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}Эти типы событий ресурсов определены в определенных признаках. Например, событие Motion определено в типаже CameraMotion . Чтобы узнать, в каком формате передаются данные о событиях, связанных с ресурсами, ознакомьтесь с документацией по каждому свойству.
Поля
| Поле | Описание | Тип данных |
|---|---|---|
eventId |
Уникальный идентификатор события. | stringПример: "0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c". |
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.
Клиентские библиотеки API Google
Для 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 приведен в справочнике.