Мероприятия

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

Информация о мероприятиях

События – это необязательная функция SDM API. Подробнее о том, как включить события, рассказывается в разделе Project.

Google Cloud Pub/Sub

Подробнее о том, как работает Pub/Sub, можно узнать из документации по Google Cloud Pub/Sub. В их числе:

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

До января 2025 г., если в вашем Projectбыли включены события, вам предоставлялась тема, размещенная на серверах Google и относящаяся к этому Project идентификатору, в следующем формате:

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

Теперь все проекты должны размещать темы Pub/Sub в собственном проекте Google Cloud (обязательно для новых проектов с января 2025 года и для всех существующих проектов с 30 ноября 2026 года) в следующем формате:

projects/gcp-project-name/subscriptions/topic-id

Если в вашем project облачном проекте Google Cloud уже используется тема с самостоятельным размещением, никаких действий не требуется. При переносе конфигурации темы издателя-подписчика существующие токены доступа пользователей и разрешения OAuth не аннулируются. Для тем и подписок с собственным хостингом действуют стандартные цены на Google Cloud Pub/Sub (включая бесплатный уровень с 10 ГБ в месяц). Подробнее о том, как создать тему…

Чтобы получать события, создайте pull- или push-подписку на эту тему в зависимости от вашего варианта использования. Поддерживается несколько подписок на тему SDM. Подробнее о том, как управлять подписками…

Инициирование событий

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

Пример можно найти на странице Авторизация в кратком руководстве по началу работы.

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

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

Подробнее о порядке сообщений…

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

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

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

События, связанные с отношениями

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

Существует три типа событий, связанных с отношениями:

  • CREATED
  • УДАЛЕНО
  • ОБНОВЛЕНО

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

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

{
  "eventId" : "5f28060e-8070-4b08-ab45-352671707d08",
  "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. В приведенном выше примере пользователь a user предоставил доступ к устройству пользователю developer, и авторизованное устройство пользователя userтеперь связано с его авторизованной структурой, что и вызывает событие.

subject может быть только комнатой или структурой. Если у a developer нет разрешения на просмотр структуры user, тоsubjectвсегда будет пустым.

Поля

Поле Описание Тип данных
eventId Уникальный идентификатор события. string
Пример: "53157f06-edcd-4410-849e-c01213a3cc8f"
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" : "ecb859f4-8d05-462a-9f62-4bc4209dee1f",
  "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" : "e119b073-90f3-45a2-9495-3879a5464867",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "fB2zl25FPHuqehIWZiXbmdMY9c...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

Поля

Поле Описание Тип данных
eventId Уникальный идентификатор события. string
Пример: "e119b073-90f3-45a2-9495-3879a5464867"
timestamp Время, когда произошло событие. string
Пример: "2019-01-01T00:00:01Z"
resourceUpdate Объект, содержащий подробную информацию об обновлении ресурса. object
userId Уникальный зашифрованный идентификатор, представляющий пользователя. string
Пример: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"
eventThreadId Уникальный идентификатор цепочки событий. string
Пример: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59"
eventThreadState Состояние цепочки событий. string
Значения: "STARTED", "UPDATED", "ENDED".
resourceGroup Объект, указывающий на ресурсы, которые могут иметь похожие обновления для этого события. Ресурс самого события (из объекта resourceUpdate) всегда будет присутствовать в этом объекте. object

Подробнее о типах событий и их работе…

Уведомления с возможностью обновления

Уведомления на основе событий ресурсов можно реализовать в приложении, например для Android или iOS. Чтобы уменьшить количество отправляемых уведомлений, может быть реализована функция обновляемых уведомлений, при которой существующие уведомления обновляются новой информацией на основе последующих событий в той же цепочке событий.

События, поддерживающие обновляемые уведомления, отмечены в документации тегом Updateable . В полезной нагрузке этих событий есть дополнительное поле eventThreadId. Используйте это поле, чтобы связать отдельные события и обновить существующее уведомление, которое было показано пользователю.

Цепочка событий – это не то же самое, что сеанс события. Цепочка событий содержит обновленный статус предыдущего события в той же цепочке. Сеанс события позволяет идентифицировать отдельные события, связанные друг с другом. В рамках одного сеанса может быть несколько цепочек событий.

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

Группировка цепочек и логика времени выполняются Google и могут быть изменены в любое время. Приложение A developer должно обновлять уведомления на основе цепочек событий и сеансов, предоставленных SDM API.

Состояние цепочки

События, поддерживающие обновляемые уведомления, также имеют поле eventThreadState, в котором указано состояние цепочки событий на определенный момент времени. Это поле может принимать следующие значения:

  • STARTED – первое событие в цепочке событий.
  • UPDATED – событие в цепочке событий. В одном потоке может быть ноль или более событий с таким статусом.
  • ENDED – последнее событие в цепочке событий. В зависимости от типа цепочки может быть дубликатом последнего события UPDATED.

Это поле можно использовать, чтобы отслеживать ход цепочки событий и ее завершение.

Фильтрация событий

В некоторых случаях события, обнаруженные устройством, могут быть отфильтрованы и не опубликованы в теме издатель-подписчик SDM. Такое поведение называется фильтрацией событий. Фильтрация событий позволяет избежать публикации слишком большого количества похожих сообщений о событиях за короткий промежуток времени.

Например, сообщение может быть опубликовано в теме SDM для исходного события движения. Другие сообщения от Motion будут отфильтровываться и не публиковаться в течение определенного периода времени. По истечении этого периода сообщение о событии этого типа может быть опубликовано снова.

В приложении Google Home отфильтрованные события по-прежнему будут показываться в истории событий user. Однако такие события не вызывают уведомлений приложения (даже если этот тип уведомлений включен).

Для каждого типа событий используется собственная логика фильтрации, которая определяется Google и может быть изменена в любое время. Эта логика фильтрации событий не зависит от потока событий и логики сеанса.

Сервисные аккаунты

Для управления подписками на SDM API и сообщениями о событиях рекомендуется использовать сервисные аккаунты. Сервисный аккаунт используется приложением или виртуальной машиной, а не человеком, и имеет собственный уникальный ключ.

Для авторизации сервисного аккаунта в API Pub/Sub используется двухсторонний протокол OAuth (2LO).

При двухэтапной авторизации:

  • developer запрашивает токен доступа с помощью сервисного ключа.
  • developer использует токен доступа при вызовах API.

Подробнее о двухэтапной авторизации Google и ее настройке рассказывается в статье Использование OAuth 2.0 для серверных приложений.

Авторизация

Сервисный аккаунт должен быть авторизован для использования с Pub/Sub API:

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

oauth2l

Google oauth2l – это инструмент командной строки для OAuth, написанный на языке Go. Установите его для macOS или 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.