סקירה כללית על Automation API ב-Android

פעולות אוטומטיות הן דרך להפוך משימות והגדרות המכשיר בבית לאוטומטיות. התכונה 'פעולות אוטומטיות' זמינה במערכת האקולוגית של Google Home כתרחישים ב-Google Home app (GHA) ובאמצעות automation script editor ב-Google Home for web.

עכשיו, פעולות אוטומטיות במערכת האקולוגית של Google Home זמינות דרך ממשקי ה-API של Home ל-Android. הם מבוססים על אותם מושגים בסיסיים שמשמשים בתרחישי GHA וב-script editor, אבל עם תכונות ויכולות משופרות שאפשר להשתמש בהן רק באמצעות ממשקי ה-API של Home, כולל:

  • גישה לכל התכונות הרגילות של Matter ולתכונות של smart home במכשיר, כפי שמוצג בממשקי ה-API של Home.
  • תמיכה בזרימות ביצוע עוקבות, מקבילות וסלקטיביות.

אוטומציות נכתבות באמצעות Automation DSL, שפה ספציפית לדומיין שמיועדת ליצירת אוטומציות ב-Kotlin.

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

הנחיות אם משתמש מבטל הרשאות מלאות

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

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

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

התהליך שעובר המפתח

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

  1. המפתח מתכנן את האוטומציה ומגדיר אותה באמצעות Automation DSL.
  2. המפתח מטמיע את הגדרת האוטומציה באפליקציית Android ב-Kotlin.
  3. האפליקציה מציגה למשתמש אוטומציות על סמך מידע על המכשירים שלו, כולל מאפיינים, תכונות, פקודות ואירועים, שנאסף באמצעות Discovery API או Device API.
    1. באמצעות Discovery API, האפליקציה יכולה ליצור טיוטה של אוטומציה מותאמת אישית לסוגי המכשירים ולמאפיינים שקיימים במבנה של המשתמש, עם או בלי קלט מהמשתמש.
    2. ‫Device API יכול לספק את רוב המידע ש-Discovery API מספק, אבל הוא לא מותאם לתרחישי שימוש באוטומציה. מידע נוסף מופיע במאמר השוואה בין Device API לבין Discovery API.
  4. האפליקציה יוצרת את האוטומציה בפועל, שמוגדרת לפי המבנה שנבחר.
  5. האוטומציה זמינה עכשיו במבנה של המשתמש, ואפשר להפעיל או למחוק אותה באמצעות שיטות של Structure API.

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

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

הצעות לאוטומציה

ממשקי ה-API של Home יכולים להציע אוטומציות לStructure על סמך גורמים כמו סוגי המכשירים שנמצאים במרחב.

ההצעות לפעולות אוטומטיות מיוצגות על ידי המחלקה AutomationSuggestion.

ממשק Structure כולל את ממשק HasSuggestions, שמספק את הפונקציה suggestions(), שמחזירה אוסף של הצעות לאוטומציה.

השיטות likeSuggestion() ו- dislikeSuggestion() מיועדות לחיבור לבקרי ממשק המשתמש ו- שהמשתמש יכול להקיש עליהם כדי לספק משוב.

שיטה שלישית, clearSuggestionFeedback(), מאפשרת למשתמש להסיר את המשוב שלו על הצעה לאוטומציה.

המשוב מהמשתמשים משפיע על ההצעות העתידיות.

בדוגמה הזו מוסבר איך לאחזר את ההצעות לאוטומציה שזמינות עבור Structure, לחלץ מזהה של הצעה ולתעד משוב ממשתמש באמצעות likeSuggestion(), clearSuggestionFeedback() ו-dislikeSuggestion().

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.home.Structure
import kotlinx.coroutines.launch

class AutomationSuggestionsViewModel(private val structure: Structure) : ViewModel() {

  fun loadAndGiveFeedback() {
    viewModelScope.launch {
      // 1. Fetch suggestions from structure
      val suggestions = structure.suggestions()
      val firstSuggestion = suggestions.firstOrNull() ?: return@launch

      // Extract string suggestion ID
      val suggestionId: String = firstSuggestion.id.id

      // 2. Like the suggestion (thumbs up)
      val liked = structure.likeSuggestion(suggestionId)

      // 3. Clear previous feedback if the user toggled it off
      if (liked) {
        structure.clearSuggestionFeedback(suggestionId)
      }

      // 4. Dislike the suggestion (thumbs down)
      structure.dislikeSuggestion(suggestionId)
    }
  }
}

פרמטרים דינמיים של פקודות

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

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

תרחיש שימוש

קישור של מתג סיבובי פיזי ששולח אירוע של לחיצה מרובה למנורה עם אפשרות לעמעום. מספר הקליקים הוא הערך הדינמי שמועבר לפקודת LevelControl step בזמן הריצה.

איך פועלים פרמטרים דינמיים

ב-Automation DSL ב-Android, פרמטרים של פקודות מקבלים מופעים של Expression או של Reference ישירות במקום ערכים קבועים סטטיים. כשיוצרים את האוטומציה, שפת ה-DSL מכניסה את ההגדרות האלה להגדרות של Parameter.

כללי אימות

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

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

שימוש בפרמטרים של פקודות דינמיות ב-Android

העברה של ביטויים דינמיים ישירות לפרמטרים של פקודות:

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val keypressAutomation = automation {
  name = "Dynamic command parameters example"
  description = "Pass starter event field directly to command"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountExpr,
        )
      )
    }
  }
}

לחלופין, אפשר להקצות ביטוי להצהרה על משתנה מקומי ולהפנות למשתנה בהמשך התהליך:

import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.automation.variable
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch

val myAutomationWithVariable = automation {
  name = "Dynamic command parameters with variables"
  description = "Declare a variable, assign value, and pass reference"
  sequential {
    val dimmerStarter = starter(
      dimmerSwitch,
      DimmerSwitchDevice,
      Switch.MultiPressOngoingEvent,
    )

    val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
      dimmerStarter,
      Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
    )

    val clickCountVar = variable<UInt>()
    clickCountVar.assign(clickCountExpr)

    action(dimmableLight, DimmableLightDevice) {
      command(
        LevelControl.step(
          stepMode = StepModeEnum.Up,
          stepSize = clickCountVar,
        )
      )
    }
  }
}

הגדרת מגבלות

מוודאים שסוגי המשתנים והביטויים תואמים להגדרת סוג הסכימה Matter הנדרשת של פרמטר הפקודה המקבל (למשל UShort,‏ UByte או UInt8).

מגבלות על משאבים

המגבלות הבאות חלות על פעולות אוטומטיות בממשקי ה-API של Home:

טבלה: מגבלות משאבים של Automation API
מדד מגבלה
מספר הפעולות האוטומטיות המקסימלי לכל מבנה 64
מספר הצמתים המקסימלי לכל אוטומציה 128
מספר מקסימלי של צמתי ביטוי לכל אוטומציה 64
מספר מקסימלי של מופעים של אוטומציה לכל מבנה 1024
מספר המופעים המקסימלי של אוטומציה לכל מפתח לכל מבנה 64
מספר ההרצות המקסימלי לכל מבנה ביום 1024
מספר ההרצות המקסימלי לכל מפתח לכל מבנה ביום 128