Тип устройства «Дверной звонок» реализован с использованием двух трейтов: PushAvStreamTransport , который обрабатывает передачу аудио- и видеопотоков с использованием протоколов на основе push-уведомлений, и WebRtcLiveView , который предоставляет возможность управления прямыми трансляциями и обратной связью.
Перед использованием каких-либо функций или попыткой обновления атрибутов всегда проверяйте поддержку атрибутов и команд для устройства. См. раздел «Управление устройствами» .Android для получения дополнительной информации.
| Главная API Тип устройства | Черты | Пример приложения на Kotlin | Вариант использования |
|---|---|---|---|
Дверной звонок Устройство, активируемое кнопкой снаружи двери, которое подает звуковой и/или визуальный сигнал и используется для привлечения внимания человека, находящегося по другую сторону двери. Дверные звонки могут иметь доступные функции прямой трансляции, двусторонней связи или обнаружения событий. | Необходимые характеристики google PushAvStreamTransport google WebRtcLiveView | Дверной звонок |
Получите основную информацию об устройстве.
Параметр BasicInformation включает в себя такую информацию, как название производителя, идентификатор производителя, идентификатор продукта, название продукта (включая информацию о модели), версия программного обеспечения и серийный номер устройства:
// 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}") }
Проверьте подключение устройства.
Проверка подключения устройства фактически осуществляется на уровне типа устройства, поскольку некоторые устройства поддерживают несколько типов. Возвращаемое состояние представляет собой комбинацию состояний подключения для всех характеристик данного устройства.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Состояние PARTIALLY_ONLINE может наблюдаться в случае использования устройств разных типов при отсутствии подключения к интернету. Стандартные характеристики Matter могут оставаться в сети благодаря локальной маршрутизации, но облачные характеристики будут отключены.
Начать прямую трансляцию
Для запуска прямой трансляции отправьте строку протокола описания сессии (SDP) в метод startLiveView() трейта WebRtcLiveView , который вернет объект WebRtcLiveViewTrait.StartLiveViewCommand.Response , содержащий три значения:
- План развития науки и техники для данной сессии.
- Продолжительность сессии в секундах.
- Идентификатор сессии, который может использоваться для продления или завершения сессии.
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) { return cameraDevice.type(GoogleDoorbellDevice).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)
Продлить прямую трансляцию
Прямые трансляции имеют заданную продолжительность, по истечении которой они завершаются. Чтобы продлить продолжительность активной трансляции, отправьте запрос на продление, используя метод 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 }
Запуск и остановка обратной связи
Чтобы запустить обратную связь, вызовите метод startTalkback() трейта WebRtcLiveView . Чтобы остановить её, используйте 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) } }
Включение и отключение функции записи
Чтобы включить запись с камеры, передайте TransportStatusEnum.Active методу setTransportStatus() трейта PushAvStreamTransport . Чтобы отключить запись, передайте TransportStatusEnum.Inactive . В следующем примере мы объединяем эти вызовы в один вызов, использующий Boolean для переключения режима записи:
// 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) } }
Включение или выключение функции записи камеры аналогично включению или выключению видеозаписи. Когда видеозапись камеры включена, она ведется (для целей фиксации событий и создания связанных видеороликов).
Когда функция записи отключена (видео с камеры выключено):
- Камера по-прежнему может отображаться как подключенная к сети в соответствии с параметром
connectivityStateтипа устройства . - Прямая трансляция недоступна, камера также не обнаруживает никаких событий, связанных с облачными сервисами.
Проверьте, включена ли функция записи.
Чтобы определить, включена ли функция записи на камере, проверьте наличие активных подключений. В следующем примере определены две функции для выполнения этой задачи:
// 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 }
Ещё один способ проверки — использование функции findTransport() с предикатом:
// Fetch the current connections suspend fun queryRecordModeState(trait: PushAvStreamTransport) { return trait.findTransport().let { it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active } }
Настройки батареи
Различные параметры батареи можно контролировать через API Home.
Настройте параметры использования батареи.
Настройка баланса энергии позволяет определить оптимальное соотношение между временем автономной работы и производительностью устройства. Вы можете создавать различные профили работы батареи, такие как «Расширенный», «Сбалансированный» и «Производительный», и переключаться между ними.
Эта функция реализуется путем обновления атрибута currentEnergyBalance трейта EnergyPreference . Атрибут принимает целочисленный индекс, соответствующий определенному профилю, заданному в списке energyBalances устройства (например, 0 для EXTENDED , 1 для BALANCED и 2 для PERFORMANCE ).
Значение currentEnergyBalance null , что указывает на использование устройством пользовательского профиля. Это состояние доступно только для чтения.
Ниже приведён пример структуры, которую будет использовать атрибут currentEnergyBalance , а затем фрагмент кода, в котором используется этот атрибут.
// 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)
Включите автоматический режим экономии заряда батареи.
Для настройки этой функции обновите атрибут currentLowPowerModeSensitivity в свойстве EnergyPreference . Этот атрибут использует индекс для выбора уровня чувствительности, где 0 обычно означает Disabled , а 1 — Enabled или 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) } }
Определите состояние зарядки аккумулятора.
Чтобы получить текущее состояние зарядки устройства (заряжается, полностью заряжено или не заряжается), используйте атрибут batChargeState трейта 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" }
Проверьте уровень заряда батареи.
Чтобы узнать текущий уровень заряда батареи, используйте атрибут batChargeLevel трейта PowerSource . Уровень может быть либо OK , Warning (низкий), либо 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" }
Найдите источник питания
Чтобы определить источник питания устройства, используйте атрибуты BatPresent и wiredPresent трейта PowerSource .
val trait: PowerSource val isWired = trait.wiredPresent val hasBattery = trait.batPresent
Настройки звука
Различные настройки звука можно контролировать с помощью API Home.
Включение или выключение микрофона
Чтобы включить или выключить микрофон устройства, обновите атрибут microphoneMuted трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setMicrophoneMuted :
// Turn the device's microphone on or off suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) { trait.update { setMicrophoneMuted(disableMicrophone) } }
Включение или выключение записи звука
Чтобы включить или выключить запись звука на устройстве, обновите атрибут recordingMicrophoneMuted трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setRecordingMicrophoneMuted :
// Turn audio recording on or off for the device suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) { trait.update { setRecordingMicrophoneMuted(disableAudioRecording) } }
Отрегулируйте громкость динамиков
Для регулировки громкости динамика устройства обновите атрибут speakerVolumeLevel трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setSpeakerVolumeLevel :
// Adjust the camera speaker volume suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) { trait.update { setSpeakerVolumeLevel(volume.toUbyte()) } }
Другие настройки
Различные другие параметры можно контролировать с помощью API Home.
Включение или выключение ночного видения
Чтобы включить или выключить ночное видение для камеры, используйте TriStateAutoEnum для обновления атрибута nightVision трейта CameraAvStreamManagement с помощью встроенной функции Kotlin setNightVision :
// Turn night vision on cameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On) } // Turn night vision off CameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off) }
Изменить яркость индикатора состояния
Чтобы изменить яркость светодиода состояния, используйте ThreeLevelAutoEnum для обновления атрибута statusLightBrightness трейта CameraAvStreamManagement с помощью встроенной функции Kotlin 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) }
Изменить область просмотра камеры
Окно просмотра камеры идентично функции масштабирования и кадрирования, описанной в статье «Масштабирование и улучшение качества видео с камер Nest» .
Область просмотра определяется в структуре ViewportStruct , которая содержит четыре значения, используемые в качестве координат области просмотра. Координаты определяются следующим образом:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
Определение значений для ViewportStruct зависит от пользовательского интерфейса приложения и реализации камеры. На самом базовом уровне, чтобы установить область просмотра видео с камеры, обновите атрибут viewport трейта CameraAvStreamManagement , указав ViewportStruct , используя встроенную функцию Kotlin 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(), ) ) }
Отрегулируйте чувствительность пробуждения устройства.
Чувствительность устройства к пробуждению используется для экономии заряда батареи за счет уменьшения диапазона, в котором устройство может обнаруживать активность, и увеличения времени пробуждения после обнаружения этой активности.
В API Home это можно установить с помощью свойства motionSensitivity объекта triggerOptions в transportOptions устройства. Эти параметры определены в трейте PushAvStreamTransport для каждого устройства.
Чувствительность к пробуждению можно установить только на следующие значения:
- 1 = Низкий
- 5 = Средний
- 10 = Высокий
Процесс обновления заключается в следующем: с помощью команды findTransport необходимо найти конфигурацию транспорта для активных потоков записи, а затем изменить конфигурацию, указав новое значение чувствительности, с помощью команды 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, ) } }
Отрегулируйте максимальную продолжительность события.
Максимальная продолжительность события — это время, в течение которого камера будет записывать видеоролик для данного события. Через API Home это можно настроить для каждого устройства отдельно, установив ту же продолжительность, что и через GHA , с интервалом в секундах:
- 10 секунд
- 15 секунд
- 30 секунд
- 60 секунд (1 минута)
- 120 секунд (2 минуты)
- 180 секунд (3 минуты)
В API Home это можно установить с помощью свойства motionTimeControl объекта triggerOptions в transportOptions устройства. Эти параметры определены в трейте PushAvStreamTransport для каждого устройства.
Процесс обновления заключается в следующем: с помощью команды findTransport необходимо найти конфигурацию транспорта для активных потоков записи, а затем изменить конфигурацию, указав новое значение длины события, используя команду 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, ) } }
Настройки звукового сигнала
Различные настройки дверного звонка можно контролировать через API Home.
Изменить звук колокольчика
Чтобы изменить звук дверного звонка, сначала получите список установленных на устройстве звуков звонка, используя атрибут installedChimeSounds трейта Chime :
// Get a list of chimes and identify the currently selected one private val doorbellChimeTraitFlow: Flow= device.traitFromType(Chime, GoogleDoorbellDevice) val chimeSounds = doorbellChimeTraitFlow.first().installedChimeSounds ?: emptyList()
Затем обновите атрибут selectedChime трейта Chime , используя встроенную функцию Kotlin setSelectedChime :
// Set the chime using the chimeId from the installed list chimeSounds.firstOrNull { it.name == name }?.let { setSelectedChime(it.chimeId) }
Используйте внешний звонок
Дверной звонок можно настроить на использование внешнего звонка, например, механического звонка, установленного внутри дома. Это следует сделать во время установки дверного звонка, чтобы избежать возможного повреждения внешнего звонка.
Чтобы указать тип установленного внешнего Chime, используйте ExternalChimeType для обновления атрибута externalChime трейта Chime с помощью встроенной функции Kotlin setExternalChime :
// Indicate the external chime is mechanical chime.update { setExternalChime(ChimeTrait.ExternalChimeType.Mechanical) }
Изменить продолжительность внешнего звукового сигнала
Продолжительность звонка внешнего звонка в секундах можно настроить через API Home. Если внешний звонок поддерживает настройку продолжительности звонка, пользователь может захотеть это сделать.
Значение, установленное здесь, зависит от технических характеристик самого внешнего звонка и рекомендуемой продолжительности его звучания.
Чтобы изменить продолжительность внешнего звукового сигнала, обновите атрибут externalChimeDurationSeconds трейта Chime , используя встроенную функцию Kotlin setExternalChimeDurationSeconds :
// Change the external chime duration chime.update { setExternalChimeDurationSeconds(newDuration.toUShort()) }
Включить тему звукового сигнала
Некоторые дверные звонки могут иметь мелодии, доступные пользователям только в течение ограниченного времени. Например, мелодии, приуроченные к праздникам. Такие мелодии называются тематическими.
Чтобы узнать, какие темы оформления Chime доступны пользователю, создайте фильтр временного интервала и используйте его для фильтрации результатов команды getAvailableThemes() из трейта ChimeThemes . Это вернет список доступных тем, включая их названия.
Следующий пример показывает, как отфильтровать список. Тема считается активной, если текущее время находится в пределах ее начального и конечного времени (значения startTimeSeconds и endTimeSeconds соответственно). Если начальное время не задано, тема считается активной с начала времени. Если конечное время не задано, тема остается активной неограниченно долго. Если оба параметра отсутствуют, тема всегда активна.
// Get themes from the ChimeThemes trait fun List<ChimeThemesTrait.ThemeStruct>.filterTimeboxedThemes(): List<ChimeThemesTrait.ThemeStruct> { val now = timeSource.instant().epochSecond.toULong() return filter { chimeStruct: ChimeThemesTrait.ThemeStruct -> val startTime: ULong = chimeStruct.startTimeSeconds.getOrNull() ?: 0UL val endTime: ULong = chimeStruct.endTimeSeconds.getOrNull() ?: MAX_VALUE startTime <= now && now <= endTime } } val availableThemes = doorbellChimeThemesTraitFlow .first() .getAvailableThemes() .themes .filterTimeboxedThemes()
Получив название нужной темы, например, Christmas , вы можете выбрать её с помощью функции setSelectedTimeboxedThemeName() в трейте ChimeThemes :
// Select a theme using the ChimeThemes trait val themeToSelect = "Christmas" if (themeToSelect in availableThemeNames) { doorbellChimeThemesTraitFlow.first().setSelectedTimeboxedThemeName(themeToSelect) }