事件是非同步的,由 Google Cloud Pub/Sub 管理,每個 Project的單一主題都包含在一個主題中。事件會提供所有裝置和結構的更新,而且您可以確保收到事件,前提是使用者並未撤銷存取權杖,且事件訊息尚未過期。
啟用活動功能
「事件」是 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 訂閱項目後首次啟動事件,請將
devices.list
API 呼叫視為一次性觸發條件。所有結構和裝置的事件會在這次呼叫後發布。
如需範例,請參閱快速入門指南中的「授權」頁面。
事件順序
Pub/Sub 無法保證事件的傳送順序,事件的接收順序也不一定能對應至事件實際發生的順序。使用 timestamp
欄位協助協調事件順序。此外,事件也可以個別抵達或合併為單一事件訊息。
詳情請參閱「排序訊息」。
使用者 ID
如果您實作的是使用者 (而非結構或裝置),請使用事件酬載中的 userID
欄位,將資源和事件建立關聯。這個欄位是代表特定使用者的經模糊處理 ID。
每個 API 呼叫的 HTTP 回應標頭中也提供 userID
。
關聯事件
關聯事件代表資源的關聯更新。例如裝置在結構中新增,或裝置從結構中刪除時。
關係事件分為三種類型:
- 已建立
- 已刪除
- 已更新
關係事件的酬載如下:
酬載
{ "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 |
事件的專屬 ID。 | string 範例:「1362476b-4ac4-4608-a8be-4c8cf4101426」 |
timestamp |
事件發生的時間。 | string 範例:「2019-01-01T00:00:01Z」 |
relationUpdate |
詳細提供關係更新相關資訊的物件。 | object |
userId |
代表使用者的不重複 ID (經過模糊處理)。 | string 範例:「AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi」 |
如要進一步瞭解不同的事件類型及其運作方式,請參閱事件。
示例
每種關係事件的事件酬載都不同:
已建立
已建立結構
"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" }
在下列情況下,系統不會傳送關聯事件:
- 已刪除聊天室
資源事件
資源事件代表特定資源的更新。這種模式可因應特徵欄位的值變動,例如變更溫度控制器的模式。 也可以代表不會變更特徵欄位的裝置動作,例如按下裝置按鈕。
為回應 trait 欄位值的變更而產生的事件會包含 traits
物件,類似裝置的 GET 呼叫:
酬載
{
"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
物件的酬載,而是包含 events
物件,而非 traits
物件:
酬載
{ "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" ] }
這些類型的資源事件是以特定特徵定義。例如,動作事件是在 CameraMotion 特徵中定義。請參閱各特徵的說明文件,瞭解這些資源事件的酬載格式。
欄位
欄位 | 說明 | 資料類型 |
---|---|---|
eventId |
事件的專屬 ID。 | string 範例:「3426d266-406b-48f3-9595-5192229a39a0」 |
timestamp |
事件發生的時間。 | string 範例:「2019-01-01T00:00:01Z」 |
resourceUpdate |
提供資源更新詳細資訊的物件。 | object |
userId |
代表使用者的不重複 ID (經過模糊處理)。 | string 範例:「AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi」 |
eventThreadId |
事件執行緒的專屬 ID。 | string 範例:「d67cd3f7-86a7-425e-8bb3-462f92ec9f59」 |
eventThreadState |
事件執行緒的狀態。 | string 值:「STARTED」、「UPDATED」、「ENDED」 |
resourceGroup |
表示資源可能會與此事件更新類似的資源。事件本身的資源 (來自 resourceUpdate 物件) 一律會出現在這個物件中。 |
object |
如要進一步瞭解不同的事件類型及其運作方式,請參閱事件。
可更新的通知
以資源事件為基礎的通知可在應用程式中實作,例如 Android 或 iOS。為了減少傳送的通知數量,您可以實作名為「可更新的通知」的功能,讓現有通知會根據相同事件執行緒中的後續事件,根據新資訊進行更新。選取事件功能支援可更新的通知,並在說明文件中標記「可更新」eventThreadId
的額外欄位。使用這個欄位將個別事件連結在一起,以更新向使用者顯示的現有通知。
事件執行緒與事件工作階段不同。事件執行緒可辨識相同執行緒中前一個事件的更新狀態。事件工作階段可識別彼此相關的不同事件,而且特定事件時段可能會有多個事件執行緒。
基於通知目的,系統會將不同類型的事件歸為不同的執行緒。
這個執行緒分組和時間邏輯是由 Google 處理,且隨時可能變更。 developer 應根據 SDM API 提供的事件執行緒和工作階段更新通知。
執行緒狀態
支援可更新通知的事件也會有 eventThreadState
欄位,指出該時間點的事件執行緒狀態。這個欄位的值如下:
- STARTED:事件串中的第一個事件。
- 已更新 - 持續性事件討論串中的事件。單一執行緒中可能有零或多個包含此狀態的事件。
- 已結束 — 事件執行緒中的最後一個事件,視討論串類型而定,可能會與最近 UPDATED 事件重複。
這個欄位可用來追蹤事件執行緒的進度和結束時間。
事件篩選
在某些情況下,系統可能會篩除裝置偵測到的事件,而不發布至 SDM Pub/Sub 主題。這種行為稱為事件篩選。事件篩選功能的用意是避免在短時間內發布太多類似的事件訊息。
舉例來說,系統可能會將初始動作事件的訊息發布至 SDM 主題。之後的其他 Motion 訊息則會過濾掉,直到一定的發布時間為止。這段期間過後,系統可能會再次發布該事件類型的事件訊息。
在 Google Home 應用程式 (GHA) 中,篩除的事件仍會顯示在 user的事件記錄中。不過,即使已啟用該通知類型,這類事件也不會產生應用程式通知。
每種事件類型都有專屬的事件篩選邏輯,由 Google 定義,隨時可能有所變動。這個事件篩選邏輯與事件執行緒和工作階段邏輯無關。
服務帳戶
建議您使用服務帳戶來管理 SDM API 訂閱和事件訊息。服務帳戶是由應用程式或虛擬機器 (而非人員) 使用,並且具有專屬的帳戶金鑰。
Pub/Sub API 的服務帳戶授權使用雙足式 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 來提取及確認訊息。
OAuth2l
Google oauth2l
是以 Go 編寫 OAuth 的指令列工具,可透過 Go 安裝在 Mac 或 Linux 上。
- 如果您的系統尚未安裝 Go,請先下載並安裝 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 錯誤代碼參考資料。