Các sự kiện là không đồng bộ và do Google Cloud Pub/Sub quản lý, trong một chủ đề duy nhất cho mỗi Project. Các sự kiện cung cấp thông tin cập nhật cho tất cả các thiết bị và cấu trúc, đồng thời đảm bảo nhận được sự kiện miễn là mã truy cập không bị người dùng thu hồi và thông báo sự kiện chưa hết hạn.
Bật sự kiện
Sự kiện là một tính năng không bắt buộc của SDM API. Hãy xem Bật sự kiện để tìm hiểu cách bật sự kiện cho Project.
Google Cloud Pub/Sub
Hãy xem tài liệu về Google Cloud Pub/Sub để tìm hiểu thêm về cách Pub/Sub hoạt động. Cụ thể:
- Tìm hiểu những điều cơ bản về Pub/Sub bằng hướng dẫn Cách thực hiện.
- Tìm hiểu cách hoạt động của tính năng Xác thực.
- Chọn Thư viện ứng dụng do chúng tôi cung cấp hoặc tự viết thư viện của riêng bạn và sử dụng các giao diện REST/HTTP hoặc gRPC API.
Đăng ký sự kiện
Trước tháng 1 năm 2025, nếu bạn đã bật sự kiện cho Project, thì bạn sẽ được cung cấp một chủ đề dành riêng cho Project ID đó, ở dạng:
projects/gcp-project-name/subscriptions/topic-id
Để nhận sự kiện, hãy tạo gói thuê bao kéo hoặc đẩy cho chủ đề đó, tuỳ thuộc vào trường hợp sử dụng của bạn. Chúng tôi hỗ trợ nhiều gói thuê bao cho chủ đề SDM. Hãy xem Quản lý gói thuê bao để biết thêm thông tin.
Khởi tạo sự kiện
Để khởi tạo sự kiện lần đầu tiên sau khi tạo gói thuê bao Pub/Sub, hãy thực hiện lệnh gọi API
devices.list
dưới dạng trình kích hoạt một lần. Các sự kiện cho tất cả cấu trúc và thiết bị sẽ phát hành sau lệnh gọi này.
Để xem ví dụ, hãy xem trang Uỷ quyền trong Hướng dẫn bắt đầu nhanh.
Thứ tự sự kiện
Pub/Sub không đảm bảo việc phân phối sự kiện theo thứ tự và thứ tự nhận sự kiện có thể không
tương ứng với thứ tự mà sự kiện thực sự xảy ra. Sử dụng trường timestamp
để hỗ trợ việc đối chiếu thứ tự sự kiện. Các sự kiện cũng có thể đến riêng lẻ hoặc kết hợp
thành một thông báo sự kiện duy nhất.
Để biết thêm thông tin, hãy xem Sắp xếp thông báo.
Mã nhận dạng người dùng
Nếu quá trình triển khai của bạn dựa trên người dùng (thay vì cấu trúc hoặc thiết bị), hãy sử dụng trường
userID từ tải trọng sự kiện để tương quan tài nguyên và sự kiện. Trường này là
một mã nhận dạng bị làm xáo trộn, đại diện cho một người dùng cụ thể.
userID cũng có trong tiêu đề phản hồi HTTP của mỗi lệnh gọi API.
Sự kiện quan hệ
Sự kiện quan hệ đại diện cho một bản cập nhật quan hệ đối với một tài nguyên. Ví dụ: khi một thiết bị được thêm vào một cấu trúc hoặc khi một thiết bị bị xoá khỏi một cấu trúc.
Có 3 loại sự kiện quan hệ:
- ĐÃ TẠO
- ĐÃ XÓA
- ĐÃ CẬP NHẬT
Tải trọng cho một sự kiện quan hệ như sau:
Tải trọng
{
"eventId" : "84527b4c-13ed-479c-a756-21b9bb4111b5",
"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"
}Trong một sự kiện quan hệ, object là tài nguyên đã kích hoạt sự kiện và
subject là tài nguyên mà object hiện có mối quan hệ. Trong
ví dụ ở trên, một user đã cấp quyền truy cập vào thiết bị cụ thể này cho một
developer, và thiết bị được uỷ quyền của user' hiện có liên quan đến cấu trúc được uỷ quyền
của họ, điều này sẽ kích hoạt sự kiện.
subject chỉ có thể là một phòng hoặc một cấu trúc. Nếu a developer không có
quyền xem cấu trúc của user's, thì subject sẽ luôn
trống.
Trường
| Trường | Mô tả | Loại dữ liệu |
|---|---|---|
eventId |
Giá trị nhận dạng riêng biệt của sự kiện. | stringVí dụ: "d3c2bcb3-6588-4747-a65c-07c7f50a482d" |
timestamp |
Thời điểm sự kiện xảy ra. | stringVí dụ: "2019-01-01T00:00:01Z" |
relationUpdate |
Một đối tượng cung cấp thông tin chi tiết về bản cập nhật quan hệ. | object |
userId |
Giá trị nhận dạng riêng biệt, bị làm xáo trộn, đại diện cho người dùng. | stringVí dụ: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
Hãy xem phần Sự kiện để biết thêm thông tin về các loại sự kiện và cách hoạt động của chúng.
Ví dụ
Tải trọng sự kiện khác nhau đối với từng loại sự kiện quan hệ:
ĐÃ TẠO
Đã tạo cấu trúc
"relationUpdate" : {
"type" : "CREATED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Đã tạo thiết bị
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Đã tạo thiết bị
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}ĐÃ CẬP NHẬT
Đã di chuyển thiết bị
"relationUpdate" : {
"type" : "UPDATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}ĐÃ XÓA
Đã xoá cấu trúc
"relationUpdate" : {
"type" : "DELETED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Đã xoá thiết bị
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Đã xoá thiết bị
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}Sự kiện quan hệ không được gửi khi:
- Một phòng bị xoá
Sự kiện tài nguyên
Sự kiện tài nguyên đại diện cho một bản cập nhật dành riêng cho một tài nguyên. Sự kiện này có thể là phản hồi cho sự thay đổi về giá trị của một trường đặc điểm, chẳng hạn như thay đổi chế độ của máy điều nhiệt. Sự kiện này cũng có thể đại diện cho một hành động của thiết bị không làm thay đổi trường đặc điểm, chẳng hạn như nhấn nút thiết bị.
Một sự kiện được tạo để phản hồi cho sự thay đổi về giá trị của trường đặc điểm chứa một
traits đối tượng, tương tự như lệnh gọi GET thiết bị:
Tải trọng
{
"eventId" : "be30516f-e855-49fb-b50d-cbf031c81c30",
"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"
]
}Một sự kiện được tạo để phản hồi cho một hành động của thiết bị không làm thay đổi trường đặc điểm cũng có một
tải trọng với đối tượng resourceUpdate, nhưng có đối tượng events
thay vì đối tượng traits:
Tải trọng
{
"eventId" : "8e70e14f-bf37-4be0-bc85-8fd56b93b412",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "Qah4OySZOSvtiUbdpFWafiRTfI...",
}
}
}
"userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}Các loại sự kiện tài nguyên này được xác định trong các đặc điểm cụ thể. Ví dụ: sự kiện Chuyển động được xác định trong CameraMotion trait. Hãy xem tài liệu của từng đặc điểm để hiểu định dạng tải trọng cho các loại sự kiện tài nguyên này.
Trường
| Trường | Mô tả | Loại dữ liệu |
|---|---|---|
eventId |
Giá trị nhận dạng riêng biệt của sự kiện. | stringVí dụ: "8e70e14f-bf37-4be0-bc85-8fd56b93b412" |
timestamp |
Thời điểm sự kiện xảy ra. | stringVí dụ: "2019-01-01T00:00:01Z" |
resourceUpdate |
Một đối tượng cung cấp thông tin chi tiết về bản cập nhật tài nguyên. | object |
userId |
Giá trị nhận dạng riêng biệt, bị làm xáo trộn, đại diện cho người dùng. | stringVí dụ: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
eventThreadId |
Giá trị nhận dạng riêng biệt của luồng sự kiện. | stringVí dụ: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59" |
eventThreadState |
Trạng thái của luồng sự kiện. | stringGiá trị: "STARTED", "UPDATED", "ENDED" |
resourceGroup |
Một đối tượng cho biết các tài nguyên có thể có thông tin cập nhật tương tự cho sự kiện này. Tài nguyên của chính sự kiện (từ đối tượng resourceUpdate) sẽ luôn có trong đối tượng này. |
object |
Hãy xem phần Sự kiện để biết thêm thông tin về các loại sự kiện và cách hoạt động của chúng.
Thông báo có thể cập nhật
Bạn có thể triển khai thông báo dựa trên sự kiện tài nguyên trong một ứng dụng, chẳng hạn như cho Android hoặc iOS. Để giảm số lượng thông báo được gửi, bạn có thể triển khai một tính năng có tên là thông báo có thể cập nhật. Tính năng này sẽ cập nhật thông báo hiện có bằng thông tin mới dựa trên các sự kiện tiếp theo trong cùng một luồng sự kiện.Chọn tính năng hỗ trợ sự kiện cho thông báo có thể cập nhật và được gắn thẻ là
Có thể cập nhật eventThreadId trong tải trọng. Sử dụng trường này để liên kết các sự kiện riêng lẻ với nhau nhằm mục đích cập nhật một thông báo hiện có đã xuất hiện cho người dùng.
Luồng sự kiện không giống như phiên sự kiện. Luồng sự kiện xác định trạng thái cập nhật cho một sự kiện trước đó trong cùng một luồng. Phiên sự kiện xác định các sự kiện riêng biệt có liên quan đến nhau và có thể có nhiều luồng sự kiện cho một phiên sự kiện nhất định.
Đối với mục đích thông báo, các loại sự kiện khác nhau được nhóm thành các luồng khác nhau.
Google xử lý logic nhóm luồng và thời gian này, đồng thời có thể thay đổi bất cứ lúc nào. A developer phải cập nhật thông báo dựa trên các luồng và phiên sự kiện do SDM API cung cấp.
Trạng thái luồng
Các sự kiện hỗ trợ thông báo có thể cập nhật cũng có một trường eventThreadState cho biết trạng thái của luồng sự kiện tại thời điểm đó. Trường này có các giá trị sau:
- STARTED – Sự kiện đầu tiên trong một luồng sự kiện.
- UPDATED – Một sự kiện trong một luồng sự kiện đang diễn ra. Có thể có 0 hoặc nhiều sự kiện có trạng thái này trong một luồng.
- ENDED – Sự kiện cuối cùng trong một luồng sự kiện, có thể là bản sao của sự kiện UPDATED cuối cùng, tuỳ thuộc vào loại luồng.
Bạn có thể sử dụng trường này để theo dõi tiến trình của một luồng sự kiện và thời điểm kết thúc.
Lọc sự kiện
Trong một số trường hợp, các sự kiện do thiết bị phát hiện có thể bị lọc ra khỏi việc phát hành vào một chủ đề SDM Pub/Sub. Hành vi này được gọi là lọc sự kiện. Mục đích của việc lọc sự kiện là tránh phát hành quá nhiều thông báo sự kiện tương tự trong một khoảng thời gian ngắn.
Ví dụ: một thông báo có thể được phát hành vào một chủ đề SDM cho sự kiện Chuyển động ban đầu. Các thông báo khác cho Chuyển động sau đó sẽ bị lọc ra khỏi việc phát hành cho đến khi một khoảng thời gian đã đặt trôi qua. Sau khi khoảng thời gian đó trôi qua, thông báo sự kiện cho loại sự kiện đó có thể được phát hành lại.
Trong Ứng dụng Google Home (GHA), các sự kiện đã được lọc vẫn sẽ xuất hiện trong nhật ký sự kiện của user. Tuy nhiên, các sự kiện như vậy không tạo ra thông báo ứng dụng (ngay cả khi loại thông báo đó được bật).
Mỗi loại sự kiện có logic lọc sự kiện riêng, do Google xác định và có thể thay đổi bất cứ lúc nào. Logic lọc sự kiện này độc lập với logic luồng và phiên sự kiện.
Tài khoản dịch vụ
Bạn nên sử dụng tài khoản dịch vụ để quản lý gói thuê bao SDM API và thông báo sự kiện. Tài khoản dịch vụ do một ứng dụng hoặc máy ảo sử dụng, không phải do một người dùng sử dụng và có khoá tài khoản riêng biệt.
Quyền uỷ quyền tài khoản dịch vụ cho Pub/Sub API sử dụng OAuth hai bên (2LO).
Trong quy trình uỷ quyền 2LO:
- Yêu cầu mã truy cập bằng khoá dịch vụ. developer
- developer Sử dụng mã truy cập với các lệnh gọi đến API.
Để tìm hiểu thêm về Google 2LO và cách thiết lập, hãy xem Sử dụng OAuth 2.0 cho ứng dụng hoạt động giữa các máy chủ.
Ủy quyền
Bạn nên uỷ quyền cho tài khoản dịch vụ để sử dụng với Pub/Sub API:
- Bật Cloud Pub/Sub API trong Google Cloud.
- Tạo tài khoản dịch vụ và khoá tài khoản dịch vụ như mô tả trong phần Tạo tài khoản dịch vụ. Bạn chỉ nên cấp cho tài khoản này vai trò Người đăng ký Pub/Sub. Đảm bảo tải khoá tài khoản dịch vụ xuống máy sẽ sử dụng Pub/Sub API.
- Cung cấp thông tin xác thực (khoá tài khoản dịch vụ) cho mã xử lý ứng dụng của bạn bằng cách làm theo hướng dẫn trên trang ở bước trước hoặc lấy mã truy cập theo cách thủ công bằng
oauth2l, nếu bạn muốn nhanh chóng kiểm thử quyền truy cập API. - Sử dụng thông tin xác thực tài khoản dịch vụ hoặc mã truy cập với
Pub/Sub
project.subscriptionsAPI để kéo và xác nhận thông báo.
oauth2l
Google oauth2l là một công cụ dòng lệnh cho OAuth được viết bằng Go. Cài đặt công cụ này cho Mac hoặc Linux bằng Go.
- Nếu bạn chưa có Go trên hệ thống, hãy tải xuống và cài đặt trước.
- Sau khi cài đặt Go, hãy cài đặt
oauth2lvà thêm vị trí của công cụ này vào biến môi trườngPATH:go install github.com/google/oauth2l@latestexport PATH=$PATH:~/go/bin - Sử dụng
oauth2lđể lấy mã truy cập cho API, bằng cách sử dụng(các) phạm vi OAuth thích hợp: Ví dụ: nếu chìa khoá dịch vụ của bạn nằm tạioauth2l 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-platformya29.c.Elo4BmHXK5...
Hãy xem tệp README oauth2l để biết thêm thông tin về cách sử dụng.
Thư viện ứng dụng API của Google
Có một số thư viện ứng dụng dành cho các API của Google sử dụng OAuth 2.0. Hãy xem phần Thư viện ứng dụng API của Google để biết thêm thông tin về ngôn ngữ bạn chọn.
Khi sử dụng các thư viện này với Pub/Sub API, hãy sử dụng(các) chuỗi phạm vi sau:
https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
Lỗi
Bạn có thể nhận được(các) mã lỗi sau đây liên quan đến hướng dẫn này:
| Thông báo lỗi | RPC | Khắc phục sự cố |
|---|---|---|
| Không còn tải được hình ảnh camera xuống. | DEADLINE_EXCEEDED |
Hình ảnh sự kiện hết hạn sau 30 giây kể từ khi sự kiện được phát hành. Đảm bảo tải hình ảnh xuống trước khi hết hạn. |
| Mã sự kiện không thuộc về camera. | FAILED_PRECONDITION |
Sử dụng eventID chính xác do sự kiện do camera ghi lại trả về. |
Hãy xem Tài liệu tham khảo về mã lỗi API để biết danh sách đầy đủ các mã lỗi API.