イベントは非同期で、 Projectごとに 1 つのトピックで Google Cloud Pub/Sub によって管理されます。イベントはすべてのデバイスと構造にアップデートを提供し、ユーザーがアクセス トークンを取り消さず、イベント メッセージの有効期限が切れていない限り、イベントの受信は保証されます。
イベントを有効にする
イベントは、SDM API のオプション機能です。 Projectでイベントを有効にする方法については、 イベントを有効にする をご覧ください。
Google Cloud Pub/Sub
Pub/Sub の仕組みの詳細については、Google Cloud Pub/Sub のドキュメントをご覧ください。具体的には、次のとおりです。
- 入門ガイドで Pub/Sub の基本を確認する。
- 認証の仕組みを理解する。
- 用意されているクライアント ライブラリを選択するか、独自のライブラリを作成して REST/HTTP または gRPC API サーフェスを使用します。
イベント サブスクリプション
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" : "fd72d3b3-41a3-42aa-a93c-84ff2aa346c3", "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
に指定できるのは、部屋またはストラクチャのみです。 userの構造を表示する権限が a developer に付与されていない場合、subject
は常に空になります。
フィールド
項目 | 説明 | データの種類 |
---|---|---|
eventId |
イベントの一意の識別子。 | string 例: 「93e6ff86-3afd-4b52-9099-a29871dcf3c4」 |
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" : "ffe48890-d114-401e-a0b0-44a17d54dc11",
"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" : "14bb7ac1-13ee-4439-9732-3adaaa5adc16",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "Vj1KmB9P-ZVR_V5KMINQsdyUKT...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
これらのタイプのリソース イベントは、特定のトレイトで定義されます。たとえば、モーション イベントは、 CameraMotion トレイトで定義されます。これらのタイプのリソース イベントのペイロード形式については、各トレイトのドキュメントをご覧ください。
フィールド
項目 | 説明 | データの種類 |
---|---|---|
eventId |
イベントの一意の識別子。 | string 例: 「14bb7ac1-13ee-4439-9732-3adaaa5adc16」 |
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 の使用を承認する必要があります。
- Google Cloud で Cloud Pub/Sub API を有効にします。
- サービス アカウントの作成の説明に従って、サービス アカウントとサービス アカウント キーを作成します。Pub/Sub サブスクライバーのロールのみ付与することをおすすめします。Pub/Sub API を使用するマシンに、サービス アカウント キーをダウンロードしてください。
- 前のステップのページの手順に沿って、認証情報(サービス アカウント キー)をアプリケーション コードに提供します。API アクセスを迅速にテストする場合は、
oauth2l
を使用してアクセス トークンを手動で取得します。 - Pub/Sub
project.subscriptions
API でサービス アカウントの認証情報またはアクセス トークンを使用して、メッセージを pull して確認応答を行います。
OAuth2l
Google oauth2l
は、Go で作成された OAuth 用のコマンドライン ツールです。Go を使用して Mac または Linux にインストールします。
- システムに Go がインストールされていない場合は、ダウンロードしてインストールしてください。
- Go をインストールしたら、
oauth2l
をインストールし、その場所をPATH
環境変数に追加します。go install github.com/google/oauth2l@latest
export PATH=$PATH:~/go/bin
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 エラーコード リファレンスをご覧ください。