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

デバイスにコマンドを送信する

コマンドの送信は、トレイトから状態属性を読み取るのと似ています。デバイスのオンとオフを切り替えるには、Google Home エコシステムのデータモデルで toggle() として定義されている OnOffTrait 切り替えコマンドを使用します。このメソッドは、onOfftrue の場合は false に変更し、false の場合は 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 のようなパラメータを使用する場合があります。

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 トレイトをサポートしていても、特定の属性をサポートしていない場合があります。たとえば、Matter にマッピングされた Cloud-to-cloud デバイスは、すべての Matter 属性をサポートしていない可能性があります。このようなケースを処理するには、トレイトレベルの isSupported プロパティを使用して、特定のデバイスで属性がサポートされているかどうかを確認します。

たとえば、デバイスが OnOff トレイトの 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 スキーマでは、一部の属性は null 許容です。これらの属性については、isSupported に加えて isNullable を使用することで、属性から返された 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)"
      )
    }
  }
}

特性属性を更新する

特定の属性の値を変更したいが、トレイトのコマンドのいずれもその処理を行わない場合、その属性は値を明示的に設定することをサポートしている可能性があります。

属性の値を変更できるかどうかは、次の 2 つの要因によって決まります。

  • 属性は書き込み可能ですか?
  • 特性コマンドの送信の副作用として、属性の値を変更できますか?

この情報は、特性とその属性のリファレンス ドキュメントに記載されています。

したがって、属性の値がどのように変更されるかを決定するプロパティの組み合わせは次のようになります。

  • 読み取り専用で、他のコマンドの影響を受けません。つまり、属性の値は変更されません。たとえば、SwitchTraitcurrentPosition 属性などです。

  • 読み取り専用で、他のコマンドの影響を受けます。つまり、属性の値を変更できるのは、コマンドを送信した結果としてのみです。たとえば、LevelControlTraitcurrentLevel 属性は読み取り専用ですが、moveToLevel などのコマンドで値を変更できます。

  • 書き込み可能で、他のコマンドの影響を受けません。つまり、トレイトの update 関数を使用して属性の値を直接変更できますが、属性の値に影響するコマンドはありません。たとえば、DoorLockTraitWrongCodeEntryLimit 属性などです。

  • 書き込み可能で、他のコマンドの影響を受ける。つまり、トレイトの update 関数を使用して属性の値を直接変更できます。また、コマンドを送信した結果として属性の値が変更されることもあります。たとえば、ThermostatTraitoccupiedCoolingSetpoint 属性は書き込み可能ですが、setpointRaiseLower コマンドで更新することもできます。

更新関数を使用して属性の値を変更する例

この例は、DoorLockTrait.wrongCodeEntryLimit 属性の値を明示的に設定する方法を示しています。

属性値を設定するには、トレイトの update 関数を呼び出し、新しい値を設定する更新関数を渡します。最初にトレイトが属性をサポートしていることを確認することをおすすめします。

次に例を示します。

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