イベントは非同期で、Google Cloud Pub/Sub によって Projectごとに 1 つのトピックで管理されます。イベントは、すべてのデバイスと構造の更新を提供します。ユーザーがアクセス トークンを取り消さず、イベント メッセージが期限切れになっていない限り、イベントの受信は保証されます。
イベントを有効にする
イベントは、SDM API のオプション機能です。 Projectでイベントを有効にする方法については、 イベントを有効にする をご覧ください。
Google Cloud Pub/Sub
Pub/Sub の仕組みについて詳しくは、Google Cloud Pub/Sub のドキュメントをご覧ください。具体的には、次のとおりです。
- 入門ガイドで Pub/Sub の基礎を学習する。
- Authentication の仕組みを理解する。
- 提供されているクライアント ライブラリを選択するか、独自のライブラリを作成して 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
フィールドは、イベントの順序の調整に役立ちます。イベントは個別に到着することも、1 つのイベント メッセージに結合することもできます。
詳細については、メッセージの並べ替えをご覧ください。
ユーザー ID
構造やデバイスではなく、ユーザーに基づいて実装する場合は、イベント ペイロードの userID
フィールドを使用して、リソースとイベントを関連付けます。このフィールドは、特定のユーザーを表す難読化された ID です。
userID
は、各 API 呼び出しの HTTP レスポンス ヘッダーでも使用できます。
関係イベント
リレーション イベントは、リソースのリレーショナル更新を表します。たとえば、デバイスがストラクチャに追加されたときや、ストラクチャからデバイスが削除された場合などです。
リレーション イベントには次の 3 つのタイプがあります。
- CREATED
- DELETED
- 更新済み
リレーション イベントのペイロードは次のとおりです。
ペイロード
{ "eventId" : "eed9763a-8735-45d9-81d9-e0621c130eb1", "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 例: 「1362476b-4ac4-4608-a8be-4c8cf4101426」 |
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" : "5b98a768-6771-4d4d-836d-58cce3a62cca",
"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" : "3426d266-406b-48f3-9595-5192229a39a0",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "8XZ1cQ76Becovj551YfM9ZnuwB...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
これらのタイプのリソース イベントは、特定のトレイトで定義されます。たとえば、Motion イベントは CameraMotion トレイトで定義されます。これらのタイプのリソース イベントのペイロード形式については、各トレイトのドキュメントをご覧ください。
フィールド
項目 | 説明 | データ型 |
---|---|---|
eventId |
イベントの一意の識別子。 | string 例: 「3426d266-406b-48f3-9595-5192229a39a0」 |
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 トピックにメッセージがパブリッシュされる場合があります。その後の Motion のその他のメッセージは、一定期間が経過するまで公開から除外されます。その期間が過ぎると、そのイベントタイプのイベント メッセージが再度パブリッシュされます。
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
- 適切な OAuth スコープ
を使用して、oauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
oauth2l
で API のアクセス トークンを取得します。たとえば、サービスキーが~/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 エラーコード リファレンスをご覧ください。