O tipo de dispositivo campainha é implementado usando três atributos:
PushAvStreamTransportTrait,
que processa o transporte de stream de áudio e vídeo usando protocolos
baseados em push,
WebRtcLiveViewTrait,
que oferece a capacidade de controlar transmissões ao vivo e talkback, e
CameraSnapshotTrait,
que fornece snapshots de visualização em cache e capturas de snapshots ao vivo.
Sempre verifique se o dispositivo é compatível com atributos e comandos antes de usar qualquer recurso ou tentar atualizar atributos. Consulte Controlar dispositivos no iOS para mais informações.
| Tipo de dispositivo das APIs Home | Características | App de exemplo do Swift | Caso de uso |
|---|---|---|---|
|
Campainha
Um dispositivo acionado por um botão do lado de fora de uma porta que emite um sinal sonoro e/ou visual, usado para chamar a atenção de uma pessoa que está do outro lado da porta. As campainhas podem ter transmissões ao vivo acessíveis, comunicação bidirecional ou eventos de detecção. |
Atributos obrigatórios google PushAvStreamTransportTrait google WebRtcLiveViewTrait |
Campainha |
Receber informações básicas sobre um dispositivo
Implementado no app de exemplo para iOS
O atributo BasicInformation
inclui informações como nome do fornecedor, ID do fornecedor, ID do produto,
nome do produto (inclui informações do modelo) e versão do software de um dispositivo:
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!
Encontrar o número de série
Implementado no app de exemplo para iOS
Para ver o número de série do dispositivo, use o
comando GetSerialNumber da
característica ExtendedBasicInformation.
O exemplo mostra como salvar o número de série em uma variável chamada serialNumber:
// Assuming extendedBasicInformationTrait: Google.ExtendedBasicInformationTrait let response = try await extendedBasicInformationTrait.getSerialNumber() let serialNumber = response.serialNumber
Respostas rápidas
O recurso de respostas rápidas permite que o usuário envie uma mensagem predefinida para um dispositivo de campainha.
Esse recurso está disponível apenas em campainhas. A lista de mensagens predefinidas está disponível para o app do parceiro, que pode apresentá-las ao usuário para que ele escolha uma. As mensagens predefinidas não podem ser editadas pelo usuário.
As respostas rápidas são implementadas pelo atributo
PresetMessage.
Reproduzir uma mensagem predefinida
Para reproduzir uma mensagem predefinida, chame o método
playPresetMessage, transmitindo um dos valores de string encontrados na propriedade
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)")
}
}
Definir idioma falado
Definir idioma falado
Defina o idioma falado ativo de um dispositivo para uma localidade específica
(por exemplo, "en_US") usando o método setActiveLocale da
característica LocalizationConfiguration.
// Setting the active language // Assuming localizationConfigurationTrait: Matter.LocalizationConfigurationTrait let selectedLocale = "en_US" try await localizationConfigurationTrait.update { $0.setActiveLocale(selectedLocale) }
Receber o horário mais recente de contato do dispositivo com a nuvem
Para encontrar o horário mais recente em que o dispositivo teve contato com a nuvem, use
o atributo lastContactTimestamp da
característica
ExtendedGeneralDiagnostics:
if let lastContactTimeStamp = extendedGeneralDiagnosticsTrait.attributes.lastContactTimestamp { self.lastContactTime = Date(timeIntervalSince1970: Double(lastConnectedTimeStamp)) }
Configurações do tipo de montagem de câmera
O atributo Mount
contém as configurações de montagem da câmera e informações de status. É possível ler
atributos como o estado de montagem, o tipo de detecção e o nome do tipo de montagem.
Além disso, é possível usar o atributo Mount para substituir a configuração padrão do tipo de montagem.
// 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) }
Verificar a conectividade de um dispositivo
A conectividade de um dispositivo é verificada no nível do tipo de dispositivo, porque alguns dispositivos são compatíveis com vários tipos. O estado retornado é uma combinação dos estados de conectividade de todos os atributos desse dispositivo.
let doorbellConnectivity = doorbellDeviceType.metadata.sourceConnectivity.connectivityState
Um estado de partiallyOnline pode ser observado no caso de tipos de dispositivos mistos
quando não há conectividade com a Internet. Os atributos padrão do Matter
ainda podem estar on-line devido ao roteamento local, mas os atributos baseados na nuvem estarão
off-line.
Encontrar o endereço IP do dispositivo
Para encontrar o endereço IP do dispositivo, use o atributo networkInterfaces do
GeneralDiagnosticsTrait.
Os endereços são retornados como objetos Data, que podem ser formatados como strings IPv4 ou IPv6 padrão usando o framework 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
}
Iniciar uma transmissão ao vivo
Implementado no app de exemplo para iOS
Para iniciar uma transmissão ao vivo, envie a string do Protocolo de Descrição de Sessão (SDP, na sigla em inglês)
para o método
startLiveView(offerSdp:)
da característica
WebRtcLiveViewTrait,
que retorna três valores:
- O SDP da sessão.
- A duração da sessão em segundos.
- O ID da sessão, que pode ser usado para estender ou encerrar a sessão.
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
}
}
Estender uma transmissão ao vivo
Implementado no app de exemplo para iOS
As transmissões ao vivo têm uma duração predefinida e expiram após esse período. Para aumentar a
duração de um stream ativo, emita uma solicitação de extensão usando o
método
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
}
}
Iniciar e interromper o TalkBack
Implementado no app de exemplo para iOS
Para iniciar o talkback, chame o método startTalkback(mediaSessionId:optionalArgsProvider:) da característica WebRtcLiveViewTrait.
Para interromper, use 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)")
}
}
Gerenciar transmissão ao vivo
Implementado no app de exemplo para iOS
Ajustar a qualidade da transmissão ao vivo é útil para otimizar o uso da largura de banda com base no contexto de visualização do cliente (por exemplo, mudar para uma resolução mais baixa ao exibir um bloco de visualização menor, uma visualização em grade ou o modo picture-in-picture).
Mudar a qualidade dinamicamente usando o atributo
WebRtcLiveView
gerencia especificamente a resolução da sessão de transmissão ao vivo ativa
em um cliente específico. Isso não é o mesmo que definir uma configuração de uso de largura de banda para todo o dispositivo, o que afetaria todos os espectadores simultâneos e a qualidade das gravações de vídeo históricas salvas na nuvem.
O exemplo a seguir demonstra como recuperar e atualizar a qualidade da transmissão ao vivo de um dispositivo:
Recuperar opções de qualidade compatíveis: receba as resoluções de streaming disponíveis compatíveis com o dispositivo. O código consulta o atributo
WebRtcLiveViewpara expor as qualidades de transmissão compatíveis como uma lista de valoresQualityHint(como.sd,.hd,.fhd,.qhdou.uhd) usando a propriedadesupportedQualityHints.Mudar a qualidade da transmissão ao vivo: aplique um
QualityHintselecionado para mudar a resolução da transmissão ao vivo ativa (por exemplo, mudar de definição padrão para alta definição). A funçãoupdateQualityHintusa o métodochangeLiveViewQualityda característicaWebRtcLiveViewpara aplicar a configuraçãoQualityHintselecionada à sessão de mídia ativa.
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 } }
Ativar e desativar o recurso de gravação
Para ativar o recurso de gravação da câmera, transmita
TransportStatusEnum.Active
para o método
setTransportStatus(transportStatus:optionalArgsProvider:)
da característica
PushAvStreamTransportTrait. Para desativar o recurso de gravação, transmita
TransportStatusEnum.Inactive.
No exemplo a seguir, agrupamos essas chamadas em uma única chamada que usa um
Boolean para alternar o recurso de gravação:
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
}
}
}
Ativar ou desativar a capacidade de gravação da câmera é o mesmo que ligar ou desligar o vídeo da câmera. Quando o vídeo de uma câmera está ativado, ela está gravando (para fins de eventos e clipes relacionados).
Quando o recurso de gravação está desativado (o vídeo da câmera está desligado):
- A câmera ainda pode aparecer como on-line de acordo com o
connectivityStatedo tipo de dispositivo. - Não é possível acessar a transmissão ao vivo, e a câmera não detecta eventos na nuvem.
Verificar se o recurso de gravação está ativado
Para determinar se o recurso de gravação de uma câmera está ativado, verifique se há conexões ativas. O exemplo a seguir define duas funções para fazer isso:
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
}
Recuperar capturas de tela da câmera
Implementado no app de exemplo para iOS
Use a característica CameraSnapshot para recuperar capturas de tela estáticas de uma câmera.
Esses snapshots são úteis em várias situações:
- Como um bloco de marcador de posição na interface enquanto uma transmissão ao vivo do WebRTC está carregando.
- Como uma imagem de prévia estática que se transforma em uma transmissão ao vivo quando o usuário interage com ela.
- Como uma tela de fundo para desenhar e configurar Zonas de Atividade personalizadas.
O atributo CameraSnapshot oferece duas maneiras de buscar capturas de tela, dependendo
se você precisa de uma captura de tela em cache para renderização rápida ou uma captura de tela ao vivo
sob demanda.
Receber um snapshot de visualização em cache
Uma captura de tela de prévia é uma imagem em cache que o SDK pode recuperar sem ativar a câmera. Esse é o método mais rápido para buscar uma imagem estática e é ideal para páginas de visão geral da câmera ou grades de painel.
Para receber o snapshot de prévia, leia o atributo de atributo preview_image_url:
guard let cameraSnapshotTrait = deviceType.traits[ Google.CameraSnapshotTrait.self ] else { print("CameraSnapshot trait not supported on this device.") return } if let previewImageUrlString = cameraSnapshotTrait .attributes.preview_image_url, let url = URL(string: previewImageUrlString) { // Load the preview image from the URL }
Dependendo da configuração e da atividade da câmera, o URL de visualização aponta para uma imagem em cache gerada de uma filmagem recente (o primeiro frame I do fragmento de vídeo mais recente) ou um snapshot enviado periodicamente pela câmera.
Para indicar a atualização da imagem, a nuvem do Google Home incorpora um cabeçalho X-Home-Image-Captured-At na imagem JPEG/PNG exibida, formatada em UTC. É possível analisar esse cabeçalho no
lado do cliente para exibir a idade do snapshot em um app.
Receber um snapshot em tempo real on demand
Para jornadas do usuário que exigem as imagens ao vivo atuais da câmera, como a configuração de Zonas de Atividade, é possível solicitar uma captura de tela ao vivo. Acionar uma captura de tela instantânea instrui a câmera a ativar, capturar um novo frame e fazer upload dele para a nuvem.
Para solicitar um snapshot em tempo real, use o comando getLiveSnapshot():
do { let response = try await cameraSnapshotTrait.getLiveSnapshot() let snapshotUrlString = response.snapshot_url if let url = URL(string: snapshotUrlString) { // Load the live snapshot image from the URL } } catch { print("Failed to get live snapshot: \(error)") }
Autenticar solicitações de snapshot
Implementado no app de exemplo para iOS
Todos os URLs de captura de tela apontam para mídia segura e exigem um token OAuth 2.0 para o
escopo da v2 das APIs Home. Para baixar e renderizar as imagens, o token OAuth precisa ser
inserido como um token do portador no cabeçalho Authorization da solicitação HTTP.
O exemplo a seguir demonstra como configurar uma solicitação de rede segura para fazer o download de um snapshot:
import UIKit func loadSnapshotImage(from url: URL, home: Home) async -> UIImage? { do { // 1. Retrieve the OAuth access token from the Home APIs SDK let (accessToken, _) = try await home.permissions.authorization() // 2. Configure the HTTP GET request with the Bearer token var request = URLRequest(url: url) request.setValue( "Bearer \(accessToken)", forHTTPHeaderField: "Authorization" ) // 3. Fetch the image data let (data, _) = try await URLSession.shared.data(for: request) return UIImage(data: data) } catch { print("Error loading snapshot image: \(error)") return nil } }
Configurações da bateria
Várias configurações de bateria podem ser controladas pelas APIs Home.
Definir a preferência de uso da bateria
A configuração do equilíbrio de energia permite definir a relação entre a duração da bateria e o desempenho de um dispositivo. É possível criar diferentes perfis de bateria, como "Estendido", "Equilibrado" e "Desempenho", e alternar entre eles.
Esse recurso é implementado atualizando o atributo
currentEnergyBalance
da característica
EnergyPreference. O atributo aceita um índice inteiro
que corresponde a um perfil específico definido na
lista energyBalances do dispositivo (por exemplo, 0 para EXTENDED,
1 para BALANCED e 2 para PERFORMANCE).
Um valor null para currentEnergyBalance indica que o dispositivo está usando um
perfil personalizado. Este é um estado somente leitura.
Veja a seguir um exemplo de estrutura que o atributo currentEnergyBalance
vai usar, seguido pelo snippet de código real que usa o atributo.
// 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) } }
Ativar a economia de bateria automática
Implementado no app de exemplo para iOS
Para configurar esse recurso, atualize o
atributo currentLowPowerModeSensitivity
da característica
EnergyPreference. Esse atributo usa um índice
para selecionar um nível de sensibilidade, em que 0 normalmente representa Disabled
e 1 representa Enabled ou Automatic.
private func setAutoBatterySaver(to value: Bool) async throws { _ = try await energyPreferenceTrait.update { $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0) } }
Verificar o estado de carregamento da bateria
Implementado no app de exemplo para iOS
Para saber o estado de carregamento atual do dispositivo (carregando, totalmente carregado ou não
carregando), use o
atributo
batChargeState
da característica
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" }
Verificar o nível de bateria
Para conferir o Nível de bateria atual, use o atributo
batChargeLevel
da característica
PowerSource. O nível é OK, Warning (baixo) ou 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" }
Acessar a fonte de energia
Para determinar a fonte de energia que o dispositivo está usando,
use os atributos
BatPresent
e
wiredPresent
da característica
PowerSource.
if powerSourceTrait.attributes.wiredPresent ?? false { self.powerSourceType = .wired } else if powerSourceTrait.attributes.batPresent ?? false { self.powerSourceType = .battery } else { self.powerSourceType = nil }
Verificar se a bateria precisa ser trocada
O atributo batReplaceability indica se a bateria não pode ser substituída, se pode ser substituída pelo usuário ou se pode ser substituída pela fábrica.
Se a bateria for substituível, o atributo
batReplacementNeeded
da característica
PowerSource
vai informar se ela precisa ser trocada.
// Get the battery replacement status var batteryStatus = powerSourceTrait.attributes.batReplacementNeeded if batteryStatus { print("Replace the battery.") }
Quando a bateria pode ser substituída pelo usuário, o
batReplacementDescription
a descreve, incluindo informações como formato, química e
fabricante preferencial.
Configurações de áudio
Várias configurações de áudio podem ser controladas pelas APIs Home.
Ativar ou desativar o microfone
Para ativar ou desativar o microfone do dispositivo, atualize o atributo
microphoneMuted
do atributo CameraAvStreamManagementTrait usando a função integrada
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
}
}
Ativar ou desativar a gravação de áudio
Para ativar ou desativar a gravação de áudio no dispositivo, atualize o atributo
recordingMicrophoneMuted
da característica CameraAvStreamManagementTrait usando a função integrada
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
}
}
Ajustar o volume do alto-falante
Para ajustar o volume do alto-falante do dispositivo, atualize o atributo
speakerVolumeLevel
do atributo CameraAvStreamManagementTrait usando a função integrada
setSpeakerVolumeLevel:
// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setSpeakerVolumeLevel(value)
}
} catch {
// Error
}
}
Configurações de Zonas de Atividade
Implementado no app de exemplo para iOS
A característica ZoneManagement fornece uma interface para gerenciar regiões de interesse personalizadas (zonas de atividade) em dispositivos de câmera e campainha.
Essas zonas são usadas para filtrar a detecção de eventos (como movimento de pessoas ou veículos) para áreas específicas no campo de visão do dispositivo.
As zonas de atividade são configuradas pelo usuário em um aplicativo de parceiro, permitindo que ele desenhe zonas sobre áreas específicas no campo de visão da câmera. Essas zonas definidas pelo usuário são traduzidas para as estruturas usadas por essa característica. Para mais informações sobre como as Zonas de Atividade funcionam, consulte Configurar e usar as Zonas de Atividade.
As zonas de atividade geralmente são definidas usando coordenadas cartesianas 2D.
O atributo fornece o
TwoDCartesianVertexStruct para vértices e o
TwoDCartesianZoneStruct
para a definição da zona (nome, vértices, cor e uso).
Verificar as Zonas de Atividade
Para exibir as zonas de atividade, verifique o atributo
zones
da característica ZoneManagement.
let zoneManagementTrait: Google.ZoneManagementTrait self.zones = zoneManagementTrait.attributes.zones ?? []
Adicionar uma Zona de Atividade
Para criar uma zona, use o comando createTwoDCartesianZone. Esse comando usa um TwoDCartesianZoneStruct,
que define o nome, os vértices, a cor e o uso da zona.
O exemplo a seguir mostra como criar uma zona chamada "Front Porch" com quatro vértices, na cor salmão (#F439A0), usada para detecção de movimento.
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 } }
Atualizar uma Zona de Atividade
Para atualizar uma zona, use o comando updateTwoDCartesianZone. Esse comando requer o zoneId e o
TwoDCartesianZoneStruct atualizado.
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 let zone: Google.ZoneManagementTrait.TwoDCartesianZoneStruct do { _ = try await zoneManagementTrait.updateTwoDCartesianZone( zoneID: zoneID, zone: zone) } catch { // Error }
Excluir uma Zona de Atividade
Para remover uma zona, use o comando
removeZone com o zoneId específico.
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 do { _ = try await zoneManagementTrait.removeZone(zoneID: zoneID) } catch { // Error }
Gatilhos de detecção de som
O atributo AvStreamAnalysis fornece uma interface para gerenciar acionadores de detecção de eventos
em dispositivos de câmera e campainha. Enquanto os acionadores baseados em visão
(como pessoas ou veículos) podem ser específicos da zona, os acionadores relacionados ao som
normalmente são configurações no nível do dispositivo.
Os seguintes tipos de acionador estão disponíveis para detecção de som com a
EventTriggerTypeEnum:
| Modo | Valor de tipo enumerado | Descrição |
|---|---|---|
| Som | Sound |
Detecção de som geral. |
| Pessoa falando | PersonTalking |
Detecta fala. |
| Latido de cachorro | DogBark |
Detecta vocalizações caninas. |
| Vidro quebrando | GlassBreak |
Detecta o som de vidro quebrando. |
| Detector de fumaça | SmokeAlarm |
Detecta detectores de fumaça, geralmente reconhecidos pelo padrão sonoro T3 (três bipes curtos seguidos por uma pausa). |
| Alarme de monóxido de carbono | CoAlarm |
Detecta alarmes de monóxido de carbono (CO), normalmente reconhecidos pelo padrão sonoro T4 (quatro bipes curtos seguidos por uma pausa). |
Verificar o status da detecção de som
Para mostrar o estado atual da detecção de som ao usuário, verifique o que o dispositivo aceita e o que está ativado pelo hardware do dispositivo. Os dois atributos a serem verificados são:
No desenvolvimento para iOS, normalmente você acessa o atributo AvStreamAnalysis
do dispositivo para ler esses atributos.
// 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) ) ) }
Atualizar o conjunto de gatilhos ativados
Para atualizar o conjunto de gatilhos ativados, use o comando
SetOrUpdateEventDetectionTriggers, que usa uma lista de estruturas 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 )
Modos de gravação
Implementado no app de exemplo para iOS
A característica RecordingMode fornece uma interface para gerenciar o comportamento de gravação de vídeo e imagem em dispositivos de câmera e campainha. Ele permite
que os usuários escolham entre gravação contínua, gravação baseada em eventos
ou desativação total da gravação (somente imagens ao vivo).
O RecordingModeEnum
define as estratégias de gravação disponíveis:
| Modo | Valor de tipo enumerado | Descrição |
|---|---|---|
| Desativada | Disabled |
A gravação está totalmente desativada. Usado principalmente por dispositivos legados. |
| CVR (gravação contínua de vídeo) | Cvr |
O vídeo é gravado 24 horas por dia, 7 dias por semana. Requer uma assinatura (por exemplo, Google Home Premium. |
| EBR (gravação baseada em eventos) | Ebr |
A gravação é acionada por eventos (pessoa, movimento). A duração do vídeo depende da duração do evento e da assinatura. |
| ETR (gravação acionada por evento) | Etr |
Gravação de prévia curta (por exemplo, 10 segundos) acionada por eventos. |
| Live View | LiveView |
A gravação está desativada, mas os usuários ainda podem acessar a transmissão ao vivo. |
| Imagens estáticas | Images |
As capturas de tela são gravadas em vez de vídeos quando ocorrem eventos. |
Verificar modos de gravação
Para exibir a configuração de gravação atual, verifique os atributos
da característica RecordingMode:
supportedRecordingModes: todos os modos possíveisavailableRecordingModes: modos selecionáveisselectedRecordingMode: o modo ativo
// 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, ) ) } }
Mudar o modo de gravação
Antes de atualizar, verifique se o índice escolhido do atributo supportedRecordingModes
está presente no atributo availableRecordingModes.
Para atualizar o modo selecionado, use a
função setSelectedRecordingMode, transmitindo o índice do modo escolhido:
let recordingModeTrait: Google.RecordingModeTrait let recordingModeID: UInt8 _ = try await recordingModeTrait.update { $0.setSelectedRecordingMode(recordingModeID) }
Outras configurações
Várias outras configurações podem ser controladas pelas APIs Home.
Ativar ou desativar a Visão Noturna
Para ativar ou desativar a visão noturna da câmera, use TriStateAutoEnum
para atualizar o atributo
nightVision
da característica CameraAvStreamManagementTrait usando a função integrada
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
}
}
Mudar o brilho do LED de status
Para mudar o brilho do LED de status, use
ThreeLevelAutoEnum
para atualizar o atributo
statusLightBrightness
da característica CameraAvStreamManagementTrait usando a função integrada
setStatusLightBrightness:
// Set the LED brightness
func setStatusLightBrightness(
to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setStatusLightBrightness(value)
}
} catch {
// Error
}
}
Mudar a janela de visualização da câmera
A janela de visualização da câmera é igual ao recurso de zoom e corte descrito no artigo de suporte Zoom e modo Enhance no vídeo da câmera Nest.
A janela de visualização é definida em um ViewportStruct que contém quatro valores, que
são usados como as coordenadas da janela de visualização. As coordenadas são definidas como:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
A determinação dos valores para o ViewportStruct depende da interface do app e
da implementação da câmera. Em um nível muito básico, para definir a janela de visualização do vídeo da câmera, atualize o atributo viewport do atributo CameraAvStreamManagementTrait com um ViewportStruct, usando a função integrada 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
}
}
}
Gerar um TransportOptionsStruct
Algumas configurações exigem modificações nas propriedades em um TransportOptionsStruct,
que é transmitido para as opções de transporte de uma conexão de streaming. No Swift, essa struct precisa ser gerada antes de atualizar as propriedades.
Use essa função auxiliar para gerar o struct que será usado com as seguintes mudanças de configuração:
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
}
Ativar ou desativar as análises
Cada dispositivo pode ativar individualmente o envio de dados de análise detalhados para a nuvem do Google Home (consulte Cloud Monitoring para APIs Home).
Para ativar as análises em um dispositivo, defina a propriedade
analyticsEnabled)
do
ExtendedGeneralDiagnosticsTrait
como true. Quando você define analyticsEnabled,
outra propriedade, logUploadEnabled, é definida automaticamente como true, o que
permite que os arquivos de registro de análise sejam enviados para a nuvem do Google Home.
// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(true)
}
// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(false)
}
Configurações de transporte e gravação
Esta seção aborda as configurações relacionadas à qualidade do stream da câmera e
ao acionamento de eventos. Essas configurações são gerenciadas pela característica
PushAvStreamTransport.
Ler configurações de transporte
Nesta seção, mostramos como recuperar a configuração atual de
uma câmera ou campainha. Ele busca a característica PushAvStreamTransport,
encontra a conexão específica usada para gravação e extrai
os valores atuais de qualidade da largura de banda, sensibilidade de ativação
e duração máxima do evento.
// 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
Atualizar as configurações de transporte
Nesta seção, mostramos como mudar as configurações de transporte.
Ele cria um novo TransportOptionsStruct com os novos valores e
usa o comando modifyPushTransport para enviar essas configurações atualizadas
de volta ao dispositivo, aplicando-as à conexão de gravação encontrada
na etapa anterior.
Para modificar essas configurações, use o
comando modifyPushTransport
com um 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 )
Determinar a qualidade da largura de banda
A propriedade videoStreamId
da TransportOptionsStruct corresponde a uma
configuração específica de stream de vídeo.
Para ver os streams de vídeo compatíveis, consulte o atributo
allocatedVideoStreams,
que é uma lista de VideoStreamStructs.
do atributo CameraAvStreamManagement do dispositivo.
Ajustar a sensibilidade de ativação do dispositivo
A propriedade motionSensitivity
de TransportTriggerOptionsStruct corresponde aos
seguintes valores:
| Marcador | Valor (UInt8) |
|---|---|
| Baixo | 1 |
| Médio | 5 |
| Alta | 10 |
Ajustar a duração máxima de eventos
A propriedade maxDuration
da TransportMotionTriggerTimeControlStruct
corresponde às seguintes durações de UInt32 (em segundos):
- 10, 15, 30, 60, 120, 180
Configurações da campainha
Várias configurações de campainha podem ser controladas pelas APIs Home.
Mudar o som da campainha
Para mudar o som da campainha, primeiro use o atributo installedChimeSounds do atributo ChimeTrait para ver a lista de sons instalados no dispositivo:
doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
return chimeSound.chimeID, chimeSound.name
}
Em seguida, atualize o atributo
selectedChime
da característica ChimeTrait usando a função integrada
setSelectedChime:
func setDoorbellChime(chimeID: UInt8) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setSelectedChime(chimeID)
}
} catch {
// Error
}
}
Usar uma campainha externa
Implementado no app de exemplo para iOS
A campainha pode ser configurada para usar um sino externo, como um sino mecânico instalado dentro da casa. Isso deve ser configurado durante a instalação da campainha para evitar possíveis danos ao sino externo.
Para indicar o tipo de campainha externa instalada, use
ExternalChimeType
para atualizar o atributo
externalChime
da característica ChimeTrait usando a função integrada
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
}
}
Mudar a duração da campainha externa
A duração, em segundos, do toque de uma campainha externa pode ser configurada pelas APIs Home. Se o sino externo for compatível com uma duração de toque, o usuário poderá configurar isso.
O valor definido aqui depende das especificações da campainha externa e da duração recomendada para ela.
Para mudar a duração do sino externo, atualize o atributo
externalChimeDurationSeconds
da característica ChimeTrait usando a função integrada
setExternalChimeDurationSeconds:
// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
do {
_ = try await doorbellChimeTrait.update {
$0.setExternalChimeDuration(value)
}
} catch {
// Error
}
}
Ativar um tema de sino
Implementado no app de exemplo para iOS
Algumas campainhas podem ter sinos que ficam disponíveis para os usuários por um tempo limitado. Por exemplo, sons específicos para datas comemorativas. Eles são chamados de temas de campainha.
Para ver quais temas de campainha estão disponíveis para um usuário, crie um filtro de período
e use-o para filtrar os resultados do comando
getAvailableThemes
do atributo
ChimeThemes. Isso retorna uma lista de temas disponíveis, incluindo os nomes deles.
O exemplo a seguir mostra como filtrar a lista.
Um tema é considerado ativo se o horário atual estiver entre os horários de início e término (os valores startTimeSeconds e endTimeSeconds, respectivamente). Se um horário de início não for definido, ele será considerado ativo desde o
início dos tempos. Se um horário de término não for definido, ele vai continuar ativo
indefinidamente. Se ambos estiverem ausentes, o tema estará sempre ativo.
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)
}
}
}
Depois de encontrar o nome do tema que você quer, como Christmas, selecione-o usando a função setSelectedTimeboxedThemeName() no atributo ChimeThemes ChimeThemes.
private func setChimeTheme(to value: String) async throws {
_ = try await chimeThemeTrait.update {
$0.setSelectedTimeboxedThemeName(value)
}
}
Configurações de avisos sobre visitas
É possível consultar e gerenciar as configurações de aviso sobre visitas para campainhas usando
o atributo
VisitorAnnouncement
das APIs Home. Esse atributo controla se a presença de um visitante é anunciada em alto-falantes ou telas inteligentes do Google quando alguém toca a campainha.
O exemplo a seguir mostra como verificar se os avisos sobre visitas estão ativados e como atualizar essa configuração:
let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled let value: Bool _ = try await self.visitorAnnouncementTrait?.update { $0.setVisitorAnnouncementsEnabled(value) }
Desativar um dispositivo
Para remover uma campainha de uma estrutura, chame
device.decommission(). A desativação mostra ao usuário uma
tela de confirmação gerenciada pelo Google avisando que todo o histórico de vídeo
24 horas, o histórico de eventos, os clipes e os dados da biblioteca de rostos conhecidos serão
excluídos permanentemente de toda a estrutura.
Para instruções detalhadas e exemplos de código, consulte Remover um dispositivo.