אירועים

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

הפעל אירועים

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

Google Cloud Pub/Sub

במסמכי התיעוד של Google Cloud Pub/Sub מוסבר איך Pub/Sub פועל. הקפידו במיוחד על הדברים הבאים:

מינוי לאירועים

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

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

מעכשיו, כל הפרויקטים צריכים לארח בעצמם את נושאי Pub/Sub בפרויקט בענן שלהם (חובה לפרויקטים חדשים החל מינואר 2025, וחובה לכל הפרויקטים הקיימים עד 30 בנובמבר 2026), בפורמט הבא:

projects/gcp-project-name/subscriptions/topic-id

אם project כבר משתמש בנושא באירוח עצמי בפרויקט בענן שלך ב-Google Cloud, אין צורך לבצע שום פעולה. העברת ההגדרות של נושא Pub/Sub לא מבטלת את תוקף טוקני הגישה הקיימים של המשתמשים או את הרשאות ה-OAuth. נושאים ומינויים באירוח עצמי כפופים לתמחור הסטנדרטי של Google Cloud Pub/Sub (שכולל תוכנית בחינם של 10GB לחודש). למידע נוסף, קראו את המאמר יצירת נושא.

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

אירועים של התחלת תהליך

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

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

סדר האירועים

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

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

מזהי משתמשים

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

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

אירועי קשרים

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

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

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

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

מטען ייעודי

{
  "eventId" : "1a2e13bc-c23c-4bc4-8366-6b5669607f0e",
  "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
דוגמה: "a121b435-e3bb-4ba1-9dea-945686b7dabf"
timestamp השעה שבה האירוע התרחש. ‫string
דוגמה: ‎"2019-01-01T00:00:01Z"‎
relationUpdate אובייקט שמפרט מידע על עדכון הקשר. object
userId מזהה ייחודי שעובר ערפול ומייצג את המשתמש. ‫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"
}

אירועי קשר לא נשלחים במקרים הבאים:

  • חדר נמחק

אירועים במשאבים

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

אירוע שנוצר בתגובה לשינוי בערך של שדה מאפיין מכיל אובייקט traits, בדומה לקריאת GET של מכשיר:

מטען ייעודי

{
  "eventId" : "caec1000-1cab-43d3-946f-bc3c5f8615c9",
  "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"
  ]
}

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

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

מטען ייעודי

{
  "eventId" : "0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "jOvQqNOSL76837k_JxTR4BJ6nw...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

שדות

שדה תיאור סוג נתונים
eventId המזהה הייחודי של האירוע. ‫string
דוגמה: "0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c"
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 מטפלת בלוגיקה של קיבוץ השרשורים והתזמון, והיא עשויה להשתנות בכל שלב. ‫A developer צריכה לעדכן את ההתראות על סמך השרשורים והסשנים של האירועים שסופקו על ידי SDM API.

מצב השרשור

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

  • ‫STARTED – האירוע הראשון בשרשור אירועים.
  • ‫UPDATED – אירוע בשרשור אירועים מתמשך. יכולים להיות אפס אירועים או יותר עם הסטטוס הזה בשרשור אחד.
  • ENDED — האירוע האחרון בשרשור אירועים, שיכול להיות כפילות של האירוע האחרון מסוג UPDATED, בהתאם לסוג השרשור.

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

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

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

לדוגמה, יכול להיות שתפורסם הודעה בנושא 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:

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

שגיאות

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

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

רשימה מלאה של קודי השגיאה של ה-API מפורטת בדף קודי השגיאה.