Тип устройства «Дверной звонок» реализован с использованием двух трейтов: PushAvStreamTransportTrait , который обрабатывает передачу аудио- и видеопотоков с использованием протоколов на основе push-уведомлений, и WebRtcLiveViewTrait , который предоставляет возможность управления потоковой передачей и обратной связью.
Перед использованием каких-либо функций или попыткой обновления атрибутов всегда проверяйте поддержку атрибутов и команд для устройства. См. раздел «Управление устройствами» .iOS для получения дополнительной информации.
| Главная API Тип устройства | Черты | Пример приложения на Swift | Вариант использования |
|---|---|---|---|
Дверной звонок Устройство, активируемое кнопкой снаружи двери, которое подает звуковой и/или визуальный сигнал и используется для привлечения внимания человека, находящегося по другую сторону двери. Дверные звонки могут иметь доступные функции прямой трансляции, двусторонней связи или обнаружения событий. | Необходимые характеристики Google PushAvStreamTransportTrait google WebRtcLiveViewTrait | Дверной звонок |
Начать прямую трансляцию
Для запуска прямой трансляции отправьте строку протокола описания сессии (SDP) методу startLiveView(offerSdp:) трейта WebRtcLiveViewTrait , который возвращает три значения:
- План развития науки и техники для данной сессии.
- Продолжительность сессии в секундах.
- Идентификатор сессии, который может использоваться для продления или завершения сессии.
public func sendOffer(offerSdp: String) async throws
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval)
{
do {
Logger.info("Sending StartLiveView command...")
let response = try await liveViewTrait.startLiveView(
offerSdp: offerSdp
)
Logger.info("Received StartLiveView response: \(response)")
return (
answerSdp: response.answerSdp,
mediaSessionId: response.mediaSessionId,
liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
)
} catch {
Logger.error("Failed to send StartLiveView command: \(error)")
throw error
}
}
Продлить прямую трансляцию
Прямые трансляции имеют заданную продолжительность, по истечении которой они завершаются. Чтобы продлить продолжительность активной трансляции, отправьте запрос на продление, используя метод extendLiveView(mediaSessionId:optionalArgsProvider:) :
public func extendLiveView(mediaSessionId: String) async throws {
do {
Logger.info("Extending live view...")
let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
Logger.info("Extended live view for \(extendedDuration.liveSessionDurationSeconds) seconds.")
} catch {
Logger.error("Failed to extend live view: \(error)")
throw error
}
}
Запуск и остановка обратной связи
Чтобы запустить обратную связь, вызовите метод startTalkback(mediaSessionId:optionalArgsProvider:) трейта WebRtcLiveViewTrait . Чтобы остановить, используйте stopTalkback(mediaSessionId:) .
public func toggleTwoWayTalk(isOn: Bool, mediaSessionId: String) async throws {
do {
Logger.info("Toggling twoWayTalk to \(isOn ? "ON" : "OFF")...")
if isOn {
try await liveViewTrait.startTalkback(mediaSessionId: mediaSessionId)
} else {
try await liveViewTrait.stopTalkback(mediaSessionId: mediaSessionId)
}
} catch {
throw HomeError.commandFailed("Failed to toggle twoWayTalk: \(error)")
}
}
Включение и отключение функции записи
Чтобы включить запись с камеры, передайте TransportStatusEnum.Active методу setTransportStatus(transportStatus:optionalArgsProvider:) трейта PushAvStreamTransportTrait . Чтобы отключить запись, передайте TransportStatusEnum.Inactive . В следующем примере мы объединяем эти вызовы в один вызов, использующий Boolean для переключения режима записи:
public func toggleIsRecording(isOn: Bool) {
self.uiState = .loading
guard let pushAvStreamTransportTrait else {
Logger.error("PushAvStreamTransportTrait not found.")
return
}
Task {
do {
try await pushAvStreamTransportTrait.setTransportStatus(
transportStatus: isOn ? .active : .inactive)
if isOn {
do {
self.player = try self.createWebRtcPlayer()
} catch {
Logger.error("Failed to initialize WebRtcPlayer: \(error)")
self.uiState = .disconnected
return
}
await self.player?.initialize()
self.uiState = .live
} else {
self.player = nil
self.uiState = .off
}
} catch {
Logger.error("Failed to toggle onOff: \(error)")
}
}
}
Включение или выключение функции записи камеры аналогично включению или выключению видеозаписи. Когда видеозапись камеры включена, она ведется (для целей фиксации событий и создания связанных видеороликов).
Когда функция записи отключена (видео с камеры выключено):
- Камера по-прежнему может отображаться как подключенная к сети в соответствии с параметром
connectivityStateтипа устройства . - Прямая трансляция недоступна, камера также не обнаруживает никаких событий, связанных с облачными сервисами.
Проверьте, включена ли функция записи.
Чтобы определить, включена ли функция записи на камере, проверьте наличие активных подключений. В следующем примере определены две функции для выполнения этой задачи:
public func isDeviceRecording() -> Bool {
guard let pushAvStreamTransportTrait else {
Logger.error("PushAvStreamTransportTrait not found.")
return false
}
guard
let hasActiveConnection =
pushAvStreamTransportTrait
.attributes
.currentConnections?
.contains(where: { $0.transportStatus == .active })
else {
return false
}
return hasActiveConnection
}
Настройки звука
Различные настройки звука камеры можно контролировать с помощью API Home.
Включение или выключение микрофона
Чтобы включить или выключить микрофон устройства, обновите атрибут microphoneMuted трейта CameraAvStreamManagementTrait , используя встроенную функцию setMicrophoneMuted :
// Turn the device's microphone on or off
func setMicrophone(on: Bool) async {
do {
_ = try await self.cameraAvStreamManagementTrait?.update {
$0.setMicrophoneMuted(!on)
}
} catch {
// Error
}
}
Включение или выключение записи звука
Чтобы включить или выключить запись звука на устройстве, обновите атрибут recordingMicrophoneMuted трейта CameraAvStreamManagementTrait , используя встроенную функцию setRecordingMicrophoneMuted :
// Turn audio recording on or off for the device
func setAudioRecording(on: Bool) async {
do {
_ = try await self.cameraAvStreamManagementTrait?.update {
$0.setRecordingMicrophoneMuted(!on)
}
} catch {
// Error
}
}
Отрегулируйте громкость динамиков
Для регулировки громкости динамика устройства обновите атрибут speakerVolumeLevel трейта CameraAvStreamManagementTrait , используя встроенную функцию setSpeakerVolumeLevel :
// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setSpeakerVolumeLevel(value)
}
} catch {
// Error
}
}
Другие настройки
Различные другие настройки камеры можно контролировать через API Home.
Включение или выключение ночного видения
Чтобы включить или выключить ночное видение для камеры, используйте TriStateAutoEnum для обновления атрибута nightVision трейта CameraAvStreamManagementTrait с помощью встроенной функции setNightVision :
// Turn night vision on or off
func setNightVision(
to value: Google.CameraAvStreamManagementTrait.TriStateAutoEnum
) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setNightVision(value)
}
} catch {
// Error
}
}
Изменить яркость индикатора состояния
Чтобы изменить яркость светодиода состояния, используйте ThreeLevelAutoEnum для обновления атрибута statusLightBrightness трейта CameraAvStreamManagementTrait с помощью встроенной функции setStatusLightBrightness :
// Set the LED brightness
func setStatusLightBrightness(
to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setStatusLightBrightness(value)
}
} catch {
// Error
}
}
Изменить область просмотра камеры
Окно просмотра камеры идентично функции масштабирования и кадрирования, описанной в статье «Масштабирование и улучшение качества видео с камер Nest» .
Область просмотра определяется в структуре ViewportStruct , которая содержит четыре значения, используемые в качестве координат области просмотра. Координаты определяются следующим образом:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
Определение значений для ViewportStruct зависит от пользовательского интерфейса приложения и реализации камеры. На самом базовом уровне, чтобы установить область просмотра видео с камеры, обновите атрибут viewport трейта CameraAvStreamManagementTrait , указав ViewportStruct , используя встроенную функцию setViewport .
func setCrop(x1: UInt16, y1: UInt16, x2: UInt16, y2: UInt16) {
let viewport = Google.CameraAvStreamManagementTrait.ViewportStruct(
x1: x1,
y1: y1,
x2: x2,
y2: y2
)
Task {
do {
try await cameraAvStreamManagementTrait.update {
$0.setViewport(viewport)
}
} catch {
// Error
}
}
}
Сгенерировать структуру TransportOptionsStruct
Для некоторых настроек требуется внести изменения в свойства структуры TransportOptionsStruct , которая затем передается в параметры транспорта потокового соединения. В Swift эту структуру необходимо сгенерировать до обновления каких-либо свойств.
Используйте эту вспомогательную функцию для генерации структуры, которая будет использоваться со следующими изменениями настроек:
- Отрегулируйте чувствительность пробуждения устройства.
- Отрегулируйте максимальную продолжительность события.
func getTransportOptions(
transportOptions: Google.PushAvStreamTransportTrait.TransportOptionsStruct,
wakeUpSensitivity: UInt8?,
maxEventLength: UInt32?
) async throws
-> Google.PushAvStreamTransportTrait.TransportOptionsStruct
{
var newMotionTimeControl:
Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct? = nil
if let maxEventLength {
guard let motionTimeControl = transportOptions.triggerOptions.motionTimeControl else {
throw HomeError.failedPrecondition(
// Error - cannot update max event length without motion time control
}
newMotionTimeControl =
Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct(
initialDuration: motionTimeControl.initialDuration,
augmentationDuration: motionTimeControl.augmentationDuration,
maxDuration: maxEventLength,
blindDuration: motionTimeControl.blindDuration
)
}
return Google.PushAvStreamTransportTrait.TransportOptionsStruct(
streamUsage: .recording,
videoStreamID: nil,
audioStreamID: nil,
tlsEndpointID: transportOptions.tlsEndpointID,
url: transportOptions.url,
triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct(
triggerType: .motion,
motionZones: nil,
motionSensitivity: wakeUpSensitivity,
motionTimeControl: newMotionTimeControl,
maxPreRollLen: nil
),
ingestMethod: .cmafIngest,
containerOptions: Google.PushAvStreamTransportTrait.ContainerOptionsStruct(
containerType: .cmaf,
cmafContainerOptions: nil
),
expiryTime: nil
)
}
private func getRecordingConnection() async throws
-> Google.PushAvStreamTransportTrait.TransportConfigurationStruct?
{
guard let pushAvStreamTransportTrait else {
// Error - PushAvStreamTransport trait not available
return nil
}
let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations
for connection in connections {
guard let transportOptions = connection.transportOptions,
transportOptions.streamUsage == .recording
else {
continue
}
return connection
}
return nil
}
Отрегулируйте чувствительность пробуждения устройства.
Чувствительность устройства к пробуждению используется для экономии заряда батареи за счет уменьшения диапазона, в котором устройство может обнаруживать активность, и увеличения времени пробуждения после обнаружения этой активности.
В API Home это можно установить с помощью свойства motionSensitivity объекта triggerOptions в transportOptions устройства. Эти параметры определены в трейте PushAvStreamTransportTrait для каждого устройства.
Чувствительность к пробуждению можно установить только на следующие значения:
- 1 = Низкий
- 5 = Средний
- 10 = Высокий
Процесс обновления заключается в поиске конфигурации транспорта для активных потоков записи с помощью команды findTransport , а затем в изменении конфигурации с новым значением чувствительности с помощью команды modifyPushTransport .
Для выполнения команды modifyPushTransport необходимо передать полный объект TransportOptionsStruct , поэтому сначала необходимо скопировать существующие значения из текущей конфигурации. См. раздел «Создание объекта TransportOptionsStruct для получения информации о вспомогательной функции, позволяющей это сделать.
func setWakeUpSensitivity(to value: UInt8) async {
do {
let connection = try await getRecordingConnection()
guard let connection,
let transportOptions = connection.transportOptions
else {
// Error - Transport options not available
return
}
guard transportOptions.triggerOptions.motionSensitivity != nil else {
// Error - Motion sensitivity not available to be updated for this device
return
}
try await pushAvStreamTransportTrait.modifyPushTransport(
connectionID: connection.connectionID,
transportOptions: self.getTransportOptions(
transportOptions: transportOptions,
wakeUpSensitivity: value,
maxEventLength: nil
)
)
} catch {
// Error
}
}
Отрегулируйте максимальную продолжительность события.
Максимальная продолжительность события — это время, в течение которого камера будет записывать видеоролик для данного события. С помощью API Home это можно настроить для каждого устройства отдельно, установив ту же продолжительность, что и в Google Home app (GHA) , с интервалом в секундах:
- 10 секунд
- 15 секунд
- 30 секунд
- 60 секунд (1 минута)
- 120 секунд (2 минуты)
- 180 секунд (3 минуты)
В API Home это можно установить с помощью свойства motionTimeControl объекта triggerOptions в transportOptions устройства. Эти параметры определены в трейте PushAvStreamTransportTrait для каждого устройства.
Процесс обновления заключается в поиске конфигурации транспорта для активных потоков записи с помощью команды findTransport , а затем в изменении конфигурации с новым значением длины события с помощью команды modifyPushTransport .
Для выполнения команды modifyPushTransport необходимо передать полный объект TransportOptionsStruct , поэтому сначала необходимо скопировать существующие значения из текущей конфигурации. См. раздел «Создание объекта TransportOptionsStruct для получения информации о вспомогательной функции, позволяющей это сделать.
func setMaxEventLength(to value: UInt32) async {
do {
let connection = try await getRecordingConnection()
guard let connection,
let transportOptions = connection.transportOptions
else {
// Error - Transport options not available
return
}
guard transportOptions.triggerOptions.motionTimeControl != nil else {
// Error - Motion time control not available to be updated for this device
return
}
try await pushAvStreamTransportTrait.modifyPushTransport(
connectionID: connection.connectionID,
transportOptions: self.getTransportOptions(
transportOptions: transportOptions,
wakeUpSensitivity: nil,
maxEventLength: value
)
)
} catch {
// Error
}
}
Настройки звукового сигнала
Различные настройки дверного звонка можно контролировать через API Home.
Изменить звук колокольчика
Чтобы изменить звук дверного звонка, сначала получите список установленных на устройстве звуков звонка, используя атрибут installedChimeSounds трейта ChimeTrait :
doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
return chimeSound.chimeID, chimeSound.name
}
Затем обновите атрибут selectedChime трейта ChimeTrait , используя встроенную функцию setSelectedChime :
func setDoorbellChime(chimeID: UInt8) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setSelectedChime(chimeID)
}
} catch {
// Error
}
}
Используйте внешний звонок
Дверной звонок можно настроить на использование внешнего звонка, например, механического звонка, установленного внутри дома. Это следует сделать во время установки дверного звонка, чтобы избежать возможного повреждения внешнего звонка.
Чтобы указать тип установленного внешнего звукового сигнала, используйте ExternalChimeType для обновления атрибута externalChime свойства ChimeTrait с помощью встроенной функции setExternalChime :
// Indicate the external chime is mechanical
func setExternalChime(to value: Google.ChimeTrait.ExternalChimeType) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setExternalChime(value)
}
} catch {
// Error
}
}
Изменить продолжительность внешнего звукового сигнала
Продолжительность звонка внешнего звонка в секундах можно настроить через API Home. Если внешний звонок поддерживает настройку продолжительности звонка, пользователь может захотеть это сделать.
Значение, установленное здесь, зависит от технических характеристик самого внешнего звонка и рекомендуемой продолжительности его звучания.
Чтобы изменить продолжительность внешнего звукового сигнала, обновите атрибут externalChimeDurationSeconds трейта ChimeTrait , используя встроенную функцию setExternalChimeDurationSeconds :
// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setExternalChimeDuration(value)
}
} catch {
// Error
}
}