門鈴裝置類型是透過兩種特徵實作:PushAvStreamTransport,可使用以推送為基礎的通訊協定處理音訊和影片串流傳輸;WebRtcLiveView,可控制即時串流和對講功能。
使用任何功能或嘗試更新屬性之前,請務必先檢查裝置是否支援屬性和指令。詳情請參閱「透過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}") println("serialNumber ${basicInformation.serialNumber}") }
檢查裝置的連線狀態
裝置的連線狀態實際上是在裝置類型層級檢查,因為部分裝置支援多種裝置類型。傳回的狀態是該裝置上所有特徵的連線狀態組合。
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
如果沒有網際網路連線,且裝置類型混用,可能會出現 PARTIALLY_ONLINE 狀態。Matter 標準特徵碼可能仍會因本機路由而處於連線狀態,但雲端特徵碼會離線。
開始直播
如要開始直播,請將工作階段描述通訊協定 (SDP) 字串傳送至 WebRtcLiveView 特徵的 startLiveView() 方法,該方法會傳回 WebRtcLiveViewTrait.StartLiveViewCommand.Response,其中包含三個值:
- 工作階段的 SDP。
- 工作階段時間長度 (以秒為單位)。
- 工作階段 ID,可用於延長或終止工作階段。
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) { return cameraDevice.type(GoogleDoorbellDevice).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) } }
啟用及停用錄製功能
如要啟用攝影機的錄影功能,請將
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 } }
電池設定
你可以透過 Home API 控制各種電池設定。
設定電池用量偏好設定
設定能源平衡可讓您在裝置的電池續航力和效能之間取捨。你可以建立不同的電池設定檔,例如「延長續航力」、「平衡」和「效能」,並在這些設定檔之間切換。
如要實作這項功能,請更新 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
音訊設定
你可以透過 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()) } }
其他設定
您也可以透過 Home API 控制其他各種設定。
開啟或關閉夜視模式
如要開啟或關閉攝影機的夜視功能,請使用 TriStateAutoEnum 更新 CameraAvStreamManagement 特徵的 nightVision 屬性,方法是使用內建的 setNightVision Kotlin 函式:
// Turn night vision on cameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On) } // Turn night vision off CameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off) }
變更狀態 LED 燈的亮度
如要變更狀態 LED 的亮度,請使用 ThreeLevelAutoEnum 更新 CameraAvStreamManagement 特徵的 statusLightBrightness 屬性,方法是使用內建的 setStatusLightBrightness Kotlin 函式:
// 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 攝影機影像」支援文章中說明的「縮放及裁剪」功能相同。
視埠定義於包含四個值的 ViewportStruct 中,這些值會做為視埠的座標。座標定義如下:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
判斷 ViewportStruct 的值取決於應用程式的 UI 和相機實作方式。在最基本的層級,如要設定攝影機影片的檢視區塊,請使用內建的 setViewport Kotlin 函式,透過 ViewportStruct 更新 CameraAvStreamManagement 特徵的 viewport 屬性:
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(), ) ) }
調整裝置喚醒靈敏度
裝置的喚醒敏感度可縮減裝置感應活動的範圍,並延長偵測到活動後喚醒裝置的時間,藉此節省電量。
在 Home API 中,這項屬性可透過裝置 transportOptions 中的 motionSensitivity 屬性設定。triggerOptions這些選項是在每個裝置的 PushAvStreamTransport 特徵中定義。
喚醒敏感度只能設為下列值:
- 1 = 低
- 5 = 中
- 10 = 高
如要更新,請使用 findTransport
指令找出有效錄製串流的傳輸設定,然後使用 modifyPushTransport
指令,以新的感應度值修改設定:
// Create a struct with the new wake-up sensitivity val toUpdate = TransportOptionsStruct( triggerOptions = TransportTriggerOptionsStruct( motionSensitivity = OptionalValue.present(wakeUpSensitivity.toUByte()) ) ) // Get the configurations for active connections val connections = pushAvStreamTransport.findTransport().transportConfigurations // Update all recording streams with the new transport options. for (connection in connections) { if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) { trait.modifyPushTransport( connectionId = connection.connectionId, transportOptions = toUpdate, ) } }
調整事件錄影時間上限
事件錄影時間上限是指攝影機錄製事件影像片段的時間長度。透過 Home API,您可以為每個裝置設定與透過 GHA 相同的長度,間隔為秒:
- 10 秒
- 15 秒
- 30 秒
- 60 秒 (1 分鐘)
- 120 秒 (2 分鐘)
- 180 秒 (3 分鐘)
在 Home API 中,這項屬性可透過裝置 transportOptions 中的 motionTimeControl 屬性設定。triggerOptions這些選項是在每個裝置的 PushAvStreamTransport 特徵中定義。
如要更新,請使用 findTransport 指令找出有效錄製串流的傳輸設定,然後使用 modifyPushTransport 指令,以新的事件長度值修改設定:
// Create a struct with the new max event length // where maxDuration is the length in seconds val toUpdate = TransportOptionsStruct( triggerOptions = TransportTriggerOptionsStruct( motionTimeControl = OptionalValue.present( TransportMotionTriggerTimeControlStruct(maxDuration = it.toUInt()) ) ) ) // Get the configurations for active connections val connections = pushAvStreamTransport.findTransport().transportConfigurations // Update all recording streams with the new transport options. for (connection in connections) { if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) { trait.modifyPushTransport( connectionId = connection.connectionId, transportOptions = toUpdate, ) } }
鈴聲設定
你可以透過 Home API 控制各種門鈴鈴聲設定。
變更鈴聲音效
如要變更門鈴鈴聲,請先使用 Chime 特徵的 installedChimeSounds 屬性,取得裝置上安裝的鈴聲清單:
// Get a list of chimes and identify the currently selected one private val doorbellChimeTraitFlow: Flow= device.traitFromType(Chime, GoogleDoorbellDevice) val chimeSounds = doorbellChimeTraitFlow.first().installedChimeSounds ?: emptyList()
然後,使用內建的 setSelectedChime Kotlin 函式,更新 Chime 特徵的 selectedChime 屬性:
// Set the chime using the chimeId from the installed list chimeSounds.firstOrNull { it.name == name }?.let { setSelectedChime(it.chimeId) }
使用外部鈴聲
你可以將門鈴設定為使用外部鈴聲,例如安裝在住家內的機械式電鈴。安裝門鈴時應設定這項功能,以免外部鈴聲可能損壞。
如要指出安裝的外部鈴聲類型,請使用 ExternalChimeType 更新 Chime 特徵的 externalChime 屬性,方法是使用內建的 setExternalChime Kotlin 函式:
// Indicate the external chime is mechanical chime.update { setExternalChime(ChimeTrait.ExternalChimeType.Mechanical) }
變更外部電鈴時長
你可以透過 Home API 設定外部鈴聲的響鈴時間 (以秒為單位)。如果外部鈴聲支援鈴聲持續時間,使用者可能需要設定這項功能。
此處設定的值取決於外部鈴聲本身的規格,以及建議的鈴聲長度。
如要變更外部鈴聲的持續時間,請使用內建的 setExternalChimeDurationSeconds Kotlin 函式,更新 Chime 特徵的 externalChimeDurationSeconds 屬性:
// Change the external chime duration chime.update { setExternalChimeDurationSeconds(newDuration.toUShort()) }
啟用鈴聲主題
部分門鈴可能提供限時鈴聲。例如節慶專屬鈴聲。這些稱為鈴聲主題。
如要查看使用者可用的鈴聲主題,請建立時間範圍篩選器,並使用該篩選器篩選 ChimeThemes 特徵的 getAvailableThemes() 指令結果。這樣會傳回可用主題清單,包括主題名稱。
以下範例說明如何篩選清單。如果目前時間介於主題的開始和結束時間 (分別為 startTimeSeconds 和 endTimeSeconds 值) 之間,系統就會將該主題視為有效。如果未設定開始時間,系統會將其視為從時間開始起就處於有效狀態。如果未設定結束時間,廣告活動會無限期持續放送。如果兩者皆未提供,主題一律會處於啟用狀態。
// Get themes from the ChimeThemes trait fun List<ChimeThemesTrait.ThemeStruct>.filterTimeboxedThemes(): List<ChimeThemesTrait.ThemeStruct> { val now = timeSource.instant().epochSecond.toULong() return filter { chimeStruct: ChimeThemesTrait.ThemeStruct -> val startTime: ULong = chimeStruct.startTimeSeconds.getOrNull() ?: 0UL val endTime: ULong = chimeStruct.endTimeSeconds.getOrNull() ?: MAX_VALUE startTime <= now && now <= endTime } } val availableThemes = doorbellChimeThemesTraitFlow .first() .getAvailableThemes() .themes .filterTimeboxedThemes()
取得所需主題的名稱 (例如 Christmas) 後,即可使用 ChimeThemes 特徵的 setSelectedTimeboxedThemeName() 函式選取該主題:
// Select a theme using the ChimeThemes trait val themeToSelect = "Christmas" if (themeToSelect in availableThemeNames) { doorbellChimeThemesTraitFlow.first().setSelectedTimeboxedThemeName(themeToSelect) }