Multipart devices on iOS

Some Matter devices are made up of multiple endpoints with the same device type. Other Matter devices are hierarchical, with endpoints nested within other endpoints. In the Home APIs, both kinds of devices are referred to as multipart devices.

Flat representation

Prior to release 1.8 of the Home APIs, multipart devices are represented by the Home APIs as a set of separate, unrelated devices. This is referred to as the flat representation.

For example, a single wall panel device with four switches appears in the Home APIs as four distinct and unrelated devices. And a hierarchical Matter device such as a refrigerator may be represented in the Home APIs as a set of devices, each corresponding to one of the endpoints.

  • Wall panel with multiple switches example showing the native Matter
          representation and Home API's flat rendering

    Flat representation of a 4-switch wall panel.

  • Refrigerator example showing the native Matter representation and
          Home API's flat rendering

    Flat representation of a refrigerator

Figure 1: Flat rendering examples

Multipart representation

Starting with release 1.8 of the Home APIs, a multipart device can be represented in the API as a single device. To enable this behavior, call the devices() method on the Home instance and set the enableMultipartDevices parameter to true:

let devices = try await self.home.devices(enableMultipartDevices: true).list()
    let device = devices.first { $0.id == powerStrip.device.id }
    let outlets = try await device.types.getAll(of: OnOffPluginUnitDeviceType.self)

The following diagrams illustrate how the enableMultipartDevices option affects the representation of a multipart device in the Home APIs:

  • Wall panel with multiple switches example showing the native Matter
    representation and Home API's multipart rendering

    Multipart representation of a wall panel.

  • Refrigerator example showing the native Matter representation and Home
    API's multipart rendering

    Multipart representation of a refrigerator.

Figure 2: Multipart rendering examples

You always have the option to get the flat representation by either omitting the enableMultipartDevices parameter, or by setting it to false.

Within a multipart device, each component instance of a device type is called a part.

Parts may be accessed directly on either the parent device or a part in a hierarchical manner, using device types or Matter semantic tags. Semantic tags are implemented in the Home APIs with SemanticTag.

The DeviceType class lets developers traverse the device tree through the parts() method:

let outlet1 = await device.parts.getAll(of: OnOffPluginUnitDeviceType.self).first {
  $0.tags.contains(SemanticTag.CommonNumber.one)
}
let outlet3 = await device.parts.getAll(of: OnOffPluginUnitDeviceType.self).first {
  $0.tags.contains(SemanticTag.CommonNumber.three)
}

The next example shows how to access the parts of a refrigerator device:

let refrigerator: RefrigeratorDeviceType? =
   await home.devices(enableMultipartDevices: true).first { $0.id == FRIDGE_ID }
// Get different cabinets of the refrigerator
let freezer = refrigerator!.parts(type: TemperatureControlledCabinetDeviceType.self).first {
  $0.tags.contains(SemanticTag.Refrigerator.freezer)
}