ממשקי Structure API ב-Android

אפשר לגשת ל-Structure APIs דרך Home APIs ל-Android. מייבאים את החבילות האלה לאפליקציה:

import com.google.home.Home
import com.google.home.Id
import com.google.home.Structure

טיפול בשגיאות

כל שיטה ב-Home APIs יכולה להחזיר HomeException, ולכן מומלץ להשתמש בבלוק try-catch כדי לתפוס HomeException בכל הקריאות.

כשמטפלים בשגיאה HomeException, צריך לבדוק את השדות error.code ו- error.message כדי לברר מה השתבש. יכול להיות שיוחזרו גם קודי שגיאה משניים, לכן צריך לקרוא לשיטה getSubErrorCodes() ולבדוק את התוצאה.

חריגים שלא טופלו יגרמו לקריסת האפליקציה.

מידע נוסף מופיע במאמר בנושא טיפול בשגיאות.

דוגמאות לשיחות

קבלת רשימת מבנים

אחרי ההפעלה, קריאה ל-structures() מחזירה Flow של מבנים שאפשר לגשת אליהם:

// Get a flow of all structures accessible to the user
val allStructuresFlow: HomeObjectsFlow<Structure> = home.structures()

// Calling list() on a HomeObjectsFlow returns the first Set of elements.
val allStructures: Set<Structure> = allStructuresFlow.list()

‫structures() API הוא תהליך שאולי לא יחזיר מיד רשימה תקינה של מבנים. אם האפליקציה שלכם היא ריאקטיבית והיא נרשמת ל-Flow הזה כדי להפעיל את ממשק המשתמש, בסופו של דבר אמורה לחזור רשימה תקינה של מבנים. יש מצבים אחרים שבהם יכול להיות שתוחזר רשימה ריקה של מבנים, למשל אם הטלפון של המשתמש מאבד את הקישוריות או אם המשתמש ביטל את ההרשאות לאפליקציה שלכם. חשוב לטפל במקרים האלה באפליקציה.

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

val everyStructure = withTimeout(5000) { home.structures().first { it.isNotEmpty() } }

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

קבלת מאפייני מבנה

אחרי שרואים את רשימת המבנים, אפשר לגשת למאפיינים שלהם:

// Get a flow on a structure. Flow emits new values on structure metadata changes: name.
val structureFlow: Flow<Structure> = home.structures().itemFlow(myStructureId)

// Get a snapshot of the structure.
val structure: Structure = structureFlow.first()

// Get structure properties
println("id ${structure.id}")
println("name ${structure.name}")

חיפוש מבנה לפי שם

אם אתם יודעים את השם של מבנה, אתם יכולים לגשת אליו גם באמצעות המאפיין name:

val myHome = home.structures().list().first { it.name == "My home" }

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

עבודה עם כמה מבנים

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

var structure1: Structure? = null
var structure2: Structure? = null

try {
  structure1 = home.structures().list().firstOrNull { it.name == "Main House" }
} catch (e: HomeException) {
  // Code for handling the exception
}
try {
  structure2 = home.structures().list().firstOrNull { it.name == "Guest Cottage" }
} catch (e: HomeException) {
  // Code for handling the exception
}

קבלת רשימת חדרים

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

val allRoomsFlow: HomeObjectsFlow<Room> = structure.rooms()
val allRooms: Set<Room> = allRoomsFlow.list()
val room: Room = allRooms.first()

println("id ${room.id}")
println("name ${room.name}")

יצירת חדר

כדי ליצור חדר חדש:

val testName = "Test Room Name"
val newRoom: Room = structure.createRoom(testName)

איך מוחקים חדרים

אפשרות אחרת היא למחוק חדר:

val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull()
    structure.deleteRoom(roomToDelete!!)

אפשר גם למחוק חדר רק באמצעות המזהה שלו:

val roomToDelete1 = allRooms.filter { it.id == testRoomId }.firstOrNull()
structure.deleteRoom(roomToDelete1!!)

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

העברת מכשירים לחדר אחר

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

val room2 = structure.rooms().get(Id("room_id_other_structure"))
    val device1 = structure.devices().get(Id("device_id1"))
    structure.moveDevicesToRoom(room2!!, listOf(device1!!))

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

structure.moveDevicesToRoom(Id("room_id_other_structure"), listOf(Id("device_id1")))

שינוי השם של חדר

מבצעים קריאה לשיטה setName() כדי לשנות את השם של החדר:

livingRoom.setName("Living Room")

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

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

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

import com.google.home.Structure
import com.google.home.DeviceType
import com.google.home.DeviceTypeFactory
import com.google.home.consentedDeviceTypes // Extension function from the SDK
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Example of how an app may monitor which device types have been granted access by a user.
 */
fun monitorDeviceConsent(structure: Structure, myScope: CoroutineScope) {
    // Obtain the flow of consented device type factories
    val consentedTypesFlow: Flow<Set<DeviceTypeFactory<out DeviceType>>> =
        structure.consentedDeviceTypes()

    myScope.launch {
        consentedTypesFlow.collect { consentedSet ->
            // Check if the user has consented to share a specific restricted
            // type, such as a Doorbell or Camera.
            val hasCameraAccess = consentedSet.any {
                it.toString() == "matter.google.type.GoogleDoorbellDevice"
            }

            if (hasCameraAccess) {
                // Enable features that require camera access
            } else {
                // Inform the user or disable camera-specific features
            }
        }
    }
}

קבוצות מכשירים

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

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

קבוצות מכשירים מיוצגות על ידי הישות Group, שהיא שונה מ-HomeDevice.

יצירת קבוצת מכשירים

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

val groupManagement = structure.trait(GroupManagementTrait)
val response = groupManagement?.createUserDefinedGroup(
  name = "Living room lights",
  memberDeviceObjectIds = listOf(light1.id.id, light2.id.id)
)

ניהול החברות בקבוצה

כדי להוסיף חברים לקבוצה קיימת:

structure.trait(GroupManagementTrait)?.addGroupMembers(
  groupObjectId = group.id.id,
  memberDeviceObjectIds = listOf(light3.id.id)
)

כדי להסיר חברים מקבוצה:

structure.trait(GroupManagementTrait)?.removeGroupMembers(
  groupObjectId = group.id.id,
  memberDeviceObjectIds = listOf(light1.id.id)
)

שינוי השם של קבוצת מכשירים

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

group.trait(GroupTrait)?.update {
  name = "Movie corner"
}

מחיקת קבוצת מכשירים

כדי למחוק קבוצת מכשירים ממבנה:

structure.trait(GroupManagementTrait)?.deleteGroup(
  groupObjectId = group.id.id
)

פעולות אוטומטיות

נקודת הכניסה ל-Automation API היא דרך מבנה. מידע נוסף על אוטומציות בממשקי Home API זמין במאמר סקירה כללית על Automation API ב-Android.