イベント

イベントは非同期で、 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 フィールドを使用します。イベントは個別に届く場合もあれば、1 つのイベント メッセージにまとめられて届く場合もあります。

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

ユーザー ID

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

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

関係イベント

関係イベントは、リソースのリレーショナル アップデートを表します。たとえば、デバイスが構造に追加されたときや、デバイスが構造から削除されたときなどです。

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

  • CREATED
  • 削除済み
  • 更新済み

関係イベントのペイロードは次のとおりです。

ペイロード

{
  "eventId" : "926638ee-4fa4-4ea1-8f00-23855553f663",
  "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 は部屋または構造体にのみ使用できます。 a developer に userの構造を表示する権限がない場合、subject は常に空になります。

フィールド

フィールド 説明 データ型
eventId イベントの一意の識別子。 string
例: "6a94ce2f-ead3-491e-8a31-4526737ff8b3"
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"
}

削除済み

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

"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" : "c5ace1ca-01af-4e3d-a0bd-36d6126225a4",
  "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" : "51f7cf64-d4e4-494b-91ce-44a4ec99bacd",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "s8RAATfdUsmSe_kmdHF-sbwQ4_...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

フィールド

フィールド 説明 データ型
eventId イベントの一意の識別子。 string
例: 「51f7cf64-d4e4-494b-91ce-44a4ec99bacd」
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 - イベントスレッドの最初のイベント。
  • 更新済み - 進行中のスレッド内のイベント。1 つのスレッドに、この状態のイベントが 0 個以上存在する可能性があります。
  • 終了 - イベントスレッドの最後のイベント。スレッドの種類によっては、最後の更新イベントの重複になる場合があります。

このフィールドは、イベントスレッドの進行状況と終了時間を追跡するために使用できます。

イベント フィルタリング

デバイスで検出されたイベントが、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 エラーコードのリファレンスをご覧ください。