在 iOS 上控制裝置

本指南延續「在 iOS 上存取裝置和裝置中繼資料」一文,並介紹其他裝置控制和存取範例。

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

import GoogleHomeSDK
import GoogleHomeTypes

確認特徵是否支援指令

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

舉例來說,如要檢查裝置是否支援 On/Off 特徵的 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 Toggle 指令,該指令在 Google Home 生態系統資料模型中定義為 toggle()。這個方法會將 onOff 變更為 false (如果目前為 true),或變更為 true (如果目前為 false):

// 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 上的參數:

offWithEffect

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

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 error as HomeError {
  // Code for handling the exception
}

確認特徵是否支援屬性

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

舉例來說,如要檢查裝置是否支援 On/Off 特徵的 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 架構中可為空值。對於這些屬性,您可以判斷屬性傳回的 nil 是因為裝置未回報該值,還是屬性的值實際上為 nil,方法是同時使用 isNullableisSupported

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