События асинхронны и управляются Google Cloud Pub/Sub, в одной теме для каждого. Project. События обеспечивают обновления для всех устройств и структур, и получение событий гарантировано до тех пор, пока токен доступа не отозван пользователем и срок действия сообщений о событиях не истек.
Включить события
События — это дополнительная функция SDM API. Видеть Включить события чтобы узнать, как включить их для вашего Project.
Google Cloud Pub/Sub
Дополнительную информацию о том, как работает Pub/Sub, см . в документации Google Cloud Pub/Sub . В частности:
- Изучите основы Pub/Sub с помощью практических руководств .
- Поймите, как работает аутентификация .
- Выберите предоставленную клиентскую библиотеку или напишите свою собственную и используйте поверхности API REST/HTTP или gRPC .
Подписка на мероприятие
Когда события включены для вашего Project, вам будет предоставлена тема, специфичная для этого Project Идентификатор в виде:
projects/sdm-prod/topics/enterprise-project-id
Чтобы получать события, создайте подписку по запросу или принудительную подписку на эту тему, в зависимости от вашего варианта использования. Поддерживаются несколько подписок на тему SDM. Дополнительную информацию см. в разделе «Управление подписками» .
Инициировать события
Чтобы инициировать события в первый раз после создания подписки Pub/Sub, выполните вызов API devices.list
в качестве однократного триггера. После этого вызова будут опубликованы события для всех структур и устройств.
Пример см. на странице «Авторизация» в Кратком руководстве.
Порядок событий
Pub/Sub не гарантирует упорядоченную доставку событий, а порядок получения событий может не соответствовать порядку, в котором события фактически произошли. Используйте поле timestamp
, чтобы облегчить согласование порядка событий. События также могут поступать индивидуально или объединяться в одно сообщение о событии.
Дополнительную информацию см. в разделе «Упорядочение сообщений» .
Идентификаторы пользователей
Если ваша реализация основана на пользователях (а не на структуре или устройстве), используйте поле userID
из полезных данных события для корреляции ресурсов и событий. Это поле представляет собой запутанный идентификатор, представляющий конкретного пользователя.
userID
также доступен в заголовке ответа HTTP каждого вызова API.
События отношений
События связи представляют собой реляционное обновление ресурса. Например, когда устройство добавляется в структуру или когда устройство удаляется из структуры.
Существует три типа событий отношений:
- СОЗДАННЫЙ
- УДАЛЕНО
- ОБНОВЛЕНО
Полезная нагрузка для события отношения следующая:
Полезная нагрузка
{ "eventId" : "5c384ea4-5513-449f-b25d-56f71bed1dce", "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 Пример: «1d1d64ec-38d7-4627-ae2d-e71bbf448c7d» |
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" : "e258ed14-5388-40d6-afbb-25cd75cefb7c",
"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" : "08dce5d6-18ff-4c58-95ae-03fea62ebeaa",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "g1RdQ1nQKLcBQLatWGbhI8rzDo...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
Эти типы событий ресурса определяются в конкретных признаках. Например, событие Motion определено в КамераДвижение черта. См. документацию по каждому признаку, чтобы понять формат полезной нагрузки для этих типов событий ресурса.
Поля
Поле | Описание | Тип данных |
---|---|---|
eventId | Уникальный идентификатор события. | string Пример: «08dce5d6-18ff-4c58-95ae-03fea62ebeaa» |
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
, которое указывает состояние потока событий в данный момент времени. Это поле имеет следующие значения:
- STARTED — первое событие в потоке событий.
- ОБНОВЛЕНО — событие в текущей цепочке событий. В одном потоке может быть ноль или более событий с этим состоянием.
- ENDED — последнее событие в потоке событий, которое может быть дубликатом последнего события UPDATED, в зависимости от типа потока.
Это поле можно использовать для отслеживания хода потока событий и момента его завершения.
Фильтрация событий
В некоторых случаях события, обнаруженные устройством, могут быть отфильтрованы при публикации в теме SDM Pub/Sub. Такое поведение называется фильтрацией событий . Цель фильтрации событий — избежать публикации слишком большого количества похожих сообщений о событиях за короткий промежуток времени.
Например, сообщение может быть опубликовано в теме SDM для начального события Motion. Остальные сообщения для 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:
- Включите Cloud Pub/Sub API в 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. См . Клиентские библиотеки 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 см. в Справочнике кодов ошибок API.