Тип устройства «Дверной звонок» реализован с использованием двух трейтов: PushAvStreamTransportTrait , который обрабатывает передачу аудио- и видеопотоков с использованием протоколов на основе push-уведомлений, и WebRtcLiveViewTrait , который предоставляет возможность управления потоковой передачей и обратной связью.
Перед использованием каких-либо функций или попыткой обновления атрибутов всегда проверяйте поддержку атрибутов и команд для устройства. См. раздел «Управление устройствами» .iOS для получения дополнительной информации.
| Главная API Тип устройства | Черты | Пример приложения на Swift | Вариант использования |
|---|---|---|---|
Дверной звонок Устройство, активируемое кнопкой снаружи двери, которое подает звуковой и/или визуальный сигнал и используется для привлечения внимания человека, находящегося по другую сторону двери. Дверные звонки могут иметь доступные функции прямой трансляции, двусторонней связи или обнаружения событий. | Необходимые характеристики Google PushAvStreamTransportTrait google WebRtcLiveViewTrait | Дверной звонок |
Получите основную информацию об устройстве.
Параметр BasicInformation включает в себя такую информацию, как название производителя, идентификатор производителя, идентификатор продукта, название продукта (включая информацию о модели) и версия программного обеспечения устройства:
// [START get_device_information] let vendorName = basicInfoTrait.attributes.vendorName! let vendorID = basicInfoTrait.attributes.vendorID! let productID = basicInfoTrait.attributes.productID! let productName = basicInfoTrait.attributes.productName! let softwareVersion = basicInfoTrait.attributes.softwareVersion! // [END get_device_information]
Получить серийный номер
Для получения серийного номера устройства используйте команду GetSerialNumber трейта ExtendedBasicInformation . В примере показано сохранение серийного номера в переменной с именем serialNumber :
// Assuming extendedBasicInformationTrait: Google.ExtendedBasicInformationTrait let response = try await extendedBasicInformationTrait.getSerialNumber() let serialNumber = response.serialNumber
Быстрые ответы
Функция «Быстрые ответы» позволяет пользователю отправлять заранее заданное сообщение на дверной звонок.
Эта функция доступна только на дверных звонках. Список предустановленных сообщений доступен партнерскому приложению, которое может отображать их пользователю на выбор. Предустановленные сообщения не подлежат редактированию пользователем.
Функция быстрых ответов реализована с помощью трейта PresetMessage .
Воспроизвести предустановленное сообщение
Для воспроизведения предустановленного сообщения вызовите метод playPresetMessage , передав ему одно из строковых значений, найденных в свойстве availablePhraseTypes .
import GoogleHomeSDK
import GoogleHomeTypes
func playDoorbellPresetMessage(device: HomeDevice, phraseTypeString: String) async {
// 1. Retrieve the GoogleDoorbellDeviceType helper on the device
guard let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) else {
print("This device is not a Google Doorbell or is currently uninitialized.")
return
}
// 2. Extract the Google.PresetMessageTrait
guard let presetMessageTrait = doorbellDeviceType.traits[Google.PresetMessageTrait.self] else {
print("PresetMessageTrait is not supported on this device.")
return
}
// 3. (Optional) Check available phrase types supported by the device
if let availablePhrases = presetMessageTrait.attributes.availablePhraseTypes {
let phraseTypeNames = availablePhrases.map { $0.phraseType }
print("Supported quick response phrases: \(phraseTypeNames)")
}
// 4. Send the playPresetMessage command asynchronously
do {
try await presetMessageTrait.playPresetMessage(phraseType: phraseTypeString)
print("Preset message successfully requested.")
} catch {
print("SDK error occurred playing preset message: \(error)")
}
}
Установить разговорный язык
Установить разговорный язык
Установите активный язык речи на устройстве на определенный языковой стандарт (например, "en_US") с помощью метода setActiveLocale трейта LocalizationConfiguration .
// Setting the active language // Assuming localizationConfigurationTrait: Matter.LocalizationConfigurationTrait let selectedLocale = "en_US" try await localizationConfigurationTrait.update { $0.setActiveLocale(selectedLocale) }
Получите самое актуальное время контакта в облаке устройства.
Чтобы узнать время последнего контакта устройства с облаком, используйте атрибут lastContactTimestamp трейта ExtendedGeneralDiagnostics :
if let lastContactTimeStamp = extendedGeneralDiagnosticsTrait.attributes.lastContactTimestamp { self.lastContactTime = Date(timeIntervalSince1970: Double(lastConnectedTimeStamp)) }
Настройки типа крепления камеры
Параметр Mount содержит настройки крепления камеры и информацию о состоянии. Вы можете прочитать такие атрибуты, как состояние крепления, тип обнаружения и имя типа крепления. Кроме того, вы можете использовать параметр Mount для переопределения конфигурации типа крепления по умолчанию.
// 1. Get the Mount trait guard let mountTrait = deviceType.traits[Google.MountTrait.self] else { print("Mount trait not supported or configured on this device.") return } // 2. Read the current mount state, detection type, and type name let mountState = mountTrait.attributes.mountState // Type: Google.MountTrait.MountStateEnum? let mountDetectionType = mountTrait.attributes.mountDetectionType // Type: Google.MountTrait.MountDetectionTypeEnum? let mountTypeName = mountTrait.attributes.mountTypeName // Type: String? // 3. Update the mount type override try await mountTrait.update { mutableTrait in mutableTrait.setMountTypeOverride(.official) }
Проверьте подключение устройства.
Проверка подключения устройства фактически осуществляется на уровне типа устройства, поскольку некоторые устройства поддерживают несколько типов. Возвращаемое состояние представляет собой комбинацию состояний подключения для всех характеристик данного устройства.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Состояние partiallyOnline может наблюдаться в случае использования устройств разных типов при отсутствии подключения к интернету. Стандартные характеристики Matter могут оставаться в сети благодаря локальной маршрутизации, но облачные характеристики будут отключены.
Получите IP-адрес устройства.
Чтобы узнать IP-адрес устройства, используйте атрибут networkInterfaces объекта GeneralDiagnosticsTrait . Адреса возвращаются в виде объектов Data , которые можно отформатировать в стандартные строки IPv4 или IPv6 с помощью фреймворка Network :
func getIpAddresses(trait: Matter.GeneralDiagnosticsTrait) -> [String] {
let interfaces = trait.attributes.networkInterfaces ?? []
var ipAddresses: [String] = []
for interface in interfaces {
for data in interface.iPv4Addresses {
if let ipv4 = IPv4Address(data) {
ipAddresses.append(String(describing: ipv4))
}
}
for data in interface.iPv6Addresses {
if let ipv6 = IPv6Address(data) {
ipAddresses.append(String(describing: ipv6))
}
}
}
return ipAddresses
}
Начать прямую трансляцию
Для запуска прямой трансляции отправьте строку протокола описания сессии (SDP) методу startLiveView(offerSdp:) трейта WebRtcLiveViewTrait , который возвращает три значения:
- План развития науки и техники для данной сессии.
- Продолжительность сессии в секундах.
- Идентификатор сессии, который может использоваться для продления или завершения сессии.
public func sendOffer(offerSdp: String) async throws
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval)
{
do {
// Sending StartLiveView command
let response = try await liveViewTrait.startLiveView(
offerSdp: offerSdp
)
// Received StartLiveView response
return (
answerSdp: response.answerSdp,
mediaSessionId: response.mediaSessionId,
liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
)
} catch {
// Failed to send StartLiveView command
throw error
}
}
Продлить прямую трансляцию
Прямые трансляции имеют заданную продолжительность, по истечении которой они завершаются. Чтобы продлить продолжительность активной трансляции, отправьте запрос на продление, используя метод extendLiveView(mediaSessionId:optionalArgsProvider:) :
public func extendLiveView(mediaSessionId: String) async throws {
do {
// Extending live view
let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
} catch {
// Failed to extend live view
throw error
}
}
Запуск и остановка обратной связи
Чтобы запустить обратную связь, вызовите метод startTalkback(mediaSessionId:optionalArgsProvider:) трейта WebRtcLiveViewTrait . Чтобы остановить, используйте stopTalkback(mediaSessionId:) .
public func toggleTwoWayTalk(isOn: Bool, mediaSessionId: String) async throws {
do {
if isOn {
try await liveViewTrait.startTalkback(mediaSessionId: mediaSessionId)
} else {
try await liveViewTrait.stopTalkback(mediaSessionId: mediaSessionId)
}
} catch {
throw HomeError.commandFailed("Failed to toggle twoWayTalk: \(error)")
}
}
Управление прямой трансляцией
Регулировка качества прямой трансляции полезна для оптимизации использования полосы пропускания в зависимости от контекста просмотра клиента (например, переключение на более низкое разрешение при отображении небольшого фрагмента предварительного просмотра, сетки или режима «картинка в картинке»).
Динамическое изменение качества с помощью трейта WebRtcLiveView позволяет управлять разрешением активной сессии прямой трансляции на конкретном клиенте. Это не то же самое, что настройка общего использования полосы пропускания на устройстве, которая повлияла бы на всех одновременно подключенных пользователей и качество сохраненных в облаке видеозаписей.
В следующем примере показано, как получить и обновить качество потокового видео для устройства:
Получение поддерживаемых параметров качества: получение доступных разрешений потоковой передачи, поддерживаемых устройством. Код запрашивает у трейта
WebRtcLiveViewинформацию о поддерживаемых качествах потока в виде списка значенийQualityHint(например.sd,.hd,.fhd,.qhdили.uhd) с помощью свойстваsupportedQualityHints.Изменение качества прямой трансляции: Примените выбранный
QualityHintдля изменения разрешения потоковой передачи активной прямой трансляции (например, переключения со стандартного разрешения на высокое разрешение). ФункцияupdateQualityHintиспользует методchangeLiveViewQualityтрейтаWebRtcLiveViewдля применения выбранной конфигурацииQualityHintк активной медиа-сессии.
public var supportedQualityHints: [Google.WebRtcLiveViewTrait.QualityHint] { return liveViewTrait?.attributes.supportedQualityHints ?? [] } public func updateQualityHint( liveViewTrait: Google.WebRtcLiveViewTrait, hint: Google.WebRtcLiveViewTrait.QualityHint, mediaSessionId: String ) async { do { _ = try await liveViewTrait.changeLiveViewQuality( mediaSessionId: mediaSessionId, qualityHint: hint ) } catch { // error } }
Включение и отключение функции записи
Чтобы включить запись с камеры, передайте TransportStatusEnum.Active методу setTransportStatus(transportStatus:optionalArgsProvider:) трейта PushAvStreamTransportTrait . Чтобы отключить запись, передайте TransportStatusEnum.Inactive . В следующем примере мы объединяем эти вызовы в один вызов, использующий Boolean для переключения режима записи:
public func toggleIsRecording(isOn: Bool) {
self.uiState = .loading
guard let pushAvStreamTransportTrait else {
// PushAvStreamTransportTrait not found.
return
}
Task {
do {
try await pushAvStreamTransportTrait.setTransportStatus(
transportStatus: isOn ? .active : .inactive)
if isOn {
do {
self.player = try self.createWebRtcPlayer()
} catch {
// Failed to initialize WebRtcPlayer
self.uiState = .disconnected
return
}
await self.player?.initialize()
self.uiState = .live
} else {
self.player = nil
self.uiState = .off
}
} catch {
// Failed to toggle onOff
}
}
}
Включение или выключение функции записи камеры аналогично включению или выключению видеозаписи. Когда видеозапись камеры включена, она ведется (для целей фиксации событий и создания связанных видеороликов).
Когда функция записи отключена (видео с камеры выключено):
- Камера по-прежнему может отображаться как подключенная к сети в соответствии с параметром
connectivityStateтипа устройства . - Прямая трансляция недоступна, камера также не обнаруживает никаких событий, связанных с облачными сервисами.
Проверьте, включена ли функция записи.
Чтобы определить, включена ли функция записи на камере, проверьте наличие активных подключений. В следующем примере определены две функции для выполнения этой задачи:
public func isDeviceRecording() -> Bool {
guard let pushAvStreamTransportTrait else {
// PushAvStreamTransportTrait not found.
return false
}
guard
let hasActiveConnection =
pushAvStreamTransportTrait
.attributes
.currentConnections?
.contains(where: { $0.transportStatus == .active })
else {
return false
}
return hasActiveConnection
}
Настройки батареи
Различные параметры батареи можно контролировать через 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" } ] }
private func setBatteryUsage(to option: UInt8) async throws { _ = try await energyPreferenceTrait.update { $0.setCurrentEnergyBalance(option) } }
Включите автоматический режим экономии заряда батареи.
Для настройки этой функции обновите атрибут currentLowPowerModeSensitivity в свойстве EnergyPreference . Этот атрибут использует индекс для выбора уровня чувствительности, где 0 обычно означает Disabled , а 1 — Enabled или Automatic .
private func setAutoBatterySaver(to value: Bool) async throws { _ = try await energyPreferenceTrait.update { $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0) } }
Определите состояние зарядки аккумулятора.
Чтобы получить текущее состояние зарядки устройства (заряжается, полностью заряжено или не заряжается), используйте атрибут batChargeState трейта PowerSource .
self.chargingState = powerSourceTrait.attributes.batChargeState var description: String switch self.chargingState { case .isCharging: description = "Charging" case .isAtFullCharge: description = "Full" case .isNotCharging: description = "Not Charging" default: description = "Unknown" }
Проверьте уровень заряда батареи.
Чтобы узнать текущий уровень заряда батареи, используйте атрибут batChargeLevel трейта PowerSource . Уровень может быть либо OK , Warning (низкий), либо Critical .
self.batteryLevel = powerSourceTrait.attributes.batChargeLevel var description: String switch self.batteryLevel { case .ok: description = "OK" case .warning: description = "Warning" case .critical: description = "Critical" default: description = "Unknown" }
Найдите источник питания
Чтобы определить источник питания устройства, используйте атрибуты BatPresent и wiredPresent трейта PowerSource .
if powerSourceTrait.attributes.wiredPresent ?? false { self.powerSourceType = .wired } else if powerSourceTrait.attributes.batPresent ?? false { self.powerSourceType = .battery } else { self.powerSourceType = nil }
Настройки звука
Различные настройки звука можно контролировать с помощью 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
}
}
Настройки зоны активности
Параметр ZoneManagement предоставляет интерфейс для управления пользовательскими областями интереса (зонами активности) на камерах и дверных звонках. Эти зоны используются для фильтрации обнаружения событий (например, движения человека или транспортного средства) в определенных областях в поле зрения устройства.
Зоны активности настраиваются пользователем в партнерском приложении, позволяя ему рисовать зоны над определенными областями в поле зрения камеры. Затем эти заданные пользователем зоны преобразуются в структуры, используемые данной характеристикой. Для получения дополнительной информации о работе зон активности см. раздел «Настройка и использование зон активности» .
Зоны активности обычно определяются с использованием двумерных декартовых координат. Данный параметр предоставляет структуру TwoDCartesianVertexStruct для вершин и структуру TwoDCartesianZoneStruct для определения зоны (имя, вершины, цвет и назначение).
Проверьте зоны активности
Для отображения зон активности проверьте атрибут zones трейта ZoneManagement .
let zoneManagementTrait: Google.ZoneManagementTrait self.zones = zoneManagementTrait.attributes.zones ?? []
Добавить зону активности
Для создания новой зоны используйте команду createTwoDCartesianZone . Эта команда принимает объект TwoDCartesianZoneStruct , который определяет имя зоны, количество вершин, цвет и назначение.
В следующем примере показано, как создать зону с названием «Передняя веранда» с четырьмя вершинами, окрашенную в лососевый цвет (#F439A0) и используемую для обнаружения движения.
import GoogleHomeSDK import GoogleHomeTypes func createFrontPorchZone(trait: Google.ZoneManagementTrait) async { // 1. Define the vertices for the zone (2D Cartesian coordinates) // Values are UInt16, typically scaled to the device's twoDCartesianMax. let vertices = [ Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 260, y = 422), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1049, y = 0), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048, y = 0), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048, y = 950), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1630, y = 1349), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 880, y = 2048), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 0, y = 2048), Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 638, y = 1090) ] // 2. Define the zone structure using the given SDK struct let newZone = Google.ZoneManagementTrait.TwoDCartesianZoneStruct( name: "Front Porch", use: [.motion], // ZoneUseEnum.motion vertices: vertices, // Color is a hex string (for example, Salmon/Pink) color: "#F439A0" ) do { // 3. Execute the raw command to add the zone to the device // This returns the created zone's ID (UInt16). var newZoneID = try await trait.createTwoDCartesianZone(zone: newZone) } catch { // Error } }
Обновить зону активности
Для обновления существующей зоны используйте команду updateTwoDCartesianZone . Для выполнения этой команды необходимы zoneId и обновленная структура TwoDCartesianZoneStruct .
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 let zone: Google.ZoneManagementTrait.TwoDCartesianZoneStruct do { _ = try await zoneManagementTrait.updateTwoDCartesianZone( zoneID: zoneID, zone: zone) } catch { // Error }
Удалить зону активности
Для удаления зоны используйте команду removeZone , указав конкретный zoneId .
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 do { _ = try await zoneManagementTrait.removeZone(zoneID: zoneID) } catch { // Error }
Звуковые триггеры событий
Трейт AvStreamAnalysis предоставляет интерфейс для управления триггерами обнаружения событий на камерах и дверных звонках. В то время как триггеры, основанные на визуальном восприятии (например, людей или транспортных средств), могут быть привязаны к конкретной зоне, триггеры, связанные со звуком, обычно представляют собой конфигурацию на уровне устройства.
Для обнаружения звука с помощью EventTriggerTypeEnum доступны следующие типы триггеров:
| Режим | Значение перечисления | Описание |
|---|---|---|
| Звук | Sound | Общее обнаружение звука. |
| Говорящий | PersonTalking | Обнаруживает речь. |
| собачий лай | DogBark | Обнаруживает вокализации собак. |
| Разбить стекло | GlassBreak | Обнаруживает звук разбивающегося стекла. |
| дымовая сигнализация | SmokeAlarm | Обнаруживает срабатывание дымовых извещателей, часто распознаваемое по звуковому сигналу T3 (три коротких звуковых сигнала с последующей паузой). |
| сигнализатор угарного газа | CoAlarm | Обнаруживает сигналы тревоги об обнаружении угарного газа (CO), которые обычно распознаются по звуковому сигналу T4 (четыре коротких звуковых сигнала с последующей паузой). |
Проверьте состояние обнаружения звука.
Чтобы отобразить пользователю текущее состояние обнаружения звука, необходимо проверить, что поддерживает устройство и что включено в его аппаратную конфигурацию. Необходимо проверить два следующих параметра:
В разработке под iOS обычно для чтения этих атрибутов используется трейт AvStreamAnalysis непосредственно на устройстве.
// Example struct to store event triggers public struct EventTrigger: Equatable { public var id: Google.AvStreamAnalysisTrait.EventTriggerTypeEnum public var enabled: Bool } let avStreamAnalysisTrait: Google.AvStreamAnalysisTrait let possibleEventTriggers = avStreamAnalysisTrait.attributes.supportedEventTriggers ?? [] let enabledEventTriggers = avStreamAnalysisTrait.attributes.enabledEventTriggers ?? [] let eventTriggers [EventTrigger] = [] for trigger in possibleEventTriggers { self.eventTriggers.append( EventTrigger( id: trigger, enabled: enabledEventTriggers.contains(trigger) ) ) }
Обновите набор включенных триггеров.
Для обновления набора включенных триггеров используйте команду SetOrUpdateEventDetectionTriggers , которая принимает список структур EventTriggerEnablement .
// Example struct to store event triggers public struct EventTrigger: Equatable { public var id: Google.AvStreamAnalysisTrait.EventTriggerTypeEnum public var enabled: Bool } let avStreamAnalysisTrait: Google.AvStreamAnalysisTrait let eventTriggers: [EventTrigger] let enabledEventTriggers = eventTriggers.map { Google.AvStreamAnalysisTrait.EventTriggerEnablement( eventTriggerType: $0.id, enablementStatus: $0.enabled ? .enabled : .disabled ) } try await avStreamAnalysisTrait.setOrUpdateEventDetectionTriggers( eventTriggerEnablements: enabledEventTriggers )
Режимы записи
Параметр RecordingMode предоставляет интерфейс для управления режимом видео- и фотозаписи на камерах и дверных звонках. Он позволяет пользователям выбирать между непрерывной записью, записью по событиям или полным отключением записи (только в режиме просмотра в реальном времени).
RecordingModeEnum определяет доступные стратегии записи:
| Режим | Значение перечисления | Описание |
|---|---|---|
| Неполноценный | Disabled | Запись полностью отключена. Используется в основном устаревшими устройствами. |
| CVR (непрерывная видеозапись) | Cvr | Видео записывается круглосуточно. Требуется подписка (например, Google Home Premium . |
| EBR (Event Based Recording) | Ebr | Запись запускается событиями (человек, движение). Длительность видео зависит от продолжительности события и подписки. |
| ETR (запись, запускаемая событием) | Etr | Короткая предварительная запись (например, 10 секунд), запускаемая событиями. |
| Прямая трансляция | LiveView | Запись отключена, но пользователи по-прежнему могут получить доступ к прямой трансляции. |
| Неподвижные изображения | Images | Вместо видеозаписи событий записываются снимки экрана. |
Проверьте режимы записи
Чтобы отобразить текущую конфигурацию записи, проверьте атрибуты трейта RecordingMode :
-
supportedRecordingModes— все возможные режимы -
availableRecordingModes— выбираемые режимы -
selectedRecordingMode- Активный режим
// Example struct to store recording modes. public struct RecordingMode: Hashable { public let id: UInt8 public let mode: Google.RecordingModeTrait.RecordingModeEnum } let recordingModeTrait: Google.RecordingModeTrait if let availableRecordingModes = recordingModeTrait.attributes.availableRecordingModes, let supportedRecordingModes = recordingModeTrait.attributes.supportedRecordingModes, let selectedRecordingMode = recordingModeTrait.attributes.selectedRecordingMode { var recordingModes: [RecordingMode] = [] for recordingModeId in availableRecordingModes { guard Int(recordingModeId) < supportedRecordingModes.count, Int(recordingModeId) >= 0 else { // Out of bounds error } recordingModes.append( RecordingMode( id: recordingModeId, mode: supportedRecordingModes[Int(recordingModeId)].recordingMode, ) ) } }
Изменить режим записи
Перед обновлением убедитесь, что выбранный индекс из атрибута supportedRecordingModes присутствует в атрибуте availableRecordingModes .
Для обновления выбранного режима используйте функцию setSelectedRecordingMode , передав в качестве параметра индекс выбранного режима:
let recordingModeTrait: Google.RecordingModeTrait let recordingModeID: UInt8 _ = try await recordingModeTrait.update { $0.setSelectedRecordingMode(recordingModeID) }
Другие настройки
Различные другие параметры можно контролировать с помощью 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
}
Включить или отключить аналитику
Каждое устройство может индивидуально включить отправку подробных аналитических данных в облако Google Home (см. API облачного мониторинга для Home ).
Чтобы включить аналитику для устройства, установите свойство analyticsEnabled объекта ExtendedGeneralDiagnosticsTrait в true . При установке analyticsEnabled автоматически устанавливается и другое свойство, logUploadEnabled , в значение true , что позволяет загружать файлы журналов аналитики в облако Google Home.
// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(true)
}
// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(false)
}
Настройки передачи и записи
В этом разделе рассматриваются настройки, связанные с качеством потоковой передачи с камеры и запуском событий. Эти настройки управляются с помощью трейта PushAvStreamTransport .
Прочитать настройки транспорта
В этом разделе показано, как получить текущую конфигурацию с камеры или дверного звонка. Программа извлекает параметр PushAvStreamTransport , определяет конкретное соединение, используемое для записи, а затем извлекает текущие значения качества полосы пропускания, чувствительности к пробуждению и максимальной длины события.
// Assuming access to // var pushAvStreamTransportTrait: Google.PushAvStreamTransportTrait let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations // Locate the connection designated for recording let recordingConnection = connections.first { connection in guard let transportOptions = connection.transportOptions else { return false } return transportOptions.streamUsage == .recording } let options = recordingConnection?.transportOptions // 1. Bandwidth Quality (Video Stream ID) let videoStreamId = options?.videoStreamID // 2. Wake-up Sensitivity (Motion Sensitivity) let wakeUpSensitivity = options?.triggerOptions.motionSensitivity // 3. Max Event Length (Motion Trigger Time Control) let maxEventLength = options?.triggerOptions.motionTimeControl?.maxDuration
Обновить настройки транспорта
В этом разделе показано, как изменить настройки транспорта. Создается новая структура TransportOptionsStruct , содержащая новые значения, а затем с помощью команды modifyPushTransport эти обновленные настройки отправляются обратно на устройство, применяясь к соединению для записи, найденному на предыдущем шаге.
Для изменения этих настроек используйте команду modifyPushTransport с параметром TransportOptionsStruct .
// Example: Updating to Max Quality and 30s duration let currentOptions = recordingConnection!.transportOptions! let newOptions = Google.PushAvStreamTransportTrait.TransportOptionsStruct( streamUsage: .recording, videoStreamID: 2, // Max Quality tlsEndpointID: currentOptions.tlsEndpointID, url: currentOptions.url, triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct( triggerType: .motion, motionSensitivity: 5, // Medium motionTimeControl: Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct( initialDuration: currentOptions.triggerOptions.motionTimeControl?.initialDuration ?? 10, augmentationDuration: currentOptions.triggerOptions.motionTimeControl?.augmentationDuration ?? 5, maxDuration: 30, blindDuration: currentOptions.triggerOptions.motionTimeControl?.blindDuration ?? 0 ) ), ingestMethod: currentOptions.ingestMethod, containerOptions: currentOptions.containerOptions ) try await pushAvStreamTransportTrait.modifyPushTransport( connectionID: recordingConnection!.connectionID, transportOptions: newOptions )
Определите качество полосы пропускания
Свойство videoStreamId структуры TransportOptionsStruct соответствует конкретной конфигурации видеопотока.
Чтобы получить список поддерживаемых видеопотоков, обратитесь к атрибуту allocatedVideoStreams , который представляет собой список VideoStreamStructs из трейта CameraAvStreamManagement для устройства.
Отрегулируйте чувствительность пробуждения устройства.
Свойство motionSensitivity структуры TransportTriggerOptionsStruct соответствует следующим значениям:
| Этикетка | Значение (UInt8) |
|---|---|
| Низкий | 1 |
| Середина | 5 |
| Высокий | 10 |
Отрегулируйте максимальную продолжительность события.
Свойство maxDuration структуры TransportMotionTriggerTimeControlStruct соответствует следующим значениям длительности в формате UInt32 (в секундах):
- 10 , 15 , 30 , 60 , 120 , 180
Настройки звукового сигнала
Различные настройки дверного звонка можно контролировать через 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
}
}
Включить тему звукового сигнала
Некоторые дверные звонки могут иметь мелодии, доступные пользователям только в течение ограниченного времени. Например, мелодии, приуроченные к праздникам. Такие мелодии называются тематическими.
Чтобы узнать, какие темы оформления Chime доступны пользователю, создайте фильтр временного интервала и используйте его для фильтрации результатов команды getAvailableThemes из трейта ChimeThemes . Это вернет список доступных тем, включая их названия.
Следующий пример показывает, как отфильтровать список. Тема считается активной, если текущее время находится в пределах ее начального и конечного времени (значения startTimeSeconds и endTimeSeconds соответственно). Если начальное время не задано, тема считается активной с начала времени. Если конечное время не задано, тема остается активной неограниченно долго. Если оба параметра отсутствуют, тема всегда активна.
let chimeThemes = try await chimeThemeTrait.getAvailableThemes().themes
if !chimeThemes.isEmpty {
var chimeThemeSettings = []
for chimeTheme in chimeThemes {
let currentDateTime = UInt64(Date().timeIntervalSince1970)
// Only show chime themes that are active.
if chimeTheme.startTimeSeconds ?? 0 <= currentDateTime
&& chimeTheme.endTimeSeconds ?? UInt64.max >= currentDateTime
{
self.chimeThemeSettings.append(chimeTheme.name)
}
}
}
Получив название нужной темы, например, Christmas , вы можете выбрать её с помощью функции setSelectedTimeboxedThemeName() в трейте ChimeThemes ChimeThemes .
private func setChimeTheme(to value: String) async throws {
_ = try await chimeThemeTrait.update {
$0.setSelectedTimeboxedThemeName(value)
}
}
Настройки уведомлений для посетителей
С помощью трейта VisitorAnnouncement из Home API вы можете запрашивать и управлять настройками оповещения о посетителях для дверных звонков. Этот трейт определяет, будет ли объявляться присутствие посетителя на умных колонках Google или отображаться при звонке в дверной звонок.
В следующем примере показано, как проверить, включены ли уведомления для посетителей, и как обновить этот параметр:
let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled let value: Bool _ = try await self.visitorAnnouncementTrait?.update { $0.setVisitorAnnouncementsEnabled(value) }