Мероприятия

События асинхронны и управляются 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" : "3a9bc513-0eb2-431a-8e31-b84300e44f35",
  "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
Пример: «b5ee6750-6c34-4e4a-b7e2-8ce795f70f36»
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" : "b9187564-6bde-4362-a6c8-247bb5d1ed59",
  "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" : "07402acf-d452-4c98-a942-d9f864ea3d45",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "OI7GLq3VM12UiIfl9HJ0hsvkL0...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

Поля

Поле Описание Тип данных
eventId Уникальный идентификатор события. string
Пример: «07402acf-d452-4c98-a942-d9f864ea3d45»
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.