События происходят асинхронно и управляются 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" : "fbe88f53-f438-4d79-8d8d-5aa8d8d19fdb",
"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Пример: "0a4575ea-fa72-40b1-8425-5ccd54bf266c" |
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" : "2b7896c6-e76c-4e9b-bc7c-2a9e00e97cea",
"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" : "c8e33f4d-69b1-4817-94ff-8d1484db39ae",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "2aatu_hTitMYORSm6BIk5cDlB2...",
}
}
}
"userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}Эти типы событий ресурсов определяются в конкретных характеристиках. Например, событие «Движение» определяется в CameraMotion Трейт. Чтобы понять формат полезной нагрузки для этих типов событий ресурсов, ознакомьтесь с документацией по каждому трейту.
Поля
| Поле | Описание | Тип данных |
|---|---|---|
eventId | Уникальный идентификатор события. | stringПример: "c8e33f4d-69b1-4817-94ff-8d1484db39ae" |
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 , которое указывает состояние потока событий в данный момент времени. Это поле принимает следующие значения:
- НАЧАЛО — Первое событие в цепочке событий.
- ОБНОВЛЕНО — событие в текущем потоке событий. В одном потоке может быть ноль или более событий с таким состоянием.
- ЗАВЕРШЕНО — Последнее событие в потоке событий, которое может быть дубликатом последнего события ОБНОВЛЕНО, в зависимости от типа потока.
Это поле можно использовать для отслеживания хода потока событий и момента его завершения.
Фильтрация событий
В некоторых случаях события, обнаруженные устройством, могут быть отфильтрованы и не допущены к публикации в теме SDM Pub/Sub. Это называется фильтрацией событий . Цель фильтрации событий — предотвратить публикацию слишком большого количества похожих сообщений о событиях за короткий промежуток времени.
Например, сообщение может быть опубликовано в теме SDM для первоначального события Motion. Дальнейшие сообщения о движении будут отфильтрованы и не будут опубликованы до истечения заданного периода времени. По истечении этого периода сообщение о событии для этого типа может быть опубликовано снова.
В приложении Google Home (GHA) отфильтрованные события по-прежнему будут отображаться. userИстория событий. Однако такие события не генерируют уведомление приложения (даже если этот тип уведомления включен).
Каждый тип событий имеет собственную логику фильтрации, определяемую Google и могущую быть измененной в любое время. Эта логика фильтрации событий не зависит от потока событий и логики сеанса.
Служебные счета
Учётные записи служб рекомендуются для управления подписками на API SDM и сообщениями о событиях. Учётная запись службы используется приложением или виртуальной машиной, а не пользователем, и имеет собственный уникальный ключ.
Авторизация учетной записи службы для API Pub/Sub использует двухсторонний протокол OAuth (2LO).
В потоке авторизации 2LO:
- Он developer запрашивает токен доступа, используя служебный ключ.
- Он 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@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, доступно несколько клиентских библиотек. Подробнее о выбранном вами языке см. в разделе «Клиентские библиотеки 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.