Multipart-Geräte auf Android-Geräten

Einige Matter Geräte bestehen aus mehreren Endpunkten mit demselben Gerätetyp. Andere Matter Geräte sind hierarchisch aufgebaut, wobei Endpunkte in anderen Endpunkten verschachtelt sind. In den Home APIs werden beide Arten von Geräten als mehrteilige Geräte bezeichnet.

Einfache Darstellung

Vor Release 1.8 der Home APIs werden mehrteilige Geräte in den Home APIs als eine Reihe separater, nicht miteinander verbundener Geräte dargestellt. Dies wird als einfache Darstellung bezeichnet.

Ein einzelnes Wandbedienfeld mit vier Schaltern wird in den Home APIs beispielsweise als vier separate und nicht miteinander verbundene Geräte angezeigt. Und ein hierarchisches Matter Gerät wie ein Kühlschrank kann in den Home APIs als eine Reihe von Geräten dargestellt werden, wobei jedes Gerät einem der Endpunkte entspricht.

  • Beispiel für ein Wandpaneel mit mehreren Schaltern, das die native Matter-Darstellung und die flache Darstellung der Home API zeigt

    Einfache Darstellung eines Wandbedienfelds mit vier Schaltern.

  • Beispiel für einen Kühlschrank mit der nativen Matter-Darstellung und der flachen Darstellung der Home API

    Einfache Darstellung eines Kühlschranks

Abbildung 1: Beispiele für die einfache Darstellung

Mehrteilige Darstellung

Ab Release 1.8 der Home APIs kann ein mehrteiliges Gerät in der API als einzelnes Gerät dargestellt werden. Rufen Sie dazu die Methode devices() für Structure, Room oder HomeManager auf und legen Sie den Parameter enableMultipartDevices auf true fest:

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)

Die folgenden Diagramme veranschaulichen, wie sich die Option enableMultipartDevices auf die Darstellung eines mehrteiligen Geräts in den Home APIs auswirkt:

  • Beispiel für ein Wandpaneel mit mehreren Schaltern, das die native Matter-Darstellung und das Multipart-Rendering der Home API zeigt

    Mehrteilige Darstellung eines Wandbedienfelds.

  • Beispiel für einen Kühlschrank mit der nativen Matter-Darstellung und der Multipart-Darstellung der Home API

    Mehrteilige Darstellung eines Kühlschranks.

Abbildung 2: Beispiele für die mehrteilige Darstellung

Sie können die einfache Darstellung jederzeit abrufen, indem Sie den Parameter enableMultipartDevices weglassen oder auf false setzen.

In einem mehrteiligen Gerät wird jede Komponenteninstanz eines Gerätetyps als Teil bezeichnet.

Auf Teile kann entweder direkt auf dem übergeordneten Gerät oder auf einem Teil in einer hierarchischen Weise zugegriffen werden, indem Gerätetypen oder Matter semantische Tags verwendet werden. Semantische Tags werden in den Home APIs mit DescriptorTrait.SemanticTagStruct implementiert.

Die DeviceType abstrakte Klasse implementiert die HasParts Schnittstelle, sodass Entwickler mit der parts Eigenschaft und der part() Methode durch den Gerätebaum navigieren können. Jede Teilinstanz implementiert auch die Schnittstelle HasParts. Wenn Sie also parts() für einen Teil aufrufen, wird eine Liste mit null oder mehr Unterteilen zurückgegeben.

Das folgende Beispiel zeigt, wie auf die Teile des Geräts mit mehreren Schaltern zugegriffen wird:

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

Das nächste Beispiel zeigt, wie auf die Teile eines Kühlschranks zugegriffen wird:

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