Điều khiển thiết bị trên iOS

Hướng dẫn này tiếp nối từ bài viết Truy cập vào thiết bị và siêu dữ liệu thiết bị trên iOS, đồng thời giới thiệu thêm các ví dụ về quyền truy cập và kiểm soát thiết bị.

Để sử dụng các loại hoặc đặc điểm cụ thể của thiết bị (chẳng hạn như Matter OnOffTrait được dùng trong nhiều ví dụ ở đây), bạn phải nhập các loại hoặc đặc điểm đó:

import GoogleHomeSDK
import GoogleHomeTypes

Kiểm tra xem một đặc điểm có hỗ trợ một lệnh hay không

Sử dụng hàm supports ở cấp đặc điểm để kiểm tra xem một lệnh có được hỗ trợ cho một thiết bị cụ thể hay không.

Ví dụ: để kiểm tra xem một thiết bị có hỗ trợ lệnh toggle của đặc điểm Bật/Tắt hay không:

// Check if the OnOff trait supports the toggle command.
if onOffTraitTest.supportsToggleCommand {
  print("onOffTrait supports toggle command")
} else {
  print("onOffTrait does not support stateful toggle command")
}

Gửi lệnh đến một thiết bị

Việc gửi lệnh cũng tương tự như việc đọc một thuộc tính trạng thái từ một đặc điểm. Để bật hoặc tắt thiết bị, hãy sử dụng OnOffTrait lệnh Chuyển đổi được xác định trong mô hình dữ liệu hệ sinh thái Google Home là toggle(). Phương thức này sẽ thay đổi onOff thành false nếu giá trị này là true hoặc thành true nếu giá trị này là false:

// Calling a command on a trait.
do {
  try await onOffTraitTest.toggle()
} catch let _ as HomeError {
  // Code for handling the exception
}

Các lệnh có thể trả về một ngoại lệ nếu hệ thống phát hiện thấy vấn đề với quy trình thực thi. Là nhà phát triển, bạn nên sử dụng khối do-catch để xử lý đúng cách các ngoại lệ này và cung cấp thông tin chi tiết cho người dùng về những trường hợp có thể khắc phục lỗi. Các ngoại lệ chưa được xử lý sẽ dừng thời gian chạy ứng dụng và có thể dẫn đến sự cố trong ứng dụng của bạn.

Ngoài ra, hãy sử dụng các lệnh off() hoặc on() để đặt trạng thái một cách rõ ràng:

do {
  try await onOffTraitTest.off()
  try await onOffTraitTest.on()
} catch let _ as HomeError {
  // Code for handling the exception
}

Sau khi gửi lệnh để thay đổi trạng thái, khi lệnh hoàn tất, bạn có thể đọc trạng thái như mô tả trong bài viết Đọc trạng thái thiết bị để xử lý trạng thái đó trong ứng dụng.

Gửi lệnh có tham số

Một số lệnh có thể sử dụng tham số, chẳng hạn như các lệnh trên OnOffTrait hoặc LevelControlTrait:

offWithEffect

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let _ as HomeError {
  // Code for handling the exception
}

moveToLevel

// Change the brightness of the light to 50%
do {
  try await levelControlTraitTest.moveToLevel(
    level: UInt8(127),
    transitionTime: 0,
    optionsMask: Matter.LevelControlTrait.OptionsBitmap(),
    optionsOverride: Matter.LevelControlTrait.OptionsBitmap()
  )
} catch let _ as HomeError {
  // Code for handling the exception
}

Kiểm tra xem một đặc điểm có hỗ trợ một thuộc tính hay không

Một số thiết bị có thể hỗ trợ một Matter đặc điểm nhưng không hỗ trợ một thuộc tính cụ thể. Ví dụ: một thiết bị Cloud-to-cloud được liên kết với Matter có thể không hỗ trợ mọi thuộc tính Matter. Để xử lý các trường hợp như vậy, hãy sử dụng thuộc tính isSupported ở cấp đặc điểm để kiểm tra xem thuộc tính đó có được hỗ trợ cho một thiết bị cụ thể hay không.

Ví dụ: để kiểm tra xem một thiết bị có hỗ trợ thuộc tính của đặc điểm Bật/Tắt hay không: onOff

// Check if the OnOff trait supports the onOff attribute.
if onOffTrait.attributes.$onOff.isSupported {
  print("onOffTrait supports onOff state")
} else {
  print("onOffTrait is for a command only device!")
}

Một số thuộc tính có thể có giá trị null trong thông số kỹ thuật Matter hoặc giản đồ Cloud-to-cloud smart home. Đối với các thuộc tính này, bạn có thể xác định xem giá trị nil mà thuộc tính trả về là do thiết bị không báo cáo giá trị đó hay giá trị của thuộc tính thực sự là nil bằng cách sử dụng isNullable ngoài isSupported:

// Check if a nullable attribute is set or is not supported.
if let deviceType = await device.types.get(OnOffLightDeviceType.self) {
  if let onOffTrait = deviceType.traits[Matter.OnOffTrait.self] {
    if onOffTrait.attributes.startUpOnOff == nil {
      if onOffTrait.attributes.$startUpOnOff.isSupported {
        print(
          "onOffTrait supports startUpOnOff and it is nil. Check the spec for the contextual meaning."
        )
      } else {
        print("onOffTrait does not support startUpOnOff!")
      }
    } else {
      print(
        "onOffTrait supports startUpOnOff and it is set to \(String(describing: onOffTrait.attributes.startUpOnOff))"
      )
    }
  }
}

Cập nhật các thuộc tính của đặc điểm

Nếu bạn muốn thay đổi giá trị của một thuộc tính nhất định và không có lệnh nào của đặc điểm thực hiện việc này, thì thuộc tính đó có thể hỗ trợ việc đặt giá trị một cách rõ ràng.

Việc có thể thay đổi giá trị của một thuộc tính hay không phụ thuộc vào 2 yếu tố:

  • Thuộc tính đó có thể ghi được không?
  • Giá trị của thuộc tính đó có thể thay đổi do tác dụng phụ của việc gửi lệnh đặc điểm không?

Tài liệu tham khảo về các đặc điểm và thuộc tính của chúng cung cấp thông tin này.

Do đó, các tổ hợp thuộc tính quyết định cách giá trị của một thuộc tính có thể thay đổi là:

  • Chỉ đọc và không bị ảnh hưởng bởi các lệnh khác. Điều này có nghĩa là giá trị của thuộc tính không thay đổi. Ví dụ: thuộc tính currentPosition của SwitchTrait.

  • Chỉ đọc và bị ảnh hưởng bởi các lệnh khác. Điều này có nghĩa là cách duy nhất để giá trị của thuộc tính có thể thay đổi là do việc gửi lệnh. Ví dụ: thuộc tính currentLevel của LevelControlTrait là chỉ đọc, nhưng giá trị của thuộc tính này có thể bị thay đổi bởi các lệnh như moveToLevel.

  • Có thể ghi và không bị ảnh hưởng bởi các lệnh khác. Điều này có nghĩa là bạn có thể trực tiếp thay đổi giá trị của thuộc tính bằng cách sử dụng hàm update của đặc điểm, nhưng không có lệnh nào ảnh hưởng đến giá trị của thuộc tính đó. Ví dụ: thuộc tính WrongCodeEntryLimit của DoorLockTrait.

  • Có thể ghi và bị ảnh hưởng bởi các lệnh khác. Điều này có nghĩa là bạn có thể trực tiếp thay đổi giá trị của thuộc tính bằng cách sử dụng hàm update của đặc điểm và giá trị của thuộc tính đó có thể thay đổi do việc gửi lệnh. Ví dụ: thuộc tính occupiedCoolingSetpoint của ThermostatTrait có thể được ghi vào nhưng cũng có thể được cập nhật bằng lệnh setpointRaiseLower command.

Ví dụ về cách sử dụng hàm cập nhật để thay đổi giá trị của một thuộc tính

Ví dụ này cho thấy cách đặt giá trị của thuộc tính DoorLockTrait.wrongCodeEntryLimit một cách rõ ràng.

Để đặt giá trị thuộc tính, hãy gọi hàm update của đặc điểm và truyền cho hàm đó một hàm cập nhật để đặt giá trị mới. Bạn nên xác minh trước rằng đặc điểm đó hỗ trợ một thuộc tính.

Ví dụ:

if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported {
  let _ = try await doorLockTraitTest.update {
    $0.setWrongCodeEntryLimit(3)
  }
}