카메라 기기 유형은 세 가지 특성을 사용하여 구현됩니다. PushAvStreamTransport는 푸시 기반 프로토콜을 사용하여 오디오 및 동영상 스트림 전송을 처리하고, WebRtcLiveView는 실시간 스트림 및 토크백을 제어하는 기능을 제공하며, CameraSnapshot는 캐시된 미리보기 스냅샷 및 실시간 스냅샷 캡처를 제공합니다.
기능을 사용하거나 속성을 업데이트하기 전에 항상 기기의 속성 및 명령어 지원을 확인하세요. 자세한 내용은 Android에서 기기 제어를 참고하세요.
| Home API 기기 유형 | 특성 | Kotlin 샘플 앱 | 사용 사례 |
|---|---|---|---|
|
카메라
정지 이미지 또는 동영상을 캡처하는 기기입니다. 카메라에는 액세스 가능한 라이브 스트림, 양방향 대화 또는 감지 활동이 포함될 수 있습니다. |
필수 특성 google PushAvStreamTransport google WebRtcLiveView |
카메라 |
기기에 관한 기본 정보 가져오기
BasicInformation 특성에는 기기의 공급업체 이름, 공급업체 ID, 제품 ID, 제품 이름 (모델 정보 포함), 소프트웨어 버전과 같은 정보가 포함됩니다.
// Get device basic information. All general information traits are on the RootNodeDevice type. device.type(RootNodeDevice).first().standardTraits.basicInformation?.let { basicInformation -> println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.productId}") println("productName ${basicInformation.productName}") println("softwareVersion ${basicInformation.softwareVersion}") }
일련번호 가져오기
기기의 일련번호를 가져오려면 ExtendedBasicInformation 트레잇의 GetSerialNumber 명령어를 사용합니다.
이 예시에서는 일련번호를 serialNumber라는 변수에 저장하는 방법을 보여줍니다.
val basicInfo: ExtendedBasicInformation = device.getTrait(ExtendedBasicInformation) val serialNumber = basicInfo.getSerialNumber().serialNumber
기기 클라우드 연결의 최근 시간 가져오기
기기가 클라우드와 연결된 가장 최근 시간을 찾으려면 ExtendedGeneralDiagnostics 특성의 lastContactTimestamp 속성을 사용합니다.
fun getLastContactTimeStamp(trait: ExtendedGeneralDiagnostics): java.time.Instant { val timestamp = trait.lastContactTimestamp return Instant.ofEpochSecond(timestamp.toLong()) }
카메라 마운트 유형 설정
Mount 특성에는 카메라 마운트 설정 및 상태 정보가 포함됩니다. 마운트 상태, 감지 유형, 마운트 유형 이름과 같은 속성을 읽을 수 있습니다. 또한 Mount 특성을 사용하여 기본 마운트 유형 구성을 재정의할 수 있습니다.
// Get the Mount trait val mountTrait: Mount = device.getTrait(Mount) // Read the current mount state and detection type val mountState = mountTrait.mountState val mountDetectionType = mountTrait.mountDetectionType // Read the current mount type name val mountTypeName = mountTrait.mountTypeName // Update the mount type override mountTrait.update { setMountTypeOverride(MountTrait.MountTypeOverrideEnum.Official) }
기기 연결 확인
일부 기기는 여러 기기 유형을 지원하므로 기기의 연결은 실제로 기기 유형 수준에서 확인됩니다. 반환되는 상태는 해당 기기의 모든 특성에 대한 연결 상태의 조합입니다.
val cameraConnectivity = cameraDevice.metadata.sourceConnectivity.connectivityState
인터넷 연결이 없는 경우 혼합 기기 유형에서 PARTIALLY_ONLINE 상태가 관찰될 수 있습니다.
Matter 표준 특성은 로컬 라우팅으로 인해 온라인 상태일 수 있지만 클라우드 기반 특성은 오프라인 상태입니다.
기기의 IP 주소 가져오기
기기의 IP 주소를 찾으려면 GeneralDiagnostics 속성의 networkInterfaces 속성을 사용합니다. 주소는 바이트 배열로 반환되며, 이를 표준 IPv4 또는 IPv6 문자열로 형식 지정할 수 있습니다.
val ipAddresses =
trait.networkInterfaces?.flatMap { networkInterface ->
(networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
try {
java.net.InetAddress.getByAddress(bytes).hostAddress
} catch (e: java.net.UnknownHostException) {
null
}
}
} ?: emptyList()
라이브 스트림 시작
라이브 스트림을 시작하려면 세션 설명 프로토콜 (SDP) 문자열을 WebRtcLiveView 트레잇의 startLiveView() 메서드로 전송합니다. 이 메서드는 다음 세 가지 값이 포함된 WebRtcLiveViewTrait.StartLiveViewCommand.Response를 반환합니다.
- 세션의 SDP입니다.
- 세션 시간(초)입니다.
- 세션 ID로, 세션을 연장하거나 종료하는 데 사용할 수 있습니다.
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) { return cameraDevice.type(GoogleCameraDevice).trait(WebRtcLiveView).first { it?.metadata?.sourceConnectivity?.connectivityState == ConnectivityState.ONLINE } } // Start the live view suspend fun startCameraStream(trait: WebRtcLiveView, offerSdp: String) { val response = trait.startLiveView(offerSdp) // Response contains three fields (see below) return response } ... // This is used to manage the WebRTC connection val peerConnection: RTCPeerConnection = ... ... val startResponse = startCameraStream(sdp) val answerSdp = startResponse?.answerSdp val sessionDuration = startResponse?.liveSessionDurationSeconds val mediaSessionId = startResponse?.mediaSessionId peerConnection.setRemoteDescription(SessionDescription.Type.ANSWER, answerSdp)
라이브 스트림 연장하기
라이브 스트림은 미리 설정된 기간이 지나면 만료됩니다. 활성 스트림의 기간을 연장하려면 WebRtcLiveView.extendLiveView() 메서드를 사용하여 연장 요청을 실행합니다.
// Assuming camera stream has just been started suspend fun scheduleExtension(trait: WebRtcLiveView, mediaSessionId: String, liveSessionDurationSeconds: UShort ) { delay(liveSessionDurationSeconds - BUFFER_SECONDS * 1000) val response = trait.extendLiveView(mediaSessionId) // returns how long the session will be live for return response.liveSessionDurationSeconds }
TalkBack 시작 및 중지
TalkBack을 시작하려면 WebRtcLiveView 트레잇의 startTalkback() 메서드를 호출합니다. 중지하려면 stopTalkback()를 사용합니다.
// Make sure camera stream is on suspend fun setTalkback(isOn: Boolean, trait: WebRtcLiveView, mediaSessionId: String) { if(isOn) { trait.startTalkback(mediaSessionId) } else { trait.stopTalkback(mediaSessionId) } }
라이브 스트림 관리
라이브 스트림 품질을 조정하면 클라이언트의 시청 컨텍스트에 따라 대역폭 사용량을 최적화하는 데 유용합니다 (예: 작은 미리보기 타일, 그리드 보기 또는 PIP 모드를 표시할 때 더 낮은 해상도로 전환).
WebRtcLiveView 속성을 사용하여 품질을 동적으로 변경하면 특정 클라이언트에서 활성 라이브 스트림 세션의 해상도를 구체적으로 관리할 수 있습니다. 이는 기기에서 직접 기기 전체의 대역폭 사용량 설정을 구성하는 것과는 다릅니다. 기기에서 직접 구성하면 동시 시청자 수와 클라우드에 저장된 이전 동영상 녹화물의 품질에 영향을 미칩니다.
다음 예에서는 기기의 라이브 스트림 품질을 검색하고 업데이트하는 방법을 보여줍니다.
지원되는 품질 옵션 가져오기: 기기에서 지원하는 사용 가능한 스트리밍 해상도를 가져옵니다. 코드는 기기 유형 흐름에서
WebRtcLiveView특성의supportedQualityHints속성을 쿼리하고 지원되는 품질을QualityHint값 (예:QUALITY_HINT_SD,QUALITY_HINT_HD,QUALITY_HINT_FHD,QUALITY_HINT_QHD,QUALITY_HINT_UHD) 목록이 포함된StateFlow로 노출합니다.라이브 스트림 품질 변경: 선택한
QualityHint를 적용하여 활성 라이브 스트림의 스트리밍 해상도를 변경합니다(예: 표준 화질에서 고화질로 전환).changeQuality함수는 기기의 라이브 스트리밍 특성을 확인하고 활성mediaSessionId및 선택한QualityHint구성으로changeLiveViewQuality를 호출합니다.
// Assuming you have a HomeDevice instance 'device' val availableQualityHints: StateFlow<List> = device.type(GoogleCameraDevice) .trait(WebRtcLiveView) .map { trait -> trait?.supportedQualityHints ?: emptyList() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) // Assuming you have a HomeDevice instance 'device' suspend fun changeQuality(mediaSessionId: String, qualityHint: QualityHint) { // Get the trait from the device val trait = device.type(GoogleCameraDevice).trait(WebRtcLiveView).first() ?: return try { trait.changeLiveViewQuality(mediaSessionId, qualityHint) } catch (e: Exception) { // Handle error } }
녹화 기능 사용 설정 및 중지
카메라의 녹화 기능을 사용 설정하려면 TransportStatusEnum.Active를 PushAvStreamTransport 트레잇의 setTransportStatus() 메서드에 전달합니다. 녹화 기능을 사용 중지하려면 TransportStatusEnum.Inactive를 전달합니다.
다음 예에서는 이러한 호출을 Boolean를 사용하여 녹음 기능을 전환하는 단일 호출로 래핑합니다.
// Start or stop recording for all connections. suspend fun setCameraRecording(trait: PushAvStreamTransport, isOn: Boolean) { if(isOn) { trait.setTransportStatus(TransportStatusEnum.Active) } else { trait.setTransportStatus(TransportStatusEnum.Inactive) } }
카메라의 녹화 기능을 사용 설정하거나 사용 중지하는 것은 카메라 동영상을 사용 설정하거나 사용 중지하는 것과 같습니다. 카메라 동영상이 사용 설정되면 녹화됩니다 (활동 및 관련 클립 목적).
녹화 기능이 사용 중지된 경우 (카메라 동영상이 꺼져 있음):
- 카메라는 기기 유형의
connectivityState에 따라 온라인으로 계속 표시될 수 있습니다. - 라이브 스트림에 액세스할 수 없으며 카메라가 클라우드 이벤트를 감지하지 않습니다.
녹화 기능이 사용 설정되어 있는지 확인하기
카메라의 녹화 기능이 사용 설정되어 있는지 확인하려면 활성 상태인 연결이 있는지 확인합니다. 다음 예시에서는 이를 위해 두 가지 함수를 정의합니다.
// Get the on/off state suspend fun onOffState(pushAvStreamTransport: PushAvStreamTransport) { return pushAvStreamTransport .currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false } // Check if the camera's recording capability is enabled fun PushAvStreamTransport.recordModeActive(): Boolean { return currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false }
또 다른 확인 방법은 조건자와 함께 findTransport() 함수를 사용하는 것입니다.
// Fetch the current connections suspend fun queryRecordModeState(trait: PushAvStreamTransport) { return trait.findTransport().let { it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active } }
카메라 스냅샷 가져오기
CameraSnapshot 특성을 사용하여 카메라에서 정적 이미지 스냅샷을 가져옵니다.
이러한 스냅샷은 여러 시나리오에서 유용합니다.
- WebRTC 라이브 스트림이 로드되는 동안 UI의 자리표시자 타일로 사용됩니다.
- 사용자 상호작용 시 라이브 스트림으로 업그레이드되는 정적 미리보기 이미지
- 맞춤 활동 감지 구역을 그리고 구성하기 위한 배경 캔버스
CameraSnapshot 특성은 빠른 렌더링을 위해 캐시된 스냅샷이 필요한지 아니면 주문형 실시간 스냅샷이 필요한지에 따라 스냅샷을 가져오는 두 가지 방법을 제공합니다.
캐시된 미리보기 스냅샷 가져오기
미리보기 스냅샷은 SDK가 카메라를 깨우지 않고 가져올 수 있는 캐시된 이미지입니다. 이 방법은 정적 이미지를 가져오는 가장 빠른 방법이며 카메라 개요 페이지나 대시보드 그리드에 적합합니다.
미리보기 스냅샷을 가져오려면 preview_image_url 특성 속성을 읽습니다.
// Get a flow of the CameraSnapshot trait val cameraSnapshotFlow: Flow<CameraSnapshot?> = cameraDevice .type(GoogleCameraDevice) .trait(CameraSnapshot) // Get the current trait state val cameraSnapshot = cameraSnapshotFlow.firstOrNull() if (cameraSnapshot != null) { val previewImageUrl = cameraSnapshot.previewImageUrl // Load the preview image from the URL } else { // CameraSnapshot trait not supported on this device }
카메라 구성 및 활동에 따라 미리보기 URL은 최근 동영상 영상 (최신 동영상 프래그먼트의 첫 번째 I-프레임)에서 생성된 캐시된 이미지 또는 카메라에서 주기적으로 업로드한 스냅샷을 가리킵니다.
이미지의 최신 상태를 나타내기 위해 Google Home 클라우드는 제공된 JPEG/PNG 이미지에 UTC 형식의 X-Home-Image-Captured-At 헤더를 삽입합니다. 클라이언트 측에서 이 헤더를 파싱하여 앱에 스냅샷의 경과 시간을 표시할 수 있습니다.
주문형 실시간 스냅샷 가져오기
활동 감지 구역 설정과 같이 카메라의 현재 실시간 보기가 필요한 사용자 여정의 경우 실시간 스냅샷을 요청할 수 있습니다. 실시간 스냅샷을 트리거하면 카메라가 절전 모드에서 해제되고 새 프레임을 캡처하여 클라우드에 업로드합니다.
라이브 스냅샷을 요청하려면 getLiveSnapshot() 명령어를 사용합니다.
try { val response = cameraSnapshot.getLiveSnapshot() val snapshotUrl = response.snapshotUrl // Load the live snapshot image from the URL } catch (e: Exception) { Log.e("CameraSnapshot", "Failed to get live snapshot: ${e.message}") }
스냅샷 요청 인증
모든 스냅샷 URL은 보안 미디어를 가리키며 Home API v2 범위에 대한 OAuth 2.0 토큰이 필요합니다. 이미지를 다운로드하고 렌더링하려면 OAuth 토큰을 HTTP 요청의 Authorization 헤더에 Bearer 토큰으로 삽입해야 합니다.
다음 예시에서는 스냅샷을 다운로드하기 위해 보안 네트워크 요청을 구성하는 방법을 보여줍니다.
import android.graphics.Bitmap import android.graphics.BitmapFactory import java.io.IOException import java.net.HttpURLConnection import java.net.URL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext /** * Downloads a snapshot from a URL using an OAuth access token. */ suspend fun loadSnapshotImage(urlString: String, oauthToken: String): Bitmap? = withContext(Dispatchers.IO) { var connection: HttpURLConnection? = null try { val url = URL(urlString) connection = url.openConnection() as HttpURLConnection // 1. Configure the HTTP GET request with the Bearer token connection.setRequestProperty("Authorization", "Bearer $oauthToken") // 2. Fetch the image data if (connection.responseCode == HttpURLConnection.HTTP_OK) { connection.inputStream.use { inputStream -> BitmapFactory.decodeStream(inputStream) } } else { null } } catch (e: IOException) { e.printStackTrace() null } finally { connection?.disconnect() } }
배터리 설정
Home API를 통해 다양한 배터리 설정을 제어할 수 있습니다.
배터리 사용 환경설정 지정
에너지 균형을 설정하면 기기의 배터리 수명과 성능 간의 균형을 구성할 수 있습니다. 'Extended', 'Balanced', 'Performance'와 같은 다양한 배터리 프로필을 만들고 전환할 수 있습니다.
이 기능은 EnergyPreference 특성의 currentEnergyBalance 속성을 업데이트하여 구현됩니다. 이 속성은 기기의 energyBalances 목록에 정의된 특정 프로필에 상응하는 정수 색인을 허용합니다 (예: EXTENDED의 경우 0, BALANCED의 경우 1, PERFORMANCE의 경우 2).
currentEnergyBalance의 null 값은 기기가 맞춤 프로필을 사용하고 있음을 나타냅니다. 읽기 전용 상태입니다.
다음은 currentEnergyBalance 속성이 사용할 구조의 예시와 이 속성을 사용하는 실제 코드 스니펫입니다.
// Example energyBalances list energy_balances: [ { step: 0, label: "EXTENDED" }, { step: 50, label: "BALANCED" }, { step: 100, label: "PERFORMANCE" } ]
// The index parameter must be within the UByte range (0-255). suspend fun setEnergyBalance(trait: EnergyPreference, index: Int) { trait.update { setCurrentEnergyBalance(index.toUByte()) } } // Setting the battery usage to more recording ie performance setEnergyBalance(energyPreference, 2)
자동 절전 모드 사용 설정
이 기능을 구성하려면 EnergyPreference 속성의 currentLowPowerModeSensitivity 속성을 업데이트합니다. 이 속성은 색인을 사용하여 민감도 수준을 선택합니다. 여기서 0은 일반적으로 Disabled을 나타내고 1은 Enabled 또는 Automatic을 나타냅니다.
suspend fun setAutomaticBatterySaver(enable: Boolean, trait: EnergyPreference) { // 0 is Disabled, 1 is Enabled val value = if (enable) 1.toUByte() else 0.toUByte() trait.update { setCurrentLowPowerModeSensitivity(value) } }
배터리 충전 상태 가져오기
기기의 현재 충전 상태 (충전 중, 완전히 충전됨, 충전 중이 아님)를 가져오려면 PowerSource 속성의 batChargeState 속성을 사용합니다.
// Get the battery charging state val batteryChargeState = powerSource.batChargeState when (batteryChargeState) { PowerSourceTrait.BatChargeStateEnum.IsCharging -> "Charging" PowerSourceTrait.BatChargeStateEnum.IsAtFullCharge -> "Full" PowerSourceTrait.BatChargeStateEnum.IsNotCharging -> "Not Charging" else -> "Unknown" }
배터리 잔량 확인
현재 배터리 잔량을 가져오려면 PowerSource 속성의 batChargeLevel 속성을 사용합니다. 수준은 OK, Warning (낮음) 또는 Critical입니다.
// Get the battery charge level val batteryLevel = powerSourceTrait.batChargeLevel when (batteryLevel) { PowerSourceTrait.BatChargeLevelEnum.OK -> "OK" PowerSourceTrait.BatChargeLevelEnum.Warning -> "Warning" PowerSourceTrait.BatChargeLevelEnum.Critical -> "Critical" else -> "Unknown" }
전원 가져오기
기기에서 사용 중인 전원을 확인하려면 PowerSource 속성의 BatPresent 및 wiredPresent 속성을 사용합니다.
val trait: PowerSource val isWired = trait.wiredPresent val hasBattery = trait.batPresent
배터리를 교체해야 하는지 확인하기
batReplaceability 속성은 배터리가 교체 불가능한지, 사용자가 교체할 수 있는지, 공장에서 교체할 수 있는지를 나타냅니다.
PowerSource 속성의 batReplacementNeeded 속성은 배터리를 교체해야 하는지 여부를 알려줍니다.
// Get the battery replacement status val batteryStatus = powerSourceTrait.batReplacementNeeded if (batteryStatus) { println("Replace the battery.") }
배터리를 사용자가 교체할 수 있는 경우 batReplacementDescription는 폼 팩터, 화학, 선호하는 제조업체와 같은 정보를 포함하여 배터리를 설명합니다.
오디오 설정
Home API를 통해 다양한 오디오 설정을 제어할 수 있습니다.
마이크 켜거나 끄기
기기의 마이크를 사용 설정 또는 사용 중지하려면 내장된 setMicrophoneMuted Kotlin 함수를 사용하여 CameraAvStreamManagement 트레잇의 microphoneMuted 속성을 업데이트합니다.
// Turn the device's microphone on or off suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) { trait.update { setMicrophoneMuted(disableMicrophone) } }
오디오 녹음 사용 설정 또는 사용 중지하기
기기의 오디오 녹음을 사용 설정 또는 중지하려면 내장된 setRecordingMicrophoneMuted Kotlin 함수를 사용하여 CameraAvStreamManagement 특성의 recordingMicrophoneMuted 속성을 업데이트합니다.
// Turn audio recording on or off for the device suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) { trait.update { setRecordingMicrophoneMuted(disableAudioRecording) } }
스피커 볼륨 조정하기
기기의 스피커 볼륨을 조정하려면 내장된 setSpeakerVolumeLevel Kotlin 함수를 사용하여 CameraAvStreamManagement 특성의 speakerVolumeLevel 속성을 업데이트합니다.
// Adjust the camera speaker volume suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) { trait.update { setSpeakerVolumeLevel(volume.toUbyte()) } }
활동 감지 구역 설정
ZoneManagement 특성은 카메라 및 초인종 기기에서 맞춤 관심 영역 (활동 감지 구역)을 관리하기 위한 인터페이스를 제공합니다.
이러한 구역은 기기의 시야 내에서 특정 영역으로 활동 감지 (예: 사람 또는 차량 움직임)를 필터링하는 데 사용됩니다.
활동 감지 구역은 사용자가 파트너 애플리케이션 내에서 구성하며, 카메라의 시야 내 특정 영역에 구역을 그릴 수 있습니다. 그런 다음 이러한 사용자 정의 영역은 이 특성에서 사용하는 구조로 변환됩니다. 활동 감지 구역의 작동 방식에 관한 자세한 내용은 활동 감지 구역 설정 및 사용하기를 참고하세요.
활동 감지 구역은 일반적으로 2D 직교 좌표를 사용하여 정의됩니다.
이 특성은 꼭짓점의 TwoDCartesianVertexStruct와 영역 정의 (이름, 꼭짓점, 색상, 사용량)의 TwoDCartesianZoneStruct를 제공합니다.
활동 감지 구역 확인하기
활동 감지 구역을 표시하려면 ZoneManagement 특성의 zones 속성을 확인하세요.
// 1. Obtain the trait flow from the device private val zoneManagementFlow: Flow= device.type(CAMERA_TYPE).flatMapLatest { it.trait(ZoneManagement) } // 2. Map the flow to the list of zone structures val activityZones: Flow<List<ZoneManagementTrait.ZoneInformationStruct>> = zoneManagementFlow.map { trait -> trait.zones ?: emptyList() }
활동 감지 구역 추가하기
새 영역을 만들려면 createTwoDCartesianZone 명령어를 사용합니다. 이 명령어는 영역의 이름, 꼭짓점, 색상, 사용을 정의하는 TwoDCartesianZoneStruct를 사용합니다.
다음 예시에서는 4개의 꼭짓점이 있고 연어색 (#F439A0)이며 움직임 감지에 사용되는 'Front Porch'라는 영역을 만드는 방법을 보여줍니다.
import com.google.home.google.ZoneManagement import com.google.home.google.ZoneManagementTrait import com.google.home.matter.serialization.OptionalValue /** * Creates a custom activity zone named "Front Porch" with a salmon color * configured for motion detection. */ suspend fun createFrontPorchZone(zoneManagement: ZoneManagement) { // 1. Define the vertices for the zone (2D Cartesian coordinates) // Values are typically scaled to a maximum defined by the device's twoDCartesianMax attribute. val vertices = listOf( ZoneManagementTrait.TwoDCartesianVertexStruct(x = 260u, y = 422u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1049u, y = 0u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048u, y = 0u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048u, y = 950u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1630u, y = 1349u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 880u, y = 2048u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 0u, y = 2048u), ZoneManagementTrait.TwoDCartesianVertexStruct(x = 638u, y = 1090u) ) // 2. Define the zone structure val newZone = ZoneManagementTrait.TwoDCartesianZoneStruct( name = "Front Porch", vertices = vertices, // Usage defines what the zone filters (for example, Motion, Person, Vehicle) use = listOf(ZoneManagementTrait.ZoneUseEnum.Motion), // Color is typically a hex string (for example, Salmon/Pink) color = OptionalValue.present("#F439A0") ) try { // 3. Execute the command to add the zone to the device zoneManagement.createTwoDCartesianZone(newZone) println("Successfully created activity zone.") } catch (e: Exception) { // Handle potential HomeException or Timeout println("Failed to create activity zone: ${e.message}") } }
활동 감지 구역 업데이트하기
기존 영역을 업데이트하려면 updateTwoDCartesianZone 명령어를 사용합니다. 이 명령어를 사용하려면 zoneId 및 업데이트된 TwoDCartesianZoneStruct가 필요합니다.
private suspend fun ZoneManagement.updateZone( zoneId: UShort, zone: ZoneManagementTrait.TwoDCartesianZoneStruct ) { // Execute the command to update the zone this.updateTwoDCartesianZone(zoneId = zoneId, zone = zone) }
활동 감지 구역 삭제하기
영역을 삭제하려면 특정 zoneId와 함께 removeZone 명령어를 사용합니다.
private suspend fun ZoneManagement.deleteZone(zoneId: UShort) { // Execute the command to remove the zone this.removeZone(zoneId = zoneId) }
소리 활동 트리거
AvStreamAnalysis 특성은 카메라 및 초인종 기기에서 활동 감지 트리거를 관리하기 위한 인터페이스를 제공합니다. 시각 기반 트리거(예: 사람 또는 차량)는 영역별로 지정할 수 있지만 소리 관련 트리거는 일반적으로 기기 수준 구성입니다.
EventTriggerTypeEnum를 사용한 소리 감지에는 다음 트리거 유형을 사용할 수 있습니다.
| 모드 | enum 값 | 설명 |
|---|---|---|
| 소리 | Sound |
일반 소리 감지 |
| 말소리 | PersonTalking |
음성을 감지합니다. |
| 개 짖는 소리 | DogBark |
개 소리를 감지합니다. |
| 유리 깨짐 | GlassBreak |
유리 깨지는 소리를 감지합니다. |
| 연기 경보 | SmokeAlarm |
연기 경보기를 감지합니다. 일반적으로 T3 가청 패턴 (짧은 경고음 3회 후 일시중지)으로 인식됩니다. |
| 일산화탄소 경보 | CoAlarm |
일산화탄소 (CO) 경보를 감지합니다. 일반적으로 T4 가청 패턴 (짧은 경고음 4회 후 일시중지)으로 인식됩니다. |
소리 감지 상태 확인하기
사용자에게 소리 감지의 현재 상태를 표시하려면 기기에서 지원하는 기능과 기기 하드웨어에서 사용 설정된 기능을 확인해야 합니다. 확인해야 할 두 가지 속성은 다음과 같습니다.
Kotlin Flow를 사용하는 Android 개발에서는 일반적으로 HomeDevice에서 AvStreamAnalysis 특성을 관찰합니다.
// Example structure to store the data class EventTriggerAttribute(val type: EventTriggerTypeEnum, val enabled: Boolean) // 1. Obtain the trait flow from the device private val avStreamAnalysisFlow: Flow<AvStreamAnalysis> = device.traitFromType(AvStreamAnalysis, CAMERA_TYPES.first { device.has(it) }) // 2. Map the flow to a list of sound event attributes val soundEventTriggersState: Flow<List<EventTriggerAttribute>> = avStreamAnalysisFlow.map { trait -> // Get raw lists from the trait attributes val supported = trait.supportedEventTriggers ?: emptyList() val enabled = trait.enabledEventTriggers ?: emptyList() // Define sound-specific triggers to filter for val soundTypes = setOf( EventTriggerTypeEnum.Sound, EventTriggerTypeEnum.PersonTalking, EventTriggerTypeEnum.DogBark, EventTriggerTypeEnum.GlassBreak, EventTriggerTypeEnum.SmokeAlarm, EventTriggerTypeEnum.CoAlarm, ) // Filter and associate status supported .filter { soundTypes.contains(it) } .map { type -> EventTriggerAttribute( type = type, enabled = enabled.contains(type) ) } }
사용 설정된 트리거 집합 업데이트
사용 설정된 트리거 집합을 업데이트하려면 SetOrUpdateEventDetectionTriggers 명령어를 사용합니다. 이 명령어는 EventTriggerEnablement 구조 목록을 사용합니다.
private suspend fun AvStreamAnalysis.updateEventTriggers( eventTriggers: List<EventTriggerAttribute> ) { val toUpdate = eventTriggers.map { EventTriggerEnablement( eventTriggerType = it.type, enablementStatus = if (it.enabled) { EnablementStatusEnum.Enabled } else { EnablementStatusEnum.Disabled }, ) } // Execute the command on the device setOrUpdateEventDetectionTriggers(toUpdate) }
녹화 모드
RecordingMode 특성은 카메라 및 초인종 기기의 동영상 및 이미지 녹화 동작을 관리하는 인터페이스를 제공합니다. 사용자는 연속 녹화, 활동 기반 녹화, 녹화 완전히 사용 중지 (실시간 보기만 사용) 중에서 선택할 수 있습니다.
RecordingModeEnum는 사용 가능한 녹음 전략을 정의합니다.
| 모드 | enum 값 | 설명 |
|---|---|---|
| 사용 중지됨 | Disabled |
녹화가 완전히 사용 중지되었습니다. 주로 기존 기기에서 사용됩니다. |
| CVR (연속 동영상 녹화) | Cvr |
동영상이 연중무휴 24시간 녹화됩니다. 구독이 필요합니다(예: Google Home Premium). |
| EBR (활동 기반 녹화) | Ebr |
녹화는 이벤트 (사람, 움직임)에 의해 트리거됩니다. 동영상 길이는 활동 지속 시간과 요금제에 따라 다릅니다. |
| ETR (활동 감지 녹화) | Etr |
이벤트에 의해 트리거되는 짧은 미리보기 녹화 (예: 10초) |
| 라이브 뷰 | LiveView |
녹화는 사용 중지되지만 사용자는 계속 라이브 스트림에 액세스할 수 있습니다. |
| 정지 이미지 | Images |
활동이 발생하면 동영상 대신 스냅샷이 녹화됩니다. |
녹화 모드 확인하기
현재 녹화 구성을 표시하려면 RecordingMode 특성의 속성을 확인합니다.
supportedRecordingModes- 모든 잠재적 모드availableRecordingModes- 선택 가능한 모드selectedRecordingMode- 활성 모드
// 1. Obtain the trait flow from the device private val recordingModeTraitFlow: Flow= device.traitFromType(RecordingMode, CAMERA_TYPES.first { device.has(it) }) // 2. Map the flow to recording mode options data class RecordingModeOptions( val recordingMode: RecordingModeTrait.RecordingModeEnum, val index: Int, val available: Boolean, val readableString: String, ) private val recordingModeOptions: Flow<List > = recordingModeTraitFlow.map { trait -> val supported = trait.supportedRecordingModes?.map { it.recordingMode } ?: emptyList() val available = trait.availableRecordingModes?.map { it.toInt() } ?: emptyList() supported.withIndex().map { (index, mode) -> RecordingModeOptions( recordingMode = mode, index = index, available = available.contains(index), readableString = mode.toReadableString(), ) } }
녹화 모드 변경하기
업데이트하기 전에 supportedRecordingModes 속성에서 선택한 색인이 availableRecordingModes 속성에 있는지 확인합니다.
선택한 모드를 업데이트하려면 setSelectedRecordingMode 함수를 사용하여 선택한 모드의 색인을 전달합니다.
private suspend fun RecordingMode.updateRecordingMode(index: Int) { // Execute the command to update the selected mode this.setSelectedRecordingMode(index.toUByte()) }
기타 설정
Home API를 통해 다양한 기타 설정을 제어할 수 있습니다.
이미지 방향 변경
카메라 이미지 (동영상)의 방향을 회전할 수 있습니다. 동영상은 180도만 회전할 수 있습니다.
카메라의 이미지 방향을 변경하려면 내장된 setImageRotation Kotlin 함수를 사용하여 CameraAvStreamManagement 특성의 imageRotation 속성을 업데이트합니다.
// Change the camera's image orientation val isRotated = false cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }
야간 적외선 조명 사용 설정 또는 중지하기
카메라의 야간 투시 기능을 사용 설정하거나 사용 중지하려면 TriStateAutoEnum를 사용하여 기본 제공 setNightVision Kotlin 함수를 통해 CameraAvStreamManagement 트레잇의 nightVision 속성을 업데이트합니다.
// Turn night vision on cameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On) } // Turn night vision off CameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off) }
상태 LED의 밝기 변경하기
상태 LED의 밝기를 변경하려면 ThreeLevelAutoEnum를 사용하여 기본 제공 setStatusLightBrightness Kotlin 함수를 통해 CameraAvStreamManagement 트레잇의 statusLightBrightness 속성을 업데이트합니다.
// Set the LED brightness to high cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High) } // Set the LED brightness to low cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low) }
카메라 표시 영역 변경
카메라 표시 영역은 Nest 카메라 동영상 확대 및 보정 지원 도움말에 설명된 확대 및 자르기 기능과 동일합니다.
표시 영역은 표시 영역의 좌표로 사용되는 4개의 값이 포함된 ViewportStruct에 정의됩니다. 좌표는 다음과 같이 정의됩니다.
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
ViewportStruct의 값을 결정하는 것은 앱의 UI 및 카메라 구현에 따라 다릅니다. 가장 기본적인 수준에서 카메라 동영상의 표시 영역을 설정하려면 내장된 setViewport Kotlin 함수를 사용하여 CameraAvStreamManagement 특성의 viewport 속성을 ViewportStruct로 업데이트합니다.
cameraAvStreamManagement .update { setViewport( CameraAvStreamManagementTrait.ViewportStruct( x1 = horizontalRange.rangeStart.roundToInt().toUShort(), x2 = horizontalRange.rangeEnd.roundToInt().toUShort(), y1 = verticalRange.rangeStart.roundToInt().toUShort(), y2 = verticalRange.rangeEnd.roundToInt().toUShort(), ) ) }
분석 사용 설정 또는 사용 중지
각 기기는 개별적으로 Google Home 클라우드에 상세 분석 데이터를 전송하도록 선택할 수 있습니다 (Home API용 Cloud Monitoring 참고).
기기의 분석을 사용 설정하려면 ExtendedGeneralDiagnosticsTrait의 analyticsEnabled 속성을 true로 설정합니다. analyticsEnabled를 설정하면 다른 속성인 logUploadEnabled가 자동으로 true로 설정되어 분석 로그 파일을 Google Home 클라우드에 업로드할 수 있습니다.
// Enable analytics extendedGeneralDiagnostics.update { setAnalyticsEnabled(true) } // Disable analytics extendedGeneralDiagnostics.update { setAnalyticsEnabled(false) }
전송 및 녹화 구성
이 섹션에서는 카메라 스트리밍 품질 및 이벤트 트리거와 관련된 설정을 다룹니다. 이러한 설정은 PushAvStreamTransport 특성으로 관리됩니다.
전송 설정 읽기
이 섹션에서는 카메라 또는 초인종 기기에서 현재 구성을 가져오는 방법을 보여줍니다. PushAvStreamTransport 특성을 가져오고, 녹화에 사용되는 특정 연결을 찾은 다음, 대역폭 품질, 카메라 센서 민감도, 최대 이벤트 길이에 대한 현재 값을 추출합니다.
val trait: PushAvStreamTransport = device.getTrait(PushAvStreamTransport) val connections = trait.findTransport().transportConfigurations // Locate the connection designated for recording val recordingConnection = connections.firstOrNull { it.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording } val options = recordingConnection?.transportOptions?.getOrNull() // 1. Bandwidth Quality (Video Stream ID) val videoStreamId = options?.videoStreamId?.getOrNull() // 2. Wake-up Sensitivity (Motion Sensitivity) val wakeUpSensitivity = options?.triggerOptions?.motionSensitivity?.getOrNull() // 3. Max Event Length (Motion Trigger Time Control) val maxEventLength = options?.triggerOptions?.motionTimeControl?.getOrNull()?.maxDuration
전송 설정 업데이트
이 섹션에서는 전송 설정을 변경하는 방법을 보여줍니다.
새 값이 포함된 새 TransportOptionsStruct를 만든 다음 modifyPushTransport 명령어를 사용하여 업데이트된 설정을 기기로 다시 전송하고 이전 단계에서 찾은 녹음 연결에 적용합니다.
이러한 설정을 수정하려면 modifyPushTransport 명령어를 TransportOptionsStruct와 함께 사용합니다.
val toUpdate = TransportOptionsStruct( videoStreamId = OptionalValue.present(2u), // e.g., Max Quality triggerOptions = TransportTriggerOptionsStruct( motionSensitivity = OptionalValue.present(5u), // e.g., Medium motionTimeControl = OptionalValue.present( TransportMotionTriggerTimeControlStruct(maxDuration = 30u) ) ) ) if (recordingConnection != null) { trait.modifyPushTransport( connectionId = recordingConnection.connectionId, transportOptions = toUpdate ) }
대역폭 품질 확인
TransportOptionsStruct의 videoStreamId 속성은 특정 동영상 스트림 구성에 상응합니다.
지원되는 동영상 스트림을 가져오려면 VideoStreamStructs 목록인 allocatedVideoStreams 속성을 참고하세요.
기기의 CameraAvStreamManagement 특성에서 가져옵니다.
기기 절전 모드 해제 민감도 조정하기
TransportTriggerOptionsStruct의 motionSensitivity 속성은 다음 값에 해당합니다.
| 라벨 | 값 (UByte) |
|---|---|
| 낮음 | 1u |
| 보통 | 5u |
| 높음 | 10u |
최대 이벤트 길이 조정
TransportMotionTriggerTimeControlStruct의 maxDuration 속성은 다음 기간 (초)에 해당합니다.
- 10u, 15u, 30u, 60u, 120u, 180u
기기 사용 중단
구조에서 카메라를 삭제하려면 device.decommissionDevice()를 호출합니다. 사용 중지하면 Google에서 관리하는 확인 화면이 사용자에게 표시되어, 기록된 모든 연속 동영상 기록, 활동 내역, 클립, 아는 사람 라이브러리 데이터가 집 전체에서 영구적으로 삭제된다는 경고가 표시됩니다.
자세한 안내와 코드 예시는 기기 삭제를 참조하세요.