Niektóre urządzenia Matter składają się z wielu punktów końcowych tego samego typu. Inne urządzenia Matter mają strukturę hierarchiczną, a punkty końcowe są zagnieżdżone w innych punktach końcowych. W interfejsach API Google Home oba rodzaje urządzeń są określane jako urządzenia wieloczęściowe.
Reprezentacja płaska
Przed wersją 1.8 interfejsów API Google Home urządzenia wieloczęściowe były reprezentowane przez te interfejsy jako zestaw oddzielnych, niezwiązanych ze sobą urządzeń. Nazywa się to reprezentacją płaską.
Na przykład pojedynczy panel ścienny z 4 przełącznikami jest widoczny w interfejsach API Google Home jako 4 oddzielne i niezwiązane ze sobą urządzenia. Urządzenie Matter o strukturze hierarchicznej, takie jak lodówka, może być reprezentowane w interfejsach API Google Home jako zestaw urządzeń, z których każde odpowiada jednemu z punktów końcowych.
Płaska reprezentacja panelu ściennego z 4 przełącznikami.
Płaska reprezentacja lodówki.
Reprezentacja wieloczęściowa
Od wersji 1.8 interfejsów API Google Home urządzenie wieloczęściowe może być reprezentowane w interfejsie API jako pojedyncze urządzenie. Aby włączyć to działanie, wywołaj metodę devices() w przypadku Structure, Room lub HomeManager i ustaw parametr enableMultipartDevices na 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)
Ilustracje poniżej pokazują, jak opcja enableMultipartDevices wpływa na reprezentację urządzenia wieloczęściowego w interfejsach API Google Home:
Reprezentacja wieloczęściowa panelu ściennego.
Reprezentacja wieloczęściowa lodówki.
Zawsze możesz uzyskać reprezentację płaską, pomijając parametr enableMultipartDevices lub ustawiając go na false.
Nawigacja po urządzeniu wieloczęściowym
W urządzeniu wieloczęściowym każda instancja komponentu typu urządzenia jest nazywana częścią.
Do części można uzyskać dostęp bezpośrednio na urządzeniu nadrzędnym lub w sposób
hierarchiczny, używając typów urządzeń lub Matter semantycznych
tagów. Tagi semantyczne są implementowane w interfejsach API Google Home za pomocą
DescriptorTrait.SemanticTagStruct.
Klasa abstrakcyjna DeviceType implementuje interfejs HasParts, co umożliwia programistom poruszanie się po drzewie urządzeń za pomocą właściwości parts i metody part(). Każda instancja części implementuje też interfejs HasParts, dzięki czemu wywołanie parts() w przypadku części powoduje utworzenie listy zawierającej 0 lub więcej podczęści.
Poniższy przykład pokazuje, jak uzyskać dostęp do części urządzenia z wieloma przełącznikami:
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()
Następny przykład pokazuje, jak uzyskać dostęp do części urządzenia lodówki:
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()