イベント

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

イベントを有効にする

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

Google Cloud Pub/Sub

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

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

2025 年 1 月より前に、 Projectでイベントが有効になっている場合は、その Project ID に固有のトピックが次の形式で 提供されます。

projects/gcp-project-name/subscriptions/topic-id
2025 年 1 月以降に作成されたプロジェクトでは、Pub/Sub トピックをセルフホストする必要があります。独自のトピック ID を指定する必要があります。詳しくは、 トピックを作成する をご覧ください。

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

イベントを開始する

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

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

イベントの順序

Pub/Sub はイベントの順序どおりの配信を保証しません。イベントの受信順序は、イベントが実際に発生した順序と一致しない場合があります 。timestamp フィールドを使用して、イベントの順序を調整します。イベントは個別に到着する場合もあれば、1 つのイベントメッセージにまとめられて到着する場合もあります。

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

ユーザー ID

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

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

関係者イベント

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

関係者イベントには次の 3 種類があります。

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

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

ペイロード

{
  "eventId" : "465db104-bacc-41df-88ec-2a9b1888c998",
  "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's の認可済みデバイスが認可済み ストラクチャに関連付けられ、イベントがトリガーされます。

subject は、チャットルームまたはストラクチャのみにできます。 が のストラクチャを表示する権限を持っていない場合、 は常に 空になります。 a developer usersubject

フィールド

フィールド 説明 データ型
eventId イベントの一意の識別子。 string
例: "d31091a1-4e8a-4600-87e1-943f93ad5ad0"
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" : "98d6b069-a607-4fea-8512-ce78b8d61458",
  "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" : "50ae838d-42fd-48b7-b46b-4c24f97787a5",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "fmLARdlpNMN9IiXyXjElNP1ZiI...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

フィールド

フィールド 説明 データ型
eventId イベントの一意の識別子。 string
例: "50ae838d-42fd-48b7-b46b-4c24f97787a5"
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 という追加のフィールドがあります。このフィールドを使用して、個々のイベントをリンクし、ユーザーに表示された既存の通知を更新します。

イベント スレッドはイベント セッションと同じではありません。 イベント スレッド は、同じスレッド内の以前のイベントの更新されたステータスを示します。イベント セッション は、互いに関連する個別のイベントを識別します。1 つのイベント セッションに複数のイベント スレッドが存在する可能性があります。

通知の目的で、さまざまな種類のイベントが異なるスレッドにグループ化されます。

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

スレッドの状態

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

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

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

イベント フィルタリング

デバイスで検出されたイベントが、SDM Pub/Sub トピックへのパブリッシュから除外されることがあります。この動作はイベント フィルタリング と呼ばれます。イベント フィルタリングの目的は、短時間に類似したイベント メッセージが大量にパブリッシュされるのを防ぐことです。

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

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

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

サービス アカウント

SDM API サブスクリプションとイベント メッセージの管理には、サービス アカウントを使用することをおすすめします。サービス アカウントは、ユーザーではなく、アプリケーションまたは仮想マシンによって使用され、独自の固有のアカウント キーを持ちます。

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

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

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

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 エラーコード リファレンスをご覧ください。