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 des API Home | Traits | Exemple d'application Kotlin | Cas d'utilisation |
|---|---|---|---|
|
Caméra
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 |
Appareil photo |
Obtenir des informations de base sur un appareil
Le trait BasicInformation inclut des informations telles que le nom du fournisseur, son ID, l'ID du produit, le nom du produit (y compris les informations sur le modèle), la version du logiciel 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}") }
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
Un état PARTIALLY_ONLINE peut être observé dans le cas de types d'appareils mixtes en l'absence de connectivité Internet.
Les traits standards Matter peuvent toujours être en ligne en raison du routage local, mais les traits basés sur le cloud seront hors ligne.
Lancer un flux en direct
Pour lancer un flux en direct, envoyez la chaîne SDP (Session Description Protocol) à la méthode startLiveView() du trait WebRtcLiveView, qui renvoie un 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 méthode startTalkback() du trait WebRtcLiveView. Pour 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. Lorsqu'une caméra est activée, elle enregistre (pour les événements et les extraits 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
connectivityStatedu 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 la 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 paramètre d'é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 (par exemple, "Autonomie prolongée", "Équilibré" et "Performances") et passer de l'un à l'autre.
Cette fonctionnalité est implémentée en mettant à jour l'attribut currentEnergyBalance du trait EnergyPreference. 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.
Vous trouverez ci-dessous un exemple de 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 l'attribut currentLowPowerModeSensitivity du trait EnergyPreference. 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 l'attribut batChargeState du 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" }
Obtenir le niveau de batterie
Pour obtenir le niveau de batterie actuel, utilisez l'attribut batChargeLevel du trait PowerSource. Le niveau est OK, Warning (bas) 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 attributs BatPresent et wiredPresent du trait PowerSource.
val trait: PowerSource val isWired = trait.wiredPresent val hasBattery = trait.batPresent
Paramètres audio
Vous pouvez contrôler différents paramètres audio à l'aide des API Home.
Activer ou désactiver le micro
Pour activer ou désactiver le micro de l'appareil, mettez à jour l'attribut microphoneMuted du trait CameraAvStreamManagement à l'aide de la fonction Kotlin setMicrophoneMuted intégrée :
// 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'attribut recordingMicrophoneMuted du trait CameraAvStreamManagement à l'aide de la fonction Kotlin setRecordingMicrophoneMuted intégrée :
// 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 ajuster le volume du haut-parleur de l'appareil, mettez à jour l'attribut speakerVolumeLevel du trait CameraAvStreamManagement à l'aide de la fonction Kotlin setSpeakerVolumeLevel intégrée :
// Adjust the camera speaker volume suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) { trait.update { setSpeakerVolumeLevel(volume.toUbyte()) } }
Autres paramètres
Vous pouvez contrôler d'autres paramètres à l'aide des API Home.
Modifier l'orientation de l'image
Vous pouvez faire pivoter l'orientation de l'image (vidéo) de la caméra. 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'attribut imageRotation du trait CameraAvStreamManagement à l'aide de la fonction Kotlin setImageRotation intégrée :
// 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'attribut nightVision du trait CameraAvStreamManagement à l'aide de la fonction Kotlin setNightVision intégrée :
// 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é de la LED d'état, utilisez ThreeLevelAutoEnum pour mettre à jour l'attribut statusLightBrightness du trait CameraAvStreamManagement à l'aide de la fonction Kotlin setStatusLightBrightness intégrée :
// 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. Pour définir le champ de vision de la vidéo de la caméra, mettez à jour l'attribut viewport du trait CameraAvStreamManagement avec un ViewportStruct à l'aide de la fonction Kotlin setViewport intégrée :
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 = Moyen
- 10 = Élevé
Pour mettre à jour la configuration, vous devez trouver la configuration du transport pour les flux d'enregistrement actifs à l'aide de la commande findTransport, puis modifier la configuration avec la nouvelle valeur de sensibilité à l'aide de la commande 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 d'enregistrement vidéo d'un événement par la caméra. Grâce aux API Home, vous pouvez configurer cette propriété pour chaque appareil, avec les mêmes durées que dans 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 mettre à jour la configuration du transport, vous devez d'abord trouver la configuration du transport pour les flux d'enregistrement actifs à l'aide de la commande findTransport, puis modifier la configuration avec la nouvelle valeur de durée de l'événement à l'aide de la commande 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, ) } }