ניפוי באגים בבית המקומי

1. לפני שמתחילים

השילובים של הבית החכם מאפשרים ל-Google Assistant לשלוט במכשירים המחוברים בתים. כדי ליצור פעולה לבית חכם, צריך לספק נקודת קצה (endpoint) של תגובה לפעולה מאתר אחר (webhook) בענן שיכולה לטפל בכוונות של בית חכם. למשל, כשמשתמש אומר, "Ok Google, turn on the lights" Assistant שולחת את הפקודה למילוי ההזמנות בענן כדי לעדכן את מצב המכשיר.

ה-Local Home SDK משפר את השילוב של הבית החכם. לשם כך, הוא מוסיף נתיב מקומי שמנתב כוונות לבית חכם ישירות למכשיר Google Home. כך ניתן לשפר את האמינות ולצמצם את זמן האחזור של עיבוד המשתמשים פקודות. היא מאפשרת לכתוב ולפרוס אפליקציית השלמה מקומית ב-TypeScript או ב-JavaScript, שמזהה מכשירים ומבצעת פקודות בכל רמקול חכם של Google Home או במסך חכם של Google Nest. לאחר מכן האפליקציה מתקשרת ישירות עם המשתמשים במכשירים חכמים קיימים ברשת האזור המקומית באמצעות פרוטוקולים סטנדרטיים קיימים לביצוע פקודות.

72ffb320986092c.png

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

דרישות מוקדמות

מה תפַתחו

ב-Codelab הזה, תיצרו מילוי הזמנות מקומי לפעולות של בית חכם ותחברו אותו ל-Assistant, ולאחר מכן תנפקו באגים באפליקציית 'Home Home' באמצעות חבילת הבדיקה לבית חכם מדדים ורישום ביומן של Google Cloud Platform (GCP).

מה תלמדו

  • איך משתמשים במדדים של GCP וברישום ביומן כדי לזהות ולפתור בעיות בסביבת הייצור.
  • איך משתמשים בכלי הבדיקה כדי לזהות בעיות פונקציונליות ובעיות ב-API.
  • איך משתמשים בכלי הפיתוח של Chrome במהלך הפיתוח של אפליקציית Home המקומית.

מה נדרש

2. הפעלה של אפליקציית מכונת הכביסה

קבלת קוד המקור

כדי להוריד את הדוגמה ל-codelab הזה למחשב הפיתוח, לוחצים על הקישור הבא:

...אפשר גם לשכפל את המאגר של GitHub משורת הפקודה:

$ git clone https://github.com/google-home/smarthome-debug-local.git

מידע על הפרויקט

האפליקציה לתחילת הפעולה מכילה ספריות משנה ופונקציות בענן דומות לאלה של הפעלת הקוד של ה-Codelab לפעולות בבית חכם. אבל במקום app-start, יש לנו כאן app-faulty. נתחיל עם אפליקציית דף בית מקומית שפועלת אבל לא כל כך טוב.

התחברות ל-Firebase

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

עוברים לספרייה app-faulty ומגדירים את ה-CLI של Firebase בפרויקט 'פעולות' שנוצר ב-codelab הפעלת מילוי הזמנות מקומי לפעולות בית חכם:

$ cd app-faulty
$ firebase use <project-id>

פריסה ב-Firebase

עוברים לתיקייה app-faulty/functions ומתקינים את כל הרכיבים התלויים הנדרשים באמצעות npm:

$ cd functions
$ npm install

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

found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

עוברים לספרייה app-faulty/local/ ומריצים את הפקודות הבאות כדי להוריד את המהדר של TypeScript ולעבד את האפליקציה:

$ cd ../local
$ npm install
$ npm run build

הפעולה הזו מהדרת את המקור index.ts (TypeScript) ומציבה את התוכן הבא בספרייה app-faulty/public/local-home/:

  • bundle.js – פלט של JavaScript שנוצר על ידי הידור, שכולל את האפליקציה המקומית ואת יחסי התלות.
  • index.html – דף אירוח מקומי המשמש להצגת האפליקציה לצורך בדיקות במכשיר.

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

$ firebase deploy

זהו הפלט במסוף שאמור להופיע:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<projectcd -id>.web.app

הפקודה הזו פורסת אפליקציית אינטרנט יחד עם כמה Cloud Functions for Firebase.

עדכון HomeGraph

פותחים את כתובת ה-URL של האירוח בדפדפן (https://<project-id>.web.app) כדי להציג את אפליקציית האינטרנט. בממשק המשתמש של האינטרנט, לוחצים על הלחצן רענון ae8d3b25777a5e30.png כדי לעדכן את HomeGraph באמצעות בקשת סנכרון עם המטא-נתונים העדכניים ביותר של המכשיר מאפליקציית הכביסה הפגומה:

fa3c47f293cfe0b7.png

פותחים את אפליקציית Google Home ומוודאים שאפשר לראות את מכונת הכביסה עם השם החדש 'מכונה פגומה'. חשוב לזכור להקצות את המכשיר לחדר שיש בו מכשיר Nest.

2a082ee11d47ad1a.png

3. הפעלת מכונת הכביסה החכמה

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

הפעלת המכשיר

עוברים לספרייה virtual-device/ ומריצים את סקריפט המכשיר, מעבירים את פרמטרים ההגדרה כארגומנטים:

$ cd ../../virtual-device
$ npm install
$ npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

יש לוודא שסקריפט המכשיר פועל עם הפרמטרים הצפויים:

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

4. בדיקת אפליקציית Home Home

לשלוח פקודות למכשיר באמצעות פקודות קוליות למכשיר Google Home, כמו:

"Hey Google, turn on my workher".

"Hey Google, start my worker".

"Ok Google, force local"

"Ok Google, stop my washer"

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

כלומר, אי אפשר לגשת למכשיר דרך נתיב מקומי. הוא עבד לפני שהפעלת את הפקודה "Ok Google, force local", כי אנחנו עוברים לשימוש בנתיב בענן כשאי אפשר לגשת למכשיר דרך נתיב מקומי. עם זאת, אחרי 'אילוץ מקומי', האפשרות לעבור לנתיב בענן מושבתת.

כדי לגלות מה הבעיה, נשתמש בכלים שלנו: Google Cloud Platform (GCP) מדדים ורישום ביומן וכלים למפתחים ב-Chrome.

5. ניפוי באגים באפליקציית Home המקומית

בקטע הבא תשתמשו בכלים של Google כדי לגלות למה לא ניתן להגיע למכשיר דרך הנתיב המקומי. אתם יכולים להשתמש בכלים למפתחים של Google Chrome כדי להתחבר למכשיר Google Home, להציג את יומני המסוף ולפתור באגים באפליקציית Home המקומית. אתם יכולים גם לשלוח יומנים מותאמים אישית אל Cloud Logging כדי לדעת מהן השגיאות הנפוצות ביותר שהמשתמשים מוצאים באפליקציית Home המקומית.

חיבור הכלים למפתחים ב-Chrome

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

  1. עליכם לוודא שקישרתם את מכשיר Google Home שלכם למשתמש עם הרשאת גישה לפרויקט Actions Console.
  2. עליך להפעיל מחדש את מכשיר Google Home כדי לקבל את כתובת ה-URL של ה-HTML וגם את הגדרות הסריקה שהזנת במסוף הפעולות.
  3. להפעיל את Chrome במחשב הפיתוח.
  4. פותחים כרטיסייה חדשה ב-Chrome ומזינים chrome://inspect בשדה הכתובת כדי להפעיל את הבודק.

אמורה להופיע בדף רשימה של מכשירים, וכתובת ה-URL של האפליקציה אמורה להופיע מתחת לשם של מכשיר Google Home.

567f97789a7d8846.png

הפעלת הכלי

לוחצים על בדיקה מתחת לכתובת ה-URL של האפליקציה כדי להפעיל את הכלים למפתחים של Chrome. בוחרים בכרטיסייה Console ומוודאים שתוכלו לראות את תוכן הכוונה IDENTIFY שנדפסה על ידי אפליקציית TypeScript.

774c460c59f9f84a.png

הפלט הזה אומר שה-handler של IDENTIFY הופעל בהצלחה, אבל ה-verificationId שהוחזר ב-IdentifyResponse לא תואם לאף אחד מהמכשירים ב-Home Graph. עכשיו נוסיף כמה יומנים מותאמים אישית כדי לגלות את הסיבה לכך.

הוספת יומנים מותאמים אישית

אמנם מוצגת שגיאה מסוג DEVICE_VERIFICATION_FAILED על ידי Local Home SDK, אבל היא לא עוזרת הרבה באיתור שורש הבעיה. נוסיף כמה יומנים מותאמים אישית כדי לוודא שאנחנו קוראים ומעבדים את נתוני הסריקה בצורה נכונה. חשוב לזכור שאם נדחה את ההבטחה עם שגיאה, הודעת השגיאה נשלחת גם ל-Cloud Logging.

local/index.ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device id.
  // Is there something wrong here?
  const localDeviceId = Buffer.from(scanData.data);
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  // Add custom logs
  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_device', 'Invalid device id from scan data ' +
        localDeviceId);
    return Promise.reject(err);
  }

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

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

local/index.ts

const localHomeSdk = new App('1.0.1');

אחרי שמוסיפים את היומנים המותאמים אישית, צריך לקמפל שוב את האפליקציה ולפרוס אותה מחדש ב-Firebase.

$ cd ../app-faulty/local
$ npm run build
$ firebase deploy --only hosting

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

ecc56508ebcf9ab.png

גישה ל-Cloud Logging

נראה איך משתמשים ב-Cloud Logging כדי למצוא את השגיאות. כדי לגשת ל-Cloud Logging בפרויקט:

  1. נכנסים לדף Projects במסוף Cloud Platform.
  2. בוחרים את הפרויקט לבית החכם.
  3. בקטע פעולות, בוחרים באפשרות רישום > Logs Explorer.

הגישה לנתוני הרישום ביומן מנוהלת באמצעות ניהול זהויות והרשאות גישה (IAM) למשתמשים בפרויקט Actions. מידע נוסף על תפקידים והרשאות לנתוני יומנים זמין במאמר בקרת גישה ב-Cloud Logging.

שימוש במסננים מתקדמים

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

לוחצים על המתג Show query, והוא אמור להפוך לתיבה Query builder. מזינים jsonPayload.intent="IDENTIFY" בתיבה Query Builder ולוחצים על הלחצן Run query.

4c0b9d2828ee2447.png

כתוצאה מכך, תקבלו את כל יומני השגיאות שיזרקו ב-handler של IDENTIFY. לאחר מכן, מרחיבים את השגיאה האחרונה. ב-handler‏ IDENTIFY תמצאו את הערכים של errorCode ו-debugString שהגדרתם כשדחיתם את ההבטחה.

71f2f156c6887496.png

מ-debugString ניתן לראות שמזהה המכשיר המקומי אינו בפורמט הצפוי. מזהה המכשיר המקומי מצפה לקבל את מזהה המכשיר המקומי כמחרוזת שמתחילה ב-deviceid ואחריה 3 ספרות, אבל מזהה המכשיר המקומי שכאן הוא מחרוזת הקסדצימלית.

תיקון השגיאה

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

local/index.ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device id.
  const localDeviceId = Buffer.from(scanData.data, 'hex');
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
      'invalid_device', 'Invalid device id from scan data ' +
      localDeviceId);
    return Promise.reject(err);
  }

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

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

local/index.ts

const localHomeSdk = new App('1.0.2');

אחרי שמתקנים את השגיאה, צריך להדר את האפליקציה ולפרוס אותה מחדש ב-Firebase. ב-app-faulty/local, מריצים את:

$ npm run build
$ firebase deploy --only hosting

בדיקת התיקון

אחרי הפריסה, צריך להפעיל מחדש את מכשיר Google Home כדי שהוא יוכל לטעון את אפליקציית הבית המקומית המעודכנת. עליך לוודא שהגרסה של אפליקציית דף הבית המקומית היא 1.0.2, והפעם לא אמורות להופיע שגיאות ב-Chrome Developers Console.

c8456f7b5f77f894.png

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

"Ok Google, forcelocal",

"Ok Google, stop my washer"

"Ok Google, turn on my washer"

...

"Ok Google, force default"

6. הפעלה של חבילת הבדיקה לבית חכם

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

הפעלה של חבילת הבדיקה לבית חכם

כדי לבדוק את הפעולה של הבית החכם באמצעות Test Suite, פועלים לפי ההוראות הבאות:

  1. בדפדפן האינטרנט, פותחים את חבילת הבדיקה לבית חכם.
  2. נכנסים לחשבון Google באמצעות הלחצן בפינה השמאלית העליונה. הפעולה הזו תאפשר לאפליקציית הבדיקה לשלוח את הפקודות ישירות אל Google Assistant.
  3. בשדה Project ID, מזינים את מזהה הפרויקט של הפעולה לבית החכם. אחר כך לוחצים על הבא כדי להמשיך.
  4. בשלב הגדרות הבדיקה, אתם אמורים לראות את מכונת הכביסה הפגומה בקטע מכשירים ומגשים.
  5. משביתים את האפשרות Test Request Sync (בדיקת סנכרון הבקשות) כי לאפליקציית מכונת הכביסה לדוגמה אין ממשק משתמש להוספה, להסרה או לשינוי השם של מכונת הכביסה. בסביבת ייצור, צריך להפעיל את האפשרות בקשת סנכרון בכל פעם שמשתמש מוסיף, מסיר מכשירים או משנה את השם שלהם.
  6. משאירים את האפשרות Local Home SDK מופעלת, כי אנחנו הולכים לבדוק גם נתיבים מקומיים וגם נתיבים בענן.
  7. לוחצים על השלב הבא: סביבת הבדיקה כדי להתחיל להריץ את הבדיקה.

67433d9190fa770e.png

כשהבדיקות יסתיימו, תוכלו לראות שהבדיקות 'השהיה' / 'המשך' בנתיב המקומי נכשלות בזמן שהבדיקות 'השהיה' / 'המשך' בנתיב הענן עוברות בהצלחה.

d1ebd5cfae2a2a47.png

ניתוח הודעת השגיאה

כדאי לבדוק לעומק את הודעות השגיאה בתרחישי הבדיקה שנכשלו. הם מאפשרים לדעת מה המצב הצפוי של הבדיקה ומה היה המצב בפועל. במקרה הזה, עבור 'השהיית מכונת הכביסה', המצב הצפוי הוא isPaused: true, אבל המצב בפועל הוא isPaused: false. באותו האופן, המצב הצפוי של 'השהיית מכונת הכביסה' הוא isPaused: true, אבל במצב בפועל קיבלנו isPaused: false.

6bfd3acef9c16b84.png

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

זיהוי ותיקון השגיאה

עכשיו נמצא את קוד המקור שאליו אפליקציית Home Home שולחת את פקודת הביצוע למכשיר. getDataCommand() היא הפונקציה שנקראת על ידי executeHandler() כדי להגדיר את payload בפקודת הביצוע שנשלחת למכשיר.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                // Is there something wrong here?
                isPaused: params.pause ? false : true
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

אנחנו אכן מגדירים את isPause במצב הפוך. צריך להגדיר אותו לערך true כשהערך של params.pause הוא true, ולערך false במקרים אחרים. אז נפתור את זה.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                isPaused: params.pause ? true : false
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

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

local/index.ts

const localHomeSdk = new App('1.0.3');

חשוב לזכור לקמפל את האפליקציה מחדש ולפרוס אותה מחדש ב-Firebase. ב-app-faulty/local, מריצים את הפקודה:

$ npm run build
$ firebase deploy --only hosting

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

בדיקת התיקון

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

b7fc8c5d3c727d8d.png

7. מזל טוב

764dbc83b95782a.png

מעולה! סיימתם ללמוד איך לפתור בעיות באפליקציית Home מקומית באמצעות חבילת הבדיקה לבית חכם ול-Cloud Logging.

מידע נוסף

יש עוד כמה דברים שאפשר לנסות:

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