Appareils multifonctions sur Android

Certains appareils Matter sont constitués de plusieurs points de terminaison avec le même type d'appareil. D'autres appareils Matter sont hiérarchiques, avec des points de terminaison imbriqués dans d'autres points de terminaison. Dans les API Home, les deux types d'appareils sont appelés appareils multipièces.

Représentation aplatie

Avant la version 1.8 des API Home, les appareils multipièces sont représentés par les API Home comme un ensemble d'appareils distincts et sans lien. Il s'agit de la représentation aplatie.

Par exemple, un seul panneau mural avec quatre interrupteurs apparaît dans les API Home comme quatre appareils distincts et sans lien. Un appareil Matter hiérarchique Matter tel qu'un réfrigérateur peut être représenté dans les API Home comme un ensemble d'appareils, chacun correspondant à l'un des points de terminaison.

  • Exemple de panneau mural avec plusieurs interrupteurs montrant la représentation Matter native et le rendu plat de l'API Home

    Représentation aplatie d'un panneau mural à quatre interrupteurs.

  • Exemple de réfrigérateur montrant la représentation Matter native et le rendu plat de l'API Home

    Représentation aplatie d'un réfrigérateur

Figure 1: Exemples de rendu aplati

Représentation multipièces

À partir de la version 1.8 des API Home, un appareil multipièces peut être représenté dans l'API comme un seul appareil. Pour activer ce comportement, appelez la méthode devices() sur Structure, Room ou HomeManager, et définissez le paramètre enableMultipartDevices sur 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)

Les schémas suivants illustrent l'impact de l'option enableMultipartDevices sur la représentation d'un appareil multipièces dans les API Home :

  • Exemple de panneau mural avec plusieurs interrupteurs montrant la représentation Matter native et le rendu multipartie de l'API Home

    Représentation multipièces d'un panneau mural.

  • Exemple de réfrigérateur montrant la représentation Matter native et le rendu multipartie de l'API Home

    Représentation multipièces d'un réfrigérateur.

Figure 2 : Exemples de rendu multipièces

Vous avez toujours la possibilité d'obtenir la représentation aplatie en omettant le paramètre enableMultipartDevices ou en le définissant sur false.

Dans un appareil multipièces, chaque instance de composant d'un type d'appareil est appelée pièce.

Vous pouvez accéder directement aux pièces sur l'appareil parent ou sur une pièce de manière hiérarchique, à l'aide de types d'appareils ou de Matter tags sémantiques. Les tags sémantiques sont implémentés dans les API Home avec DescriptorTrait.SemanticTagStruct.

La classe abstraite DeviceType implémente l'interface HasParts, ce qui permet aux développeurs de parcourir l'arborescence des appareils via la propriété parts et la méthode part(). Chaque instance de pièce implémente également l'interface HasParts. Par conséquent, l'appel de parts() sur une pièce génère une liste de zéro ou plusieurs sous-pièces.

L'exemple suivant montre comment accéder aux pièces de l'appareil multi-interrupteur :

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()

L'exemple suivant montre comment accéder aux pièces d'un réfrigérateur :

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()