Guia de dispositivos de câmera para Android

O tipo de dispositivo de câmera é implementado usando duas características: PushAvStreamTransport, que processa o transporte de stream de áudio e vídeo usando protocolos baseados em push, e WebRtcLiveView, que oferece a capacidade de controlar transmissões ao vivo e talkback.

Sempre verifique se um dispositivo é compatível com atributos e comandos antes de usar qualquer recurso ou tentar atualizar atributos. Consulte Controlar dispositivos no Android para mais informações.

Tipo de dispositivo das APIs do Google Home Características App de exemplo em Kotlin Caso de uso

Câmera

GoogleCameraDevice

home.matter.6006.types.0158

Um dispositivo que captura imagens estáticas ou vídeo. As câmeras podem ter transmissões ao vivo acessíveis, comunicação bidirecional ou eventos de detecção.

Traços obrigatórios
     google PushAvStreamTransport
     google WebRtcLiveView

Câmera

Receber informações básicas sobre um dispositivo

O traço BasicInformation inclui informações como nome do fornecedor, ID do fornecedor, ID do produto, nome do produto (inclui informações do modelo), versão do software e o número de série de um 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}")
    }

Receber a hora mais recente de contato do dispositivo com a nuvem

Para encontrar a hora mais recente em que o dispositivo teve contato com a nuvem, use o atributo lastContactTimestamp da característica ExtendedGeneralDiagnostics:

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

Verificar a conectividade de um dispositivo

A conectividade de um dispositivo é verificada no nível do tipo de dispositivo porque alguns dispositivos são compatíveis com vários tipos. O estado retornado é uma combinação dos estados de conectividade de todas as características do dispositivo.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

Um estado de PARTIALLY_ONLINE pode ser observado no caso de tipos de dispositivos mistos quando não há conectividade com a Internet. Os traços padrão do Matter ainda podem estar on-line devido ao roteamento local, mas os traços baseados na nuvem vão ficar off-line.

Iniciar uma transmissão ao vivo

Para iniciar uma transmissão ao vivo, envie a string do Session Description Protocol (SDP) para o método startLiveView() do traço WebRtcLiveView, que retorna um WebRtcLiveViewTrait.StartLiveViewCommand.Response com três valores:

  • O SDP da sessão.
  • A duração da sessão em segundos.
  • O ID da sessão, que pode ser usado para estender ou encerrar a sessão.
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)

Estender uma transmissão ao vivo

As transmissões ao vivo têm uma duração predefinida após a qual expiram. Para aumentar a duração de um stream ativo, envie uma solicitação de extensão usando o método 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
}

Iniciar e interromper o TalkBack

Para iniciar o talkback, chame o método startTalkback() da característica WebRtcLiveView. Para parar, use 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)
  }
}

Ativar e desativar a capacidade de gravação

Para ativar a capacidade de gravação da câmera, transmita TransportStatusEnum.Active ao método PushAvStreamTransport da característica setTransportStatus(). Para desativar a capacidade de gravação, transmita-a TransportStatusEnum.Inactive. No exemplo a seguir, agrupamos essas chamadas em uma única chamada que usa um Boolean para ativar ou desativar a capacidade de gravação:

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

Ativar ou desativar a capacidade de gravação da câmera é o mesmo que ligar ou desligar o vídeo dela. Quando o vídeo de uma câmera está ativado, ela está gravando (para fins de eventos e clipes relacionados).

Quando a capacidade de gravação está desativada (o vídeo da câmera está desligado):

Verificar se a capacidade de gravação está ativada

Para determinar se a capacidade de gravação de uma câmera está ativada, verifique se há conexões ativas. O exemplo a seguir define duas funções para fazer isso:

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

Outra maneira de verificar é usar a função findTransport() com um predicado:

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

Configurações de bateria

Várias configurações de bateria podem ser controladas pelas APIs Home.

Definir a preferência de uso da bateria

Ao definir o equilíbrio energético, você configura a compensação entre a duração da bateria e o desempenho de um dispositivo. Você pode criar diferentes perfis de bateria, como "Estendido", "Equilibrado" e "Performance", e alternar entre eles.

Esse recurso é implementado atualizando o atributo currentEnergyBalance da característica EnergyPreference. O atributo aceita um índice inteiro que corresponde a um perfil específico definido na lista energyBalances do dispositivo (por exemplo, 0 para EXTENDED, 1 para BALANCED e 2 para PERFORMANCE).

Um valor null para currentEnergyBalance indica que o dispositivo está usando um perfil personalizado. Este é um estado somente leitura.

A seguir, mostramos um exemplo de estrutura que o atributo currentEnergyBalance vai usar, seguido pelo snippet de código real que usa o atributo.

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

Ativar a Economia de bateria automática

Para configurar esse recurso, atualize o atributo currentLowPowerModeSensitivity da característica EnergyPreference. Esse atributo usa um índice para selecionar um nível de sensibilidade, em que 0 geralmente representa Disabled e 1 representa Enabled ou 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) }
}

Receber o estado de carregamento da bateria

Para saber o estado de carregamento atual do dispositivo (carregando, totalmente carregado ou não carregando), use o atributo batChargeState da característica 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"
}

Receber o nível de bateria

Para saber o nível de bateria atual, use o atributo batChargeLevel da característica PowerSource. O nível é OK, Warning (baixo) ou 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"
}

Encontre a fonte de alimentação

Para determinar a fonte de energia que o dispositivo está usando, use os atributos BatPresent e wiredPresent da característica PowerSource.

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

Configurações de áudio

Várias configurações de áudio podem ser controladas pelas APIs Home.

Ativar ou desativar o microfone

Para ativar ou desativar o microfone do dispositivo, atualize o atributo microphoneMuted da característica CameraAvStreamManagement usando a função setMicrophoneMuted do Kotlin:

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

Ativar ou desativar a gravação de áudio

Para ativar ou desativar a gravação de áudio no dispositivo, atualize o atributo recordingMicrophoneMuted da característica CameraAvStreamManagement usando a função setRecordingMicrophoneMuted do Kotlin integrada:

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

Ajustar o volume do alto-falante

Para ajustar o volume do alto-falante do dispositivo, atualize o atributo speakerVolumeLevel da característica CameraAvStreamManagement usando a função setSpeakerVolumeLevel do Kotlin integrada:

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

Configurações de zonas de atividade

O traço ZoneManagement fornece uma interface para gerenciar regiões de interesse personalizadas (zonas de atividade) em câmeras e campainhas. Essas zonas são usadas para filtrar a detecção de eventos (como movimento de pessoas ou veículos) em áreas específicas no campo de visão do dispositivo.

As Zonas de atividade são configuradas pelo usuário em um aplicativo parceiro, permitindo que ele desenhe zonas em áreas específicas do campo de visão da câmera. Essas zonas definidas pelo usuário são traduzidas nas estruturas usadas por essa característica. Para mais informações sobre como as Zonas de Atividade funcionam, consulte Configurar e usar as Zonas de Atividade.

As zonas de atividade geralmente são definidas usando coordenadas cartesianas 2D. O traço fornece o TwoDCartesianVertexStruct para vértices e o TwoDCartesianZoneStruct para a definição de zona (nome, vértices, cor e uso).

Verificar zonas de atividade

Para mostrar as zonas de atividade, marque o atributo zones da característica 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()
  }

Adicionar uma Zona de Atividade

Para criar uma zona, use o comando createTwoDCartesianZone. Esse comando usa um TwoDCartesianZoneStruct, que define o nome, os vértices, a cor e o uso da zona.

O exemplo a seguir mostra como criar uma zona chamada "Front Porch" com quatro vértices, cor salmão (#F439A0) e usada para detecção de 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}")
  }
}

Atualizar uma Zona de Atividade

Para atualizar uma zona, use o comando updateTwoDCartesianZone. Esse comando exige o zoneId e o TwoDCartesianZoneStruct atualizado.

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

Excluir uma Zona de Atividade

Para remover uma zona, use o comando removeZone com o zoneId específico.

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

Gatilhos de eventos sonoros

O trait AvStreamAnalysis oferece uma interface para gerenciar gatilhos de detecção de eventos em dispositivos de câmera e campainha. Embora os gatilhos baseados em visão (como pessoas ou veículos) possam ser específicos de uma zona, os gatilhos relacionados a som geralmente são configurações no nível do dispositivo.

Os seguintes tipos de gatilho estão disponíveis para detecção de som com o EventTriggerTypeEnum:

Modo Valor de tipo enumerado Descrição
Som Sound Detecção geral de som.
Pessoa falando PersonTalking Detecta fala.
Latido de cachorro DogBark Detecta vocalizações caninas.
Vidro quebrando GlassBreak Detecta o som de vidro quebrando.
Detector de fumaça SmokeAlarm Detecta alarmes de fumaça, geralmente reconhecidos pelo padrão audível T3 (três bips curtos seguidos de uma pausa).
Alarme de monóxido de carbono CoAlarm Detecta alarmes de monóxido de carbono (CO), geralmente reconhecidos pelo padrão audível T4 (quatro bipes curtos seguidos por uma pausa).

Verificar o status da detecção de som

Para mostrar ao usuário o estado atual da detecção de som, verifique o que o dispositivo oferece suporte e o que está ativado pelo hardware dele. Os dois atributos a serem verificados são:

No desenvolvimento Android usando fluxos Kotlin, normalmente você observa a característica AvStreamAnalysis do 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)
        )
      }
  }

Atualizar o conjunto de acionadores ativados

Para atualizar o conjunto de gatilhos ativados, use o comando SetOrUpdateEventDetectionTriggers, que recebe uma lista de estruturas 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)
}

Modos de gravação

A característica RecordingMode fornece uma interface para gerenciar o comportamento de gravação de vídeo e imagem em dispositivos de câmera e campainha. Ele permite que os usuários escolham entre gravação contínua, gravação baseada em eventos ou desativação total da gravação (somente na Live View).

O RecordingModeEnum define as estratégias de gravação disponíveis:

Modo Valor de tipo enumerado Descrição
Desativada Disabled A gravação é completamente desativada. Usado principalmente por dispositivos legados.
CVR (gravação contínua de vídeo) Cvr O vídeo é gravado 24 horas por dia, 7 dias por semana. Requer uma assinatura (por exemplo, do Google Google Home Premium.
EBR (gravação baseada em eventos) Ebr A gravação é acionada por eventos (pessoa, movimento). A duração do vídeo depende da duração do evento e da assinatura.
ETR (gravação acionada por evento) Etr Gravação de prévia curta (por exemplo, 10 segundos) acionada por eventos.
Imagens ao Vivo LiveView A gravação está desativada, mas os usuários ainda podem acessar a transmissão ao vivo.
Imagens estáticas Images Os instantâneos são gravados em vez de vídeos quando ocorrem eventos.

Verificar os modos de gravação

Para mostrar a configuração de gravação atual, verifique os atributos da característica 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(),
            )
        }
    }

Mudar o modo de gravação

Antes de atualizar, verifique se o índice escolhido do atributo supportedRecordingModes está presente no atributo availableRecordingModes.

Para atualizar o modo selecionado, use a função setSelectedRecordingMode, transmitindo o índice do modo escolhido:

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

Outras configurações

Várias outras configurações podem ser controladas pelas APIs Home.

Mudar a orientação da imagem

A orientação da imagem da câmera (vídeo) pode ser girada. O vídeo só pode ser girado em 180 graus.

Para mudar a orientação da imagem da câmera, atualize o atributo imageRotation da característica CameraAvStreamManagement usando a função setImageRotation do Kotlin integrada:

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

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

Ativar ou desativar a visão noturna

Para ativar ou desativar a visão noturna da câmera, use TriStateAutoEnum para atualizar o atributo nightVision da característica CameraAvStreamManagement usando a função setNightVision do Kotlin:

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

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

Mudar o brilho do LED de status

Para mudar o brilho do LED de status, use ThreeLevelAutoEnum para atualizar o atributo statusLightBrightness da característica CameraAvStreamManagement usando a função setStatusLightBrightness do Kotlin integrada:

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

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

Mudar a janela de visualização da câmera

A janela de visualização da câmera é a mesma do recurso de zoom e corte descrito no artigo de suporte Zoom e modo Enhance no vídeo da câmera Nest.

A janela de visualização é definida em um ViewportStruct que contém quatro valores, usados como coordenadas da janela. As coordenadas são definidas como:

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

A determinação dos valores para ViewportStruct depende da interface do app e da implementação da câmera. Em um nível muito básico, para definir a janela de visualização do vídeo da câmera, atualize o atributo viewport da característica CameraAvStreamManagement com um ViewportStruct, usando a função setViewport integrada do Kotlin:

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

Ajustar a sensibilidade de ativação do dispositivo

A sensibilidade de ativação do dispositivo é usada para economizar bateria, diminuindo o alcance em que o dispositivo pode detectar atividade e aumentando o tempo para ativar após detectar essa atividade.

Nas APIs Home, isso pode ser definido usando a propriedade motionSensitivity do triggerOptions no transportOptions do dispositivo. Essas opções são definidas no traço PushAvStreamTransport de cada dispositivo.

A sensibilidade de ativação só pode ser definida com os seguintes valores:

  • 1 = Baixa
  • 5 = Médio
  • 10 = Alto

Para atualizar, encontre a configuração de transporte para fluxos de gravação ativos usando o comando findTransport e modifique a configuração com o novo valor de sensibilidade usando o comando 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,
      )
    }
  }

Ajustar a duração máxima de eventos

A duração máxima de eventos é o tempo que a câmera vai gravar um clipe para um evento. Usando as APIs Home, isso pode ser configurado por dispositivo com os mesmos comprimentos que no GHA, em intervalos de segundos:

  • 10 segundos
  • 15 segundos
  • 30 segundos
  • 60 segundos (1 minuto)
  • 120 segundos (2 minutos)
  • 180 segundos (3 minutos)

Nas APIs Home, isso pode ser definido usando a propriedade motionTimeControl do triggerOptions no transportOptions do dispositivo. Essas opções são definidas no traço PushAvStreamTransport de cada dispositivo.

Para atualizar, encontre a configuração de transporte para fluxos de gravação ativos usando o comando findTransport e modifique a configuração com o novo valor de duração do evento usando o comando 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,
      )
    }
  }

Ativar ou desativar a análise

Cada dispositivo pode ativar individualmente o envio de dados de análise detalhados para a nuvem do Google Home. Consulte Cloud Monitoring para APIs do Home.

Para ativar a análise de um dispositivo, defina a propriedade analyticsEnabled do ExtendedGeneralDiagnosticsTrait como true. Quando você define analyticsEnabled, outra propriedade, logUploadEnabled, é definida automaticamente como true, o que permite que os arquivos de registro de análise sejam enviados para a nuvem do Google Home.

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

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