Przewodnik po dzwonku do drzwi na iOS

Typ urządzenia dzwonek jest implementowany za pomocą 3 atrybutów: PushAvStreamTransportTrait, który obsługuje transport strumienia audio i wideo za pomocą protokołów push, WebRtcLiveViewTrait, który umożliwia sterowanie transmisjami na żywo i funkcją TalkBack, oraz CameraSnapshotTrait, który zapewnia podgląd zrzutów ekranu z pamięci podręcznej i zrzuty ekranu na żywo.

Przed użyciem jakichkolwiek funkcji lub próbą aktualizacji atrybutów zawsze sprawdź, czy urządzenie obsługuje dany atrybut i polecenie. Więcej informacji znajdziesz w artykule Sterowanie urządzeniami naiOS.

Typ urządzenia w interfejsach API Google Home Cechy Przykładowa aplikacja Swift Przypadek użycia

Dzwonek

GoogleDoorbellDeviceType

home.matter.6006.types.0113

Urządzenie uruchamiane przyciskiem na zewnątrz drzwi, które emituje sygnał dźwiękowy lub wizualny, służące do zwrócenia uwagi osoby znajdującej się po drugiej stronie drzwi. Dzwonki mogą oferować dostęp do transmisji na żywo, dwukierunkowej komunikacji lub wykrywania zdarzeń.

Wymagane cechy
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

Dzwonek

Uzyskiwanie podstawowych informacji o urządzeniu

   Zaimplementowano w przykładowej aplikacji na iOS   

Atrybut BasicInformation zawiera informacje takie jak nazwa dostawcy, identyfikator dostawcy, identyfikator produktu, nazwa produktu (w tym informacje o modelu) i wersja oprogramowania urządzenia:

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!

Uzyskiwanie numeru seryjnego

   Zaimplementowano w przykładowej aplikacji na iOS   

Aby uzyskać numer seryjny urządzenia, użyj polecenia GetSerialNumber cechy ExtendedBasicInformation. W przykładzie pokazano zapisywanie numeru seryjnego w zmiennej o nazwie serialNumber:

// Assuming extendedBasicInformationTrait: Google.ExtendedBasicInformationTrait
let response = try await extendedBasicInformationTrait.getSerialNumber()
let serialNumber = response.serialNumber

szybkie odpowiedzi.

Funkcja szybkich odpowiedzi umożliwia użytkownikowi wysłanie wstępnie zdefiniowanej wiadomości do dzwonka.

Ta funkcja jest dostępna tylko na dzwonkach. Lista wstępnie zdefiniowanych wiadomości jest dostępna dla aplikacji partnera, która może je wyświetlić użytkownikowi, aby mógł wybrać jedną z nich. Wiadomości wstępnie zdefiniowanych nie można edytować.

Szybkie odpowiedzi są implementowane za pomocą cechy PresetMessage.

Odtwarzanie gotowej wiadomości

Aby odtworzyć gotową wiadomość, wywołaj metodę playPresetMessage, przekazując jej jedną z wartości ciągu znaków we właściwości 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)")
    }
}

Ustawianie języka wypowiedzi

Ustawianie języka wypowiedzi

Ustaw aktywny język mówiony urządzenia na określone ustawienia regionalne (np. „pl_PL”) za pomocą metody setActiveLocale cechy LocalizationConfiguration.

// Setting the active language
// Assuming localizationConfigurationTrait: Matter.LocalizationConfigurationTrait
let selectedLocale = "en_US"
try await localizationConfigurationTrait.update {
    $0.setActiveLocale(selectedLocale)
}

Pobieranie czasu ostatniego kontaktu urządzenia z chmurą

Aby znaleźć ostatni moment, w którym urządzenie miało kontakt z chmurą, użyj atrybutu lastContactTimestamp cechy ExtendedGeneralDiagnostics:

if let lastContactTimeStamp = extendedGeneralDiagnosticsTrait.attributes.lastContactTimestamp {
  self.lastContactTime = Date(timeIntervalSince1970: Double(lastConnectedTimeStamp))
}

Ustawienia typu mocowania kamery

Atrybut Mount zawiera ustawienia uchwytu kamery i informacje o jego stanie. Możesz odczytywać atrybuty, takie jak stan podłączenia, typ wykrywania i nazwa typu podłączenia. Możesz też użyć cechy Mount, aby zastąpić domyślną konfigurację typu montażu.

// 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)
}

Sprawdzanie połączenia urządzenia

Połączenie urządzenia jest sprawdzane na poziomie typu urządzenia, ponieważ niektóre urządzenia obsługują wiele typów urządzeń. Zwracany stan jest kombinacją stanów połączenia wszystkich cech na tym urządzeniu.

let doorbellConnectivity = doorbellDeviceType.metadata.sourceConnectivity.connectivityState

W przypadku różnych typów urządzeń, gdy nie ma połączenia z internetem, może być widoczny stan partiallyOnline. Niektóre standardowe cechy Matter mogą nadal być dostępne online dzięki lokalnemu routingowi, ale cechy działające w chmurze będą offline.

Uzyskiwanie adresu IP urządzenia

Aby znaleźć adres IP urządzenia, użyj atrybutu networkInterfaces zasobu GeneralDiagnosticsTrait. Adresy są zwracane jako obiekty Data, które można sformatować jako standardowe ciągi IPv4 lub IPv6 za pomocą platformy 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
}

Rozpoczynanie transmisji na żywo

   Zaimplementowano w przykładowej aplikacji na iOS   

Aby rozpocząć transmisję na żywo, wyślij ciąg protokołu opisu sesji (SDP) do metody startLiveView(offerSdp:) cechy WebRtcLiveViewTrait, która zwraca 3 wartości:

  • SDP sesji.
  • Czas trwania sesji w sekundach.
  • Identyfikator sesji, który może służyć do przedłużenia lub zakończenia sesji.
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
  }
}

Przedłużanie transmisji na żywo

   Zaimplementowano w przykładowej aplikacji na iOS   

Transmisje na żywo mają wstępnie ustawiony czas trwania, po którym wygasają. Aby wydłużyć czas trwania aktywnej transmisji, wyślij prośbę o rozszerzenie za pomocą metody 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
  }
}

Włączanie i wyłączanie TalkBack

   Zaimplementowano w przykładowej aplikacji na iOS   

Aby rozpocząć rozmowę, wywołaj metodę startTalkback(mediaSessionId:optionalArgsProvider:) cechy WebRtcLiveViewTrait. Aby zatrzymać, użyj 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)")
  }
}

Zarządzanie transmisją na żywo

   Zaimplementowano w przykładowej aplikacji na iOS   

Dostosowanie jakości transmisji na żywo jest przydatne do optymalizacji wykorzystania przepustowości na podstawie kontekstu wyświetlania klienta (np. przełączenie na niższą rozdzielczość podczas wyświetlania mniejszego kafelka podglądu, widoku siatki lub trybu obrazu w obrazie).

Dynamiczna zmiana jakości za pomocą cechy WebRtcLiveView pozwala zarządzać rozdzielczością aktywnej sesji transmisji na żywo na konkretnym kliencie. Nie jest to to samo co skonfigurowanie ustawienia wykorzystania przepustowości na całym urządzeniu bezpośrednio na urządzeniu, co wpłynęłoby na wszystkich jednoczesnych widzów i jakość historycznych nagrań wideo zapisanych w chmurze.

Poniższy przykład pokazuje, jak pobrać i zaktualizować jakość transmisji na żywo na urządzeniu:

  • Pobieranie obsługiwanych opcji jakości: pobierz dostępne rozdzielczości strumieniowania obsługiwane przez urządzenie. Kod wysyła zapytanie do cechy WebRtcLiveView, aby udostępnić obsługiwane jakości strumienia jako listę wartości QualityHint (takich jak .sd, .hd, .fhd, .qhd lub .uhd) za pomocą właściwości supportedQualityHints.

  • Zmień jakość transmisji na żywo: zastosuj wybraną wartość QualityHint, aby zmienić rozdzielczość aktywnej transmisji na żywo (np. przełączyć ze standardowej rozdzielczości na wysoką rozdzielczość). Funkcja updateQualityHint używa metody changeLiveViewQuality cechy WebRtcLiveView, aby zastosować wybraną konfigurację QualityHint do aktywnej sesji multimedialnej.

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
  }
}

Włączanie i wyłączanie funkcji nagrywania

Aby włączyć funkcję nagrywania, przekaż TransportStatusEnum.Active do metody setTransportStatus(transportStatus:optionalArgsProvider:) cechy PushAvStreamTransportTrait. Aby wyłączyć możliwość nagrywania, przekaż wartość TransportStatusEnum.Inactive. W przykładzie poniżej opakowujemy te wywołania w jedno wywołanie, które używa Boolean do przełączania funkcji nagrywania:

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
    }
  }
}

Włączenie lub wyłączenie funkcji nagrywania przez kamerę jest równoznaczne z włączeniem lub wyłączeniem nagrywania przez nią filmów. Gdy nagrywanie przez kamerę jest włączone, kamera nagrywa (na potrzeby zdarzeń i powiązanych klipów).

Gdy funkcja nagrywania jest wyłączona (obraz z kamery jest wyłączony):

  • Kamera może nadal wyświetlać się jako online zgodnie z connectivityState typu urządzenia.
  • Nie można uzyskać dostępu do transmisji na żywo, a kamera nie wykrywa żadnych zdarzeń w chmurze.

Sprawdzanie, czy funkcja nagrywania jest włączona

Aby sprawdzić, czy funkcja nagrywania jest włączona, sprawdź, czy są aktywne jakieś połączenia. W poniższym przykładzie zdefiniowano 2 funkcje, które to robią:

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
}

Pobieranie zrzutów z kamery

   Zaimplementowano w przykładowej aplikacji na iOS   

Użyj cechy CameraSnapshot, aby pobierać statyczne migawki z kamery. Te zrzuty są przydatne w kilku sytuacjach:

  • jako kafelek zastępczy w interfejsie podczas wczytywania transmisji na żywo WebRTC.
  • jako statyczny obraz podglądu, który po interakcji użytkownika zmienia się w transmisję na żywo;
  • jako tło do rysowania i konfigurowania niestandardowych miejsc aktywności;

Cecha CameraSnapshot umożliwia pobieranie zdjęć na 2 sposoby, w zależności od tego, czy potrzebujesz zdjęcia z pamięci podręcznej do szybkiego renderowania, czy zdjęcia na żywo na żądanie.

Pobieranie podglądu z pamięci podręcznej

Zrzut podglądu to obraz z pamięci podręcznej, który pakiet SDK może pobrać bez wybudzania kamery. Jest to najszybsza metoda pobierania obrazu statycznego, która idealnie nadaje się do stron przeglądu kamer lub siatek panelu.

Aby uzyskać podgląd, odczytaj atrybut cechy 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
}

W zależności od konfiguracji i aktywności kamery adres URL podglądu wskazuje obraz z pamięci podręcznej wygenerowany na podstawie ostatniego nagrania wideo (pierwsza klatka kluczowa ostatniego fragmentu filmu) lub zrzut okresowo przesyłany przez kamerę.

Aby wskazać aktualność obrazu, chmura Google Home umieszcza w serwowanym obrazie JPEG/PNG nagłówek X-Home-Image-Captured-At w formacie UTC. Możesz przeanalizować ten nagłówek po stronie klienta, aby wyświetlić wiek migawki w aplikacji.

Pobieranie zrzutu na żywo na żądanie

W przypadku ścieżek użytkownika, które wymagają bieżącego podglądu na żywo z kamery (np. konfigurowania miejsc aktywności), możesz poprosić o migawkę na żywo. Uruchomienie podglądu na żywo powoduje wybudzenie kamery, przechwycenie nowej klatki i przesłanie jej do chmury.

Aby poprosić o zrzut na żywo, użyj polecenia 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)")
}

Uwierzytelnianie żądań zrzutów

   Zaimplementowano w przykładowej aplikacji na iOS   

Wszystkie adresy URL zdjęć wskazują bezpieczne multimedia i wymagają tokena OAuth 2.0 dla zakresu interfejsów Home API w wersji 2. Aby pobrać i wyrenderować obrazy, token OAuth musi zostać wstawiony jako token okaziciela w nagłówku Authorization żądania HTTP.

Poniższy przykład pokazuje, jak skonfigurować bezpieczne żądanie sieciowe, aby pobrać zrzut:

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
  }
}

Ustawienia baterii

Za pomocą interfejsów Home API można sterować różnymi ustawieniami baterii.

Ustawianie preferencji dotyczących wykorzystania baterii

Ustawienie balansu energii pozwala skonfigurować kompromis między czasem pracy na baterii a wydajnością urządzenia. Możesz utworzyć różne profile baterii, takie jak „Wydłużony”, „Zrównoważony” i „Wydajność”, i przełączać się między nimi.

Tę funkcję implementuje się przez zaktualizowanie atrybutu currentEnergyBalance cechy EnergyPreference. Atrybut akceptuje indeks liczby całkowitej, który odpowiada konkretnemu profilowi zdefiniowanemu na liście energyBalances urządzenia (np. 0 dla EXTENDED, 1 dla BALANCED i 2 dla PERFORMANCE).

Wartość null dla currentEnergyBalance oznacza, że urządzenie używa profilu niestandardowego. To jest stan tylko do odczytu.

Poniżej znajdziesz przykład struktury, której będzie używać atrybut currentEnergyBalance, a następnie rzeczywisty fragment kodu, który używa tego atrybutu.

// 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)
  }
}

Włączanie automatycznego oszczędzania baterii

   Zaimplementowano w przykładowej aplikacji na iOS   

Aby skonfigurować tę funkcję, zaktualizuj atrybut currentLowPowerModeSensitivity cechy EnergyPreference. Ten atrybut używa indeksu do wyboru poziomu czułości, gdzie 0 zwykle reprezentuje Disabled, a 1 reprezentuje Enabled lub Automatic.

private func setAutoBatterySaver(to value: Bool) async throws {
  _ = try await energyPreferenceTrait.update {
    $0.setCurrentLowPowerModeSensitivity(value ? 1 : 0)
  }
}

Sprawdzanie stanu ładowania baterii

   Zaimplementowano w przykładowej aplikacji na iOS   

Aby sprawdzić bieżący stan ładowania urządzenia (ładowanie, pełne naładowanie lub brak ładowania), użyj atrybutu batChargeState cechy 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"
}

Sprawdzanie poziomu baterii

Aby sprawdzić bieżący poziom baterii, użyj atrybutu batChargeLevel cechy PowerSource. Poziom może być OK, Warning (niski) lub 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"
}

Pobieranie źródła zasilania

Aby określić źródło zasilania, którego używa urządzenie, użyj atrybutów BatPresent i wiredPresent cechy PowerSource.

if powerSourceTrait.attributes.wiredPresent ?? false {
  self.powerSourceType = .wired
} else if powerSourceTrait.attributes.batPresent ?? false {
  self.powerSourceType = .battery
} else {
  self.powerSourceType = nil
}

Sprawdzanie, czy bateria wymaga wymiany

Atrybut batReplaceability wskazuje, czy bateria jest niewymienna, wymienna przez użytkownika czy wymienna przez producenta.

Jeśli bateria jest wymienna, atrybut batReplacementNeeded cechy PowerSource informuje, czy należy ją wymienić.

// Get the battery replacement status
var batteryStatus = powerSourceTrait.attributes.batReplacementNeeded

if batteryStatus {
  print("Replace the battery.")
}

Jeśli bateria może być wymieniana przez użytkownika, batReplacementDescription opisuje ją, podając informacje takie jak format, skład chemiczny i preferowany producent.

Ustawienia dźwięku

Za pomocą interfejsów Home API można sterować różnymi ustawieniami dźwięku.

Włączanie i wyłączanie mikrofonu

Aby włączyć lub wyłączyć mikrofon urządzenia, zaktualizuj atrybut microphoneMuted cechy CameraAvStreamManagementTrait, używając wbudowanej funkcji 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
  }
}

Włączanie i wyłączanie nagrywania dźwięku

Aby włączyć lub wyłączyć nagrywanie dźwięku na urządzeniu, zaktualizuj atrybut recordingMicrophoneMuted cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji 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
  }
}

Regulowanie głośności głośnika

Aby dostosować głośność głośnika urządzenia, zaktualizuj atrybut speakerVolumeLevel cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji setSpeakerVolumeLevel:

// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setSpeakerVolumeLevel(value)
    }
  } catch {
    // Error
  }
}

Ustawienia strefy aktywności

   Zaimplementowano w przykładowej aplikacji na iOS   

Atrybut ZoneManagement udostępnia interfejs do zarządzania niestandardowymi obszarami zainteresowania (miejscami aktywności) na kamerach i dzwonkach. Te strefy służą do filtrowania wykrywania zdarzeń (takich jak ruch osoby lub pojazdu) w określonych obszarach w polu widzenia urządzenia.

Miejsca aktywności są konfigurowane przez użytkownika w aplikacji partnera, co pozwala mu na rysowanie stref nad określonymi obszarami w polu widzenia kamery. Te zdefiniowane przez użytkownika strefy są następnie przekształcane w struktury używane przez tę cechę. Więcej informacji o tym, jak działają miejsca aktywności, znajdziesz w artykule Konfigurowanie i używanie miejsc aktywności.

Miejsca aktywności są zwykle definiowane za pomocą współrzędnych kartezjańskich 2D. Atrybut udostępnia TwoDCartesianVertexStruct dla wierzchołków i TwoDCartesianZoneStruct dla definicji strefy (nazwa, wierzchołki, kolor i użycie).

Sprawdzanie miejsc aktywności

Aby wyświetlić miejsca aktywności, sprawdź atrybut zones cechy ZoneManagement.

let zoneManagementTrait: Google.ZoneManagementTrait

self.zones = zoneManagementTrait.attributes.zones ?? []

Dodawanie strefy aktywności

Aby utworzyć nową strefę, użyj polecenia createTwoDCartesianZone. To polecenie przyjmuje parametr TwoDCartesianZoneStruct, który określa nazwę, wierzchołki, kolor i zastosowanie strefy.

Poniższy przykład pokazuje, jak utworzyć strefę o nazwie „Ganek” z 4 wierzchołkami, w kolorze łososiowym (#F439A0), która będzie używana do wykrywania ruchu.

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
  }
}

Aktualizowanie strefy aktywności

Aby zaktualizować istniejącą strefę, użyj polecenia updateTwoDCartesianZone. To polecenie wymaga zoneId i zaktualizowanego TwoDCartesianZoneStruct.

let zoneManagementTrait: Google.ZoneManagementTrait
let zoneID: UInt16
let zone: Google.ZoneManagementTrait.TwoDCartesianZoneStruct

do {
  _ = try await zoneManagementTrait.updateTwoDCartesianZone(
        zoneID: zoneID, zone: zone)
} catch {
  // Error
}

Usuwanie miejsc aktywności

Aby usunąć strefę, użyj polecenia removeZone z określonym zoneId.

let zoneManagementTrait: Google.ZoneManagementTrait
let zoneID: UInt16

do {
  _ = try await zoneManagementTrait.removeZone(zoneID: zoneID)
} catch {
  // Error
}

Aktywatory wykrycia dźwięku

Cecha AvStreamAnalysis udostępnia interfejs do zarządzania aktywatorami wykrywania zdarzeń na kamerach i wideodomofonach. Wyzwalacze oparte na obrazie (np. osoby lub pojazdy) mogą być przypisane do konkretnej strefy, natomiast wyzwalacze związane z dźwiękiem są zwykle konfigurowane na poziomie urządzenia.

W przypadku wykrywania dźwięku za pomocą EventTriggerTypeEnum dostępne są te typy aktywatorów:

Tryb Wartość typu wyliczeniowego Opis
Dźwięk Sound Ogólne wykrywanie dźwięku.
Ktoś coś mówi PersonTalking Wykrywa mowę.
szczekanie psa, DogBark Wykrywa odgłosy psów.
Odgłos tłuczonego szkła GlassBreak Wykrywa odgłos tłuczonego szkła.
Alarm z czujnika dymu SmokeAlarm Wykrywa alarmy z czujnika dymu, często rozpoznawane po wzorcu dźwiękowym T3 (3 krótkie sygnały dźwiękowe, po których następuje przerwa).
alarm z czujnika tlenku węgla CoAlarm Wykrywa alarmy tlenku węgla (CO), zwykle rozpoznawane po wzorcu dźwiękowym T4 (4 krótkie sygnały dźwiękowe, po których następuje przerwa).

Sprawdzanie stanu wykrywania dźwięku

Aby wyświetlić użytkownikowi bieżący stan wykrywania dźwięku, musisz sprawdzić, co obsługuje urządzenie i co jest włączone przez sprzęt urządzenia. Te 2 atrybuty to:

W przypadku programowania na iOS zwykle uzyskuje się dostęp do cechy AvStreamAnalysis z urządzenia, aby odczytać te atrybuty.

// 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)
    )
  )
}

Zaktualizuj zestaw włączonych reguł.

Aby zaktualizować zestaw włączonych aktywatorów, użyj polecenia SetOrUpdateEventDetectionTriggers, które przyjmuje listę struktur 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
)

Tryby nagrywania

   Zaimplementowano w przykładowej aplikacji na iOS   

Atrybut RecordingMode udostępnia interfejs do zarządzania nagrywaniem filmów i robieniem zdjęć na kamerach i dzwonkach. Umożliwia użytkownikom wybór między nagrywaniem ciągłym, nagrywaniem zdarzeń lub całkowitym wyłączeniem nagrywania (tylko podgląd na żywo).

RecordingModeEnum definiuje dostępne strategie nagrywania:

Tryb Wartość typu wyliczeniowego Opis
Wyłączono Disabled Nagrywanie jest całkowicie wyłączone. Używany głównie przez starsze urządzenia.
CVR (nagrywanie ciągłe) Cvr Filmy są nagrywane przez całą dobę. Wymaga subskrypcji (np. Google Home Premium.
Nagrywanie zdarzeń Ebr Nagrywanie jest aktywowane przez zdarzenia (osoba, ruch). Długość wideo zależy od czasu trwania zdarzenia i subskrypcji.
ETR (Event Triggered Recording) Etr Krótkie nagranie podglądu (np. 10 sekund) wywoływane przez zdarzenia.
Live View LiveView Nagrywanie jest wyłączone, ale użytkownicy nadal mogą uzyskać dostęp do transmisji na żywo.
Grafika Images W przypadku wystąpienia zdarzeń zamiast filmów są rejestrowane zdjęcia.

Sprawdzanie trybów nagrywania

Aby wyświetlić bieżącą konfigurację nagrywania, sprawdź atrybuty cechy RecordingMode:

// 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,
      )
    )
  }
}

Zmiana trybu nagrywania

Przed aktualizacją upewnij się, że indeks wybrany z atrybutu supportedRecordingModes jest obecny w atrybucie availableRecordingModes.

Aby zaktualizować wybrany tryb, użyj funkcji setSelectedRecordingMode, przekazując indeks wybranego trybu:

let recordingModeTrait: Google.RecordingModeTrait
let recordingModeID: UInt8

_ = try await recordingModeTrait.update {
  $0.setSelectedRecordingMode(recordingModeID)
}

Inne ustawienia

Za pomocą interfejsów Home API można kontrolować różne inne ustawienia.

Włączanie i wyłączanie trybu nocnego

Aby włączyć lub wyłączyć tryb nocny kamery, użyj TriStateAutoEnum, aby zaktualizować atrybut nightVision cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji 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
  }
}

Zmienianie jasności diody LED stanu

Aby zmienić jasność diody LED stanu, użyj ThreeLevelAutoEnum, aby zaktualizować atrybut statusLightBrightness cechy CameraAvStreamManagementTrait za pomocą wbudowanej funkcji setStatusLightBrightness:

// Set the LED brightness
func setStatusLightBrightness(
  to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setStatusLightBrightness(value)
    }
  } catch {
    // Error
  }
}

Zmiana widoku z kamery

Okno kamery jest takie samo jak w przypadku funkcji powiększania i przycinania opisanej w artykule pomocy Powiększanie i ulepszanie nagrań z kamery Nest.

Okno jest zdefiniowane w elemencie ViewportStruct, który zawiera 4 wartości używane jako współrzędne okna. Współrzędne są zdefiniowane w ten sposób:

(x1,y1) -- (x2,y1)
   |          |
(x1,y2) -- (x2,y2)

Określenie wartości ViewportStruct zależy od interfejsu aplikacji i implementacji aparatu. Aby ustawić obszar wyświetlania obrazu z kamery, zaktualizuj atrybut viewport cechy CameraAvStreamManagementTrait za pomocą ViewportStruct, używając wbudowanej funkcji 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
    }
  }

}

Wygeneruj TransportOptionsStruct

Niektóre ustawienia wymagają modyfikacji właściwości w obiekcie TransportOptionsStruct, który jest następnie przekazywany do opcji transportu połączenia strumieniowego. W przypadku Swift tę strukturę należy wygenerować przed zaktualizowaniem właściwości.

Użyj tej funkcji pomocniczej, aby wygenerować strukturę do użycia z tymi zmianami ustawień:

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
}

Włączanie i wyłączanie statystyk

Każde urządzenie może indywidualnie wyrazić zgodę na wysyłanie szczegółowych danych analitycznych do chmury Google Home (patrz Cloud Monitoring dla interfejsów API Home).

Aby włączyć statystyki na urządzeniu, ustaw właściwość analyticsEnabled) obiektu ExtendedGeneralDiagnosticsTrait na true. Gdy ustawisz analyticsEnabled, inna właściwość, logUploadEnabled, zostanie automatycznie ustawiona na true, co umożliwi przesyłanie plików dziennika statystyk do chmury Google Home.

// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
  $0.setAnalyticsEnabled(true)
}

// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
  $0.setAnalyticsEnabled(false)
}

Konfiguracje transportu i nagrywania

Ta sekcja zawiera ustawienia związane z jakością strumienia z kamery i wyzwalaniem zdarzeń. Tymi ustawieniami zarządza cecha PushAvStreamTransport.

Odczytywanie ustawień transportu

W tej sekcji dowiesz się, jak pobrać bieżącą konfigurację z kamery lub dzwonka. Pobiera cechę PushAvStreamTransport, znajduje konkretne połączenie używane do nagrywania, a następnie wyodrębnia bieżące wartości jakości przepustowości, czułości wybudzania i maksymalnej długości zdarzenia.

// 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

Aktualizowanie ustawień transportu

W tej sekcji dowiesz się, jak zmienić ustawienia transportu. Tworzy nowy obiekt TransportOptionsStruct zawierający nowe wartości, a następnie używa polecenia modifyPushTransport, aby odesłać te zaktualizowane ustawienia do urządzenia i zastosować je do połączenia nagrywania znalezionego w poprzednim kroku.

Aby zmodyfikować te ustawienia, użyj polecenia modifyPushTransport z 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
)

Określanie jakości przepustowości

Właściwość videoStreamId obiektu TransportOptionsStruct odpowiada konkretnej konfiguracji strumienia wideo.

Aby uzyskać obsługiwane strumienie wideo, zapoznaj się z atrybutem allocatedVideoStreams, który jest listą VideoStreamStructs. z cechy CameraAvStreamManagement urządzenia.

Dostosowywanie czułości wybudzania urządzenia

Właściwość motionSensitivity obiektu TransportTriggerOptionsStruct odpowiada tym wartościom:

Etykieta Wartość (UInt8)
Niski 1
Średni 5
Wysoka 10

Dostosowywanie maksymalnej długości wydarzenia

Właściwość maxDuration elementu TransportMotionTriggerTimeControlStruct odpowiada tym czasom trwania UInt32 (w sekundach):

  • 10, 15, 30, 60, 120, 180

Ustawienia dzwonka

Za pomocą interfejsów Home API można sterować różnymi ustawieniami dzwonka.

Zmiana dźwięku dzwonka

Aby zmienić dźwięk dzwonka, najpierw pobierz listę dźwięków dzwonka zainstalowanych na urządzeniu, używając atrybutu installedChimeSounds cechy ChimeTrait:

doorbellChimeTrait.attributes.installedChimeSounds?.compactMap { chimeSound in
  return chimeSound.chimeID, chimeSound.name
}

Następnie zaktualizuj atrybut selectedChime cechy ChimeTrait za pomocą wbudowanej funkcji setSelectedChime:

func setDoorbellChime(chimeID: UInt8) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setSelectedChime(chimeID)
    }
  } catch {
    // Error
  }
}

Używanie zewnętrznego dzwonka

   Zaimplementowano w przykładowej aplikacji na iOS   

Dzwonek można skonfigurować tak, aby używał zewnętrznego dzwonka, np. mechanicznego dzwonka zainstalowanego w domu. Należy to skonfigurować podczas instalacji dzwonka, aby uniknąć potencjalnego uszkodzenia dzwonka zewnętrznego.

Aby wskazać, jaki typ dzwonka zewnętrznego jest zainstalowany, użyj ExternalChimeType, aby zaktualizować atrybut externalChime cechy ChimeTrait za pomocą wbudowanej funkcji 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
  }
}

Zmienianie czasu trwania dzwonka zewnętrznego

Czas trwania dzwonka zewnętrznego w sekundach można skonfigurować za pomocą interfejsów Home API. Jeśli dzwonek zewnętrzny obsługuje czas trwania dzwonka, użytkownik może chcieć go skonfigurować.

Ustawiona tu wartość zależy od specyfikacji dzwonka zewnętrznego i zalecanego czasu trwania dzwonka.

Aby zmienić czas trwania dzwonka zewnętrznego, zaktualizuj atrybut externalChimeDurationSeconds cechy ChimeTrait, używając wbudowanej funkcji setExternalChimeDurationSeconds:

// Change the external chime duration
func setExternalChimeDuration(to value: UInt16) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setExternalChimeDuration(value)
    }
  } catch {
    // Error
  }
}

Włączanie motywu dzwonka

   Zaimplementowano w przykładowej aplikacji na iOS   

Niektóre dzwonki mogą mieć dzwonki, które są dostępne dla użytkowników tylko przez ograniczony czas. Na przykład dzwonki związane ze świętami. Są to tzw. motywy dzwonka.

Aby sprawdzić, które motywy dzwonka są dostępne dla użytkownika, utwórz filtr przedziału czasu i użyj go do filtrowania wyników polecenia getAvailableThemes z cechy ChimeThemes. Spowoduje to wyświetlenie listy dostępnych motywów wraz z ich nazwami.

Poniższy przykład pokazuje, jak filtrować listę. Motyw jest uznawany za aktywny, jeśli bieżący czas mieści się w jego godzinach rozpoczęcia i zakończenia (odpowiednio wartości startTimeSeconds i endTimeSeconds). Jeśli nie ustawisz czasu rozpoczęcia, będzie on uznawany za aktywny od początku czasu. Jeśli nie ustawisz godziny zakończenia, będzie ona aktywna przez cały czas. Jeśli brakuje obu tych elementów, motyw jest zawsze aktywny.

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 &lt;= currentDateTime
      &amp;&amp; chimeTheme.endTimeSeconds ?? UInt64.max &gt;= currentDateTime
    {
      self.chimeThemeSettings.append(chimeTheme.name)
    }
  }
}

Gdy poznasz nazwę motywu, którego chcesz użyć, np. Christmas, możesz go wybrać za pomocą funkcji setSelectedTimeboxedThemeName() w cesze ChimeThemes ChimeThemes.

private func setChimeTheme(to value: String) async throws {
  _ = try await chimeThemeTrait.update {
    $0.setSelectedTimeboxedThemeName(value)
  }
}

Ustawienia komunikatów o gościach

Możesz sprawdzać ustawienia komunikatów o gościach dla dzwonków i nimi zarządzać za pomocą cechy VisitorAnnouncement interfejsów Home API. Ta cecha określa, czy obecność gościa jest ogłaszana na inteligentnych głośnikach lub wyświetlaczach Google, gdy ktoś dzwoni do drzwi.

Poniższy przykład pokazuje, jak sprawdzić, czy komunikaty o gościach są włączone, i jak zaktualizować to ustawienie:

let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled

let value: Bool
_ = try await self.visitorAnnouncementTrait?.update {
  $0.setVisitorAnnouncementsEnabled(value)
}

Wycofywanie urządzenia

Aby usunąć dzwonek z domu, wywołaj funkcję device.decommission(). Wycofanie powoduje wyświetlenie użytkownikowi zarządzanego przez Google ekranu potwierdzenia z ostrzeżeniem, że cała historia całodobowych nagrań wideo, historia zdarzeń, klipy i dane z biblioteki znajomych twarzy zostaną trwale usunięte z całej struktury.

Szczegółowe instrukcje i przykłady kodu znajdziesz w artykule Usuwanie urządzenia.