События асинхронны и управляются 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" : "19acd7f4-38ce-4c70-b9af-1c6579bb8494", "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 Пример: «3143d6a4-d205-49eb-b6eb-95a9020b3b66» |
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" : "7f985c81-619f-44eb-ba37-e138cd3f8ef2",
"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" : "2177931c-833e-4758-8123-27d1106738b9",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "fKBZlxiPAw-5cUTM7wTUzSwxBi...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
Эти типы событий ресурса определяются в конкретных признаках. Например, событие Motion определено в КамераДвижение черта. См. документацию по каждому признаку, чтобы понять формат полезной нагрузки для этих типов событий ресурса.
Поля
Поле | Описание | Тип данных |
---|---|---|
eventId | Уникальный идентификатор события. | string Пример: «2177931c-833e-4758-8123-27d1106738b9» |
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.