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 切り替えコマンドを使用します。このコマンドは、Google Home エコシステム データモデルで toggle() として定義されています。このメソッドは、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 プロパティを使用して、特定のデバイスで属性がサポートされているかどうかを確認します。

たとえば、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 スキーマで 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 コマンドで更新することもできます。

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

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

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

次に例を示します。

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