Некоторые устройства Matter состоят из нескольких конечных точек одного типа. Другие устройства Matter имеют иерархическую структуру, в которой конечные точки вложены в другие конечные точки. В API для умного дома оба типа устройств называются многокомпонентными устройствами.
Плоское представление
До версии 1.8 Home API многокомпонентные устройства представлялись в Home API как набор отдельных, не связанных друг с другом устройств. Такое представление называется плоским.
Например, одна настенная панель с четырьмя переключателями будет представлена в API умного дома как четыре отдельных устройства, не связанных друг с другом. Иерархическое устройство, например холодильник, может быть представлено в API Home как набор устройств, каждое из которых соответствует одной из конечных точек.Matter
Плоское изображение настенной панели с четырьмя переключателями.
Плоское изображение холодильника
Многокомпонентное представление
Начиная с версии 1.8 API Google Home, многокомпонентное устройство может быть представлено в API как одно устройство. Чтобы включить такое поведение, вызовите метод devices() для Structure, Room или HomeManager и задайте для параметра enableMultipartDevices значение true:
var multipartDevice = structure.devices(enableMultipartDevices = multipartEnabled) var multipartDevice = multipartDevices.list().filter{ device -> device.has(PowerStrip)}
На приведенных ниже схемах показано, как параметр enableMultipartDevices влияет на представление многокомпонентного устройства в Home API.
Многокомпонентное представление стеновой панели.
Изображение холодильника, состоящее из нескольких частей.
Вы всегда можете получить плоское представление, либо опустив параметр enableMultipartDevices, либо задав для него значение false.
Как перемещаться по многокомпонентному устройству
В многокомпонентном устройстве каждый экземпляр компонента определенного типа называется частью.
Доступ к частям может быть получен непосредственно на родительском устройстве или иерархически, с использованием типов устройств или семантических тегов Matter. Семантические теги реализованы в API для умного дома с помощью 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()