Guide des caméras pour Android

Le type d'appareil "Caméra" est implémenté à l'aide de deux traits : PushAvStreamTransport, qui gère le transport des flux audio et vidéo à l'aide de protocoles de type push, et WebRtcLiveView, qui permet de contrôler les flux en direct et la fonctionnalité de communication bidirectionnelle.

Assurez-vous toujours qu'un appareil prend en charge les attributs et les commandes nécessaires avant d'utiliser une fonctionnalité ou de tenter de mettre à jour des attributs. Pour en savoir plus, consultez Contrôler les appareils surAndroid.

Type d'appareil de l'API Home Traits de caractère Exemple d'application Kotlin Cas d'utilisation

Caméra

GoogleCameraDevice

home.matter.6006.types.0158

Appareil qui capture des images fixes ou enregistre des vidéos. Les caméras peuvent proposer un accès à des flux en direct, une fonctionnalité de communication bidirectionnelle ou générer des événements de détection.

Traits requis
     google PushAvStreamTransport
     google WebRtcLiveView

Caméra

Obtenir des informations de base sur un appareil

Le BasicInformation trait inclut des informations telles que le nom du fournisseur, l'ID du fournisseur, l'ID du produit, le nom du produit (y compris les informations sur le modèle), la version logicielle, et le numéro de série d'un appareil :

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

Obtenir la dernière heure de contact de l'appareil avec le cloud

Pour connaître la dernière heure à laquelle l'appareil a contacté le cloud, utilisez l'attribut lastContactTimestamp du ExtendedGeneralDiagnostics trait :

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

Vérifier la connectivité d'un appareil

La connectivité d'un appareil est en fait vérifiée au niveau du type d'appareil, car certains appareils sont compatibles avec plusieurs types d'appareils. L'état renvoyé est une combinaison des états de connectivité de tous les traits de cet appareil.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

L'état PARTIALLY_ONLINE peut être observé dans le cas de types d'appareils mixtes en l'absence de connectivité Internet. Matter Les traits standards peuvent toujours être en ligne en raison du routage local, mais les traits basés sur le cloud seront hors connexion.

Lancer un flux en direct

Pour lancer un flux en direct, envoyez la chaîne SDP (Session Description Protocol) à la WebRtcLiveView méthode du trait startLiveView(), qui renvoie une WebRtcLiveViewTrait.StartLiveViewCommand.Response contenant trois valeurs :

  • SDP de la session
  • Durée de la session en secondes
  • ID de la session, qui peut être utilisé pour la prolonger ou y mettre fin
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)

Prolonger un flux en direct

Les flux en direct ont une durée prédéfinie au terme de laquelle ils expirent. Pour prolonger la durée d'un flux actif, utilisez la méthode 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
}

Démarrer et arrêter la conversation bidirectionnelle

Pour démarrer la conversation bidirectionnelle, appelez la WebRtcLiveView méthode startTalkback() du trait. Pour l'arrêter, utilisez 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)
  }
}

Activer et désactiver la capacité d'enregistrement

Pour activer la capacité d'enregistrement de la caméra, transmettez TransportStatusEnum.Active à la méthode setTransportStatus() du trait PushAvStreamTransport. Pour désactiver la capacité d'enregistrement, transmettez-lui TransportStatusEnum.Inactive. Dans l'exemple suivant, nous encapsulons ces appels dans un seul appel qui utilise un Boolean pour activer ou désactiver la capacité d'enregistrement :

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

Activer ou désactiver la capacité d'enregistrement de la caméra revient à activer ou désactiver la vidéo de la caméra. Lorsque la vidéo d'une caméra est activée, elle enregistre (pour les événements et les clips associés).

Lorsque la capacité d'enregistrement est désactivée (la vidéo de la caméra est désactivée) :

  • La caméra peut toujours apparaître comme étant en ligne, conformément à la connectivityState du type d'appareil.
  • Le flux en direct n'est pas accessible et la caméra ne détecte aucun événement cloud.

Vérifier si la capacité d'enregistrement est activée

Pour savoir si la capacité d'enregistrement d'une caméra est activée, vérifiez si des connexions sont actives. L'exemple suivant définit deux fonctions pour ce faire :

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

Vous pouvez également utiliser la fonction findTransport() avec un prédicat :

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

Paramètres de batterie

Vous pouvez contrôler différents paramètres de batterie via les API Home.

Définir la préférence d'utilisation de la batterie

Le réglage de l'équilibre énergétique vous permet de configurer le compromis entre l'autonomie de la batterie et les performances d'un appareil. Vous pouvez créer différents profils de batterie, tels que "Prolongé", "Équilibré" et "Performances", et passer de l'un à l'autre.

Cette fonctionnalité est implémentée en mettant à jour l' currentEnergyBalance attribut du EnergyPreference trait. L'attribut accepte un index entier qui correspond à un profil spécifique défini dans la liste energyBalances de l'appareil (par exemple, 0 pour EXTENDED, 1 pour BALANCED et 2 pour PERFORMANCE).

Une valeur null pour currentEnergyBalance indique que l'appareil utilise un profil personnalisé. Il s'agit d'un état en lecture seule.

L'exemple suivant montre une structure que l'attribut currentEnergyBalance utilisera, suivi de l'extrait de code réel qui utilise l'attribut.

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

Activer l'économiseur de batterie automatique

Pour configurer cette fonctionnalité, mettez à jour le currentLowPowerModeSensitivity attribut du EnergyPreference trait. Cet attribut utilise un index pour sélectionner un niveau de sensibilité, où 0 représente généralement Disabled et 1 représente 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) }
}

Obtenir l'état de charge de la batterie

Pour obtenir l'état de charge actuel de l'appareil (en charge, complètement chargé ou non en charge), utilisez lebatChargeState attribut du PowerSource trait.

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

Obtenir le niveau de batterie

Pour obtenir le niveau de batterie actuel, utilisez l' batChargeLevel attribut du PowerSource trait. Le niveau est OK, Warning (faible) 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"
}

Obtenir la source d'alimentation

Pour déterminer la source d'alimentation utilisée par l'appareil, utilisez les BatPresent et wiredPresent attributs du PowerSource trait.

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

Paramètres audio

Vous pouvez contrôler différents paramètres audio via les API Home.

Activer ou désactiver le micro

Pour activer ou désactiver le micro de l'appareil, mettez à jour l' microphoneMuted attribut du trait CameraAvStreamManagement à l'aide de la fonction Kotlin intégrée setMicrophoneMuted :

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

Activer ou désactiver l'enregistrement audio

Pour activer ou désactiver l'enregistrement audio de l'appareil, mettez à jour l' recordingMicrophoneMuted attribut du trait CameraAvStreamManagement à l'aide de la fonction Kotlin intégrée setRecordingMicrophoneMuted :

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

Régler le volume du haut-parleur

Pour régler le volume du haut-parleur de l'appareil, mettez à jour l' speakerVolumeLevel attribut du trait CameraAvStreamManagement à l'aide de la fonction Kotlin intégrée setSpeakerVolumeLevel :

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

Paramètres de zone d'activité

Le trait ZoneManagement fournit une interface permettant de gérer les régions d'intérêt personnalisées (zones d'activité) sur les caméras et les sonnettes. Ces zones sont utilisées pour filtrer la détection d'événements (tels que le mouvement d'une personne ou d'un véhicule) dans des zones spécifiques du champ de vision de l'appareil.

Les zones d'activité sont configurées par l'utilisateur dans une application partenaire, ce qui lui permet de dessiner des zones sur des zones spécifiques du champ de vision de la caméra. Ces zones définies par l'utilisateur sont ensuite traduites dans les structures utilisées par ce trait. Pour en savoir plus sur le fonctionnement des zones d'activité, consultez Configurer et utiliser des zones d'activité.

Les zones d'activité sont généralement définies à l'aide de coordonnées cartésiennes 2D. Le trait fournit le TwoDCartesianVertexStruct pour les sommets et le TwoDCartesianZoneStruct pour la définition de la zone (nom, sommets, couleur et utilisation).

Vérifier les zones d'activité

Pour afficher les zones d'activité, cochez le zones attribut du trait 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()
  }

Ajouter une zone d'activité

Pour créer une zone, utilisez la createTwoDCartesianZone commande. Cette commande prend un TwoDCartesianZoneStruct, qui définit le nom, les sommets, la couleur et l'utilisation de la zone.

L'exemple suivant montre comment créer une zone nommée "Porche" avec quatre sommets, de couleur saumon (#F439A0) et utilisée pour la détection de mouvement.

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

Mettre à jour une zone d'activité

Pour mettre à jour une zone existante, utilisez la updateTwoDCartesianZone commande. Cette commande nécessite le zoneId et le mis à jour TwoDCartesianZoneStruct.

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

Supprimer une zone d'activité

Pour supprimer une zone, utilisez la removeZone commande avec le zoneId spécifique.

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

Déclencheurs d'événements sonores

Le trait AvStreamAnalysis fournit une interface permettant de gérer les déclencheurs de détection d'événements sur les caméras et les sonnettes. Bien que les déclencheurs basés sur la vision (tels que les personnes ou les véhicules) puissent être spécifiques à une zone, les déclencheurs liés au son sont généralement des configurations au niveau de l'appareil.

Les types de déclencheurs suivants sont disponibles pour la détection des sons avec le EventTriggerTypeEnum :

Mode Valeur d'énumération Description
Son Sound Détection générale des sons.
Voix PersonTalking Détecte la parole.
Aboiement DogBark Détecte les vocalisations canines.
Bris de verre GlassBreak Détecte le bruit du verre brisé.
Détecteur de fumée SmokeAlarm Détecte les détecteurs de fumée, souvent reconnus par le schéma sonore T3 audible pattern (trois bips courts suivis d'une pause).
Alarme monoxyde carbone CoAlarm Détecte les alarmes de monoxyde de carbone (CO), généralement reconnues par le schéma sonore T4 (quatre bips courts suivis par une pause).

Vérifier l'état de la détection des sons

Pour afficher l'état actuel de la détection des sons à l'utilisateur, vous devez vérifier ce que l'appareil prend en charge et ce qui est activé par le matériel de l'appareil. Les deux attributs à vérifier sont les suivants :

Dans le développement Android à l'aide de Kotlin Flows, vous observez généralement le trait AvStreamAnalysis à partir du 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)
        )
      }
  }

Mettre à jour l'ensemble des déclencheurs activés

Pour mettre à jour l'ensemble des déclencheurs activés, utilisez la SetOrUpdateEventDetectionTriggers commande, qui prend une liste de EventTriggerEnablement structures.

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

Modes d'enregistrement

Le trait RecordingMode fournit une interface permettant de gérer le comportement d'enregistrement vidéo et d'image sur les caméras et les sonnettes. Il permet aux utilisateurs de choisir entre l'enregistrement continu, l'enregistrement en cas d'événement ou la désactivation complète de l'enregistrement (Live View uniquement).

Le RecordingModeEnum définit les stratégies d'enregistrement disponibles :

Mode Valeur d'énumération Description
Désactivé Disabled L'enregistrement est complètement désactivé. Principalement utilisé par les appareils hérités.
CVR (Continuous Video Recording, enregistrement vidéo en continu) Cvr La vidéo est enregistrée 24h/24 et 7j/7. Nécessite un abonnement (par exemple, Google Google Home Premium).
EBR (Event Based Recording, enregistrement en cas d'événement) Ebr L'enregistrement est déclenché par des événements (personne, mouvement). La durée de la vidéo dépend de la durée de l'événement et de l'abonnement.
ETR (Event Triggered Recording, enregistrement déclenché par un événement) Etr Enregistrement d'un aperçu court (par exemple, 10 secondes) déclenché par des événements.
Live View LiveView L'enregistrement est désactivé, mais les utilisateurs peuvent toujours accéder au flux en direct.
Images fixes Images Des instantanés sont enregistrés à la place de la vidéo lorsque des événements se produisent.

Vérifier les modes d'enregistrement

Pour afficher la configuration d'enregistrement actuelle, vérifiez les attributs du 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(),
            )
        }
    }

Modifier le mode d'enregistrement

Avant de mettre à jour, assurez-vous que l'index choisi dans l'attribut supportedRecordingModes est présent dans l'attribut availableRecordingModes.

Pour mettre à jour le mode sélectionné, utilisez la fonction setSelectedRecordingMode, en transmettant l'index du mode choisi :

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

Autres paramètres

Vous pouvez contrôler différents autres paramètres via les API Home.

Modifier l'orientation de l'image

L'orientation de l'image de la caméra (vidéo) peut être modifiée. La vidéo ne peut être pivotée que de 180 degrés.

Pour modifier l'orientation de l'image de la caméra, mettez à jour l' imageRotation attribut du trait CameraAvStreamManagement à l'aide de la fonction Kotlin intégrée setImageRotation :

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

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

Activer ou désactiver la vision nocturne

Pour activer ou désactiver la vision nocturne de la caméra, utilisez TriStateAutoEnum pour mettre à jour l' nightVision attribut du trait CameraAvStreamManagement à l'aide de la fonction Kotlin intégrée setNightVision :

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

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

Modifier la luminosité du voyant d'état

Pour modifier la luminosité du voyant d'état, utilisez ThreeLevelAutoEnum pour mettre à jour l'attribut statusLightBrightness du trait CameraAvStreamManagement à l'aide de la fonction Kotlin intégrée 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)
}

Modifier le champ de vision de la caméra

Le champ de vision de la caméra est identique à la fonctionnalité "Zoomer et recadrer" décrite dans l'article d'aide Zoomer et améliorer l'affichage vidéo de la caméra Nest.

Le champ de vision est défini dans un ViewportStruct qui contient quatre valeurs utilisées comme coordonnées du champ de vision. Les coordonnées sont définies comme suit :

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

La détermination des valeurs pour ViewportStruct dépend de l'UI et de l'implémentation de la caméra d'une application. À un niveau très basique, pour définir le champ de vision de la caméra vidéo, mettez à jour l' viewport attribut du trait CameraAvStreamManagement avec un ViewportStruct à l'aide de la fonction Kotlin intégrée 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(),
    )
) }

Ajuster la sensibilité d'activation de l'appareil

La sensibilité d'activation de l'appareil permet d'économiser la batterie en réduisant la plage à laquelle l'appareil peut détecter une activité et en augmentant le temps d'activation après la détection de cette activité.

Dans les API Home, cette propriété peut être définie à l'aide de la propriété motionSensitivity de triggerOptions dans les transportOptions de l'appareil. Ces options sont définies dans le trait PushAvStreamTransport pour chaque appareil.

La sensibilité d'activation ne peut être définie que sur les valeurs suivantes :

  • 1 = Faible
  • 5 = Moyenne
  • 10 = Élevée

Pour effectuer la mise à jour, recherchez la configuration de transport pour les flux d'enregistrement actifs à l'aide de la findTransport , puis modifiez la configuration avec la nouvelle valeur de sensibilité à l'aide de la 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,
      )
    }
  }

Ajuster la durée maximale des événements

La durée maximale des événements correspond à la durée pendant laquelle la caméra enregistre un clip pour un événement. Via les API Home, vous pouvez configurer cette durée pour chaque appareil, avec les mêmes durées que dans le GHA, par intervalles de secondes :

  • 10 secondes
  • 15 secondes
  • 30 secondes
  • 60 secondes (1 minute)
  • 120 secondes (2 minutes)
  • 180 secondes (3 minutes)

Dans les API Home, cette propriété peut être définie à l'aide de la propriété motionTimeControl de triggerOptions dans les transportOptions de l'appareil. Ces options sont définies dans le trait PushAvStreamTransport pour chaque appareil.

Pour effectuer la mise à jour, recherchez la configuration de transport pour les flux d'enregistrement actifs à l'aide de la findTransport commande, puis modifiez la configuration avec la nouvelle valeur de durée de l'événement à l'aide de la modifyPushTransport commande :

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

Activer ou désactiver les analyses

Chaque appareil peut choisir individuellement d'envoyer des données d'analyse détaillées au cloud Google Home (voir Cloud Monitoring pour les API Home).

Pour activer les analyses pour un appareil, définissez la analyticsEnabled propriété de la ExtendedGeneralDiagnosticsTrait sur true. Lorsque vous définissez analyticsEnabled, une autre propriété, logUploadEnabled, est automatiquement définie sur true, ce qui permet d'importer les fichiers journaux d'analyse dans le cloud Google Home.

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

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