イベント

イベントは非同期で、 Projectごとに 1 つのトピックで Google Cloud Pub/Sub によって管理されます。イベントはすべてのデバイスと構造にアップデートを提供し、ユーザーがアクセス トークンを取り消さず、イベント メッセージの有効期限が切れていない限り、イベントの受信は保証されます。

イベントを有効にする

イベントは、SDM API のオプション機能です。 Projectでイベントを有効にする方法については、 イベントを有効にする をご覧ください。

Google Cloud Pub/Sub

Pub/Sub の仕組みの詳細については、Google Cloud Pub/Sub のドキュメントをご覧ください。具体的には、次のとおりです。

イベント サブスクリプション

Projectでイベントを有効にすると、その Project ID に固有のトピックが次の形式で提供されます。

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

イベントを受信するには、ユースケースに応じて、そのトピックに pull または push サブスクリプションを作成します。SDM トピックへの複数のサブスクリプションがサポートされています。詳しくは、定期購入の管理をご覧ください。

イベントを開始する

Pub/Sub サブスクリプションの作成後にイベントを初めて開始するには、1 回限りのトリガーとして devices.list API 呼び出しを行います。この呼び出しの後に、すべてのストラクチャとデバイスのイベントが公開されます。

例については、クイック スタートガイドの承認ページをご覧ください。

イベントの順序

Pub/Sub はイベントの順序付けされた配信を保証するものではありません。イベントの受信順序は、イベントが実際に発生した順序と一致しない場合があります。timestamp フィールドは、イベントの順序の調整に役立ちます。イベントは、個別に到着することも、単一のイベント メッセージに結合されて到着することもできます。

詳細については、メッセージの順序指定をご覧ください。

ユーザー ID

実装が(構造やデバイスではなく)ユーザーに基づいている場合は、イベント ペイロードの userID フィールドを使用して、リソースとイベントを関連付けます。このフィールドは、特定のユーザーを表す難読化された ID です。

userID は、各 API 呼び出しの HTTP レスポンス ヘッダーでも使用できます。

関係イベント

リレーション イベントは、リソースのリレーショナル更新を表します。たとえば、デバイスがストラクチャに追加された場合や、デバイスがストラクチャから削除されている場合などです。

リレーション イベントには次の 3 種類があります。

  • CREATED
  • DELETED
  • 更新済み

リレーション イベントのペイロードは次のとおりです。

ペイロード

{
  "eventId" : "c99e8d92-99e5-4b87-8d75-0336bcfb0dfe",
  "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 はイベントをトリガーしたリソースであり、subjectobject がリレーションを持つリソースです。上記の例では、 user がこの特定のデバイスへのアクセスを developerに付与し、 userの承認済みデバイスがその承認済み構造に関連付けられ、イベントがトリガーされます。

subject に指定できるのは、部屋またはストラクチャのみです。 userの構造を表示する権限が a developer に付与されていない場合、subject は常に空になります。

フィールド

項目 説明 データの種類
eventId イベントの一意の識別子。 string
例: 「f8ef1ed6-91e8-418b-807a-4d7960a54a24」
timestamp イベントが発生した時刻。 string
例: 「2019-01-01T00:00:01Z」
relationUpdate リレーションの更新に関する詳細情報を含むオブジェクト。 object
userId ユーザーを表す、難読化された一意の識別子。 string
例: 「AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi」

さまざまな種類のイベントとその仕組みについて詳しくは、イベントをご覧ください。

イベント ペイロードは、リレーション イベントのタイプごとに異なります。

CREATED

ストラクチャを作成しました

"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"
}

DELETED

ストラクチャを削除しました

"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"
}

次の場合、リレーション イベントは送信されません。

  • 部屋が削除された

リソース イベント

リソース イベントは、リソースに固有の更新を表します。サーモスタットのモードの変更など、トレイト フィールドの値の変化に対応できます。 デバイス ボタンを押すなど、トレイト フィールドを変更しないデバイス アクションを表すこともできます。

トレイト フィールドの値の変更に応じて生成されるイベントには、デバイスの GET 呼び出しと同様に、traits オブジェクトが含まれます。

ペイロード

{
  "eventId" : "478a1e7b-502d-4aef-a5a5-0a6145c9c266",
  "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 オブジェクトを含むペイロードが含まれますが、traits オブジェクトではなく events オブジェクトが含まれます。

ペイロード

{
  "eventId" : "bd9e7098-83fb-4eb2-b0d2-fed8fde1b235",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "bmDabQeKfbw8GpDxsIjsD0yJJl...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

これらのタイプのリソース イベントは、特定のトレイトで定義されます。たとえば、モーション イベントは、 CameraMotion トレイトで定義されます。これらのタイプのリソース イベントのペイロード形式については、各トレイトのドキュメントをご覧ください。

フィールド

項目 説明 データの種類
eventId イベントの一意の識別子。 string
例: 「bd9e7098-83fb-4eb2-b0d2-fed8fde1b235」
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 などのアプリに実装できます。送信される通知の数を減らすために、「更新可能な通知」と呼ばれる機能が実装されます。この機能では、同じイベント スレッドの後続のイベントに基づいて、既存の通知が新しい情報で更新されます。

一部のイベント機能では更新可能な通知がサポートされており、ドキュメントでは更新可能 とタグ付けされています。これらのイベントのペイロードには、eventThreadId という追加フィールドがあります。このフィールドを使用して、ユーザーに表示される既存の通知を更新する目的で、個々のイベントをリンクします。

イベント スレッドはイベント セッションとは異なります。イベント スレッドは、同じスレッド内の以前のイベントについて、更新されたステータスを識別します。イベント セッションは、互いに関連する個別のイベントを識別します。特定のイベント セッションには複数のイベント スレッドが存在する場合があります。

通知を目的として、さまざまなタイプのイベントが別々のスレッドにグループ化されます。

このスレッドのグループ化とタイミングのロジックは Google によって処理され、随時変更される可能性があります。 developer は、SDM API によって提供されるイベント スレッドとセッションに基づいて通知を更新する必要があります。

スレッドの状態

更新可能な通知をサポートするイベントには、その時点でのイベント スレッドの状態を示す eventThreadState フィールドもあります。このフィールドには次の値があります。

  • STARTED - イベント スレッドの最初のイベント。
  • UPDATED - 進行中のイベント スレッド内のイベント。1 つのスレッドに、この状態のイベントが 0 個以上存在する可能性があります。
  • ENDED - イベント スレッドの最後のイベント。スレッドの種類によっては、最後の UPDATED イベントと重複する場合があります。

このフィールドを使用して、イベント スレッドの進行状況と終了タイミングを追跡できます。

イベント フィルタリング

場合によっては、デバイスによって検出されたイベントが、SDM Pub/Sub トピックへのパブリッシュから除外されることがあります。この動作は、イベント フィルタリングと呼ばれます。イベントをフィルタリングする目的は、短期間に多数の類似したイベント メッセージをパブリッシュしすぎないようにすることです。

たとえば、最初のモーション イベントのメッセージを SDM トピックにパブリッシュできます。その後のモーションに関する他のメッセージは、一定期間が経過するまで公開から除外されます。その期間が過ぎると、そのイベントタイプのイベント メッセージが再度パブリッシュされます。

Google Home アプリ(GHA)では、フィルタされたアクティビティは引き続き userのアクティビティ履歴に表示されます。ただし、このようなイベントでは、アプリ通知は生成されません(通知タイプが有効になっていても)。

イベントのタイプごとに、独自のイベント フィルタリング ロジックがあります。このロジックは Google によって定義されており、いつでも変更される可能性があります。このイベント フィルタリング ロジックは、イベント スレッドとセッション ロジックに依存しません。

サービス アカウント

サービス アカウントは、SDM API サブスクリプションとイベント メッセージの管理に推奨されます。サービス アカウントは、ユーザーではなくアプリケーションまたは仮想マシンによって使用され、固有のアカウント キーがあります。

Pub/Sub API のサービス アカウント認証では、Two-legged OAuth(2LO)を使用します。

2LO 承認フローでは、次のようになります。

  • developer はサービスキーを使用してアクセス トークンをリクエストします。
  • developer は、API の呼び出しでアクセス トークンを使用します。

Google 2LO の詳細と設定方法については、サーバー間アプリケーションでの OAuth 2.0 の使用をご覧ください。

認可

サービス アカウントに Pub/Sub API の使用を承認する必要があります。

  1. Google Cloud で Cloud Pub/Sub API を有効にします
  2. サービス アカウントの作成の説明に従って、サービス アカウントとサービス アカウント キーを作成します。Pub/Sub サブスクライバーのロールのみ付与することをおすすめします。Pub/Sub API を使用するマシンに、サービス アカウント キーをダウンロードしてください。
  3. 前のステップのページの手順に沿って、認証情報(サービス アカウント キー)をアプリケーション コードに提供します。API アクセスを迅速にテストする場合は、oauth2l を使用してアクセス トークンを手動で取得します。
  4. Pub/Sub project.subscriptions API でサービス アカウントの認証情報またはアクセス トークンを使用して、メッセージを pull して確認応答を行います。

OAuth2l

Google oauth2l は、Go で作成された OAuth 用のコマンドライン ツールです。Go を使用して Mac または Linux にインストールします。

  1. システムに Go がインストールされていない場合は、ダウンロードしてインストールしてください。
  2. Go をインストールしたら、oauth2l をインストールし、その場所を PATH 環境変数に追加します。
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. oauth2l を使用して、適切な OAuth スコープを使用して API のアクセス トークンを取得します。
    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...

使用方法の詳細については、oauth2l README をご覧ください。

Google API クライアント ライブラリ

OAuth 2.0 を利用する Google API で使用できるクライアント ライブラリはいくつかあります。使用する言語の詳細については、Google API クライアント ライブラリをご覧ください。

Pub/Sub APIでこれらのライブラリを使用する場合は、次のスコープ文字列を使用します。

https://www.googleapis.com/auth/pubsub
https://www.googleapis.com/auth/cloud-platform

エラー

このガイドに関連して、次のエラーコードが返される場合があります。

エラー メッセージ RPC トラブルシューティング
カメラ画像はダウンロードできなくなりました。 DEADLINE_EXCEEDED イベント画像は、イベントの公開から 30 秒後に期限切れになります。有効期限が切れる前に、画像をダウンロードしてください。
アクティビティ ID はカメラのものではありません。 FAILED_PRECONDITION カメラ イベントから返された正しい eventID を使用します。

API エラーコードの完全なリストについては、API エラーコード リファレンスをご覧ください。