Android의 기기 및 기기 메타데이터에 액세스

기기 API는 Android용 Home API를 통해 액세스할 수 있습니다. 다음 패키지를 앱으로 가져옵니다.

import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id

기기 API와 함께 특정 기기 유형이나 특성을 사용하려면 개별적으로 가져와야 합니다.

예를 들어 Matter On/Off 특성과 On/Off 플러그인 장치 유형을 사용하려면 다음 패키지를 애플리케이션으로 가져옵니다.

import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice

자세한 내용은 Android의 데이터 모델을 참고하세요.

오류 처리

Home API의 모든 메서드는 HomeException를 발생시킬 수 있으므로 try-catch 블록을 사용하여 모든 호출에서 HomeException를 포착하는 것이 좋습니다.

HomeException를 처리할 때는 codemessage 필드를 확인하여 무엇이 잘못되었는지 알아봅니다.

처리되지 않은 예외가 있으면 앱이 비정상 종료됩니다.

자세한 내용은 오류 처리를 참고하세요.

예는 기기에 명령어 전송을 참고하세요.

샘플 호출

기기 목록 가져오기

구조를 사용할 수 있으면 devices() 호출은 해당 구조에서 액세스할 수 있는 기기의 흐름을 반환합니다.

// Get a flow of all devices accessible to the user
val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices()

// Calling list() on a HomeObjectsFlow returns the first Set of elements.
val allDevices: Set<HomeDevice> = allDevicesFlow.list()

여기에서 각 기기의 상태에 액세스할 수 있으며 지원되는 명령어를 기기로 전송할 수 있습니다.

기기 상태 읽기

기기의 켜짐/꺼짐 특성에서 OnOff 속성을 확인하는 예를 살펴보겠습니다. 이 특성이 OnOff로 식별되는 Home API 특성 데이터 모델을 사용하여 기기 유형의 standardTraits 클래스를 통해 특성 데이터를 가져올 수 있습니다.

// Assuming we have a device.
val deviceFlow = home.devices().itemFlow(myDeviceId)

val device = deviceFlow.first()

// Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger
// on the specific trait changes and not the whole type.
val onOffTraitFlow: Flow<OnOff?> =
  device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged()

val onOffTrait: OnOff = onOffTraitFlow.first()!!

Kotlin 흐름 함수에 대해 자세히 알아보려면 distinctUntilChanged를 참고하세요.

특성 구독에서 상태 무효화

TraitStateInvalidation 인터페이스는 상태가 올바르게 보고되지 않는 경우 타겟 기기에 대한 구독을 통해 검색된 상태를 무효화하는 기능을 제공합니다. 상태가 올바르게 보고되지 않는 경우의 예로는 품질이 'C'인 Matter 특성에서 속성을 사용하거나 기기 구현으로 인해 예기치 않게 문제가 발생하는 경우를 들 수 있습니다.

이 API는 현재 특성 상태의 강제 읽기를 실행하고 기존 특성 흐름을 통해 결과를 반환합니다.

특성을 가져온 후 특성에서 forceRead를 실행합니다.

val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()

기기 유형 특성 목록 가져오기

기기 유형은 특성을 읽는 진입점으로 사용해야 합니다. 기기를 기능적 부분 (예: Matter의 엔드포인트)으로 분해하기 때문입니다.

또한 기기에 두 가지 기기 유형이 있는 경우를 고려합니다. 두 기기 유형 모두 동일한 특성을 가질 수 있습니다. 예를 들어 기기가 스피커와 조광 가능한 조명인 경우 두 개의 On/Off 특성과 두 개의 Level Control 특성이 있습니다.

조광 가능 조명 기기 유형에 사용 가능한 특성 목록을 가져오려면 다음을 실행하세요.

// Get all types available on this device. Requires the types to be part of the registry during
// SDK initialization.
val typesFlow: Flow<Set<DeviceType>> = device.types()

// Get a snapshot of all types.
val types: Set<DeviceType> = typesFlow.first()

// Get the DimmableLightDevice instance from the set of types.
val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull()

// Get all traits in the type + traits registered
val allTraits: Set<Trait> = dimmableLightDevice!!.traits()

기기에 이름이 같은 두 가지 특성이 있는 경우 다른 종류의 특성 충돌이 발생할 수 있습니다. 예를 들어 onOff는 표준 OnOff 특성의 인스턴스를 참조할 수도 있고 제조업체 정의 OnOff 특성의 인스턴스를 참조할 수도 있습니다. 의도한 특성이 무엇인지에 관한 잠재적인 모호성을 없애려면 기기를 통해 참조되는 Trait 인스턴스 앞에 적격 네임스페이스가 와야 합니다. 표준 특성(Matter 표준 클러스터와 유사한 특성)의 경우 standardTraits을 사용합니다. Google 특성의 경우 googleTraits를 사용합니다.

// Accessing standard traits on the type.
val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff
val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl

제조업체별 특성에 액세스하려면 직접 참조하세요.

// Accessing a custom trait on the type.
val customTrait = dimmableLightDevice.trait(MyCustomTrait)

특정 특성이 있는 기기 목록 가져오기

Kotlin의 filter 함수를 사용하여 API 호출을 추가로 세부 조정할 수 있습니다. 예를 들어 집에 있는 기기 중 모두 On/Off 특성이 있는 기기의 목록을 가져오려면 다음을 실행합니다.

// Get all devices that support OnOff
val onOffDevices: Flow<List<HomeDevice>> =
  home.devices().map { devices -> devices.filter { it.has(OnOff) } }

Home API에서 사용할 수 있는 특성의 전체 목록은 Trait 인터페이스를 참고하세요.

유사한 기기 유형의 기기 목록 가져오기

홈의 모든 조명을 나타내는 기기 목록을 가져오려면 다음을 실행하세요.

// Get a list of devices with similar device types (lights)
val lightDevices =
  home.devices().map { devices ->
    devices.filter {
      it.has(DimmableLightDevice) ||
        it.has(OnOffLightDevice) ||
        it.has(ColorTemperatureLightDevice) ||
        it.has(ExtendedColorLightDevice)
    }
  }

Home API에는 핵심 기기 유형을 나타낼 수 있는 여러 기기 유형이 있습니다. 예를 들어 '조명' 기기 유형은 없습니다. 대신 앞의 예와 같이 조명을 나타낼 수 있는 네 가지 다른 기기 유형이 있습니다. 따라서 홈에서 상위 수준 기기 유형을 포괄적으로 확인하려면 필터링된 흐름에 여러 기기 유형이 포함되어야 합니다.

Home API에서 사용할 수 있는 기기 유형의 전체 목록은 DeviceType 인터페이스를 참고하세요.

기기의 공급업체 ID 또는 제품 ID 가져오기

BasicInformation 특성에는 공급업체 ID, 제품 ID, 제품 이름, 기기의 일련번호와 같은 정보가 포함됩니다.

// Get device basic information. All general information traits are on the RootNodeDevice type.
val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!!
println("vendorName ${basicInformation.vendorName}")
println("vendorId ${basicInformation.vendorId}")
println("productId ${basicInformation.productId}")

기기 제조업체를 위한 클라우드 간 기기 식별

기기 제조업체이고 Cloud-to-cloud 기기를 빌드하는 경우 BasicInformation 특성을 통해 Cloud-to-cloud 기기를 식별하기 위해 SYNC 응답에 다음 문자열 필드를 포함할 수 있습니다.

  • Connectivity Standards Alliance (CSA)에서 발급한 공급업체 ID: "matterOriginalVendorId": "0xfff1",

  • 공급업체의 제품을 고유하게 식별하는 제품 식별자입니다. "matterOriginalProductId": "0x1234",

  • 제조업체별 방식으로 구성된 기기의 고유 식별자입니다. "matterUniqueId": "matter-device-id",

이러한 문자열 필드를 입력할 때 Matter 공급업체 및 제품 ID가 있는 경우 이를 사용하세요. CSA 회원이 아니고 이러한 ID가 할당되지 않은 경우 matterOriginalVendorIdmatterOriginalProductId 필드를 비워 두고 matterUniqueId를 식별자로 제공하면 됩니다.

다음은 이러한 필드를 사용하는 SYNC 응답의 예입니다.

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "456",
        "type": "action.devices.types.LIGHT",
        "traits": [
          "action.devices.traits.OnOff",
          "action.devices.traits.Brightness",
          "action.devices.traits.ColorSetting",
        ],
        "willReportState": true,
        "deviceInfo": { ... },
        "matterOriginalVendorId": "0xfff1",
        "matterOriginalProductId": "0x1234",
        "matterUniqueId": "matter-device-id",
        "otherDeviceIds": [
          {
            "deviceId": "local-device-id",
          }
        ]
      }
    ]
  }
}

자세한 내용은 Cloud-to-cloud SYNC 문서를 참고하세요.

기기 및 특성 메타데이터

Home API의 기기와 특성에는 메타데이터가 연결되어 있어 앱에서 사용자 환경을 관리하는 데 도움이 됩니다.

Home API의 각 특성에는 특성의 온라인 상태 및 위치(로컬 또는 원격 라우팅)에 관한 정보가 있는 sourceConnectivity 속성이 포함됩니다.

기기의 기본 유형 가져오기

일부 기기는 Home API를 통해 여러 기기 유형을 표시할 수 있습니다. 사용자에게 기기에 적합한 옵션 (예: 기기 제어 및 추천 자동화)이 앱에 표시되도록 하려면 기기의 기본 기기 유형을 확인하는 것이 좋습니다.

먼저 type()를 사용하여 기기 유형을 가져온 다음 기본 유형을 확인합니다.

val types = device.types().first()
val primaryTypes = types.filter { it.metadata.isPrimaryType }

특성이 온라인인지 확인

connectivityState() 메서드를 사용하여 특성의 연결을 확인합니다.

val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState

일부 특성(일반적으로 Google smart home 특성)은 기기가 인터넷에 연결되어 있지 않으면 오프라인으로 표시될 수 있습니다. 이러한 특성은 클라우드 기반이며 로컬 라우팅이 없기 때문입니다.

기기의 연결 확인

일부 기기는 여러 기기 유형을 지원하므로 기기의 연결은 실제로 기기 유형 수준에서 확인됩니다. 반환된 상태는 해당 기기의 모든 특성의 연결 상태를 조합한 것입니다.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

인터넷 연결이 없는 경우 혼합 기기 유형에서 PARTIALLY_ONLINE 상태가 관찰될 수 있습니다. Matter 표준 특성은 로컬 라우팅으로 인해 온라인 상태일 수 있지만 클라우드 기반 특성은 오프라인 상태입니다.

특성의 네트워크 라우팅 확인

특성의 지역은 Home API에서도 사용할 수 있습니다. dataSourceLocality는 특성이 원격으로 라우팅되는지 (클라우드를 통해), 로컬로 라우팅되는지 (로컬 허브를 통해), 아니면 피어 투 피어로 라우팅되는지 (기기에서 기기로 직접, 허브 없음)를 나타냅니다.

예를 들어 앱이 부팅 중이고 아직 기기 연결을 위한 허브나 서버에 도달하지 않은 동안에는 알 수 없는 지역 값 UNSPECIFIED이 가능합니다. 이러한 기기는 연결할 수 없으며 명령어 또는 이벤트의 상호작용 요청이 실패합니다. 이러한 기기를 처리하는 방법은 클라이언트가 결정합니다.

val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality

기기의 네트워크 라우팅 확인

연결과 마찬가지로 지역성은 기기 유형 수준에서 확인됩니다. 반환된 상태는 해당 기기의 모든 특성의 지역성의 조합입니다.

val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality

PARTIALLY_ONLINE 연결과 유사한 시나리오에서 MIXED 상태가 관찰될 수 있습니다. 일부 특성은 클라우드 기반이고 다른 특성은 로컬입니다.

기기 이름 변경

setName() 메서드를 호출하여 기기 이름을 변경합니다.

mixerDevice.setName("Grendel")

이름이 유니코드 코드 포인트(문자) 제한인 60을 초과하면 잘리며 오류가 발생하지 않습니다. 개발자는 긴 이름을 처리해야 하며, 예를 들어 사용자에게 이름이 잘린다는 사실을 알릴지 여부를 결정할 수 있습니다.

API 목록

Home 인스턴스가 생성되면 다음 기기 API를 통해 액세스할 수 있습니다.

API 설명
devices() Google 계정의 모든 구조에 있는 모든 기기를 가져옵니다. 추가 검색 및 필터링 옵션을 제공하는 HomeObjectsFlow를 반환합니다.

HomeDevice이 있으면 다음 API를 통해 액세스할 수 있습니다.

API 설명
allCandidates() 기기와 그 하위 요소의 모든 자동화 후보를 반환합니다.
candidates() 기기의 모든 자동화 후보를 반환합니다.
connectivityStateChanged 기기 상태가 가장 최근에 변경된 시간입니다.
events(event) 특정 이벤트의 흐름을 가져옵니다.
events(trait) 이 특성의 모든 이벤트 흐름을 가져옵니다.
events(traits) 이러한 특성별로 모든 이벤트의 흐름을 가져옵니다.
getSourceConnectivity(trait) 특정 특성의 메타데이터를 가져옵니다. SourceConnectivity를 반환합니다.
has(trait) 현재 요청된 특성이 기기에서 지원되는지 확인합니다.
has(type) 기기에서 제공된 유형을 지원하는 경우
id 기기의 고유 시스템 ID입니다.
isInRoom 기기가 방에 있는 경우
isInStructure 기기가 구조에 있는 경우
isMatterDevice 기기가 Matter로 지원되는 경우
name 사용자가 제공한 기기 이름입니다.
room() 기기가 할당된 방입니다. Room를 반환합니다.
roomId 기기가 할당된 방의 ID입니다. Id을 반환합니다.
sourceConnectivity 기기의 소스 연결로, 기기 특성의 집계된 연결 상태와 네트워크 지역성을 나타냅니다.
structure() 기기가 할당된 구조입니다. Structure를 반환합니다.
structureId 기기가 할당된 구조의 ID입니다. Id을 반환합니다.
type(type) 직접 액세스를 위해 특성이 채워진 유형 정의를 가져옵니다 (사용 가능한 경우). 항상 최신 특성 스냅샷을 반환합니다.
types() 기기에서 사용 가능한 모든 유형의 목록을 가져옵니다.