기기 제어

트레잇이 명령어를 지원하는지 확인

트레잇 명령어의 지원도 확인할 수 있습니다. 또한 트레잇 수준 supports 함수를 사용하여 특정 기기에서 명령어가 지원되는지 확인합니다.

예를 들어 기기에서 켜기/끄기 트레잇의 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")
}

기기에 명령어 전송

명령어를 전송하는 것은 트레잇에서 상태 속성을 읽는 것과 유사합니다. 기기를 켜거나 끄려면 Google Home 생태계 데이터 모델에 toggle()로 정의된 OnOff 트레잇의 전환 명령어를 사용하세요. 이 메서드는 onOfftrue인 경우 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 명령어에는 두 가지 선택적 인수가 있습니다.

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 enum을 사용하여 특정 기기에서 속성이 지원되는지 확인합니다.

예를 들어 기기에서 켜기/끄기 트레잇의 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!")
}

트레잇 속성 업데이트

특정 속성의 값을 변경하려고 하는데 트레잇의 명령어 중에서 이를 실행하는 명령어가 없는 경우 속성이 값을 명시적으로 설정하는 것을 지원할 수 있습니다.

속성 값을 변경할 수 있는지 여부는 다음 두 가지 요소에 따라 달라집니다.

  • 속성을 쓸 수 있나요?
  • 트레잇 명령어를 전송하는 부작용으로 속성 값이 변경될 수 있나요?

트레잇 및 속성에 관한 참조 문서에서 이 정보를 확인할 수 있습니다.

따라서 속성 값이 변경되는 방식을 지정하는 속성 조합은 다음과 같습니다.

  • 읽기 전용이며 다른 명령어의 영향을 받지 않습니다. 즉, 속성 값은 변경되지 않습니다. 예를 들어 Switch 트레잇의 currentPosition 속성

  • 읽기 전용이며 다른 명령어의 영향을 받습니다. 즉, 명령어를 전송한 결과로만 속성 값이 변경될 수 있습니다. 예를 들어 LevelControl Matter 트레잇의 currentLevel 속성은 읽기 전용이지만 moveToLevel와 같은 명령어로 값을 변경할 수 있습니다.

  • 쓸 수 있으며 다른 명령어의 영향을 받지 않습니다. 즉, 트레잇의 update 함수를 사용하여 속성 값을 직접 변경할 수 있지만 속성 값에 영향을 미치는 명령어는 없습니다. 예를 들어 DoorLock 트레잇의 WrongCodeEntryLimit 속성을 들 수 있습니다.

  • 쓰기가 가능하며 다른 명령어의 영향을 받습니다. 즉, 트레잇의 update 함수를 사용하여 속성 값을 직접 변경할 수 있으며, 명령어를 전송하면 속성 값이 변경될 수 있습니다. 예를 들어 Thermostat 트레잇의 occupiedCoolingSetpoint 속성은 쓰거나 setpointRaiseLower 명령어를 사용하여 업데이트할 수 있습니다.

update 함수를 사용하여 속성 값을 변경하는 예

이 예에서는 DoorLockTrait.WrongCodeEntryLimit 속성의 값을 명시적으로 설정하는 방법을 보여줍니다.

속성 값을 설정하려면 트레잇의 update 함수를 호출하고 새 값을 설정하는 mutator 함수를 전달합니다. 먼저 트레잇이 속성을 지원하는지 확인하는 것이 좋습니다.

예를 들면 다음과 같습니다.

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