אירועים

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

הפעל אירועים

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

Google Cloud Pub/Sub

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

הרשמה לאירועים

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

projects/gcp-project-name/subscriptions/topic-id
בפרויקטים שנוצרו אחרי ינואר 2025, צריך לארח את הנושאים ב-Pub/Sub באופן עצמאי ולציין מזהה נושא משלכם. מידע נוסף זמין במאמר בנושא יצירת נושא.

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

הפעלת אירועים

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

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

סדר האירועים

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

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

מזהי משתמשים

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

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

אירועים שקשורים למערכות יחסים

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

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

  • נוצר
  • נמחק
  • מעודכן

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

מטען ייעודי

{
  "eventId" : "81688b62-4f69-432f-bbe0-5270032f5466",
  "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
דוגמה: "4ec221c5-4cbc-4fd5-ae2e-6eebd1311876"
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" : "b5a3cb32-3ca8-4b0b-9510-c6a9e70f00f4",
  "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" : "803821e5-2626-41d5-8ea2-04b6fdb88f8c",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "HEQiFiTuneH7NJVZ-kHxnbZyU9...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

שדות

שדה תיאור סוג הנתונים
eventId המזהה הייחודי של האירוע. string
דוגמה: "803821e5-2626-41d5-8ea2-04b6fdb88f8c"
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. כדי להפחית את מספר ההתראות שנשלחות, יכול להיות שנשתמש בתכונה שנקראת התראות שניתנות לעדכון. התכונה הזו מאפשרת לעדכן התראות קיימות במידע חדש על סמך אירועים עוקבים באותו שרשור אירועים.

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

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

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

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

מצב השרשור

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

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

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

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

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

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

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

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

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

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

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

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

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

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

אישור

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

  1. מפעילים את Cloud Pub/Sub API ב-Google Cloud.
  2. יוצרים חשבון שירות ומפתח לחשבון השירות כמו שמתואר במאמר בנושא יצירת חשבון שירות. מומלץ להעניק לו רק את התפקיד Pub/Sub Subscriber. חשוב להוריד את המפתח של חשבון השירות למחשב שבו ישתמשו ב-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...

מידע נוסף על השימוש מופיע בoauth2lקובץ ה-README.

ספריות לקוח של 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 מופיעה רשימה מלאה של הקודים האלה.