Thiết bị có nhiều phần trên Android

Một số thiết bị Matter được tạo thành từ nhiều điểm cuối có cùng loại thiết bị. Các thiết bị Matter khác được phân cấp, với các điểm cuối được lồng trong các điểm cuối khác. Trong Home API, cả hai loại thiết bị đều được gọi là thiết bị nhiều phần.

Biểu diễn phẳng

Trước bản phát hành 1.8 của Home API, các thiết bị nhiều phần được Home API biểu thị dưới dạng một tập hợp các thiết bị riêng biệt, không liên quan. Đây được gọi là biểu diễn phẳng.

Ví dụ: một thiết bị bảng điều khiển gắn tường có 4 công tắc sẽ xuất hiện trong Home API dưới dạng 4 thiết bị riêng biệt và không liên quan. Ngoài ra, một thiết bị Matter phân cấp (chẳng hạn như tủ lạnh) có thể được biểu thị trong Home API dưới dạng một tập hợp thiết bị, mỗi thiết bị tương ứng với một trong các điểm cuối.

  • Ví dụ về bảng điều khiển trên tường có nhiều công tắc cho thấy cách biểu thị Matter gốc và cách kết xuất phẳng của Home API

    Hình ảnh phẳng của bảng điều khiển gắn tường có 4 công tắc.

  • Ví dụ về tủ lạnh cho thấy cách biểu thị Matter gốc và
          kết xuất phẳng của Home API

    Hình ảnh phẳng của tủ lạnh

Hình 1: Ví dụ về kết xuất phẳng

Biểu diễn nhiều phần

Kể từ phiên bản 1.8 của Home API, một thiết bị nhiều phần có thể được biểu thị trong API dưới dạng một thiết bị duy nhất. Để bật hành vi này, hãy gọi phương thức devices() trên Structure, Room hoặc HomeManager rồi đặt tham số enableMultipartDevices thành true:

var multipartDevice = structure.devices(enableMultipartDevices = multipartEnabled)
var multipartDevice = multipartDevices.list().filter{ device ->  device.has(PowerStrip)}

Các biểu đồ sau đây minh hoạ cách tuỳ chọn enableMultipartDevices ảnh hưởng đến việc biểu thị một thiết bị nhiều phần trong Home API:

  • Ví dụ về bảng điều khiển trên tường có nhiều công tắc cho thấy cách biểu thị Matter gốc và cách kết xuất nhiều phần của Home API

    Biểu diễn nhiều phần của một tấm tường.

  • Ví dụ về tủ lạnh cho thấy cách biểu thị Matter gốc và cách kết xuất nhiều phần của Home API

    Hình ảnh tủ lạnh gồm nhiều phần.

Hình 2: Ví dụ về kết xuất nhiều phần

Bạn luôn có thể chọn nhận bản trình bày phẳng bằng cách bỏ qua tham số enableMultipartDevices hoặc đặt tham số này thành false.

Trong một thiết bị nhiều phần, mỗi thực thể thành phần của một loại thiết bị được gọi là một phần.

Bạn có thể truy cập trực tiếp vào các bộ phận trên thiết bị mẹ hoặc một bộ phận theo cách phân cấp, sử dụng các loại thiết bị hoặc thẻ ngữ nghĩa Matter. Thẻ ngữ nghĩa được triển khai trong Home API bằng DescriptorTrait.SemanticTagStruct.

Lớp trừu tượng DeviceType triển khai giao diện HasParts, cho phép nhà phát triển di chuyển trong cây thiết bị thông qua thuộc tính parts và phương thức part(). Mỗi thực thể phần cũng triển khai giao diện HasParts, nhờ đó, việc gọi parts() trên một phần sẽ tạo ra danh sách gồm 0 hoặc nhiều phần phụ.

Ví dụ sau đây cho thấy cách truy cập vào các phần của thiết bị có nhiều công tắc:

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

Ví dụ tiếp theo cho thấy cách truy cập vào các bộ phận của thiết bị tủ lạnh:

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