Мероприятия

События асинхронны и управляются Google Cloud Pub/Sub, в одной теме для каждого. Project. События обеспечивают обновления для всех устройств и структур, и получение событий гарантировано до тех пор, пока токен доступа не отозван пользователем и срок действия сообщений о событиях не истек.

Включить события

События — это дополнительная функция SDM API. Видеть Включить события чтобы узнать, как включить их для вашего Project.

Google Cloud Pub/Sub

Дополнительную информацию о том, как работает Pub/Sub, см . в документации Google Cloud Pub/Sub . В частности:

Подписка на события

Когда события включены для вашего Project, вам будет предоставлена ​​тема, специфичная для этого Project Идентификатор в виде:

projects/sdm-prod/topics/enterprise-project-id

Чтобы получать события, создайте подписку по запросу или принудительную подписку на эту тему, в зависимости от вашего варианта использования. Поддерживаются несколько подписок на тему SDM. Дополнительную информацию см. в разделе «Управление подписками» .

Инициировать события

Чтобы инициировать события в первый раз после создания подписки Pub/Sub, выполните вызов API devices.list в качестве однократного триггера. События для всех структур и устройств будут опубликованы после этого вызова.

Пример см. на странице «Авторизация» в Кратком руководстве.

Порядок событий

Pub/Sub не гарантирует упорядоченную доставку событий, а порядок получения событий может не соответствовать порядку, в котором события фактически произошли. Используйте поле timestamp , чтобы облегчить согласование порядка событий. События также могут поступать по отдельности или объединяться в одно сообщение о событии.

Дополнительную информацию см. в разделе «Упорядочение сообщений» .

Идентификаторы пользователей

Если ваша реализация основана на пользователях (а не на структуре или устройстве), используйте поле userID из полезных данных события для корреляции ресурсов и событий. Это поле представляет собой запутанный идентификатор, представляющий конкретного пользователя.

userID также доступен в заголовке ответа HTTP каждого вызова API.

События отношений

События связи представляют собой реляционное обновление ресурса. Например, когда устройство добавляется в структуру или когда устройство удаляется из структуры.

Существует три типа событий отношений:

  • СОЗДАННЫЙ
  • УДАЛЕНО
  • ОБНОВЛЕНО

Полезная нагрузка для события отношения следующая:

Полезная нагрузка

{
  "eventId" : "d5c0f0bd-de65-44fd-ac60-686c302e56eb",
  "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
Пример: «64b87b46-1aec-42a4-8c01-997a407814df»
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" : "a88bc884-d2b8-42d6-adba-b7be92c232a3",
  "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" : "4f80de08-1b77-42a4-b33e-40876a2a1865",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "MWJ253hZMPAsJZJWbrGM4ThsKM...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

Эти типы событий ресурса определяются в конкретных признаках. Например, событие Motion определено в КамераДвижение черта. См. документацию по каждому признаку, чтобы понять формат полезной нагрузки для этих типов событий ресурса.

Поля

Поле Описание Тип данных
eventId Уникальный идентификатор события. string
Пример: «4f80de08-1b77-42a4-b33e-40876a2a1865»
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:

  1. Включите Cloud Pub/Sub API в Google Cloud.
  2. Создайте учетную запись службы и ключ учетной записи службы, как описано в разделе Создание учетной записи службы . Мы рекомендуем предоставить ему только роль подписчика Pub/Sub . Обязательно загрузите ключ сервисной учетной записи на компьютер, который будет использовать API Pub/Sub.
  3. Предоставьте свои учетные данные для аутентификации (ключ учетной записи службы) в код вашего приложения, следуя инструкциям на странице предыдущего шага, или получите токен доступа вручную с помощью oauth2l , если вы хотите быстро протестировать доступ к API.
  4. Используйте учетные данные учетной записи службы или токен доступа с API Pub/Sub project.subscriptions для получения и подтверждения сообщений.

oauth2l

Google oauth2l — это инструмент командной строки для OAuth, написанный на Go. Установите его для Mac или Linux с помощью Go.

  1. Если в вашей системе нет Go, сначала загрузите и установите его .
  2. После установки Go установите oauth2l и добавьте его местоположение в переменную среды PATH :
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Используйте 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.