Android 裝置的門鈴裝置指南

門鈴裝置類型是透過兩種特徵實作: PushAvStreamTransport,使用以推送為基礎的通訊協定處理音訊和影像串流傳輸;以及 WebRtcLiveView,提供控制即時串流和對講功能的權限。

使用任何功能或嘗試更新屬性前,請務必先檢查裝置是否支援屬性和指令。詳情請參閱「在Android上控制裝置」。

Home API 裝置類型 特徵 Kotlin 範例應用程式 用途

門鈴

GoogleDoorbellDevice

home.matter.6006.types.0113

門外的按鈕啟動裝置後,會發出聲音和/或視覺訊號,用來吸引門另一側的人注意。門鈴可能具備無障礙即時串流、對講功能或偵測事件。

必要特徵
     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

應答短訊

使用者可以透過應答短訊功能,將預先定義的訊息傳送至門鈴裝置。

這項功能僅適用於門鈴裝置。合作夥伴應用程式可存取預先定義的訊息清單,並向使用者顯示這些訊息供選擇。預先定義的訊息無法由使用者編輯。

應答短訊功能是透過 PresetMessage 特徵實作。

播放預設訊息

如要播放預設訊息,請呼叫 playPresetMessage 方法,並傳遞 availablePhraseTypes 屬性中的其中一個字串值。

import com.google.home.HomeDevice
import com.google.home.HomeException
import com.google.home.google.GoogleDoorbellDevice
import com.google.home.google.PresetMessage
import kotlinx.coroutines.flow.first

suspend fun playDoorbellPresetMessage(device: HomeDevice, phraseTypeString: String) {
    try {
        // 1. Retrieve the first snapshot of the doorbell device type
        val doorbellDevice = device.type(GoogleDoorbellDevice).first()

        // 2. Extract the PresetMessage trait
        val presetMessageTrait = doorbellDevice.trait(PresetMessage)
        if (presetMessageTrait == null) {
            println("PresetMessage trait is not supported on this doorbell device.")
            return
        }

        // 3. (Optional) Check available phrase types supported by the device
        val availablePhrases = presetMessageTrait.availablePhraseTypes
        if (availablePhrases != null) {
            val phraseTypesList = availablePhrases.map { it.phraseType }
            println("Supported quick response phrases: $phraseTypesList")
        }

        // 4. Send the playPresetMessage command to the doorbell
        presetMessageTrait.playPresetMessage(phraseType = phraseTypeString)
        println("Preset message command sent successfully.")

    } catch (e: HomeException) {
        println("Home API error occurred: ${e.message}")
    } catch (e: Exception) {
        println("Unexpected failure: ${e.message}")
    }
}

設定使用的語言

使用 LocalizationConfiguration 特徵的 setActiveLocale 方法,將裝置的有效口語語言設為特定語言代碼 (例如「en_US」)。

import java.util.Locale

// Convert underscore format (en_US) to Java Locale
fun String.toLocale(): Locale = Locale.forLanguageTag(this.replace('_', '-'))

// Setting the active language
val trait: LocalizationConfiguration = device.getTrait(LocalizationConfiguration)
val selectedLocale = "en_US" // Target locale string
trait.update {
    setActiveLocale(selectedLocale)
}

取得裝置與雲端連線的最新時間

如要找出裝置最近一次與雲端連線的時間,請使用 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 lightConnectivity = dimmableLightDevice.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(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)
  }
}

啟用或停用攝影機的錄影功能,等同於開啟或關閉攝影機影像。攝影機影像開啟時,攝影機就會錄影 (用於事件和相關影像片段)。

錄影功能停用時 (相機影片關閉):

確認是否已啟用錄製功能

如要判斷攝影機的錄影功能是否已啟用,請檢查是否有任何連線處於啟用狀態。以下範例定義了兩個執行這項操作的函式:

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

管理直播

調整直播品質有助於根據用戶的觀看環境 (例如在顯示較小的預覽圖塊、格狀檢視畫面或子母畫面模式時切換至較低解析度),最佳化頻寬用量。

使用 WebRtcLiveView 特徵動態變更畫質,可專門管理特定用戶端上現正進行的直播工作階段解析度。這與直接在裝置上設定裝置的頻寬用量設定不同,後者會影響所有同時觀看者,以及儲存至雲端的過往錄影品質。

以下範例說明如何擷取及更新裝置的直播品質:

  • 擷取支援的畫質選項:取得裝置支援的可用串流解析度。這段程式碼會查詢裝置類型流程中的 WebRtcLiveView 特徵 supportedQualityHints 屬性,並將支援的畫質公開為 StateFlow,其中包含 QualityHint 值清單 (例如 QUALITY_HINT_SDQUALITY_HINT_HDQUALITY_HINT_FHDQUALITY_HINT_QHDQUALITY_HINT_UHD)。

  • 變更直播畫質:套用所選的 QualityHint,變更目前直播的串流解析度 (例如從標準畫質切換為高畫質)。changeQuality 函式會解析裝置的直播特徵,並使用目前的 mediaSessionId 和所需的 QualityHint 設定呼叫 changeLiveViewQuality

// Assuming you have a HomeDevice instance 'device'
val availableQualityHints: StateFlow<List> =
    device.type(GoogleDoorbellDevice)
        .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(GoogleDoorbellDevice).trait(WebRtcLiveView).first() ?: return
    try {
        trait.changeLiveViewQuality(mediaSessionId, qualityHint)
    } catch (e: Exception) {
        // Handle error
    }
}

電池設定

你可以透過 Home API 控制各種電池設定。

設定電池用量偏好設定

設定能源平衡可讓您在裝置的電池續航力和效能之間取捨。您可以建立不同的電池設定檔,例如「延長」、「平衡」和「效能」,並在這些設定檔之間切換。

如要實作這項功能,請更新 EnergyPreference 特徵的 currentEnergyBalance 屬性。這個屬性接受與裝置 energyBalances 清單中定義的特定設定檔對應的整數索引 (例如 EXTENDED0BALANCED1,以及 PERFORMANCE2)。

currentEnergyBalancenull 值表示裝置使用自訂設定檔。這是唯讀狀態。

以下範例顯示 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 代表 EnabledAutomatic

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 屬性。電量為 OKWarning (低) 或 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 特徵的 BatPresentwiredPresent 屬性。

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

活動區設定

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,定義區域的名稱、頂點、顏色和用途。

以下範例說明如何建立名為「前廊」的區域,其中包含四個頂點,顏色為鮭魚色 (#F439A0),並用於動作偵測。

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

刪除活動區

如要移除區域,請使用 removeZone zoneId 指令。

private suspend fun ZoneManagement.deleteZone(zoneId: UShort) {
  // Execute the command to remove the zone
  this.removeZone(zoneId = zoneId)
}

聲響偵測事件觸發條件

AvStreamAnalysis 特徵提供介面,可管理攝影機和門鈴裝置的事件偵測觸發條件。視覺觸發條件 (例如人物或車輛) 可指定區域,但聲音觸發條件通常是裝置層級的設定。

使用 EventTriggerTypeEnum 進行聲響偵測時,可用的觸發條件類型如下:

模式 列舉值 說明
音效 Sound 一般聲響偵測。
有人說話 PersonTalking 偵測語音。
狗吠聲 DogBark 偵測犬隻的叫聲。
玻璃碎裂 GlassBreak 偵測玻璃破裂聲。
煙霧警報 SmokeAlarm 偵測煙霧警報器,通常會辨識 T3 可聽見的模式 (三聲短促的嗶聲,然後暫停)。
一氧化碳警報 CoAlarm 偵測一氧化碳警報,通常會發出 T4 聲音模式 (四聲短促的嗶聲,接著暫停)。

查看聲響偵測狀態

如要向使用者顯示聲響偵測的目前狀態,您必須檢查裝置支援的項目,以及裝置硬體啟用的項目。要檢查的屬性有以下兩項:

在 Android 開發作業中,使用 Kotlin Flows 時,您通常會從 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 定義可用的記錄策略:

模式 列舉值 說明
已停用 Disabled 錄製功能已完全停用。主要用於舊版裝置。
CVR (連續錄影) Cvr 攝影機全天候錄影,須訂閱 (例如 Google Home Premium)。
事件錄影 Ebr 錄影功能會由事件 (人員、動作) 觸發。 影片長度取決於活動時間長度和訂閱方案。
ETR (事件觸發錄影) Etr 事件觸發的短時間預覽錄製內容 (例如 10 秒)。
實景 LiveView 錄製功能已停用,但使用者仍可觀看直播。
靜態圖片 Images 發生事件時,系統會錄製快照,而非影片。

檢查錄製模式

如要顯示目前的錄製設定,請檢查 RecordingMode 特徵的屬性:

// 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 控制其他設定。

開啟或關閉夜視模式

如要開啟或關閉攝影機的夜視功能,請使用 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(),
    )
) }

啟用或停用數據分析

每部裝置都可以個別選擇是否要將詳細的數據分析資料傳送至 Google Home 雲端 (請參閱「Google Home API 的 Cloud Monitoring 功能」)。

如要為裝置啟用數據分析功能,請將 ExtendedGeneralDiagnosticsTraitanalyticsEnabled 屬性設為 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 指令將這些更新的設定傳回裝置,並套用至上一個步驟中找到的錄製連線。

如要修改這些設定,請搭配 TransportOptionsStruct 使用 modifyPushTransport 指令

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

判斷頻寬品質

TransportOptionsStructvideoStreamId 屬性會對應至特定影片串流設定。

如要取得支援的影片串流,請參閱 allocatedVideoStreams 屬性,這是 VideoStreamStructs 的清單。裝置的 CameraAvStreamManagement 特徵。

調整裝置的喚醒靈敏度

TransportTriggerOptionsStructmotionSensitivity 屬性對應下列值:

標籤 值 (UByte)
1u
5u
10u

調整事件錄影時間上限

TransportMotionTriggerTimeControlStructmaxDuration maxDuration 屬性對應下列時間長度 (以秒為單位):

  • 10u15u30u60u120u180u

電鈴設定

你可以透過 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() 指令結果。這會傳回可用主題清單,包括主題名稱。

以下範例說明如何篩選清單。如果目前時間介於主題的開始和結束時間 (分別為 startTimeSecondsendTimeSeconds 值) 之間,該主題就會視為有效。如果未設定開始時間,系統會將其視為從時間開始時就處於有效狀態。如果未設定結束時間,規則會無限期保持啟用狀態。如果兩者都缺少,主題一律會處於啟用狀態。

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

訪客通報設定

你可以使用 Home API 的 VisitorAnnouncement 特徵,查詢及管理門鈴的訪客通報設定。這項特徵可控制有人按門鈴時,是否要在 Google 智慧音箱或螢幕上通報訪客。

以下範例說明如何檢查訪客通報是否已啟用,以及如何更新這項設定:

// Read the current visitor announcements state
val isEnabled = visitorAnnouncementTrait.visitorAnnouncementsEnabled

// Toggle the visitor announcements setting
visitorAnnouncementTrait.update {
    setVisitorAnnouncementsEnabled(true)
}