Guida ai dispositivi di ripresa per Android

Il tipo di dispositivo Videocamera viene implementato utilizzando due tratti: PushAvStreamTransport, che gestisce il trasporto di stream audio e video utilizzando protocolli basati sul push, e WebRtcLiveView, che offre la possibilità di controllare i live streaming e il talkback.

Prima di utilizzare qualsiasi funzionalità o tentare di aggiornare gli attributi, controlla sempre se un dispositivo supporta gli attributi e i comandi. Per ulteriori informazioni, consulta Controllare i dispositivi su Android.

Tipo di dispositivo API Home Tratti App di esempio Kotlin Caso d'uso

Videocamera

GoogleCameraDevice

home.matter.6006.types.0158

Un dispositivo che acquisisce immagini statiche o video. Le videocamere possono includere live streaming accessibili, talkback bidirezionale o eventi di rilevamento.

Tratti obbligatori
     google PushAvStreamTransport
     google WebRtcLiveView

Videocamera

Ottenere informazioni di base su un dispositivo

Il BasicInformation tratto include informazioni come il nome del fornitore, l'ID fornitore, l'ID prodotto, il nome del prodotto (incluse le informazioni sul modello), la versione del software, e il numero di serie di un dispositivo:

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

Ottenere l'ultima volta che il dispositivo ha contattato il cloud

Per trovare l'ultima volta che il dispositivo ha contattato il cloud, utilizza l'attributo lastContactTimestamp del ExtendedGeneralDiagnostics tratto:

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

Controllare la connettività di un dispositivo

La connettività di un dispositivo viene effettivamente controllata a livello di tipo di dispositivo perché alcuni dispositivi supportano più tipi di dispositivi. Lo stato restituito è una combinazione degli stati di connettività di tutti i tratti del dispositivo.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

In caso di tipi di dispositivi misti, quando non è presente la connettività internet, è possibile osservare uno stato PARTIALLY_ONLINE. Matter I tratti standard potrebbero essere ancora online a causa del routing locale, ma i tratti basati sul cloud saranno offline.

Avviare un live streaming

Per avviare un live streaming, invia la stringa SDP (Session Description Protocol) al WebRtcLiveView tratto startLiveView() metodo, che restituisce un WebRtcLiveViewTrait.StartLiveViewCommand.Response contenente tre valori:

  • L'SDP per la sessione.
  • La durata della sessione in secondi.
  • L'ID sessione, che può essere utilizzato per estendere o terminare la sessione.
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)

Estendere un live streaming

I live streaming hanno una durata preimpostata dopo la quale scadono. Per aumentare la durata di uno stream attivo, invia una richiesta di estensione utilizzando il WebRtcLiveView.extendLiveView() metodo:

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

Avviare e interrompere il talkback

Per avviare il talkback, chiama il WebRtcLiveView metodo startTalkback() del tratto. Per interrompere, utilizza 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)
  }
}

Abilitare e disabilitare la funzionalità di registrazione

Per abilitare la funzionalità di registrazione della videocamera, passa TransportStatusEnum.Active al PushAvStreamTransport tratto's setTransportStatus() metodo. Per disabilitare la funzionalità di registrazione, passala a TransportStatusEnum.Inactive. Nell'esempio seguente, racchiudiamo queste chiamate in una singola chiamata che utilizza un Boolean per attivare/disattivare la funzionalità di registrazione:

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

L'abilitazione o la disabilitazione della funzionalità di registrazione della videocamera equivale all'attivazione o alla disattivazione del video della videocamera. Quando il video di una videocamera è attivo, la videocamera registra (ai fini degli eventi e dei clip correlati).

Quando la funzionalità di registrazione è disabilitata (il video della videocamera è disattivato):

Verificare se la funzionalità di registrazione è abilitata

Per determinare se la funzionalità di registrazione di una videocamera è abilitata, controlla se sono attive delle connessioni. L'esempio seguente definisce due funzioni per eseguire questa operazione:

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

Un altro modo per controllare è utilizzare la funzione findTransport() con un predicato:

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

Impostazioni batteria

È possibile controllare varie impostazioni della batteria tramite le API Home.

Impostare la preferenza di utilizzo della batteria

L'impostazione del bilanciamento energetico consente di configurare il compromesso tra durata della batteria e prestazioni di un dispositivo. Puoi creare diversi profili della batteria, ad esempio "Esteso", "Bilanciato" e "Prestazioni", e passare da uno all'altro.

Questa funzionalità viene implementata aggiornando l' currentEnergyBalance attributo del EnergyPreference tratto. L'attributo accetta un indice intero che corrisponde a un profilo specifico definito nell'elenco energyBalances del dispositivo (ad esempio, 0 per EXTENDED, 1 per BALANCED e 2 per PERFORMANCE).

Un valore null per currentEnergyBalance indica che il dispositivo utilizza un profilo personalizzato. Questo è uno stato di sola lettura.

Di seguito è riportato un esempio di struttura che verrà utilizzata dall'attributo currentEnergyBalance, seguito dallo snippet di codice effettivo che utilizza l'attributo.

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

Attivare il risparmio energetico automatico

Per configurare questa funzionalità, aggiorna l' currentLowPowerModeSensitivity attributo del EnergyPreference tratto. Questo attributo utilizza un indice per selezionare un livello di sensibilità, dove 0 in genere rappresenta Disabled e 1 rappresenta Enabled o 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) }
}

Ottenere lo stato di ricarica della batteria

Per ottenere lo stato di ricarica attuale del dispositivo (in carica, completamente carico o non in carica), utilizza l' batChargeState attributo del PowerSource tratto.

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

Ottenere il livello batteria

Per ottenere il livello batteria attuale, utilizza l' batChargeLevel attributo del PowerSource trait. Il livello è OK, Warning (basso) o 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"
}

Ottenere la fonte di alimentazione

Per determinare la fonte di alimentazione utilizzata dal dispositivo, utilizza gli attributi BatPresent e wiredPresent del tratto PowerSource.

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

Impostazioni audio

È possibile controllare varie impostazioni audio tramite le API Home.

Attivare o disattivare il microfono

Per attivare o disattivare il microfono del dispositivo, aggiorna l'attributo microphoneMuted del tratto CameraAvStreamManagementutilizzando la funzione Kotlin integrata setMicrophoneMuted:

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

Attivare o disattivare la registrazione audio

Per attivare o disattivare la registrazione audio per il dispositivo, aggiorna l' recordingMicrophoneMuted attributo del tratto CameraAvStreamManagement utilizzando la funzione Kotlin integrata setRecordingMicrophoneMuted:

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

Regolare il volume dello speaker

Per regolare il volume dello speaker del dispositivo, aggiorna l' speakerVolumeLevel attributo del tratto CameraAvStreamManagement utilizzando la funzione Kotlin integrata setSpeakerVolumeLevel:

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

Impostazioni delle zone attive

Il tratto ZoneManagement fornisce un'interfaccia per la gestione delle regioni di interesse personalizzate (zone attive) su videocamere e campanelli. Queste zone vengono utilizzate per filtrare il rilevamento degli eventi (ad esempio il movimento di persone o veicoli) in aree specifiche all'interno del campo visivo del dispositivo.

Le zone attive vengono configurate dall'utente all'interno di un'applicazione partner, consentendogli di disegnare zone su aree specifiche nel campo visivo della videocamera. Queste zone definite dall'utente vengono poi tradotte nelle strutture utilizzate da questo tratto. Per ulteriori informazioni sul funzionamento delle zone attive, consulta Configurare e utilizzare le zone attive.

Le zone attive vengono in genere definite utilizzando coordinate cartesiane 2D. Il tratto fornisce il TwoDCartesianVertexStruct per i vertici e il TwoDCartesianZoneStruct per la definizione della zona (nome, vertici, colore e utilizzo).

Controllare le zone attive

Per visualizzare le zone attive, controlla l' zones attributo del ZoneManagement tratto.

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

Aggiungere una zona attiva

Per creare una nuova zona, utilizza il createTwoDCartesianZone comando. Questo comando accetta un TwoDCartesianZoneStruct, che definisce il nome, i vertici, il colore e l'utilizzo della zona.

L'esempio seguente mostra come creare una zona denominata "Veranda" con quattro vertici, color salmone (#F439A0) e utilizzata per il rilevamento del movimento.

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

Aggiornare una zona attiva

Per aggiornare una zona esistente, utilizza il updateTwoDCartesianZone comando. Questo comando richiede zoneId e aggiornato TwoDCartesianZoneStruct.

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

Eliminare una zona attiva

Per rimuovere una zona, utilizza il removeZone comando con il zoneIdspecifico.

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

Trigger evento audio

Il tratto AvStreamAnalysis fornisce un'interfaccia per la gestione dei trigger di rilevamento degli eventi su videocamere e campanelli. Sebbene i trigger basati sulla visione (ad esempio persone o veicoli) possano essere specifici per zona, i trigger relativi all'audio sono in genere configurazioni a livello di dispositivo.

I seguenti tipi di trigger sono disponibili per il rilevamento audio con il EventTriggerTypeEnum:

Modalità Valore enum Descrizione
Suono Sound Rilevamento dei suoni generale.
Persona che parla PersonTalking Rileva il parlato.
Cane che abbaia DogBark Rileva le vocalizzazioni canine.
Vetri rotti GlassBreak Rileva il suono di vetri rotti.
Allarme fumo SmokeAlarm Rileva gli allarmi fumo, spesso riconosciuti dal pattern audio T3 (tre brevi segnali acustici seguiti da una pausa).
Allarme CO CoAlarm Rileva gli allarmi di monossido di carbonio (CO), in genere riconosciuti dal pattern audio T4 (quattro brevi segnali acustici seguiti da una pausa).

Controllare lo stato del rilevamento dei suoni

Per mostrare all'utente lo stato attuale del rilevamento dei suoni, devi controllare cosa supporta il dispositivo e cosa è abilitato dall'hardware del dispositivo. I due attributi da controllare sono:

Nello sviluppo Android utilizzando Kotlin Flows, in genere si osserva il tratto AvStreamAnalysis da 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)
        )
      }
  }

Aggiornare il set di trigger abilitati

Per aggiornare il set di trigger abilitati, utilizza il SetOrUpdateEventDetectionTriggers comando, che accetta un elenco di EventTriggerEnablement strutture.

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

Modalità di registrazione

Il tratto RecordingMode fornisce un'interfaccia per la gestione del comportamento di registrazione di video e immagini su videocamere e campanelli. Consente agli utenti di scegliere tra la registrazione continua, la registrazione basata sugli eventi o la disattivazione completa della registrazione (solo Live View).

Il RecordingModeEnum definisce le strategie di registrazione disponibili:

Modalità Valore enum Descrizione
Disabilitata Disabled La registrazione è completamente disabilitata. Utilizzata principalmente dai dispositivi legacy.
CVR (registrazione video continua) Cvr Il video viene registrato 24 ore su 24, 7 giorni su 7. È richiesto un abbonamento (ad esempio, Google Google Home Premium.
EBR (registrazione basata sugli eventi) Ebr La registrazione viene attivata dagli eventi (persona, movimento). La durata del video dipende dalla durata dell'evento e dall'abbonamento.
ETR (registrazione attivata da eventi) Etr Registrazione di anteprima breve (ad esempio, 10 secondi) attivata da eventi.
Live View LiveView La registrazione è disabilitata, ma gli utenti possono comunque accedere al live streaming.
Immagini statiche Images Quando si verificano eventi, vengono registrate le istantanee anziché i video.

Controllare le modalità di registrazione

Per visualizzare la configurazione di registrazione attuale, controlla gli attributi del tratto 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(),
            )
        }
    }

Modificare la modalità di registrazione

Prima di aggiornare, assicurati che l'indice scelto dall'attributo supportedRecordingModes sia presente nell'attributo availableRecordingModes.

Per aggiornare la modalità selezionata, utilizza la funzione setSelectedRecordingMode, passando l'indice della modalità scelta:

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

Altre impostazioni

È possibile controllare varie altre impostazioni tramite le API Home.

Modificare l'orientamento dell'immagine

È possibile ruotare l'orientamento dell'immagine (video) della videocamera. Il video può essere ruotato solo di 180 gradi.

Per modificare l'orientamento dell'immagine della videocamera, aggiorna l' imageRotation attributo del tratto CameraAvStreamManagement utilizzando la funzione Kotlin integrata setImageRotation:

// Change the camera's image orientation
val isRotated = false

cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }

Attivare o disattivare la visione notturna

Per attivare o disattivare la visione notturna della videocamera, utilizza TriStateAutoEnum per aggiornare l' nightVision attributo del tratto CameraAvStreamManagement utilizzando la funzione Kotlin integrata setNightVision:

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

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

Modificare la luminosità del LED di stato

Per modificare la luminosità del LED di stato, utilizza ThreeLevelAutoEnum per aggiornare l'attributo statusLightBrightness del tratto CameraAvStreamManagement utilizzando la funzione Kotlin integrata setStatusLightBrightness:

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

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

Modificare la finestra della videocamera

La finestra della videocamera è la stessa della funzionalità Zoom e ritaglio descritta nell' articolo del Centro assistenza Aumentare lo zoom e migliorare i video della videocamera Nest.

La finestra viene definita in un ViewportStruct che contiene quattro valori, utilizzati come coordinate della finestra. Le coordinate sono definite come:

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

La determinazione dei valori per ViewportStruct dipende dall'interfaccia utente e dall'implementazione della videocamera di un'app. A un livello molto base, per impostare la finestra del video della videocamera, aggiorna l' viewport attributo del tratto CameraAvStreamManagement con un ViewportStruct, utilizzando la funzione Kotlin integrata setViewport:

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

Regolare la sensibilità di riattivazione del dispositivo

La sensibilità di riattivazione del dispositivo viene utilizzata per risparmiare batteria riducendo l'intervallo in cui il dispositivo può rilevare l'attività e aumentando il tempo di riattivazione dopo aver rilevato l'attività.

Nelle API Home, questa impostazione può essere configurata utilizzando la proprietà motionSensitivity di triggerOptions in transportOptions del dispositivo. Queste opzioni sono definite all'interno del tratto PushAvStreamTransport per ogni dispositivo.

La sensibilità riattivazione può essere impostata solo sui seguenti valori:

  • 1 = Bassa
  • 5 = Media
  • 10 = Alta

La procedura di aggiornamento consiste nel trovare la configurazione di trasporto per gli stream di registrazione attivi utilizzando il findTransport comando, quindi modificare la configurazione con il nuovo valore di sensibilità utilizzando il modifyPushTransport comando:

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

Regolare la durata massima degli eventi

La durata massima degli eventi è la durata della registrazione di un clip da parte della videocamera per un evento. Tramite le API Home, questa impostazione può essere configurata, per ogni dispositivo, con le stesse durate dell'app Google HomeGHA, a intervalli di secondi:

  • 10 secondi
  • 15 secondi
  • 30 secondi
  • 60 secondi (1 minuto)
  • 120 secondi (2 minuti)
  • 180 secondi (3 minuti)

Nelle API Home, questa impostazione può essere configurata utilizzando la proprietà motionTimeControl di triggerOptions in transportOptions del dispositivo. Queste opzioni sono definite all'interno del tratto PushAvStreamTransport per ogni dispositivo.

La procedura di aggiornamento consiste nel trovare la configurazione di trasporto per gli stream di registrazione attivi utilizzando il findTransport, quindi modificare la configurazione con il nuovo valore di durata dell'evento utilizzando il 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,
      )
    }
  }

Attivare o disattivare l'analisi

Ogni dispositivo può attivare individualmente l'invio di dati di analisi dettagliati al cloud Google Home (vedi Cloud Monitoring per le API Home).

Per attivare l'analisi per un dispositivo, imposta la analyticsEnabled proprietà di ExtendedGeneralDiagnosticsTrait su true. Quando imposti analyticsEnabled, un'altra proprietà, logUploadEnabled, viene impostata automaticamente su true, il che consente di caricare i file di log di analisi nel cloud Google Home.

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

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