在 iOS 上控制裝置

本指南是「在 iOS 上存取裝置和裝置中繼資料」的延伸,將介紹更多裝置控制和存取權的範例。

如要使用特定裝置類型或特徵 (例如這裡許多範例中使用的 Matter OnOffTrait),必須匯入這些類型或特徵:

import GoogleHomeSDK
import GoogleHomeTypes

檢查特徵是否支援指令

使用特徵層級 supports 函式,檢查特定裝置是否支援指令。

舉例來說,如要檢查裝置是否支援開/關特徵的 toggle 指令,請按照下列步驟操作:

// 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")
}

將指令傳送至裝置

傳送指令的做法類似於從特徵讀取狀態屬性。如要開啟或關閉裝置,請使用 OnOffTrait 切換指令,在 Google Home 生態系統資料模型中,這項指令的定義為 toggle()。如果 onOfftrue,這個方法會將其變更為 false;如果 onOfffalse,則會變更為 true

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

如果執行流程中發生問題,指令可能會傳回例外狀況。開發人員應使用 do-catch 區塊妥善處理這些例外狀況,並在錯誤可採取行動的情況下,向使用者顯示詳細資訊。未處理的例外狀況會停止應用程式執行階段,並可能導致應用程式當機。

或者,您也可以使用 off()on() 指令明確設定狀態:

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

傳送指令變更狀態後,在指令完成後,您可以依照「讀取裝置狀態」一節的說明讀取狀態,在應用程式中加以處理。

傳送含有參數的指令

部分指令可能會使用參數,例如 OnOffTraitLevelControlTrait 上的參數:

// Turn off the light using the DyingLight effect.
do {
  try await onOffTraitTest.offWithEffect(
    effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight,
    effectVariant: 0
  )
} catch let error as HomeError {
  // Code for handling the exception
}
// 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 error as HomeError {
  // Code for handling the exception
}

檢查特徵是否支援屬性

部分裝置可能支援 Matter 特徵,但不支援特定屬性。舉例來說,已對應至 MatterCloud-to-cloud 裝置可能不支援所有 Matter 屬性。如要處理這類情況,請使用特徵層級 isSupported 屬性,檢查特定裝置是否支援該屬性。

舉例來說,如要檢查裝置是否支援開/關特徵的 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!")
}

Matter 規格或 Cloud-to-cloud smart home 架構中,部分屬性可為空值。針對這些屬性,您可以使用 isNullableisSupported,判斷屬性傳回的 nil 是因為裝置未回報該值,還是屬性值實際上是 nil

// 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 \(onOffTrait.attributes.startUpOnOff)"
      )
    }
  }
}

更新特徵屬性

如果您想變更特定屬性的值,但特徵的命令都無法執行此操作,則該屬性可能支援明確設定值。

屬性的值是否可變更,取決於兩個因素:

  • 屬性是否可寫入?
  • 屬性值是否會因傳送特徵指令而產生副作用?

特徵及其屬性的參考說明文件會提供這項資訊。

因此,決定屬性值變更方式的屬性組合如下:

使用更新函式變更屬性值的範例

這個範例說明如何明確設定 DoorLockTrait.wrongCodeEntryLimit 屬性的值。

如要設定屬性值,請呼叫特徵的 update 函式,並傳遞設定新值的更新函式。建議您先確認特徵是否支援屬性

例如:

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