Il tipo di dispositivo Videocamera viene implementato utilizzando tre tratti:
PushAvStreamTransport,
che gestisce il trasporto di stream audio e video utilizzando protocolli
basati su push,
WebRtcLiveView,
che offre la possibilità di controllare i live streaming e il talkback, e
CameraSnapshot,
che fornisce istantanee di anteprima memorizzate nella cache e acquisizioni di istantanee in tempo reale.
Controlla sempre il supporto di attributi e comandi per un dispositivo prima di utilizzare qualsiasi funzionalità o di tentare di aggiornare gli attributi. Per saperne di più, consulta Controlla i dispositivi su Android.
| Tipo di dispositivo delle API Home | Tratti | App di esempio Kotlin | Caso d'uso |
|---|---|---|---|
|
Fotocamera
Un dispositivo che acquisisce immagini statiche o video. Le videocamere possono includere live streaming accessibili, talkback bidirezionale o eventi di rilevamento. |
Tratti richiesti google PushAvStreamTransport google WebRtcLiveView |
Fotocamera |
Ricevi informazioni di base su un dispositivo
Implementato nell'app di esempio per Android
Il tratto BasicInformation include informazioni come il nome del fornitore, l'ID fornitore, l'ID prodotto, il nome del prodotto (incluse le informazioni sul modello) e la versione software 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}") }
Recupera il numero di serie
Per ottenere il numero di serie del dispositivo, utilizza il comando GetSerialNumber del tratto ExtendedBasicInformation.
L'esempio mostra il salvataggio del numero di serie in una variabile denominata serialNumber:
val basicInfo: ExtendedBasicInformation = device.getTrait(ExtendedBasicInformation) val serialNumber = basicInfo.getSerialNumber().serialNumber
Ottieni l'ora più recente del contatto del dispositivo con il cloud
Per trovare l'ora più recente in cui il dispositivo ha avuto contatto con il cloud, utilizza
l'attributo lastContactTimestamp del
tratto
ExtendedGeneralDiagnostics:
fun getLastContactTimeStamp(trait: ExtendedGeneralDiagnostics): java.time.Instant { val timestamp = trait.lastContactTimestamp return Instant.ofEpochSecond(timestamp.toLong()) }
Impostazioni del tipo di supporto per videocamera
Il tratto Mount contiene le impostazioni e le informazioni sullo stato del supporto della videocamera. Puoi leggere attributi come lo stato di montaggio, il tipo di rilevamento e il nome del tipo di montaggio. Inoltre, puoi utilizzare la caratteristica Mount per eseguire l'override della configurazione del tipo di montaggio predefinito.
// Get the Mount trait val mountTrait: Mount = device.getTrait(Mount) // Read the current mount state and detection type val mountState = mountTrait.mountState val mountDetectionType = mountTrait.mountDetectionType // Read the current mount type name val mountTypeName = mountTrait.mountTypeName // Update the mount type override mountTrait.update { setMountTypeOverride(MountTrait.MountTypeOverrideEnum.Official) }
Controlla 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à per tutti i trait di quel dispositivo.
val cameraConnectivity = cameraDevice.metadata.sourceConnectivity.connectivityState
In caso di tipi di dispositivi misti, quando non è presente una connessione a internet, potrebbe essere visualizzato lo stato PARTIALLY_ONLINE.
I tratti standard di Matter potrebbero essere ancora online grazie al routing locale, ma i tratti basati su cloud saranno offline.
Recupera l'indirizzo IP del dispositivo
Per trovare l'indirizzo IP del dispositivo, utilizza l'attributo networkInterfaces del tratto GeneralDiagnostics. Gli indirizzi vengono restituiti come array di byte, che puoi formattare in stringhe IPv4 o IPv6 standard:
val ipAddresses =
trait.networkInterfaces?.flatMap { networkInterface ->
(networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
try {
java.net.InetAddress.getByAddress(bytes).hostAddress
} catch (e: java.net.UnknownHostException) {
null
}
}
} ?: emptyList()
Avvia un live streaming
Implementato nell'app di esempio per Android
Per avviare un live streaming, invia la stringa SDP (Session Description Protocol) al metodo startLiveView() del tratto WebRtcLiveView, 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)
Estendi un live streaming
Implementato nell'app di esempio per Android
I live streaming hanno una durata preimpostata, dopo la quale scadono. Per allungare la durata di uno stream attivo, invia una richiesta di estensione utilizzando il metodo 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 }
Avvia e interrompi TalkBack
Implementato nell'app di esempio per Android
Per avviare la conversazione, chiama il metodo startTalkback() del tratto WebRtcLiveView. 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) } }
Gestisci il live streaming
La regolazione della qualità del live streaming è utile per ottimizzare l'utilizzo della larghezza di banda in base al contesto di visualizzazione del client (ad esempio, passando a una risoluzione inferiore quando viene visualizzato un riquadro di anteprima più piccolo, una visualizzazione griglia o una modalità Picture in picture).
La modifica dinamica della qualità tramite il tratto WebRtcLiveView gestisce in modo specifico la risoluzione della sessione di live streaming attiva su un determinato client. Non è la stessa cosa che configurare un'impostazione di utilizzo della larghezza di banda a livello di dispositivo direttamente sul dispositivo, che influirebbe su tutti gli spettatori simultanei e sulla qualità delle registrazioni video storiche salvate sul cloud.
L'esempio seguente mostra come recuperare e aggiornare la qualità del livestream per un dispositivo:
Recuperare le opzioni di qualità supportate: ottieni le risoluzioni di streaming disponibili supportate dal dispositivo. Il codice esegue una query sull'attributo
supportedQualityHintsdel trattoWebRtcLiveViewsul flusso del tipo di dispositivo ed espone le qualità supportate comeStateFlowcontenente un elenco di valoriQualityHint(comeQUALITY_HINT_SD,QUALITY_HINT_HD,QUALITY_HINT_FHD,QUALITY_HINT_QHDoQUALITY_HINT_UHD).Modifica la qualità del live streaming: applica un
QualityHintselezionato per modificare la risoluzione di streaming del live streaming attivo (ad esempio, passando dalla definizione standard all'alta definizione). La funzionechangeQualityrisolve il tratto di live streaming del dispositivo e chiamachangeLiveViewQualitycon l'mediaSessionIdattivo e la configurazioneQualityHintscelta.
// Assuming you have a HomeDevice instance 'device' val availableQualityHints: StateFlow<List> = device.type(GoogleCameraDevice) .trait(WebRtcLiveView) .map { trait -> trait?.supportedQualityHints ?: emptyList() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) // Assuming you have a HomeDevice instance 'device' suspend fun changeQuality(mediaSessionId: String, qualityHint: QualityHint) { // Get the trait from the device val trait = device.type(GoogleCameraDevice).trait(WebRtcLiveView).first() ?: return try { trait.changeLiveViewQuality(mediaSessionId, qualityHint) } catch (e: Exception) { // Handle error } }
Attivare e disattivare la funzionalità di registrazione
Per attivare la funzionalità di registrazione della videocamera, passa
TransportStatusEnum.Active
al metodo
setTransportStatus()
del tratto
PushAvStreamTransport. Per disattivare la funzionalità di registrazione, passa
TransportStatusEnum.Inactive.
Nell'esempio seguente, inseriamo queste chiamate in un'unica 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'attivazione o la disattivazione 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 sta registrando (ai fini degli eventi e dei clip correlati).
Quando la funzionalità di registrazione è disattivata (il video della videocamera è disattivato):
- La videocamera può comunque risultare online in base alla
connectivityStatedel tipo di dispositivo. - Non è possibile accedere al live streaming e la videocamera non rileva eventi cloud.
Verifica se la funzionalità di registrazione è attiva
Per determinare se la funzionalità di registrazione di una videocamera è attiva, controlla se sono attive connessioni. L'esempio seguente definisce due funzioni per farlo:
// 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 verificare è 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 } }
Recupera istantanee della videocamera
Implementato nell'app di esempio per Android
Utilizza il tratto CameraSnapshot per recuperare istantanee di immagini statiche da una videocamera.
Questi snapshot sono utili in diversi scenari:
- Come riquadro segnaposto nell'interfaccia utente durante il caricamento di un live streaming WebRTC.
- Come immagine di anteprima statica che si aggiorna a un live streaming in seguito all'interazione dell'utente.
- Come sfondo per disegnare e configurare zone attive personalizzate.
Il tratto CameraSnapshot offre due modi per recuperare gli snapshot, a seconda che tu abbia bisogno di uno snapshot memorizzato nella cache per un rendering rapido o di uno snapshot in tempo reale on demand.
Ottieni uno snapshot di anteprima memorizzato nella cache
Un'istantanea di anteprima è un'immagine memorizzata nella cache che l'SDK può recuperare senza riattivare la videocamera. Questo è il metodo più rapido per recuperare un'immagine statica ed è ideale per le pagine Panoramica della videocamera o le griglie della dashboard.
Per ottenere l'istantanea dell'anteprima, leggi l'attributo della caratteristica preview_image_url:
// Get a flow of the CameraSnapshot trait val cameraSnapshotFlow: Flow<CameraSnapshot?> = cameraDevice .type(GoogleCameraDevice) .trait(CameraSnapshot) // Get the current trait state val cameraSnapshot = cameraSnapshotFlow.firstOrNull() if (cameraSnapshot != null) { val previewImageUrl = cameraSnapshot.previewImageUrl // Load the preview image from the URL } else { // CameraSnapshot trait not supported on this device }
A seconda della configurazione e dell'attività della videocamera, l'URL di anteprima rimanda a un'immagine memorizzata nella cache generata da un filmato recente (il primo I-frame dell'ultimo frammento video) o a un'istantanea caricata periodicamente dalla videocamera.
Per indicare l'aggiornamento dell'immagine, il cloud di Google Home incorpora un'intestazione X-Home-Image-Captured-At nell'immagine JPEG/PNG pubblicata, formattata in UTC. Puoi analizzare questa intestazione sul lato client per visualizzare l'età dello snapshot in un'app.
Ottieni un'istantanea in diretta on demand
Per i percorsi dell'utente che richiedono la visione in diretta attuale della videocamera, ad esempio la configurazione delle zone attive, puoi richiedere un'istantanea in diretta. L'attivazione di un'istantanea in tempo reale indica alla videocamera di riattivarsi, acquisire un nuovo fotogramma e caricarlo sul cloud.
Per richiedere uno snapshot in tempo reale, utilizza il comando getLiveSnapshot():
try { val response = cameraSnapshot.getLiveSnapshot() val snapshotUrl = response.snapshotUrl // Load the live snapshot image from the URL } catch (e: Exception) { Log.e("CameraSnapshot", "Failed to get live snapshot: ${e.message}") }
Autentica le richieste di snapshot
Implementato nell'app di esempio per Android
Tutti gli URL degli snapshot rimandano a contenuti multimediali protetti e richiedono un token OAuth 2.0 per l'ambito delle API Home v2. Per scaricare ed eseguire il rendering delle immagini, il token OAuth deve essere inserito come token di connessione nell'intestazione Authorization della richiesta HTTP.
L'esempio seguente mostra come configurare una richiesta di rete sicura per scaricare uno snapshot:
import android.graphics.Bitmap import android.graphics.BitmapFactory import java.io.IOException import java.net.HttpURLConnection import java.net.URL import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext /** * Downloads a snapshot from a URL using an OAuth access token. */ suspend fun loadSnapshotImage(urlString: String, oauthToken: String): Bitmap? = withContext(Dispatchers.IO) { var connection: HttpURLConnection? = null try { val url = URL(urlString) connection = url.openConnection() as HttpURLConnection // 1. Configure the HTTP GET request with the Bearer token connection.setRequestProperty("Authorization", "Bearer $oauthToken") // 2. Fetch the image data if (connection.responseCode == HttpURLConnection.HTTP_OK) { connection.inputStream.use { inputStream -> BitmapFactory.decodeStream(inputStream) } } else { null } } catch (e: IOException) { e.printStackTrace() null } finally { connection?.disconnect() } }
Impostazioni batteria
Tramite le API Home è possibile controllare varie impostazioni della batteria.
Imposta la preferenza di utilizzo della batteria
L'impostazione del bilanciamento energetico ti consente di configurare il compromesso tra durata della batteria e prestazioni di un dispositivo. Puoi creare diversi profili della batteria, come "Estesa", "Bilanciata" e "Prestazioni", e passare da uno all'altro.
Questa funzionalità viene implementata aggiornando l'attributo currentEnergyBalance del tratto EnergyPreference. 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)
Attiva il risparmio energetico automatico
Per configurare questa funzionalità, aggiorna l'attributo currentLowPowerModeSensitivity del tratto EnergyPreference. 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) } }
Recupera 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'attributo
batChargeState
del tratto
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" }
Controllare il livello batteria
Per ottenere il livello batteria attuale, utilizza l'attributo batChargeLevel del tratto PowerSource. 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" }
Procurati 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
Controlla se la batteria deve essere sostituita
L'attributo batReplaceability indica se la batteria non è sostituibile, se è sostituibile dall'utente o se è sostituibile in fabbrica.
L'attributo batReplacementNeeded del tratto PowerSource indica se la batteria deve essere sostituita.
// Get the battery replacement status val batteryStatus = powerSourceTrait.batReplacementNeeded if (batteryStatus) { println("Replace the battery.") }
Quando la batteria è sostituibile dall'utente,
batReplacementDescription
descrive la batteria, incluse informazioni come fattore di forma, chimica e
produttore preferito.
Impostazioni audio
Tramite le API Home è possibile controllare varie impostazioni audio.
Attiva o disattiva il microfono
Per attivare o disattivare il microfono del dispositivo, aggiorna l'attributo
microphoneMuted
del tratto CameraAvStreamManagement utilizzando la funzione Kotlin
setMicrophoneMuted integrata:
// Turn the device's microphone on or off suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) { trait.update { setMicrophoneMuted(disableMicrophone) } }
Attiva o disattiva la registrazione audio
Per attivare o disattivare la registrazione audio per il dispositivo, aggiorna l'attributo recordingMicrophoneMuted del tratto CameraAvStreamManagement utilizzando la funzione Kotlin setRecordingMicrophoneMuted integrata:
// Turn audio recording on or off for the device suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) { trait.update { setRecordingMicrophoneMuted(disableAudioRecording) } }
Regola il volume dello speaker
Per regolare il volume dell'altoparlante del dispositivo, aggiorna l'attributo speakerVolumeLevel del tratto CameraAvStreamManagement utilizzando la funzione Kotlin setSpeakerVolumeLevel integrata:
// Adjust the camera speaker volume suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) { trait.update { setSpeakerVolumeLevel(volume.toUbyte()) } }
Impostazioni della zona attiva
Implementato nell'app di esempio per Android
Il tratto ZoneManagement fornisce un'interfaccia per la gestione di zone di interesse personalizzate (zone attive) sui dispositivi con videocamera e campanello.
Queste zone vengono utilizzate per filtrare il rilevamento di 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 maggiori informazioni sul funzionamento delle zone attive, consulta Configura e usa le zone attive.
Le zone attive vengono in genere definite utilizzando coordinate cartesiane 2D.
Il tratto fornisce
TwoDCartesianVertexStruct per i vertici e
TwoDCartesianZoneStruct
per la definizione della zona (nome, vertici, colore e utilizzo).
Controlla le zone attive
Per visualizzare le zone attive, controlla l'attributo zones del tratto 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() }
Aggiungi una zona attiva
Per creare una nuova zona, utilizza il comando createTwoDCartesianZone. 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 "Front Porch" con quattro vertici, di colore salmone (#F439A0) e utilizzata per il rilevamento dei movimenti.
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}") } }
Aggiorna una zona attiva
Per aggiornare una zona esistente, utilizza il comando updateTwoDCartesianZone. Questo comando richiede zoneId e TwoDCartesianZoneStruct aggiornato.
private suspend fun ZoneManagement.updateZone( zoneId: UShort, zone: ZoneManagementTrait.TwoDCartesianZoneStruct ) { // Execute the command to update the zone this.updateTwoDCartesianZone(zoneId = zoneId, zone = zone) }
Elimina una zona attiva
Per rimuovere una zona, utilizza il comando removeZone con il valore zoneId specifico.
private suspend fun ZoneManagement.deleteZone(zoneId: UShort) { // Execute the command to remove the zone this.removeZone(zoneId = zoneId) }
Trigger di eventi sonori
Il tratto AvStreamAnalysis fornisce un'interfaccia per la gestione dei trigger di rilevamento degli eventi sui dispositivi con videocamera e campanello. Mentre gli attivatori basati sulla visione (come persone o veicoli) possono essere specifici per una zona, gli attivatori relativi ai suoni sono in genere configurazioni a livello di dispositivo.
I seguenti tipi di attivatori sono disponibili per il rilevamento dei suoni con
EventTriggerTypeEnum:
| Modalità | Valore enum | Descrizione |
|---|---|---|
| Suono | Sound |
Rilevamento dei suoni generici. |
| Persona che parla | PersonTalking |
Rileva il parlato. |
| Cane che abbaia | DogBark |
Rileva le vocalizzazioni dei cani. |
| Rottura di vetri | GlassBreak |
Rileva il rumore di vetri infranti. |
| Allarme fumo | SmokeAlarm |
Rileva gli allarmi fumo, spesso riconosciuti dal pattern acustico T3 (tre brevi segnali acustici seguiti da una pausa). |
| Allarme CO | CoAlarm |
Rileva gli allarmi di monossido di carbonio (CO), generalmente riconosciuti dal segnale acustico T4 (quattro brevi segnali acustici seguiti da una pausa). |
Controlla 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 è attivato dall'hardware del dispositivo. I due attributi da controllare sono:
Nello sviluppo Android con i flussi Kotlin, in genere si osserva la caratteristica
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) ) } }
Aggiorna l'insieme di trigger attivati
Per aggiornare l'insieme di trigger abilitati, utilizza il comando SetOrUpdateEventDetectionTriggers, che accetta un elenco di strutture 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) }
Modalità di registrazione
Implementato nell'app di esempio per Android
Il tratto RecordingMode fornisce un'interfaccia per gestire il comportamento di registrazione di video e immagini sui dispositivi con videocamera e campanello. Consente agli utenti di scegliere tra registrazione continua, registrazione basata sugli eventi o disattivazione completa della registrazione (solo Visione in diretta).
RecordingModeEnum
definisce le strategie di registrazione disponibili:
| Modalità | Valore enum | Descrizione |
|---|---|---|
| Disabilitata | Disabled |
La registrazione è completamente disattivata. Utilizzato principalmente dai dispositivi legacy. |
| CVR (registrazione video continua) | Cvr |
Il video viene registrato 24 ore su 24, 7 giorni su 7. Richiede un abbonamento (ad esempio, Google Home Premium. |
| EBR (registrazione basata sugli eventi) | Ebr |
La registrazione viene attivata da eventi (persona, movimento). La durata del video dipende dalla durata dell'evento e dall'abbonamento. |
| ETR (Registrazione attivata da eventi) | Etr |
Breve registrazione di anteprima (ad esempio, 10 secondi) attivata da eventi. |
| Live View | LiveView |
La registrazione è disattivata, ma gli utenti possono comunque accedere al live streaming. |
| Immagini fisse | Images |
Quando si verificano eventi, vengono registrate istantanee anziché video. |
Controlla le modalità di registrazione
Per visualizzare la configurazione di registrazione corrente, controlla gli attributi del tratto RecordingMode:
supportedRecordingModes- Tutte le modalità potenzialiavailableRecordingModes- Modalità selezionabiliselectedRecordingMode- La modalità attiva
// 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(), ) } }
Cambia la modalità di registrazione
Prima di eseguire l'aggiornamento, 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
Tramite le API Home è possibile controllare varie altre impostazioni.
Modifica l'orientamento dell'immagine
L'orientamento dell'immagine della videocamera (video) può essere ruotato. Il video può essere ruotato solo di 180 gradi.
Per modificare l'orientamento dell'immagine della videocamera, aggiorna l'attributo imageRotation del tratto CameraAvStreamManagement utilizzando la funzione Kotlin setImageRotation integrata:
// Change the camera's image orientation val isRotated = false cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }
Attiva o disattiva la visione notturna
Per attivare o disattivare la visione notturna della videocamera, utilizza TriStateAutoEnum
per aggiornare l'attributo
nightVision
del tratto CameraAvStreamManagement utilizzando la funzione Kotlin
setNightVision integrata:
// Turn night vision on cameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On) } // Turn night vision off CameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off) }
Modifica 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
setStatusLightBrightness integrata:
// Set the LED brightness to high cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High) } // Set the LED brightness to low cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low) }
Modifica l'area visibile della videocamera
L'area visibile della videocamera è la stessa della funzionalità Zoom e ritaglio descritta nell'articolo di assistenza Aumenta lo zoom e migliora la qualità del video della videocamera Nest.
L'area visibile è definita in un ViewportStruct che contiene quattro valori, che vengono utilizzati come coordinate dell'area visibile. Le coordinate sono definite come segue:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
La determinazione dei valori per ViewportStruct dipende dall'interfaccia utente e dall'implementazione della fotocamera di un'app. A un livello molto di base, per impostare l'area visibile del video della videocamera, aggiorna l'attributo viewport della caratteristica CameraAvStreamManagement con un ViewportStruct, utilizzando la funzione Kotlin setViewport integrata:
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(), ) ) }
Attiva o disattiva l'analisi
Ogni dispositivo può attivare singolarmente l'invio di dati di analisi dettagliati al cloud di Google Home (consulta Cloud Monitoring per le API Home).
Per attivare l'analisi per un dispositivo, imposta la proprietà analyticsEnabled 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 sul cloud di Google Home.
// Enable analytics extendedGeneralDiagnostics.update { setAnalyticsEnabled(true) } // Disable analytics extendedGeneralDiagnostics.update { setAnalyticsEnabled(false) }
Configurazioni di trasporto e registrazione
Questa sezione riguarda le impostazioni relative alla qualità dello streaming della videocamera e
all'attivazione degli eventi. Queste impostazioni sono gestite dal tratto
PushAvStreamTransport.
Leggi le impostazioni di trasporto
Questa sezione mostra come recuperare la configurazione corrente da
un dispositivo videocamera o campanello. Recupera il tratto PushAvStreamTransport,
trova la connessione specifica utilizzata per la registrazione, quindi estrae
i valori attuali per la qualità della larghezza di banda, la sensibilità riattivazione
e la durata massima dell'evento.
val trait: PushAvStreamTransport = device.getTrait(PushAvStreamTransport) val connections = trait.findTransport().transportConfigurations // Locate the connection designated for recording val recordingConnection = connections.firstOrNull { it.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording } val options = recordingConnection?.transportOptions?.getOrNull() // 1. Bandwidth Quality (Video Stream ID) val videoStreamId = options?.videoStreamId?.getOrNull() // 2. Wake-up Sensitivity (Motion Sensitivity) val wakeUpSensitivity = options?.triggerOptions?.motionSensitivity?.getOrNull() // 3. Max Event Length (Motion Trigger Time Control) val maxEventLength = options?.triggerOptions?.motionTimeControl?.getOrNull()?.maxDuration
Aggiorna le impostazioni di trasporto
Questa sezione mostra come modificare le impostazioni di trasporto.
Crea un nuovo TransportOptionsStruct contenente i nuovi valori e poi utilizza il comando modifyPushTransport per inviare queste impostazioni aggiornate al dispositivo, applicandole alla connessione di registrazione trovata nel passaggio precedente.
Per modificare queste impostazioni, utilizza il comando modifyPushTransport con un TransportOptionsStruct.
val toUpdate = TransportOptionsStruct( videoStreamId = OptionalValue.present(2u), // e.g., Max Quality triggerOptions = TransportTriggerOptionsStruct( motionSensitivity = OptionalValue.present(5u), // e.g., Medium motionTimeControl = OptionalValue.present( TransportMotionTriggerTimeControlStruct(maxDuration = 30u) ) ) ) if (recordingConnection != null) { trait.modifyPushTransport( connectionId = recordingConnection.connectionId, transportOptions = toUpdate ) }
Determina la qualità della larghezza di banda
La proprietà videoStreamId di TransportOptionsStruct corrisponde a una configurazione specifica dello stream video.
Per ottenere gli stream video supportati, consulta l'attributo allocatedVideoStreams, che è un elenco di VideoStreamStructs.
dal tratto CameraAvStreamManagement del dispositivo.
Regola la sensibilità riattivazione del dispositivo
La proprietà motionSensitivity di TransportTriggerOptionsStruct corrisponde ai seguenti valori:
| Etichetta | Valore (UByte) |
|---|---|
| Bassa | 1u |
| Media | 5u |
| Alto | 10u |
Regola la durata massima degli eventi
La proprietà maxDuration di TransportMotionTriggerTimeControlStruct corrisponde alle seguenti durate (in secondi):
- 10u, 15u, 30u, 60u, 120u, 180u
Dismetti un dispositivo
Per rimuovere una videocamera da una struttura, chiama
device.decommissionDevice(). La dismissione mostra all'utente una schermata di conferma gestita da Google che avvisa che tutti i dati registrati della cronologia video 24/7, della cronologia eventi, dei clip e della raccolta di volti riconosciuti verranno eliminati definitivamente in tutta la struttura.
Per istruzioni dettagliate ed esempi di codice, consulta Rimuovi un dispositivo.