Panduan perangkat bel pintu untuk Android

Jenis perangkat Bel Pintu diimplementasikan menggunakan dua trait: PushAvStreamTransport, yang menangani transportasi streaming audio dan video menggunakan protokol berbasis push, dan WebRtcLiveView, yang memberikan kemampuan untuk mengontrol live stream dan talkback.

Selalu periksa dukungan atribut dan perintah untuk perangkat sebelum menggunakan fitur atau mencoba memperbarui atribut. Lihat Mengontrol perangkat di Android untuk mengetahui informasi selengkapnya.

Jenis Perangkat Home API Sifat Aplikasi Contoh Kotlin Kasus Penggunaan

Bel pintu

GoogleDoorbellDevice

home.matter.6006.types.0113

Perangkat yang diaktifkan oleh tombol di luar pintu yang menghasilkan sinyal suara dan/atau visual, yang digunakan untuk meminta perhatian seseorang yang berada di sisi lain pintu. Bel pintu mungkin memiliki fitur livestream yang dapat diakses, talkback dua arah, atau peristiwa deteksi.

Ciri Wajib
     google PushAvStreamTransport
     google WebRtcLiveView

Bel pintu

Mendapatkan informasi dasar tentang perangkat

Trait BasicInformation mencakup informasi seperti nama vendor, ID vendor, ID produk, nama produk (mencakup informasi model), dan versi software untuk perangkat:

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

Mendapatkan nomor seri

Untuk mendapatkan nomor seri perangkat, gunakan perintah GetSerialNumber dari trait ExtendedBasicInformation. Contoh ini menunjukkan penyimpanan nomor seri dalam variabel bernama serialNumber:

val basicInfo: ExtendedBasicInformation = device.getTrait(ExtendedBasicInformation)
val serialNumber = basicInfo.getSerialNumber().serialNumber

Menyetel bahasa lisan

Menetapkan bahasa lisan aktif perangkat ke lokalitas tertentu (misalnya, "en_US") menggunakan metode setActiveLocale dari trait LocalizationConfiguration.

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

Mendapatkan waktu terbaru saat perangkat menghubungi cloud

Untuk menemukan waktu terbaru saat perangkat terhubung dengan cloud, gunakan atribut lastContactTimestamp dari ExtendedGeneralDiagnostics trait:

fun getLastContactTimeStamp(trait: ExtendedGeneralDiagnostics): java.time.Instant {
  val timestamp = trait.lastContactTimestamp
  return Instant.ofEpochSecond(timestamp.toLong())
}

Memeriksa konektivitas perangkat

Konektivitas untuk perangkat sebenarnya diperiksa di tingkat jenis perangkat karena beberapa perangkat mendukung beberapa jenis perangkat. Status yang ditampilkan adalah kombinasi status konektivitas untuk semua fitur di perangkat tersebut.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

Status PARTIALLY_ONLINE dapat diamati dalam kasus jenis perangkat campuran saat tidak ada konektivitas internet. Ciri standar Matter mungkin masih online karena perutean lokal, tetapi ciri berbasis cloud akan offline.

Dapatkan alamat IP perangkat

Untuk menemukan alamat IP perangkat, gunakan atribut networkInterfaces dari trait GeneralDiagnostics. Alamat ditampilkan sebagai array byte, yang dapat Anda format ke string IPv4 atau IPv6 standar:

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

Memulai livestream

Untuk memulai livestream, kirim string Session Description Protocol (SDP) ke metode startLiveView() trait WebRtcLiveView, yang menampilkan WebRtcLiveViewTrait.StartLiveViewCommand.Response yang berisi tiga nilai:

  • SDP untuk sesi.
  • Durasi sesi dalam hitungan detik.
  • ID sesi, yang dapat digunakan untuk memperpanjang atau menghentikan sesi.
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)

Memperpanjang livestream

Livestream memiliki durasi preset setelah itu akan berakhir. Untuk memperpanjang durasi streaming aktif, kirim permintaan perpanjangan menggunakan metode 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
}

Memulai dan menghentikan TalkBack

Untuk memulai TalkBack, panggil metode startTalkback() trait WebRtcLiveView. Untuk berhenti, gunakan 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)
  }
}

Mengaktifkan dan menonaktifkan kemampuan perekaman

Untuk mengaktifkan kemampuan perekaman kamera, teruskan TransportStatusEnum.Active ke metode setTransportStatus() trait PushAvStreamTransport. Untuk menonaktifkan kemampuan merekam, teruskan TransportStatusEnum.Inactive. Dalam contoh berikut, kita menggabungkan panggilan ini dalam satu panggilan yang menggunakan Boolean untuk mengaktifkan/menonaktifkan kemampuan perekaman:

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

Mengaktifkan atau menonaktifkan kemampuan perekaman kamera sama dengan mengaktifkan atau menonaktifkan video kamera. Jika video kamera aktif, kamera akan merekam (untuk tujuan peristiwa dan klip terkait).

Jika kemampuan perekaman dinonaktifkan (video kamera nonaktif):

  • Kamera masih dapat ditampilkan sebagai online sesuai dengan connectivityState jenis perangkat.
  • Livestream tidak dapat diakses, dan kamera tidak mendeteksi peristiwa cloud apa pun.

Memeriksa apakah kemampuan perekaman diaktifkan

Untuk menentukan apakah kemampuan perekaman kamera diaktifkan, periksa apakah ada koneksi yang aktif. Contoh berikut menentukan dua fungsi untuk melakukannya:

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

Cara lain untuk memeriksa adalah menggunakan fungsi findTransport() dengan predikat:

// Fetch the current connections
suspend fun queryRecordModeState(trait: PushAvStreamTransport) {
  return trait.findTransport().let {
      it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active
    }
}

Setelan baterai

Berbagai setelan baterai dapat dikontrol melalui Home API.

Menyetel preferensi penggunaan baterai

Dengan menyetel keseimbangan energi, Anda dapat mengonfigurasi keseimbangan antara daya tahan baterai dan performa perangkat. Anda dapat membuat profil baterai yang berbeda, seperti "Diperpanjang", "Seimbang", dan "Performa", serta beralih di antara profil tersebut.

Fitur ini diterapkan dengan memperbarui atribut currentEnergyBalance dari sifat EnergyPreference. Atribut ini menerima indeks bilangan bulat yang sesuai dengan profil tertentu yang ditentukan dalam daftar energyBalances perangkat (misalnya, 0 untuk EXTENDED, 1 untuk BALANCED, dan 2 untuk PERFORMANCE).

Nilai null untuk currentEnergyBalance menunjukkan bahwa perangkat menggunakan profil kustom. Ini adalah status hanya baca.

Berikut ini contoh struktur yang akan digunakan atribut currentEnergyBalance, diikuti dengan cuplikan kode sebenarnya yang menggunakan atribut tersebut.

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

Mengaktifkan penghemat baterai otomatis

Untuk mengonfigurasi fitur ini, perbarui atribut currentLowPowerModeSensitivity dari sifat EnergyPreference. Atribut ini menggunakan indeks untuk memilih tingkat sensitivitas, dengan 0 biasanya mewakili Disabled dan 1 mewakili Enabled atau 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) }
}

Mendapatkan status pengisian daya baterai

Untuk mendapatkan status pengisian daya perangkat saat ini (sedang mengisi daya, terisi daya penuh, atau tidak mengisi daya), gunakan atribut batChargeState dari trait PowerSource.

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

Mendapatkan level baterai

Untuk mendapatkan level baterai saat ini, gunakan atribut batChargeLevel dari PowerSource trait. Levelnya adalah OK, Warning (rendah), atau 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"
}

Dapatkan sumber listrik

Untuk menentukan sumber listrik yang digunakan perangkat, gunakan atribut BatPresent dan wiredPresent dari karakteristik PowerSource.

  val trait: PowerSource
  val isWired = trait.wiredPresent
  val hasBattery = trait.batPresent

Setelan audio

Berbagai setelan audio dapat dikontrol melalui Home API.

Mengaktifkan atau menonaktifkan mikrofon

Untuk mengaktifkan atau menonaktifkan mikrofon perangkat, perbarui atribut microphoneMuted dari trait CameraAvStreamManagement menggunakan fungsi Kotlin setMicrophoneMuted bawaan:

// Turn the device's microphone on or off
suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setMicrophoneMuted(disableMicrophone) }
}

Mengaktifkan atau menonaktifkan rekaman audio

Untuk mengaktifkan atau menonaktifkan perekaman audio untuk perangkat, perbarui atribut recordingMicrophoneMuted dari trait CameraAvStreamManagement menggunakan fungsi Kotlin setRecordingMicrophoneMuted bawaan:

// Turn audio recording on or off for the device
suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setRecordingMicrophoneMuted(disableAudioRecording) }
}

Menyesuaikan volume speaker

Untuk menyesuaikan volume speaker perangkat, perbarui atribut speakerVolumeLevel dari trait CameraAvStreamManagement menggunakan fungsi Kotlin setSpeakerVolumeLevel bawaan:

// Adjust the camera speaker volume
suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) {
  trait.update { setSpeakerVolumeLevel(volume.toUbyte()) }
}

Setelan zona aktivitas

Trait ZoneManagement menyediakan antarmuka untuk mengelola area minat (zona aktivitas) kustom di perangkat kamera dan bel pintu. Zona ini digunakan untuk memfilter deteksi peristiwa (seperti gerakan orang atau kendaraan) ke area tertentu dalam bidang pandang perangkat.

Zona aktivitas dikonfigurasi oleh pengguna dalam aplikasi partner, sehingga mereka dapat menggambar zona di area tertentu dalam ruang pandang kamera. Zona yang ditentukan pengguna ini kemudian diterjemahkan ke dalam struktur yang digunakan oleh sifat ini. Untuk mengetahui informasi selengkapnya tentang cara kerja zona aktivitas, lihat Menyiapkan dan menggunakan Zona Aktivitas.

Zona aktivitas biasanya ditentukan menggunakan koordinat Kartesius 2D. Trait ini menyediakan TwoDCartesianVertexStruct untuk verteks dan TwoDCartesianZoneStruct untuk definisi zona (nama, verteks, warna, dan penggunaan).

Memeriksa zona aktivitas

Untuk menampilkan zona aktivitas, periksa atribut zones dari sifat ZoneManagement.

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

Menambahkan zona aktivitas

Untuk membuat zona baru, gunakan perintah createTwoDCartesianZone. Perintah ini mengambil TwoDCartesianZoneStruct, yang menentukan nama, verteks, warna, dan penggunaan zona.

Contoh berikut menunjukkan cara membuat zona bernama "Front Porch" dengan empat verteks, berwarna salmon (#F439A0), dan digunakan untuk deteksi gerakan.

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

Memperbarui zona aktivitas

Untuk memperbarui zona yang ada, gunakan perintah updateTwoDCartesianZone. Perintah ini memerlukan zoneId dan TwoDCartesianZoneStruct yang diperbarui.

private suspend fun ZoneManagement.updateZone(
  zoneId: UShort,
  zone: ZoneManagementTrait.TwoDCartesianZoneStruct
) {
  // Execute the command to update the zone
  this.updateTwoDCartesianZone(zoneId = zoneId, zone = zone)
}

Menghapus zona aktivitas

Untuk menghapus zona, gunakan perintah removeZone dengan zoneId tertentu.

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

Pemicu Peristiwa Suara

Trait AvStreamAnalysis menyediakan antarmuka untuk mengelola pemicu deteksi peristiwa di perangkat kamera dan bel pintu. Meskipun pemicu berbasis penglihatan (seperti orang atau kendaraan) dapat bersifat spesifik per zona, pemicu terkait suara biasanya merupakan konfigurasi tingkat perangkat.

Jenis pemicu berikut tersedia untuk deteksi suara dengan EventTriggerTypeEnum:

Mode Nilai enum Deskripsi
Suara Sound Deteksi suara umum.
Orang berbicara PersonTalking Mendeteksi ucapan.
Gonggongan DogBark Mendeteksi vokalisasi.
Kaca pecah GlassBreak Mendeteksi suara kaca pecah.
Alarm asap SmokeAlarm Mendeteksi alarm asap, yang sering kali dikenali oleh pola suara T3 (tiga bunyi bip pendek diikuti dengan jeda).
alarm gas CO CoAlarm Mendeteksi alarm karbon monoksida (CO), yang biasanya dikenali oleh pola suara T4 (empat bunyi bip pendek diikuti dengan jeda).

Memeriksa status deteksi suara

Untuk menampilkan status deteksi suara saat ini kepada pengguna, Anda harus memeriksa apa yang didukung perangkat dan apa yang diaktifkan oleh hardware perangkat. Dua atribut yang perlu diperiksa adalah:

Dalam pengembangan Android menggunakan Flow Kotlin, Anda biasanya akan mengamati sifat AvStreamAnalysis dari HomeDevice.

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

Memperbarui set pemicu yang diaktifkan

Untuk memperbarui set pemicu yang diaktifkan, gunakan perintah SetOrUpdateEventDetectionTriggers, yang menggunakan daftar struktur 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)
}

Mode perekaman

Trait RecordingMode menyediakan antarmuka untuk mengelola perilaku perekaman video dan gambar di perangkat kamera dan bel pintu. Fitur ini memungkinkan pengguna memilih antara perekaman berkelanjutan, perekaman berbasis peristiwa, atau menonaktifkan perekaman sepenuhnya (Khusus Tampilan Live).

RecordingModeEnum menentukan strategi perekaman yang tersedia:

Mode Nilai enum Deskripsi
Disabled Disabled Perekaman dinonaktifkan sepenuhnya. Digunakan terutama oleh perangkat lama.
CVR (Perekaman Video Nonstop) Cvr Video direkam 24x7. Memerlukan langganan (misalnya, Google Home Premium.
EBR (Rekaman Peristiwa Penting) Ebr Perekaman dipicu oleh peristiwa (orang, gerakan). Durasi video bergantung pada durasi acara dan langganan.
ETR (Event Triggered Recording) Etr Perekaman pratinjau singkat (misalnya, 10 detik) dipicu oleh peristiwa.
Tampilan Live LiveView Perekaman dinonaktifkan, tetapi pengguna tetap dapat mengakses livestream.
Gambar Diam Images Snapshot direkam, bukan video, saat peristiwa terjadi.

Memeriksa mode perekaman

Untuk menampilkan konfigurasi perekaman saat ini, periksa atribut dari trait 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(),
            )
        }
    }

Mengubah mode perekaman

Sebelum memperbarui, pastikan indeks yang dipilih dari atribut supportedRecordingModes ada di atribut availableRecordingModes.

Untuk memperbarui mode yang dipilih, gunakan fungsi setSelectedRecordingMode, dengan meneruskan indeks mode yang dipilih:

private suspend fun RecordingMode.updateRecordingMode(index: Int) {
    // Execute the command to update the selected mode
    this.setSelectedRecordingMode(index.toUByte())
}

Setelan lainnya

Berbagai setelan lainnya dapat dikontrol melalui Home API.

Mengaktifkan atau menonaktifkan penglihatan malam

Untuk mengaktifkan atau menonaktifkan penglihatan malam untuk kamera, gunakan TriStateAutoEnum untuk memperbarui atribut nightVision dari trait CameraAvStreamManagement menggunakan fungsi Kotlin setNightVision bawaan:

// Turn night vision on
cameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On)
}

// Turn night vision off
CameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off)
}

Mengubah kecerahan LED status

Untuk mengubah kecerahan LED status, gunakan ThreeLevelAutoEnum untuk memperbarui atribut statusLightBrightness trait CameraAvStreamManagement menggunakan fungsi Kotlin setStatusLightBrightness bawaan:

// Set the LED brightness to high
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High)
}

// Set the LED brightness to low
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low)
}

Mengubah area pandang kamera

Viewport kamera sama dengan fitur Zoom dan Pangkas yang dijelaskan dalam artikel dukungan Memperbesar dan mengoptimalkan video kamera Nest.

Area tampilan ditentukan dalam ViewportStruct yang berisi empat nilai, yang digunakan sebagai koordinat area tampilan. Koordinat didefinisikan sebagai:

(x1,y1) -- (x2,y1)
   |          |
(x1,y2) -- (x2,y2)

Penentuan nilai untuk ViewportStruct bergantung pada UI aplikasi dan implementasi kamera. Pada tingkat yang sangat dasar, untuk menyetel area tampilan video kamera, perbarui atribut viewport dari sifat CameraAvStreamManagement dengan ViewportStruct, menggunakan fungsi Kotlin setViewport bawaan:

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

Mengaktifkan atau menonaktifkan analisis

Setiap perangkat dapat memilih untuk mengirim data analisis mendetail ke cloud Google Home secara terpisah (lihat Cloud Monitoring for Home APIs).

Untuk mengaktifkan analisis untuk perangkat, tetapkan properti analyticsEnabled dari ExtendedGeneralDiagnosticsTrait ke true. Saat Anda menetapkan analyticsEnabled, properti lain, logUploadEnabled, otomatis ditetapkan ke true, yang memungkinkan file log analytics diupload ke cloud Google Home.

// Enable analytics
extendedGeneralDiagnostics.update {
  setAnalyticsEnabled(true)
}

// Disable analytics
extendedGeneralDiagnostics.update {
  setAnalyticsEnabled(false)
}

Konfigurasi transportasi dan perekaman

Bagian ini membahas setelan yang terkait dengan kualitas streaming kamera dan pemicuan peristiwa. Setelan ini dikelola oleh PushAvStreamTransport trait.

Membaca setelan transportasi

Bagian ini menunjukkan cara mengambil konfigurasi saat ini dari perangkat kamera atau bel pintu. Layanan ini mengambil trait PushAvStreamTransport, menemukan koneksi spesifik yang digunakan untuk perekaman, lalu mengekstrak nilai saat ini untuk kualitas bandwidth, sensitivitas aktivasi, dan durasi peristiwa maksimum.

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

Memperbarui setelan transportasi

Bagian ini menunjukkan cara mengubah setelan transportasi. Langkah ini akan membuat TransportOptionsStruct baru yang berisi nilai baru dan kemudian menggunakan perintah modifyPushTransport untuk mengirim setelan yang diperbarui ini kembali ke perangkat, menerapkannya ke koneksi perekaman yang ditemukan pada langkah sebelumnya.

Untuk mengubah setelan ini, gunakan perintah modifyPushTransport dengan 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
    )
}

Menentukan kualitas bandwidth

Properti videoStreamId dari TransportOptionsStruct sesuai dengan konfigurasi streaming video tertentu.

Untuk mendapatkan streaming video yang didukung, lihat atribut allocatedVideoStreams, yang merupakan daftar VideoStreamStructs. dari trait CameraAvStreamManagement untuk perangkat.

Menyesuaikan sensitivitas aktivasi perangkat

Properti motionSensitivity dari TransportTriggerOptionsStruct sesuai dengan nilai berikut:

Label Nilai (UByte)
Rendah 1u
Sedang 5u
Tinggi 10u

Menyesuaikan durasi peristiwa maksimum

Properti maxDuration dari TransportMotionTriggerTimeControlStruct sesuai dengan durasi berikut (dalam detik):

  • 10u, 15u, 30u, 60u, 120u, 180u

Setelan bel

Berbagai setelan bunyi bel pintu dapat dikontrol melalui Home API.

Mengubah suara bel

Untuk mengubah suara bel pintu, pertama-tama dapatkan daftar suara bel yang diinstal di perangkat, menggunakan atribut installedChimeSounds dari trait Chime:

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

Kemudian, perbarui atribut selectedChime dari trait Chime menggunakan fungsi Kotlin setSelectedChime bawaan:

// Set the chime using the chimeId from the installed list
chimeSounds.firstOrNull { it.name == name }?.let { setSelectedChime(it.chimeId) }

Menggunakan bel eksternal

Bel pintu dapat dikonfigurasi untuk menggunakan bel eksternal, seperti bel mekanis yang dipasang di dalam rumah. Setelan ini harus dikonfigurasi selama pemasangan bel pintu untuk menghindari potensi kerusakan pada bel eksternal.

Untuk menunjukkan jenis bel eksternal yang terpasang, gunakan ExternalChimeType untuk memperbarui atribut externalChime dari trait Chime menggunakan fungsi Kotlin setExternalChime bawaan:

// Indicate the external chime is mechanical
chime.update {
  setExternalChime(ChimeTrait.ExternalChimeType.Mechanical)
}

Mengubah durasi bel eksternal

Durasi dering bel eksternal, dalam detik, dapat dikonfigurasi melalui Home API. Jika bel eksternal mendukung durasi bel, pengguna mungkin ingin mengonfigurasi durasi ini.

Nilai yang ditetapkan di sini bergantung pada spesifikasi bel eksternal itu sendiri, dan durasi bel yang direkomendasikan.

Untuk mengubah durasi bel eksternal, perbarui atribut externalChimeDurationSeconds dari trait Chime menggunakan fungsi Kotlin setExternalChimeDurationSeconds bawaan:

// Change the external chime duration
chime.update {
  setExternalChimeDurationSeconds(newDuration.toUShort())
}

Mengaktifkan tema bunyi bel

Beberapa bel pintu mungkin memiliki bel yang hanya tersedia untuk pengguna dalam waktu terbatas. Misalnya, bunyi bel khusus untuk hari libur. Ini disebut tema bunyi notifikasi.

Untuk melihat tema bel yang tersedia bagi pengguna, buat filter timebox dan gunakan untuk memfilter hasil perintah getAvailableThemes() dari trait ChimeThemes. Tindakan ini akan menampilkan daftar tema yang tersedia, termasuk nama tema.

Contoh berikut menunjukkan cara memfilter daftar. Tema dianggap aktif jika waktu saat ini berada dalam waktu mulai dan berakhirnya (nilai startTimeSeconds dan endTimeSeconds, masing-masing). Jika waktu mulai tidak ditetapkan, perangkat dianggap aktif sejak awal waktu. Jika waktu berakhir tidak ditetapkan, waktu akan terus aktif tanpa batas. Jika keduanya tidak ada, tema akan selalu aktif.

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

Setelah memiliki nama tema yang diinginkan, seperti Christmas, Anda dapat memilihnya menggunakan fungsi setSelectedTimeboxedThemeName() pada karakteristik ChimeThemes:

// Select a theme using the ChimeThemes trait
val themeToSelect = "Christmas"
if (themeToSelect in availableThemeNames) {
  doorbellChimeThemesTraitFlow.first().setSelectedTimeboxedThemeName(themeToSelect)
}