События происходят асинхронно и управляются Google Cloud Pub/Sub в одной теме на ProjectСобытия обеспечивают обновления для всех устройств и структур, а получение событий гарантировано до тех пор, пока токен доступа не отозван пользователем и срок действия сообщений о событиях не истек.
Включить события
События — это дополнительная функция API SDM. См. Включить события чтобы узнать, как включить их для вашего Project.
Google Cloud Pub/Sub
Подробнее о работе Pub/ Sub можно узнать в документации Google Cloud Pub/ Sub. В частности:
- Изучите основы Pub/Sub с помощью их руководств .
- Понять, как работает аутентификация .
- Выберите предоставленную клиентскую библиотеку или напишите свою собственную и используйте поверхности API REST/HTTP или gRPC .
Подписка на события
До января 2025 года, если события были включены для вашего Project, вам бы была предоставлена тема, специфичная для этого Project Удостоверение личности в форме:
projects/gcp-project-name/subscriptions/topic-id
Чтобы получать события, создайте подписку на нужную тему по запросу (pull) или по запросу (push) , в зависимости от вашего варианта использования. Поддерживается несколько подписок на тему SDM. Подробнее см. в разделе «Управление подписками» .
Инициировать события
Чтобы инициировать события впервые после создания подписки Pub/Sub, выполните однократный вызов API devices.list
. События для всех структур и устройств будут опубликованы после этого вызова.
Пример см. на странице «Авторизация» в кратком руководстве пользователя.
Порядок событий
Pub/Sub не гарантирует упорядоченную доставку событий, и порядок получения событий может не соответствовать порядку их фактического возникновения. Используйте поле timestamp
для упрощения сверки порядка событий. События также могут приходить по отдельности или объединяться в одно сообщение о событии.
Более подробную информацию смотрите в разделе Заказ сообщений .
Идентификаторы пользователей
Если ваша реализация основана на пользователях (а не на структуре или устройстве), используйте поле userID
из полезной нагрузки события для сопоставления ресурсов и событий. Это поле представляет собой замаскированный идентификатор, представляющий конкретного пользователя.
userID
также доступен в заголовке HTTP-ответа каждого вызова API.
События отношений
События отношения представляют собой реляционное обновление ресурса. Например, при добавлении устройства в структуру или при удалении устройства из структуры.
Существует три типа событий отношений:
- СОЗДАННЫЙ
- УДАЛЕНО
- ОБНОВЛЕНО
Полезная нагрузка для события отношения выглядит следующим образом:
Полезная нагрузка
{ "eventId" : "81688b62-4f69-432f-bbe0-5270032f5466", "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 Пример: «4ec221c5-4cbc-4fd5-ae2e-6eebd1311876» |
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" : "b5a3cb32-3ca8-4b0b-9510-c6a9e70f00f4",
"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" : "803821e5-2626-41d5-8ea2-04b6fdb88f8c",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "HEQiFiTuneH7NJVZ-kHxnbZyU9...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
Эти типы событий ресурсов определяются в конкретных характеристиках. Например, событие «Движение» определяется в CameraMotion Трейт. Чтобы понять формат полезной нагрузки для этих типов событий ресурсов, ознакомьтесь с документацией по каждому трейту.
Поля
Поле | Описание | Тип данных |
---|---|---|
eventId | Уникальный идентификатор события. | string Пример: «803821e5-2626-41d5-8ea2-04b6fdb88f8c» |
timestamp | Время, когда произошло событие. | string Пример: «2019-01-01T00:00:01Z» |
resourceUpdate | Объект, содержащий подробную информацию об обновлении ресурса. | object |
userId | Уникальный, скрытый идентификатор, представляющий пользователя. | string Пример: «AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi» |
eventThreadId | Уникальный идентификатор потока событий. | string Пример: «d67cd3f7-86a7-425e-8bb3-462f92ec9f59» |
eventThreadState | Состояние потока событий. | string Значения: «НАЧАЛО», «ОБНОВЛЕНО», «ЗАВЕРШЕНО» |
resourceGroup | Объект, указывающий ресурсы, которые могут иметь обновления, аналогичные данному событию. Ресурс самого события (из объекта resourceUpdate ) всегда будет присутствовать в этом объекте. | object |
Дополнительную информацию о различных типах мероприятий и принципах их работы см. в разделе События.
Обновляемые уведомления
Уведомления, основанные на событиях ресурсов, можно реализовать в приложении, например, для Android или iOS. Чтобы сократить количество отправляемых уведомлений, можно реализовать функцию, называемую обновляемыми уведомлениями , которая позволяет обновлять существующие уведомления новой информацией на основе последующих событий в той же цепочке событий. Некоторые события поддерживают обновляемые уведомления и помечены в документации как «Обновляемые» . В полезных данных этих событий есть дополнительное поле eventThreadId
. Используйте это поле, чтобы связать отдельные события для обновления существующего уведомления, отображаемого для пользователя.
Поток событий — это не то же самое, что сеанс событий. Поток событий определяет обновлённый статус предыдущего события в том же потоке. Сеанс событий определяет отдельные события, связанные друг с другом, и для одного сеанса событий может быть несколько потоков событий.
В целях оповещения различные типы событий группируются в разные потоки.
Логика группировки потоков и синхронизации обрабатывается Google и может быть изменена в любое время. developer следует обновлять уведомления на основе потоков событий и сеансов, предоставляемых API SDM.
Состояние потока
События, поддерживающие обновляемые уведомления, также имеют поле eventThreadState
, которое указывает состояние потока событий в данный момент времени. Это поле принимает следующие значения:
- НАЧАЛО — Первое событие в цепочке событий.
- ОБНОВЛЕНО — событие в текущем потоке событий. В одном потоке может быть ноль или более событий с таким состоянием.
- ENDED — последнее событие в потоке событий, которое может быть дубликатом последнего события UPDATED, в зависимости от типа потока.
Это поле можно использовать для отслеживания хода потока событий и момента его завершения.
Фильтрация событий
В некоторых случаях события, обнаруженные устройством, могут быть отфильтрованы и не допущены к публикации в теме SDM Pub/Sub. Это называется фильтрацией событий . Цель фильтрации событий — предотвратить публикацию слишком большого количества похожих сообщений о событиях за короткий промежуток времени.
Например, сообщение может быть опубликовано в теме SDM для первоначального события Motion. Дальнейшие сообщения о движении будут отфильтрованы и не будут опубликованы до истечения заданного периода времени. По истечении этого периода сообщение о событии для этого типа может быть опубликовано снова.
В приложении Google Home (GHA) события, которые были отфильтрованы, по-прежнему будут отображаться в userИстория событий. Однако такие события не генерируют уведомления приложения (даже если этот тип уведомлений включён).
Каждый тип событий имеет собственную логику фильтрации, определяемую Google и могущую быть измененной в любое время. Эта логика фильтрации событий не зависит от потока событий и логики сеанса.
Учетные записи служб
Учётные записи служб рекомендуются для управления подписками на API SDM и сообщениями о событиях. Учётная запись службы используется приложением или виртуальной машиной, а не пользователем, и имеет собственный уникальный ключ.
Авторизация учетной записи службы для API Pub/Sub использует двухсторонний протокол OAuth (2LO).
В потоке авторизации 2LO:
- The developer запрашивает токен доступа, используя служебный ключ.
- The developer использует токен доступа при вызовах API.
Дополнительную информацию о Google 2LO и настройке см. в разделе Использование OAuth 2.0 для межсерверных приложений .
Авторизация
Учетная запись службы должна быть авторизована для использования с API Pub/Sub:
- Включите API Cloud Pub/Sub в Google Cloud.
- Создайте учётную запись службы и ключ учётной записи службы, как описано в разделе Создание учётной записи службы . Мы рекомендуем назначить ей только роль подписчика Pub/Sub . Обязательно загрузите ключ учётной записи службы на компьютер, который будет использовать API Pub/Sub.
- Предоставьте свои учетные данные для аутентификации (ключ учетной записи службы) в коде приложения, следуя инструкциям на странице в предыдущем шаге, или получите токен доступа вручную с помощью
oauth2l
, если вы хотите быстро протестировать доступ к API. - Используйте учетные данные учетной записи службы или токен доступа с API Pub/Sub
project.subscriptions
для извлечения и подтверждения сообщений.
oauth2l
Google oauth2l
— это инструмент командной строки для OAuth, написанный на Go. Установите его на Mac или Linux с помощью Go.
- Если на вашей системе нет Go, сначала загрузите и установите его .
- После установки Go установите
oauth2l
и добавьте его расположение в переменную средыPATH
:go install github.com/google/oauth2l@latest
export 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-platform
ya29.c.Elo4BmHXK5...
Дополнительную информацию об использовании см. в файле README oauth2l
.
Клиентские библиотеки Google API
Для API Google, использующих OAuth 2.0, доступно несколько клиентских библиотек. Подробнее о выбранном вами языке см. в разделе «Клиентские библиотеки API Google».
При использовании этих библиотек с Pub/Sub API, используйте следующие строки области действия:
https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
Ошибки
В отношении данного руководства могут быть возвращены следующие коды ошибок:
Сообщение об ошибке | RPC | Поиск неисправностей |
---|---|---|
Изображение с камеры больше не доступно для загрузки. | DEADLINE_EXCEEDED | Изображения событий удаляются через 30 секунд после публикации. Обязательно загрузите изображение до истечения срока действия. |
Идентификатор события не принадлежит камере. | FAILED_PRECONDITION | Используйте правильный eventID , возвращаемый событием камеры. |
Полный список кодов ошибок API см. в Справочнике кодов ошибок API.