אירועים

האירועים הם אסינכרוניים ומנוהלים על ידי Google Cloud Pub/Sub, בנושא אחד לכל Project. אירועים מספקים עדכונים לכל המכשירים והמבנים, וקבלת אירועים מובטחת כל עוד המשתמש לא ביטל את אסימון הגישה והודעות האירוע עדיין בתוקף.

הפעל אירועים

אירועים הם תכונה אופציונלית של SDM API. כדאי לעיין במאמר הפעלת אירועים כדי ללמוד איך להפעיל אותם ב Project.

Google Cloud Pub/Sub

למידע נוסף על אופן הפעולה של Pub/Sub, עיינו במשאבי העזרה של Google Cloud Pub/Sub. הקפידו במיוחד על הדברים הבאים:

מינוי לאירוע

כשמפעילים אירועים עבור Project, תקבלו נושא ספציפי למזהה Project הזה, בפורמט של:

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

כדי לקבל אירועים, צריך ליצור מינוי pull או push לנושא הזה, בהתאם לתרחיש לדוגמה שלך. יש תמיכה במינויים מרובים לנושא SDM. למידע נוסף אפשר לעיין בניהול מינויים.

יצירת אירועים

כדי להתחיל אירועים בפעם הראשונה לאחר יצירת המינוי ל-Pub/Sub, יש לבצע קריאה ל-API של devices.list כטריגר חד-פעמי. אירועים של כל המבנים והמכשירים יפורסמו לאחר השיחה הזו.

לדוגמה, אפשר לעיין בדף Authorize במדריך למתחילים.

סדר האירוע

השימוש ב-Pub/Sub לא מבטיח שאירועים יישלחו בהתאם להזמנה, וייתכן שסדר הקבלה של אירועים לא יהיה תואם לסדר שבו האירועים התרחשו בפועל. אפשר להשתמש בשדה timestamp כדי לעזור בהתאמה של סדר האירועים. אירועים יכולים גם להגיע בנפרד או משולבים בהודעה אחת של אירוע.

למידע נוסף ראו הזמנת הודעות.

מזהי משתמשים

אם ההטמעה מבוססת על משתמשים (ולא על מבנה או מכשיר), אפשר להשתמש בשדה userID ממטען הייעודי (payload) של האירועים כדי להתאים בין משאבים לאירועים. השדה הזה הוא מזהה מעורפל שמייצג משתמש ספציפי.

השדה userID זמין גם בכותרת תגובת ה-HTTP של כל קריאה ל-API.

אירועי קשר

אירועי קשר מייצגים עדכון יחסי למשאב. לדוגמה, כשמוסיפים מכשיר למבנה או נמחק מכשיר ממבנה.

יש שלושה סוגים של אירועי קשר:

  • CREATED
  • נמחק
  • מעודכן

המטען הייעודי (payload) של אירוע קשר הוא:

מטען ייעודי (Payload)

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

בקטע אירועים אפשר לקרוא מידע נוסף על סוגי האירועים השונים ועל אופן הפעולה שלהם.

דוגמאות

מטענים ייעודיים (payloads) של אירועים משתנים בין כל סוג של אירוע קשר:

מועד היצירה

המבנה נוצר

"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 של מכשיר:

מטען ייעודי (Payload)

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

אפשר להיעזר במסמכי התיעוד בנושא traits בודדים כדי להבין את הפורמט של המטען הייעודי (payload) של כל אירוע של שינוי שדה trait.

לאירוע שנוצר בתגובה לפעולת מכשיר שלא משנה את שדה ה-trait יש גם מטען ייעודי (payload) עם אובייקט resourceUpdate, אבל עם אובייקט events במקום אובייקט traits:

מטען ייעודי (Payload)

{
  "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 . אפשר לעיין במסמכי התיעוד של כל תכונה כדי להבין את הפורמט של המטען הייעודי (payload) לסוגים האלה של אירועי משאבים.

שדות

שדה תיאור סוג הנתונים
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. כדי לצמצם את מספר ההתראות שנשלחות, יכול להיות שתטמיעו את התכונה התראות הניתנות לעדכון, וההתראות הקיימות מתעדכנות במידע חדש על סמך האירועים הבאים באותו שרשור אירועים.

אירועים נבחרים שתומכים בהתראות הניתנות לעדכון, והם מתויגים בתור ניתן לעדכון  בתיעוד. במטען הייעודי (payloads) של האירועים האלה יש שדה נוסף שנקרא eventThreadId. אפשר להשתמש בשדה הזה כדי לקשר אירועים נפרדים כדי לעדכן התראה קיימת שהוצגה למשתמש.

שרשור של אירוע הוא לא סשן של אירוע. שרשור האירוע מזהה סטטוס מעודכן של אירוע קודם באותו שרשור. סשן האירוע מזהה אירועים נפרדים שקשורים זה לזה, ויכולים להיות כמה שרשורי אירועים בכל סשן נתון של האירוע.

כדי לשלוח התראות, סוגים שונים של אירועים מקובצים בשרשורים שונים.

הלוגיקה של קיבוץ השרשורים והתזמון מנוהלים על ידי Google, ועשויה להשתנות בכל שלב. developer צריך לעדכן התראות על סמך שרשורי האירועים והסשנים שסופקו על ידי SDM API.

מצב השרשור

אירועים שתומכים בהתראות ניתנות לעדכון כוללים גם שדה eventThreadState שמציין את המצב של שרשור האירועים בנקודת הזמן הזו. לשדה הזה יש את הערכים הבאים:

  • התחיל – האירוע הראשון בשרשור של אירוע.
  • מעודכן – אירוע בשרשור של אירוע מתמשך. יכולים להיות אפס אירועים או יותר במצב הזה בשרשור אחד.
  • הסתיים – האירוע האחרון בשרשור של אירוע, שעשוי להיות עותק כפול של האירוע המעודכן האחרון, בהתאם לסוג השרשור.

אפשר להשתמש בשדה הזה כדי לעקוב אחרי ההתקדמות של שרשור אירוע ומתי הוא הסתיים.

סינון אירועים

במקרים מסוימים, יכול להיות שאירועים שזוהו על ידי מכשיר יסוננו ולא יפורסמו לנושא SDM Pub/Sub. ההתנהגות הזו נקראת סינון אירועים. המטרה של סינון אירועים היא למנוע פרסום יותר מדי הודעות של אירועים דומים בפרק זמן קצר.

לדוגמה, יכול להיות שהודעה תפורסם בנושא SDM בתגובה לאירוע תנועה ראשוני. הודעות אחרות שתושמע ב-Motion יסוננו כך שלא ניתן יהיה לפרסם אותן עד שיחלוף פרק זמן מוגדר. כשפרק הזמן הזה יחלוף, ייתכן שתפורסם שוב הודעת אירוע עבור אותו סוג אירוע.

באפליקציית Google Home (GHA), אירועים שסוננו עדיין יופיעו בהיסטוריית האירועים של user. עם זאת, אירועים כאלה לא יוצרים התראה באפליקציה (גם אם סוג ההתראות הזה מופעל).

לכל סוג של אירוע יש לוגיקה משלו לסינון אירועים, שאותה מגדירה Google ועשויה להשתנות בכל שלב. הלוגיקה של סינון האירועים לא תלויה בלוגיקת הסשן ובשרשור האירועים.

חשבונות שירות

מומלץ להשתמש בחשבונות שירות לניהול מינויים ל-SSD API והודעות על אירועים. חשבון שירות משמש אפליקציה או מכונה וירטואלית, ולא אדם, ויש לו מפתח חשבון ייחודי משלו.

הרשאה באמצעות חשבון שירות ל-Pub/Sub API משתמשת ב-OAuth דו-רגלי (2LO).

בתהליך ההרשאה של 2LO:

  • הקוד developer מבקש אסימון גישה באמצעות מפתח שירות.
  • הקוד developer משתמש באסימון הגישה עם הקריאות ל-API.

למידע נוסף על Google 2LO ועל אופן ההתקנה, קראו את המאמר שימוש ב-OAuth 2.0 לאפליקציות משרת לשרת.

אישור

לחשבון השירות צריכה להיות הרשאה לשימוש עם ה-Pub/Sub API:

  1. מפעילים את Cloud Pub/Sub API ב-Google Cloud.
  2. יוצרים חשבון שירות ומפתח לחשבון שירות, כמו שמתואר במאמר יצירת חשבון שירות. מומלץ לתת לו רק את התפקיד מנוי ב-Pub/Sub. הקפידו להוריד את המפתח של חשבון השירות למכונה שתשתמש ב-Pub/Sub API.
  3. כדי לבדוק במהירות את הגישה ל-API במהירות, מספקים את פרטי הכניסה לאימות (מפתח חשבון שירות) לפי ההוראות המפורטות בשלב הקודם. לחלופין, מקבלים אסימון גישה באופן ידני באמצעות oauth2l.
  4. משתמשים בפרטי הכניסה לחשבון השירות או באסימון הגישה עם Pub/Sub project.subscriptions API כדי לשלוף ולאשר הודעות.

Oauth2l

Google oauth2l הוא כלי שורת פקודה ל-OAuth שנכתב ב-Go. ניתן להתקין אותו ל-Mac או ל-Linux באמצעות Go.

  1. אם אפליקציית Go לא מותקנת במערכת שלכם, קודם צריך להוריד ולהתקין אותה.
  2. אחרי ההתקנה של Go, מתקינים את oauth2l ומוסיפים את המיקום שלו למשתנה הסביבה PATH:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. כדי לקבל אסימון גישה ל-API באמצעות oauth2l, צריך להשתמש בהיקפי ההרשאות המתאימים של OAuth:
    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...

למידע נוסף על השימוש, קראו את קובץ README של oauth2l.

ספריות לקוח של Google API

יש כמה ספריות לקוח שזמינות ל-Google APIs עם OAuth 2.0. למידע נוסף על השפה הרצויה, ראו ספריות לקוח של Google API.

כשמשתמשים בספריות האלה עם Pub/Sub API, צריך להשתמש במחרוזות הבאות של היקף:

https://www.googleapis.com/auth/pubsub
https://www.googleapis.com/auth/cloud-platform

שגיאות

ניתן להחזיר את קודי השגיאה הבאים בהקשר למדריך זה:

הודעת שגיאה הכנסה לקליק פתרון בעיות
תמונת המצלמה כבר לא זמינה להורדה. DEADLINE_EXCEEDED התוקף של תמונות אירוע פג 30 שניות לאחר פרסום האירוע. חשוב להקפיד להוריד את התמונה לפני תאריך התפוגה.
מזהה האירוע לא שייך למצלמה. FAILED_PRECONDITION צריך להשתמש בערך eventID הנכון שהוחזר על ידי אירוע המצלמה.

הרשימה המלאה של קודי השגיאות ב-API זמינה בחומר העזר בנושא קוד שגיאה ב-API.