Sự kiện

Các sự kiện không đồng bộ và do Google Cloud Pub/Sub quản lý, thuộc một chủ đề duy nhất cho mỗi Project. Sự kiện cung cấp bản cập nhật cho tất cả thiết bị và cấu trúc, đồng thời đảm bảo nhận được sự kiện, miễn là người dùng chưa thu hồi mã truy cập 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 API SDM. 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 hoạt động của Pub/Sub. Cụ thể:

Gói thuê bao sự kiện

Khi sự kiện được bật cho Project, bạn sẽ nhận được một chủ đề dành riêng cho mã Project đó, dưới dạng:

projects/sdm-prod/topics/enterprise-project-id

Để nhận sự kiện, hãy tạo một gói thuê bao pull hoặc push cho chủ đề đó, tuỳ thuộc vào trường hợp sử dụng của bạn. Hỗ trợ nhiều gói thuê bao về chủ đề SDM. Hãy xem bài viết Quản lý gói thuê bao để biết thêm thông tin.

Bắt đầu sự kiện

Để bắt đầu 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 lệ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ẽ được xuất bản 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ự biên nhận của các sự kiện có thể không tương ứng với thứ tự mà các sự kiện thực sự diễn ra. Sử dụng trường timestamp để hỗ trợ điều chỉnh thứ tự sự kiện. Các sự kiện cũng có thể được gửi 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 phần Đặt hàng thông báo.

Mã nhận dạng người dùng

Nếu cách triển khai 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 để liên kết tài nguyên và sự kiện. Trường này là một mã nhận dạng bị làm rối mã nguồ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ệ biểu thị nội dung cập nhật quan hệ cho 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ó ba loại sự kiện liên quan:

  • TẠO
  • DELETED (ĐÃ XOÁ)
  • ĐÃ CẬP NHẬT

Tải trọng cho một sự kiện liên quan như sau:

Dung lượng

{
  "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"
}

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, user đã cấp quyền truy cập vào thiết bị cụ thể này cho developervà thiết bị được uỷ quyền của userhiện liên quan đến cấu trúc được uỷ quyền của họ, cấu trúc 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, thì subject sẽ luôn trống.

Trường

Trường Nội dung mô tả Loại dữ liệu
eventId Giá trị nhận dạng duy nhất của sự kiện. string
Ví dụ: "1362476b-4ac4-4608-a8be-4c8cf4101426"
timestamp Thời gian xảy ra sự kiện. string
Ví dụ: "2019-01-01T00:00:01Z"
relationUpdate Đối tượng cung cấp thông tin chi tiết về việc cập nhật mối quan hệ. object
userId Giá trị nhận dạng duy nhất, bị làm rối mã nguồn đại diện cho người dùng. string
Ví 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 khác nhau và cách hoạt động của các sự kiện đó.

Ví dụ

Tải trọng sự kiện thay đổi tuỳ theo loại sự kiện liên quan:

ĐÃ 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"
}

DELETED (ĐÃ XOÁ)

Đã 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 mối 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 biểu thị nội dung cập nhật cụ thể cho một tài nguyên. Dữ liệu này có thể để phản hồi khi có thay đổi về giá trị của trường trait, chẳng hạn như thay đổi chế độ của máy điều nhiệt. Thao tác này cũng có thể biểu thị một thao tác trên thiết bị không làm thay đổi trường trait, chẳng hạn như nhấn vào nút thiết bị.

Một sự kiện được tạo để phản hồi thay đổi trong giá trị của trường trait sẽ chứa đối tượng traits, tương tự như lệnh gọi GET của thiết bị:

Dung lượng

{
  "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"
  ]
}

Hãy sử dụng tài liệu về đặc điểm riêng lẻ để hiểu định dạng tải trọng cho mọi sự kiện thay đổi tài nguyên về trường trait.

Một sự kiện được tạo để phản hồi hành động trên thiết bị không làm thay đổi trường trait cũng có tải trọng với đối tượng resourceUpdate, nhưng với đối tượng events thay vì đối tượng traits:

Dung lượng

{
  "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" ] }

Các loại sự kiện tài nguyên này được xác định theo các đặc điểm cụ thể. Ví dụ: Sự kiện chuyển động được xác định trong thuộc tính CameraMotion . Hãy xem tài liệu về từng tính năng để 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 Nội dung mô tả Loại dữ liệu
eventId Giá trị nhận dạng duy nhất của sự kiện. string
Ví dụ: "3426d266-406b-48f3-9595-5192229a39a0"
timestamp Thời gian xảy ra sự kiện. string
Ví dụ: "2019-01-01T00:00:01Z"
resourceUpdate Một đối tượng cung cấp thông tin chi tiết về việc cập nhật tài nguyên. object
userId Giá trị nhận dạng duy nhất, bị làm rối mã nguồn đại diện cho người dùng. string
Ví dụ: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"
eventThreadId Giá trị nhận dạng duy nhất cho chuỗi sự kiện. string
Ví dụ: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59"
eventThreadState Trạng thái của chuỗi sự kiện. string
Giá trị: "STARTED", "UPDATED", "ENDED"
resourceGroup Một đối tượng cho biết những tài nguyên có thể có nội dung cập nhật tương tự đối với sự kiện này. Tài nguyên của chính sự kiện đó (từ đối tượng resourceUpdate) sẽ luôn xuất hiện 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 khác nhau và cách hoạt động của các sự kiện đó.

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 tính năng có tên là thông báo có thể cập nhật, trong đó các thông báo hiện có được cập nhật thông tin mới dựa trên các sự kiện tiếp theo trong cùng một chuỗi sự kiện.

Chọn lựa chọn hỗ trợ tính năng sự kiện cho các thông báo có thể cập nhật và được gắn thẻ là Có thể cập nhật  trong tài liệu. Những sự kiện này có thêm một trường tên là eventThreadId trong tải trọng của chúng. Hãy sử dụng trường này để liên kết các sự kiện riêng lẻ với nhau nhằm cập nhật một thông báo hiện đã hiển thị cho người dùng.

Chuỗi sự kiện không giống với một 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 với nhau, và có thể có nhiều chuỗi sự kiện cho một phiên sự kiện nhất định.

Nhằm mục đích thông báo, các loại sự kiện khác nhau được nhóm thành các chuỗi khác nhau.

Việc nhóm luồng và logic thời gian này do Google xử lý và 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 API SDM 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ó trường eventThreadState cho biết trạng thái của chuỗi sự kiện tại thời điểm đó. Trường này có các giá trị sau:

  • BẮT ĐẦU — Sự kiện đầu tiên trong chuỗi sự kiện.
  • UPDATED — Một sự kiện trong chuỗi sự kiện đang diễn ra. Có thể không có hoặc nhiều sự kiện có trạng thái này trong một luồng.
  • ĐÃ KẾT THÚC – Sự kiện cuối cùng trong một chuỗi sự kiện, có thể trùng lặp với sự kiện ĐÃ CẬP NHẬT gần đây nhất, tùy thuộc vào loại chuỗi.

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 luồng đó đã 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 bỏ để không phát hành sang chủ đề SDM Pub/Sub. Hành vi này được gọi là lọc sự kiện. Mục đích của tính năng 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 xuất bản lên một chủ đề SDM cho sự kiện Chuyển động ban đầu. Sau đó, các thông báo khác cho Chuyển động sẽ bị lọc ra khỏi quá trình phát hành cho đến khi một khoảng thời gian nhất định 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 sẽ vẫn hiển thị trong lịch sử sự kiện của user. Tuy nhiên, các sự kiện đó sẽ không tạo thông báo của ứ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. Logic này 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 luồng sự kiện và logic phiê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ý các gói thuê bao API SDM và thông báo sự kiện. Tài khoản dịch vụ được một ứng dụng hoặc máy ảo sử dụng, chứ không phải một người, đồng thời có khoá tài khoản duy nhất của riêng mình.

Hoạt động uỷ quyền tài khoản dịch vụ cho API Pub/Sub sử dụng OAuth hai bên (2LO).

Trong quy trình uỷ quyền 2LO:

  • developer yêu cầu mã truy cập bằng khoá dịch vụ.
  • 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 phần Sử dụng OAuth 2.0 cho các ứng dụng từ máy chủ đến máy chủ.

Ủy quyền

Tài khoản dịch vụ phải được uỷ quyền để sử dụng với API Pub/Sub:

  1. Bật API Cloud Pub/Sub trong Google Cloud.
  2. 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 vai trò Người đăng ký Pub/Sub. Hãy nhớ tải khoá tài khoản dịch vụ xuống máy sẽ sử dụng API Pub/Sub.
  3. 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 trong bước trước, hoặc nhận mã truy cập theo cách thủ công bằng oauth2l, nếu bạn muốn kiểm thử nhanh quyền truy cập vào API.
  4. 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 API project.subscriptions Pub/Sub để lấy 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. Hãy cài đặt công cụ này cho máy Mac hoặc Linux bằng Go.

  1. Nếu bạn chưa có ứng dụng Go trên hệ thống của mình, hãy tải xuống và cài đặt ứng dụng này trước tiên.
  2. Sau khi cài đặt Go, hãy cài đặt oauth2l và thêm vị trí của ứng dụng đó vào PATH biến môi trường:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Sử dụng oauth2l để nhận mã truy cập cho API bằng cách dùng(các) phạm vi OAuth thích hợp:
    oauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub
    https://www.googleapis.com/auth/cloud-platform
    Ví dụ: nếu khoá dịch vụ của bạn nằm ở ~/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...

Hãy xem phần 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 cho những API của Google sử dụng OAuth 2.0. Hãy xem Thư viện ứng dụng API của Google để biết thêm thông tin về ngôn ngữ mà 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

Liên quan đến hướng dẫn này, có thể trả về(các) mã lỗi sau:

Thông báo lỗi RPC Khắc phục sự cố
Không tải được hình ảnh trong máy ảnh xuống nữa. DEADLINE_EXCEEDED Hình ảnh sự kiện sẽ hết hạn sau 30 giây kể từ khi sự kiện được xuất bản. Hãy nhớ tải hình ảnh xuống trước khi hết hạn.
Mã sự kiện không thuộc về máy ảnh. FAILED_PRECONDITION Sử dụng đúng eventID do sự kiện máy ảnh 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.