חלק ממכשירי Matter מורכבים מכמה נקודות קצה עם אותו סוג מכשיר. מכשירי Matter אחרים הם היררכיים, עם נקודות קצה שמוטמעות בתוך נקודות קצה אחרות. ב-Home APIs, שני סוגי המכשירים נקראים מכשירים מרובי חלקים.
ייצוג שטוח
לפני גרסה 1.8 של ממשקי ה-API של Home, מכשירים מרובי חלקים מיוצגים על ידי ממשקי ה-API של Home כקבוצה של מכשירים נפרדים שלא קשורים זה לזה. הייצוג הזה נקרא שטוח.
לדוגמה, מכשיר יחיד של לוח בקרה לקיר עם ארבעה מתגים מופיע בממשקי ה-API של Home כמכשיר אחד עם ארבעה מתגים נפרדים שלא קשורים זה לזה. מכשיר Matter היררכי, כמו מקרר, יכול להיות מיוצג בממשקי ה-API של Home כקבוצה של מכשירים, כשכל מכשיר תואם לאחת מנקודות הקצה.
ייצוג שטוח של פנל קיר עם 4 מתגים.
ייצוג שטוח של מקרר
ייצוג של כמה חלקים
החל מגרסה 1.8 של ממשקי ה-API של Home, אפשר לייצג מכשיר מרובה חלקים בממשק ה-API כמכשיר יחיד. כדי להפעיל את ההתנהגות הזו, קוראים לשיטה devices() ב-Structure, Room או HomeManager ומגדירים את הפרמטר enableMultipartDevices לערך true:
let devices = try await self.home.devices(enableMultipartDevices: true).list() let device = try XCTUnwrap(devices.first { $0.id == powerstripID }) let outlets = try await device.types.getAll(of: OnOffPluginUnitDeviceType.self)
בתרשימים הבאים אפשר לראות איך האפשרות enableMultipartDevices משפיעה על הייצוג של מכשיר מרובה חלקים בממשקי ה-API של Home:
ייצוג של לוח קיר מרובה חלקים.
ייצוג של מקרר שמורכב מכמה חלקים.
תמיד יש לכם אפשרות לקבל את הייצוג השטוח על ידי השמטת הפרמטר enableMultipartDevices או על ידי הגדרתו לערך false.
ניווט במכשיר מרובה חלקים
במכשיר מרובה חלקים, כל מופע רכיב של סוג מכשיר נקרא חלק.
אפשר לגשת לחלקים ישירות במכשיר הראשי או לחלק באופן היררכי, באמצעות סוגי מכשירים או Matterתגים סמנטיים. תגים סמנטיים מוטמעים בממשקי ה-API של Home באמצעות DescriptorTrait.SemanticTagStruct.
המחלקה המופשטת DeviceType מטמיעה את הממשק HasParts, ומאפשרת למפתחים לנווט בפירוט מבנה המכשיר (DT) באמצעות המאפיין 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()