האירועים הם אסינכרוניים ומנוהלים על ידי Google Cloud Pub/Sub, בנושא אחד לכל Project. אירועים מספקים עדכונים לכל המכשירים והמבנים, וקבלה של אירועים מובטחת כל עוד משתמש לא ביטל את אסימון הגישה ופג התוקף של הודעות האירוע.
הפעל אירועים
אירועים הם תכונה אופציונלית של SDM API. במאמר הפעלת אירועים כאן מוסבר איך להפעיל אותם ב- Project.
Google Cloud Pub/Sub
מידע נוסף על אופן הפעולה של Pub/Sub זמין במשאבי העזרה של Google Cloud Pub/Sub. הקפידו במיוחד על הדברים הבאים:
- מידע בסיסי על Pub/Sub מופיע במדריכים שלו.
- הסבר על אימות
- בוחרים ספריית לקוח או כותבים משלכם, ומשתמשים בפלטפורמות של API ל-REST/HTTP או ל-gRPC.
מינוי לאירוע
כשאירועים מופעלים עבור 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.
אירועי קשר
אירועי קשר מייצגים עדכון יחסי של משאב. לדוגמה, הוספה של מכשיר למבנה או מחיקת מכשיר ממבנה.
יש שלושה סוגים של אירועי קשר:
- נוצר
- נמחק
- מעודכן
המטען הייעודי (Payload) של אירוע קשור הוא:
מטען ייעודי (payload)
{ "eventId" : "fd72d3b3-41a3-42aa-a93c-84ff2aa346c3", "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 לדוגמה: '93e6ff86-3afd-4b52-9099-a29871dcf3c4' |
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" : "ffe48890-d114-401e-a0b0-44a17d54dc11",
"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) לכל אירוע של שינוי בשדה trait.
לאירוע שנוצר בתגובה לפעולה במכשיר שלא משנה את השדה trait יש גם מטען ייעודי (payload) עם אובייקט resourceUpdate
, אבל עם אובייקט events
במקום אובייקט traits
:
מטען ייעודי (payload)
{ "eventId" : "14bb7ac1-13ee-4439-9732-3adaaa5adc16",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion
" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "Vj1KmB9P-ZVR_V5KMINQsdyUKT...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }
סוגים אלה של אירועי משאבים מוגדרים בתכונות ספציפיות. לדוגמה, האירוע 'תנועה' מוגדר בתכונה CameraMotion . אפשר לעיין במסמכי התיעוד של כל תכונה כדי להבין את הפורמט של המטען הייעודי (Payload) לסוגים אלה של אירועי משאבים.
שדות
שדה | תיאור | סוג הנתונים |
---|---|---|
eventId |
המזהה הייחודי של האירוע. | string דוגמה: '14b7ac1-13ee-4439-9732-3adaaa5adc16' |
timestamp |
השעה שבה התרחש האירוע. | string לדוגמה: '2019-01-01T00:00:01Z' |
resourceUpdate |
אובייקט שמכיל מידע על עדכון המשאב. | object |
userId |
מזהה ייחודי ומעורפל שמייצג את המשתמש. | string דוגמה: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
eventThreadId |
המזהה הייחודי של השרשור. | string דוגמה: 'd67cd3f7-86a7-425e-8b3-462f92ec9f59' |
eventThreadState |
מצב השרשור של האירוע. | string ערכים: "STARTED", "UPDATED", "ENDED" |
resourceGroup |
אובייקט שמציין משאבים שייתכן שיש להם עדכונים דומים לאירוע הזה. המשאב של האירוע עצמו (מהאובייקט resourceUpdate ) תמיד יופיע באובייקט הזה. |
object |
מידע נוסף על סוגי האירועים השונים ועל אופן הפעולה שלהם מופיע במאמר אירועים.
התראות הניתנות לעדכון
אפשר להטמיע התראות על סמך אירועים של משאבים באפליקציה, למשל ב-Android או ב-iOS. כדי לצמצם את מספר ההתראות שנשלחות, צריך להטמיע תכונה שנקראת התראות הניתנות לעדכון, שבה ההתראות הקיימות מתעדכנות במידע חדש על סמך האירועים הבאים באותו שרשור של האירועים.אירועים נבחרים עם תמיכה בהתראות הניתנות לעדכון, והם מתויגים בתור עדכון eventThreadId
במטענים הייעודיים (payloads). אפשר להשתמש בשדה הזה כדי לקשר בין אירועים נפרדים כדי לעדכן התראה קיימת שהוצגה למשתמש.
שרשור של אירוע הוא לא סשן של אירוע. השרשור של האירוע מציין את הסטטוס המעודכן של אירוע קודם באותו השרשור. סשן של אירוע מזהה אירועים נפרדים שקשורים זה לזה, ויכול להיות מספר שרשורים של אירועים לכל סשן נתון של אירוע.
למטרות התראות, סוגים שונים של אירועים מקובצים לשרשורים שונים.
לוגיקת הקיבוץ והתזמון של השרשורים מטופלת על ידי Google, והיא עשויה להשתנות בכל שלב. developer צריך לעדכן את ההתראות על סמך השרשורים והסשנים של האירועים שמסופקים על ידי SDM API.
מצב השרשור
אירועים שתומכים בהתראות שניתן לעדכן כוללים גם את השדה eventThreadState
שמציין את מצב השרשור של האירוע באותה נקודת זמן. בשדה הזה מופיעים הערכים הבאים:
- התחיל – האירוע הראשון בשרשור של אירועים.
- עודכן – אירוע בשרשור של אירוע פעיל. בשרשור אחד יכולים להיות אפס אירועים או יותר במצב הזה.
- הסתיים – האירוע האחרון בשרשור של אירוע, שיכול להיות כפילות של האירוע האחרון שמעודכן, בהתאם לסוג השרשור.
אפשר להשתמש בשדה הזה כדי לעקוב אחרי ההתקדמות של שרשור אירוע ומתי הוא הסתיים.
סינון אירועים
בחלק מהמקרים, אירועים שזוהו על ידי מכשיר יסוננו כך שלא יפורסמו לנושא SDM Pub/Sub. ההתנהגות הזו נקראת סינון אירועים. מטרת סינון האירועים היא למנוע פרסום של יותר מדי הודעות אירועים דומות בפרק זמן קצר.
לדוגמה, יכול להיות שהודעה תפורסם בנושא SDM לאירוע ראשוני של תנועה. הודעות אחרות שיוצגו לאחר מכן ב'תנועה' מסוננות כך שלא יפורסמו עד לסיום פרק זמן מוגדר. כשפרק הזמן הזה יחלוף, יכול להיות שהודעת אירוע לסוג האירוע הזה תפורסם שוב.
באפליקציית Google Home (GHA), אירועים שסוננו עדיין יופיעו בהיסטוריית האירועים של user. עם זאת, אירועים כאלה לא יוצרים התראה באפליקציה (גם אם סוג ההתראה הזה מופעל).
לכל סוג של אירוע יש לוגיקה משלו לסינון אירועים, שמוגדרת על ידי Google וכפופה לשינויים בכל שלב. הלוגיקה הזו של סינון האירועים לא תלויה בלוגיקה של שרשור האירועים ובלוגיקת הסשן.
חשבונות שירות
מומלץ להשתמש בחשבונות שירות לניהול מינויים ל-SDM API והודעות על אירועים. חשבון שירות משמש אפליקציה או מכונה וירטואלית ולא של אדם, ויש לו מפתח חשבון ייחודי משלו.
בהרשאה באמצעות חשבון שירות ל-Pub/Sub API נעשה שימוש ב-OAuth דו-שלבי (2LO).
בתהליך ההרשאה של 2LO:
- התקבלה בקשה של developer לאסימון גישה באמצעות מפתח שירות.
- ה- developer משתמש באסימון הגישה עם קריאות ל-API.
למידע נוסף על Google 2LO ועל אופן ההגדרה, ראו שימוש ב-OAuth 2.0 לאפליקציות משרת לשרת.
אישור
לחשבון השירות צריכה להיות הרשאה לשימוש עם API של Pub/Sub:
- מפעילים את Cloud Pub/Sub API ב-Google Cloud.
- יוצרים חשבון שירות ומפתח של חשבון שירות, כפי שמתואר במאמר יצירת חשבון שירות. מומלץ להקצות לו רק את התפקיד מנוי ב-Pub/Sub. חשוב להוריד את המפתח של חשבון השירות למכונה שישתמשה ב-Pub/Sub API.
- מזינים את פרטי הכניסה לאימות (מפתח לחשבון השירות) לקוד האפליקציה לפי ההוראות שמופיעות בדף
בשלב הקודם, או מקבלים אסימון גישה באופן ידני באמצעות
oauth2l
, אם רוצים לבדוק את הגישה ל-API במהירות. - משתמשים בפרטי הכניסה של חשבון השירות או באסימון הגישה באמצעות Pub/Sub
project.subscriptions
API כדי לשלוף ולאשר הודעות.
Oauth2l
oauth2l
של Google הוא כלי שורת הפקודה OAuth שנכתב ב-Go. אפשר להתקין אותו ל-Mac או ל-Linux באמצעות Go.
- אם אפליקציית Go לא מותקנת במערכת, קודם מורידים ומתקינים אותה.
- לאחר ההתקנה של Go, מתקינים את
oauth2l
ומוסיפים את המיקום שלו למשתנה הסביבהPATH
:go install github.com/google/oauth2l@latest
export PATH=$PATH:~/go/bin
- משתמשים ב-
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.