トレイトがコマンドをサポートしているかどうかを確認する
サポートは、trait コマンドで確認することもできます。また、トレイトレベルの supports
関数を使用して、特定のデバイスでコマンドがサポートされているかどうかを確認します。
たとえば、On/Off トレイトの toggle
コマンドをデバイスがサポートしているかどうかを確認するには、次のようにします。
// Check if the OnOff trait supports the toggle command. if (onOffTrait.supports(OnOff.Command.Toggle)) { println("onOffTrait supports toggle command") } else { println("onOffTrait does not support stateful toggle command") }
デバイスにコマンドを送信する
コマンドの送信は、トレイトから状態属性を読み取ることに似ています。デバイスのオン / オフを切り替えるには、OnOff
トレイトの切り替えコマンドを使用します。このコマンドは、Google Home エコシステム データモデルで toggle()
として定義されています。このメソッドは、onOff
が true
の場合は false
に、false
の場合は true
に変更します。
// Calling a command on a trait. try { onOffTrait.toggle() } catch (e: HomeException) { // Code for handling the exception }
すべての特性コマンドは suspend
関数であり、API からレスポンスが返された場合にのみ完了します(デバイスの状態が変更されたことを確認するなど)。実行フローで問題が検出されると、コマンドが例外を返すことがあります。デベロッパーは、try-catch
ブロックを使用してこれらの例外を適切に処理し、エラーに対処できる場合はユーザーに詳細情報を表示する必要があります。例外が処理されないと、アプリのランタイムが停止し、アプリがクラッシュする可能性があります。
または、off()
コマンドまたは on()
コマンドを使用して、状態を明示的に設定します。
onOffTrait.off() onOffTrait.on()
状態を変更するコマンドを送信したら、コマンドが完了したら、デバイスの状態を読み取るで説明されているように状態を読み取り、アプリで処理できます。または、状態をモニタリングするで説明されているようにフローを使用します。これは推奨される方法です。
パラメータ付きのコマンドを送信する
一部のコマンドは、OnOff
または LevelControl
トレイトのパラメータを使用します。
offWithEffect
// Turn off the light using the DyingLight effect. onOffTrait.offWithEffect( effectIdentifier = OnOffTrait.EffectIdentifierEnum.DyingLight, effectVariant = 0u, )
moveToLevel
// Change the brightness of the light to 50% levelControlTrait.moveToLevel( level = 127u.toUByte(), transitionTime = null, optionsMask = LevelControlTrait.OptionsBitmap(), optionsOverride = LevelControlTrait.OptionsBitmap(), )
一部のコマンドには、必須の引数の後に続くオプションの引数があります。
たとえば、FanControl
トレイトの step
コマンドには、次の 2 つのオプション引数があります。
val fanControlTraitFlow: Flow<FanControl?> = device.type(FanDevice).map { it.standardTraits.fanControl }.distinctUntilChanged() val fanControl = fanControlTraitFlow.firstOrNull() // Calling a command with optional parameters not set. fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) // Calling a command with optional parameters. fanControl?.step(direction = FanControlTrait.StepDirectionEnum.Increase) { wrap = true }
トレイトが属性をサポートしているかどうかを確認する
デバイスによっては、Matter トレイトはサポートしていても、特定の属性はサポートしていない場合があります。たとえば、Matter にマッピングされた Cloud-to-cloud デバイスは、すべての Matter 属性をサポートしていない場合があります。このようなケースを処理するには、トレイトレベルの supports
関数とトレイトの Attribute
列挙型を使用して、特定のデバイスで属性がサポートされているかどうかを確認します。
たとえば、On/Off トレイトの onOff
属性をデバイスがサポートしているかどうかを確認するには、次のようにします。
// Check if the OnOff trait supports the onOff attribute. if (onOffTrait.supports(OnOff.Attribute.onOff)) { println("onOffTrait supports onOff state") } else { println("onOffTrait is for a command only device!") }
一部の属性は、Matter 仕様または Cloud-to-cloud smart home スキーマで null にできます。これらの属性の場合、supports
に加えて isNullable
を使用すると、属性から返された null がデバイスがその値を報告していないためか、属性の値が実際に null
であるかを判断できます。
// Check if a nullable attribute is set or is not supported. if (onOffTrait.supports(OnOff.Attribute.startUpOnOff)) { // The device supports startupOnOff, it is safe to expect this value in the trait. if (OnOff.Attribute.startUpOnOff.isNullable && onOffTrait.startUpOnOff == null) { // This value is nullable and set to null. Check the specification as to // what null in this case means println("onOffTrait supports startUpOnOff and it is null") } else { // This value is nullable and set to a value. println("onOffTrait supports startUpOnOff and it is set to ${onOffTrait.startUpOnOff}") } } else { println("onOffTrait does not support startUpOnOff!") }
特徴属性を更新する
特定の属性の値を変更したいが、トレイトのコマンドでは変更できない場合、その属性は値を明示的に設定できる可能性があります。
属性の値を変更できるかどうかは、次の 2 つの要因によって異なります。
- 属性は書き込み可能か
- トレイト コマンドの送信の副作用として、属性の値が変更される可能性がありますか?
この情報は、トレイトとその属性のリファレンス ドキュメントで確認できます。
したがって、属性の値を変更する方法を指定するプロパティの組み合わせは次のとおりです。
読み取り専用で、他のコマンドの影響を受けません。つまり、属性の値は変更されません。たとえば、
Switch
トレイトのcurrentPosition
属性などです。読み取り専用で、他のコマンドの影響を受けます。つまり、属性の値を変更できるのは、コマンドを送信した結果のみです。たとえば、
LevelControl
Matter トレイトのcurrentLevel
属性は読み取り専用ですが、その値はmoveToLevel
などのコマンドで変更できます。書き込み可能で、他のコマンドの影響を受けません。つまり、トレイトの
update
関数を使用して属性の値を直接変更できますが、属性の値に影響するコマンドは存在しません。たとえば、DoorLock
トレイトのWrongCodeEntryLimit
属性などです。書き込み可能で、他のコマンドの影響を受けます。つまり、トレイトの
update
関数を使用して属性の値を直接変更できます。また、コマンドの送信の結果として属性の値が変更されることもあります。たとえば、Thermostat
トレイトのoccupiedCoolingSetpoint
属性は書き込み可能であるだけでなく、setpointRaiseLower
コマンドで更新することもできます。
update 関数を使用して属性の値を変更する例
この例は、DoorLockTrait.WrongCodeEntryLimit
属性の値を明示的に設定する方法を示しています。
属性値を設定するには、トレイトの update
関数を呼び出し、新しい値を設定するミュータタ関数を渡します。最初に、トレイトが属性をサポートしていることを確認することをおすすめします。
次に例を示します。
var doorLockDevice = home.devices().list().first { device -> device.has(DoorLock) } val traitFlow: Flow<DoorLock?> = doorLockDevice.type(DoorLockDevice).map { it.standardTraits.doorLock }.distinctUntilChanged() val doorLockTrait: DoorLock = traitFlow.first()!! if (doorLockTrait.supports(DoorLock.Attribute.wrongCodeEntryLimit)) { val unused = doorLockTrait.update { setWrongCodeEntryLimit(3u) } }