אירועים

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

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

אירועי יחס

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

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

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

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

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

{
  "eventId" : "19acd7f4-38ce-4c70-b9af-1c6579bb8494",
  "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 תמיד יהיה ריק.

שדות

Field תיאור סוג הנתונים
eventId המזהה הייחודי של האירוע. string
דוגמה: ‎3143d6a4-d205-49eb-b6eb-95a9020b3b66‎
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 של מכשיר:

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

{
  "eventId" : "7f985c81-619f-44eb-ba37-e138cd3f8ef2",
  "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"
  ]
}

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

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

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

{
  "eventId" : "2177931c-833e-4758-8123-27d1106738b9",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "fKBZlxiPAw-5cUTM7wTUzSwxBi...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

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

שדות

Field תיאור סוג הנתונים
eventId המזהה הייחודי של האירוע. string
דוגמה: ‎2177931c-833e-4758-8123-27d1106738b9‎
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 – האירוע הראשון בשרשור אירועים.
  • עודכן – אירוע בשרשור אירועים מתמשך. יכולים להיות אפס או יותר אירועים עם המצב הזה בשרשור יחיד.
  • הסתיים – האירוע האחרון בשרשור אירועים, שעשוי להיות כפולה של האירוע האחרון עם סטטוס 'עודכן', בהתאם לסוג השרשור.

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

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

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

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

שגיאות

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

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

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