מכשירים מרובי חלקים ב-Android

חלק ממכשירי Matter מורכבים מכמה נקודות קצה (endpoints) עם אותו סוג מכשיר. מכשירים אחרים של Matter הם היררכיים, עם נקודות קצה שמוטמעות בתוך נקודות קצה אחרות. בממשקי ה-API של Home, שני סוגי המכשירים נקראים מכשירים עם כמה חלקים.

ייצוג שטוח

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

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

  • דוגמה ללוח בקרה עם כמה מתגים, שמראה את הייצוג המקורי של Matter ואת העיבוד השטוח של Home API

    ייצוג שטוח של לוח קיר עם 4 מתגים.

  • דוגמה למקרר שמראה את הייצוג המקורי של Matter ואת העיבוד השטוח של Home API

    ייצוג שטוח של מקרר

איור 1: דוגמאות לעיבוד שטוח

ייצוג של כמה חלקים

החל מגרסה 1.8 של ממשקי ה-API של Home, מכשיר עם כמה חלקים יכול להיות מיוצג ב-API כמכשיר אחד. כדי להפעיל את ההתנהגות הזו, מפעילים את השיטה devices() ב-Structure, ב-Room או ב-HomeManager ומגדירים את הפרמטר enableMultipartDevices לערך true:

var multipartDevice = structure.devices(enableMultipartDevices = multipartEnabled)
var multipartDevice = multipartDevices.list().filter{ device ->  device.has(PowerStrip)}

התרשימים הבאים ממחישים איך האפשרות enableMultipartDevices משפיעה על הייצוג של מכשיר עם כמה חלקים בממשקי ה-API של Home:

  • דוגמה ללוח בקרה עם כמה מתגים שמראה את הייצוג המקורי של Matter ואת העיבוד של כמה חלקים ב-Home API

    ייצוג של לוח קיר שמורכב מכמה חלקים.

  • דוגמה למקרר שמראה את הייצוג המקורי של Matter ואת העיבוד של Home API בכמה חלקים

    ייצוג של מקרר שמורכב מכמה חלקים.

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

תמיד אפשר לקבל את הייצוג השטוח על ידי השמטת הפרמטר enableMultipartDevices או על ידי הגדרתו ל-false.

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

אפשר לגשת לחלקים ישירות במכשיר הראשי או בחלק באופן היררכי, באמצעות סוגי מכשירים או תגים סמנטיים של Matter. תגים סמנטיים מוטמעים בממשקי ה-API של Home באמצעות DescriptorTrait.SemanticTagStruct.

המחלקה המופשטת DeviceType מטמיעה את הממשק HasParts, ומאפשרת למפתחים לנווט בפירוט מבנה המכשיר באמצעות המאפיין parts והשיטה part(). כל מופע של חלק מיישם גם את הממשק HasParts, כך שקריאה ל-parts() בחלק מסוים יוצרת רשימה של אפס או יותר חלקי משנה.

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

val device =
      homeManager
        .devices(enableMultipartDevices = true)
        .itemFlow(Id(MULTI_SWITCH_DEVICE))
        .first()

// Here at top-level, we are using the homeDevice.parts() API to access flow of
// all the switches. Then we get the part ids.
val partIds =
      device
        .parts()
        .map { parts ->
          parts.filter { it.has(Switch) }.mapNotNull { it.metadata.partId }
        }
        .first()
        .toSet()

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

val rootDevice = homeManager.devices(true).itemFlow(Id("device@uuid1"))

// On the top level, HomeDevice provides both plural (parts)
// and singular (part) APIs.
// The parts() API returns all the parts accessible from the top level,
// including Endpoint 0 and its children.
val childParts = rootDevice.parts().first()
// childParts contain (EP0 as RootNode, EP1 as Refrigerator)

// The singular part() API accepts DeviceType and tags (optional).
val refrigerator = rootDevice.part(Refrigerator).first()

// Get the refrigerator device which in this case is just device@uuid1
val refrigeratorDevice = homeManager.devices(false).itemFlow(refrigerator.metadata.partId.deviceId)

// DeviceType uses a synchronous API for providing access to parts
val cabinets = refrigerator.parts  // [EP2, EP3]

// Get the HomeDevice for these cabinets (device@uuid2 and device@uuid3)
val cabinetDeviceIds = cabinets.map { it.metadata.partId }

// Now use the devices API with enableMultipartDevices = false.
val cabinetDevices = homeManager.devices(false)
    .map { devices ->
devices.filter { it.id in cabinetDeviceIds }
}.first()