Kamera-Geräteanleitung für iOS

Der Gerätetyp „Kamera“ wird mit zwei Traits implementiert: PushAvStreamTransportTrait, das den Transport von Audio- und Videostreams über Push-basierte Protokolle übernimmt, und WebRtcLiveViewTrait, das die Steuerung von Livestreams und Gegensprechen ermöglicht.

Prüfen Sie immer, ob ein Gerät Attribute und Befehle unterstützt, bevor Sie Funktionen verwenden oder versuchen, Attribute zu aktualisieren. Weitere Informationen finden Sie unter Geräte aufiOS steuern.

Gerätetyp für Home-APIs Merkmale Swift-Beispiel-App Anwendungsfall

Kamera

GoogleCameraDeviceType

home.matter.6006.types.0158

Ein Gerät, mit dem Standbilder oder Videos aufgenommen werden. Kameras können zugängliche Livestreams, Zweiwege-Audio oder Erkennungsereignisse bieten.

Erforderliche Attribute
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

Kamera

Grundlegende Informationen zu einem Gerät abrufen

Das Attribut BasicInformation enthält Informationen wie den Namen des Anbieters, die Anbieter-ID, die Produkt-ID, den Produktnamen (einschließlich Modellinformationen) und die Softwareversion für ein Gerät:

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

Seriennummer abrufen

Verwenden Sie den Befehl GetSerialNumber des Traits ExtendedBasicInformation, um die Seriennummer des Geräts abzurufen. Im Beispiel wird die Seriennummer in einer Variablen mit dem Namen serialNumber gespeichert:

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

Letzten Zeitpunkt des Cloud-Kontakts des Geräts abrufen

Verwende das Attribut lastContactTimestamp des Traits ExtendedGeneralDiagnostics, um den letzten Zeitpunkt zu ermitteln, zu dem das Gerät Kontakt mit der Cloud hatte:

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

Verbindung für ein Gerät prüfen

Die Verbindung für ein Gerät wird tatsächlich auf der Ebene des Gerätetyps geprüft, da einige Geräte mehrere Gerätetypen unterstützen. Der zurückgegebene Status ist eine Kombination der Verbindungsstatus für alle Merkmale auf diesem Gerät.

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

Der Status partiallyOnline kann bei gemischten Gerätetypen auftreten, wenn keine Internetverbindung besteht. Matter-Standardmerkmale sind aufgrund des lokalen Routings möglicherweise weiterhin online, cloudbasierte Merkmale jedoch nicht.

IP-Adresse des Geräts abrufen

Verwenden Sie das Attribut networkInterfaces des GeneralDiagnosticsTrait, um die IP-Adresse des Geräts zu ermitteln. Die Adressen werden als Data-Objekte zurückgegeben, die Sie mit dem Network-Framework in standardmäßige IPv4- oder IPv6-Strings formatieren können:

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
}

Livestream starten

Wenn Sie einen Livestream starten möchten, senden Sie den SDP-String (Session Description Protocol) an die Methode startLiveView(offerSdp:) des Traits WebRtcLiveViewTrait. Diese gibt drei Werte zurück:

  • Das SDP für die Sitzung.
  • Die Sitzungsdauer in Sekunden.
  • Die Sitzungs-ID, die zum Verlängern oder Beenden der Sitzung verwendet werden kann.
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
  }
}

Livestream verlängern

Livestreams haben eine voreingestellte Dauer, nach der sie ablaufen. Wenn Sie die Dauer eines aktiven Streams verlängern möchten, senden Sie eine Verlängerungsanfrage mit der Methode 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
  }
}

TalkBack starten und beenden

Rufen Sie die Methode startTalkback(mediaSessionId:optionalArgsProvider:) des Traits WebRtcLiveViewTrait auf, um TalkBack zu starten. Verwenden Sie stopTalkback(mediaSessionId:), um die Aufnahme zu beenden.

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

Aufzeichnungsfunktion aktivieren und deaktivieren

Um die Aufnahmefunktion der Kamera zu aktivieren, übergeben Sie TransportStatusEnum.Active an die Methode setTransportStatus(transportStatus:optionalArgsProvider:) des Traits PushAvStreamTransportTrait. Wenn Sie die Aufnahmefunktion deaktivieren möchten, übergeben Sie TransportStatusEnum.Inactive. Im folgenden Beispiel fassen wir diese Aufrufe in einem einzigen Aufruf zusammen, der ein Boolean verwendet, um die Aufnahmefunktion zu aktivieren oder zu deaktivieren:

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

Das Aktivieren oder Deaktivieren der Aufnahmefunktion der Kamera entspricht dem Ein- oder Ausschalten des Kameravideos. Wenn das Video einer Kamera aktiviert ist, wird es für Ereignisse und zugehörige Clips aufgezeichnet.

Wenn die Aufzeichnungsfunktion deaktiviert ist (das Kameravideo ist deaktiviert):

  • Die Kamera kann gemäß dem connectivityState des Gerätetyps weiterhin als online angezeigt werden.
  • Auf den Livestream kann nicht zugegriffen werden und die Kamera erkennt keine Cloud-Ereignisse.

Prüfen, ob die Aufnahmefunktion aktiviert ist

Wenn Sie feststellen möchten, ob die Aufnahmefunktion einer Kamera aktiviert ist, prüfen Sie, ob Verbindungen aktiv sind. Im folgenden Beispiel werden zwei Funktionen definiert, um dies zu tun:

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
}

Akkueinstellungen

Über die Home-APIs können verschiedene Akku-Einstellungen gesteuert werden.

Einstellung für die Akkunutzung festlegen

Mit der Einstellung für die Energiebilanz können Sie den Kompromiss zwischen Akkulaufzeit und Leistung für ein Gerät konfigurieren. Sie können verschiedene Akkuprofile erstellen, z. B. „Erweitert“, „Ausgewogen“ und „Leistung“, und zwischen ihnen wechseln.

Diese Funktion wird durch Aktualisieren des Attributs currentEnergyBalance des Traits EnergyPreference implementiert. Das Attribut akzeptiert einen Ganzzahlindex, der einem bestimmten Profil in der energyBalances-Liste des Geräts entspricht (z. B. 0 für EXTENDED, 1 für BALANCED und 2 für PERFORMANCE).

Ein null-Wert für currentEnergyBalance gibt an, dass das Gerät ein benutzerdefiniertes Profil verwendet. Dies ist ein schreibgeschützter Status.

Im Folgenden sehen Sie ein Beispiel für eine Struktur, die vom Attribut currentEnergyBalance verwendet wird, gefolgt vom tatsächlichen Code-Snippet, in dem das Attribut verwendet wird.

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

Automatischen Energiesparmodus aktivieren

Aktualisieren Sie das Attribut currentLowPowerModeSensitivity des Traits EnergyPreference, um diese Funktion zu konfigurieren. Für dieses Attribut wird ein Index verwendet, um eine Vertraulichkeitsstufe auszuwählen. Dabei steht 0 in der Regel für Disabled und 1 für Enabled oder Automatic.

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

Akkuladestatus abrufen

Verwende das Attribut batChargeState des Trait PowerSource, um den aktuellen Ladestatus des Geräts abzurufen (wird geladen, vollständig geladen oder wird nicht geladen).

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

Akkustand abrufen

Verwende das Attribut batChargeLevel des Traits PowerSource, um den aktuellen Akkustand abzurufen. Der Wert ist entweder OK, Warning (niedrig) oder 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"
}

Stromquelle

Verwende die Attribute BatPresent und wiredPresent des Traits PowerSource, um die Stromquelle des Geräts zu ermitteln.

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

Audioeinstellungen

Über die Home-APIs lassen sich verschiedene Audioeinstellungen steuern.

Mikrofon ein- und ausschalten

Aktualisieren Sie das Attribut microphoneMuted des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setMicrophoneMuted, um das Mikrofon des Geräts zu aktivieren oder zu deaktivieren:

// Turn the device's microphone on or off
func setMicrophone(on: Bool) async {
  do {
    _ = try await self.cameraAvStreamManagementTrait?.update {
      $0.setMicrophoneMuted(!on)
    }
  } catch {
    // Error
  }
}

Audioaufnahme ein- oder ausschalten

Wenn Sie die Audioaufnahme für das Gerät aktivieren oder deaktivieren möchten, aktualisieren Sie das Attribut recordingMicrophoneMuted des Traits CameraAvStreamManagementTrait mit der integrierten Funktion 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
  }
}

Lautsprecherlautstärke anpassen

Wenn Sie die Lautsprecherlautstärke für das Gerät anpassen möchten, aktualisieren Sie das Attribut speakerVolumeLevel des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setSpeakerVolumeLevel:

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

Einstellungen für Alarmbereiche

Das ZoneManagement-Merkmal bietet eine Schnittstelle zum Verwalten benutzerdefinierter interessanter Bereiche (Alarmbereiche) auf Kamera- und Türklingelgeräten. Mit diesen Zonen kann die Ereigniserkennung (z. B. Bewegung von Personen oder Fahrzeugen) auf bestimmte Bereiche im Sichtfeld des Geräts gefiltert werden.

Alarmbereiche werden vom Nutzer in einer Partneranwendung konfiguriert. Er kann Bereiche im Sichtfeld der Kamera markieren. Diese benutzerdefinierten Zonen werden dann in die Strukturen übersetzt, die von diesem Merkmal verwendet werden. Weitere Informationen zur Funktionsweise von Alarmbereichen findest du unter Alarmbereiche einrichten und verwenden.

Alarmbereiche werden in der Regel mit 2D-kartesischen Koordinaten definiert. Das Attribut stellt die TwoDCartesianVertexStruct für Eckpunkte und die TwoDCartesianZoneStruct für die Zonendefinition (Name, Eckpunkte, Farbe und Verwendung) bereit.

Alarmbereiche prüfen

Wenn Sie Alarmbereiche anzeigen möchten, prüfen Sie das Attribut zones des Traits ZoneManagement.

let zoneManagementTrait: Google.ZoneManagementTrait

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

Alarmbereich hinzufügen

Verwenden Sie zum Erstellen einer neuen Zone den Befehl createTwoDCartesianZone. Dieser Befehl verwendet ein TwoDCartesianZoneStruct, das den Namen, die Eckpunkte, die Farbe und die Verwendung der Zone definiert.

Im folgenden Beispiel wird eine Zone mit dem Namen „Front Porch“ (Veranda) mit vier Eckpunkten erstellt, die lachsfarben (#F439A0) ist und für die Bewegungserkennung verwendet wird.

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

Alarmbereich aktualisieren

Verwenden Sie den Befehl updateTwoDCartesianZone, um eine vorhandene Zone zu aktualisieren. Für diesen Befehl sind die zoneId und die aktualisierte TwoDCartesianZoneStruct erforderlich.

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

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

Alarmbereich löschen

Verwenden Sie zum Entfernen einer Zone den Befehl removeZone mit dem entsprechenden zoneId.

let zoneManagementTrait: Google.ZoneManagementTrait
let zoneID: UInt16

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

Trigger für Geräuschereignisse

Das Attribut AvStreamAnalysis bietet eine Schnittstelle zum Verwalten von Triggern für die Ereigniserkennung auf Kamera- und Türklingelgeräten. Während sichtbasierte Auslöser (z. B. Personen oder Fahrzeuge) zonenbezogen sein können, sind tonbezogene Auslöser in der Regel Konfigurationen auf Geräteebene.

Für die Geräuscherkennung mit dem EventTriggerTypeEnum sind die folgenden Triggertypen verfügbar:

Modus Enum-Wert Beschreibung
Ton Sound Allgemeine Geräuscherkennung.
Sprechende Person PersonTalking Erkennt Sprache.
Hundegebell DogBark Erkennt Hundegebell.
Zerbrechendes Glas GlassBreak Erkennt das Geräusch von zerbrechendem Glas.
Rauchalarm SmokeAlarm Erkennt Rauchmelder, die oft am T3-Signal (drei kurze Pieptöne gefolgt von einer Pause) zu erkennen sind.
Kohlenmonoxidalarm CoAlarm Erkennt Kohlenmonoxid-Alarme (CO-Alarme), die in der Regel am T4-Signal erkannt werden (vier kurze Signaltöne, gefolgt von einer Pause).

Status der Geräuscherkennung prüfen

Um dem Nutzer den aktuellen Zustand der Geräuscherkennung anzuzeigen, müssen Sie prüfen, was das Gerät unterstützt und was von der Gerätehardware aktiviert wird. Die beiden Attribute, die Sie prüfen sollten, sind:

In der iOS-Entwicklung greifen Sie in der Regel über das Gerät auf das AvStreamAnalysis-Merkmal zu, um diese Attribute zu lesen.

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

Aktivierte Trigger aktualisieren

Verwenden Sie den Befehl SetOrUpdateEventDetectionTriggers, der eine Liste von EventTriggerEnablement-Strukturen akzeptiert, um die Gruppe der aktivierten Trigger zu aktualisieren.

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

Aufnahmemodi

Das RecordingMode-Trait bietet eine Schnittstelle zum Verwalten des Verhaltens bei der Video- und Bildaufzeichnung auf Kamera- und Türklingelgeräten. Nutzer können zwischen der Videoaufzeichnung rund um die Uhr, dem ereignisbasierten Videoverlauf oder der vollständigen Deaktivierung der Aufzeichnung (nur Live-Ansicht) wählen.

Der Enum-Wert RecordingModeEnum definiert die verfügbaren Aufzeichnungsstrategien:

Modus Enum-Wert Beschreibung
Deaktiviert Disabled Die Aufzeichnung ist vollständig deaktiviert. Wird hauptsächlich von älteren Geräten verwendet.
CVR (Videoaufzeichnung rund um die Uhr) Cvr Videos werden rund um die Uhr aufgezeichnet. Abo erforderlich (z. B. Google Home Premium).
EBR (Event Based Recording, ereignisbasierter Videoverlauf) Ebr Die Aufzeichnung wird durch Ereignisse (Person, Bewegung) ausgelöst. Die Videolänge hängt von der Dauer des Events und dem Abo ab.
ETR (Event Triggered Recording, ereignisbasierte Aufzeichnung) Etr Kurze Vorschauaufnahmen (z. B. 10 Sekunden), die durch Ereignisse ausgelöst werden.
Live View LiveView Die Aufzeichnung ist deaktiviert, Nutzer können aber weiterhin auf den Livestream zugreifen.
Standbilder Images Bei Ereignissen werden Momentaufnahmen anstelle von Videos aufgezeichnet.

Aufnahmemodi prüfen

Die aktuelle Aufzeichnungskonfiguration wird in den Attributen des Traits RecordingMode angezeigt:

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

Aufnahmemodus ändern

Prüfen Sie vor dem Aktualisieren, ob der ausgewählte Index aus dem Attribut supportedRecordingModes im Attribut availableRecordingModes vorhanden ist.

Verwenden Sie die Funktion setSelectedRecordingMode, um den ausgewählten Modus zu aktualisieren. Übergeben Sie dazu den Index des ausgewählten Modus:

let recordingModeTrait: Google.RecordingModeTrait
let recordingModeID: UInt8

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

Weitere Einstellungen

Über die Home-APIs lassen sich verschiedene andere Einstellungen steuern.

Bildausrichtung ändern

Die Ausrichtung des Kamerabilds (Videos) kann gedreht werden. Das Video kann nur um 180 Grad gedreht werden.

Wenn Sie die Bildausrichtung der Kamera ändern möchten, aktualisieren Sie das Attribut imageRotation des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setImageRotation:

// Change the camera's image orientation
// Value must be 0 or 180
func setImageRotation(to value: UInt16) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setImageRotation(value)
    }
  } catch {
    // Error
  }
}

Nachtsichtmodus aktivieren oder deaktivieren

Wenn Sie die Nachtsicht für die Kamera aktivieren oder deaktivieren möchten, verwenden Sie TriStateAutoEnum, um das Attribut nightVision des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setNightVision zu aktualisieren:

// Turn night vision on or off
func setNightVision(
  to value: Google.CameraAvStreamManagementTrait.TriStateAutoEnum
) async {
  do {
    _ = try await cameraAvStreamManagementTrait.update {
      $0.setNightVision(value)
    }
  } catch {
    // Error
  }
}

Helligkeit der Status-LED ändern

Wenn Sie die Helligkeit der Status-LED ändern möchten, verwenden Sie ThreeLevelAutoEnum, um das Attribut statusLightBrightness des Traits CameraAvStreamManagementTrait mit der integrierten Funktion setStatusLightBrightness zu aktualisieren:

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

Kamera-Darstellungsbereich ändern

Die Kameraansicht entspricht der Funktion „Zoomen und zuschneiden“, die im Hilfeartikel zum Zoomen und Optimieren von Nest-Kameravideos beschrieben wird.

Der Viewport wird in einem ViewportStruct definiert, das vier Werte enthält, die als Koordinaten des Viewports verwendet werden. Die Koordinaten sind so definiert:

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

Die Werte für ViewportStruct hängen von der Benutzeroberfläche und der Kameraimplementierung einer App ab. Um den Viewport des Kameravideos festzulegen, müssen Sie das Attribut viewport des Traits CameraAvStreamManagementTrait mit einem ViewportStruct aktualisieren. Verwenden Sie dazu die integrierte Funktion 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 generieren

Für einige Einstellungen sind Änderungen an Eigenschaften in einem TransportOptionsStruct erforderlich, das dann an die Transportoptionen einer Streamingverbindung übergeben wird. In Swift muss diese Struktur generiert werden, bevor Eigenschaften aktualisiert werden.

Mit dieser Hilfsfunktion können Sie die Struktur für die Verwendung mit den folgenden Einstellungsänderungen generieren:

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
}

Analyse aktivieren oder deaktivieren

Jedes Gerät kann einzeln zustimmen, detaillierte Analysedaten an die Google Home-Cloud zu senden (siehe Cloud Monitoring for Home APIs).

Wenn Sie die Analyse für ein Gerät aktivieren möchten, legen Sie die Eigenschaft analyticsEnabled) des ExtendedGeneralDiagnosticsTrait auf true fest. Wenn Sie analyticsEnabled festlegen, wird automatisch eine weitere Property, logUploadEnabled, auf true gesetzt. Dadurch können die Analyselogdateien in die Google Home-Cloud hochgeladen werden.

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

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

Transport- und Aufnahmekonfigurationen

In diesem Abschnitt werden Einstellungen für die Streamingqualität der Kamera und die Ereignisauslösung behandelt. Diese Einstellungen werden über das Merkmal PushAvStreamTransport verwaltet.

Transporteinstellungen lesen

In diesem Abschnitt wird gezeigt, wie Sie die aktuelle Konfiguration eines Kamera- oder Türklingelgeräts abrufen. Es ruft das PushAvStreamTransport-Trait ab, sucht nach der für die Aufzeichnung verwendeten Verbindung und extrahiert dann die aktuellen Werte für Bandbreitenqualität, Empfindlichkeit für die Beendigung des Ruhemodus und maximale Ereignislänge.

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

Transporteinstellungen aktualisieren

In diesem Abschnitt wird beschrieben, wie Sie die Transporteinstellungen ändern. Dabei wird ein neues TransportOptionsStruct mit den neuen Werten erstellt und dann mit dem Befehl modifyPushTransport an das Gerät gesendet. Die aktualisierten Einstellungen werden auf die im vorherigen Schritt gefundene Aufzeichnungsverbindung angewendet.

Verwenden Sie den Befehl modifyPushTransport mit einem TransportOptionsStruct, um diese Einstellungen zu ändern.

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

Bandbreitenqualität ermitteln

Die Eigenschaft videoStreamId des TransportOptionsStruct entspricht einer bestimmten Videostreamkonfiguration.

Die unterstützten Videostreams finden Sie im Attribut allocatedVideoStreams, das eine Liste von VideoStreamStructs ist. aus dem CameraAvStreamManagement-Trait für das Gerät.

Empfindlichkeit für die Beendigung des Ruhemodus anpassen

Das Attribut motionSensitivity des TransportTriggerOptionsStruct entspricht den folgenden Werten:

Label Wert (UInt8)
Niedrig 1
Mittel 5
Hoch 10

Maximale Ereignisdauer anpassen

Die maxDuration-Property von TransportMotionTriggerTimeControlStruct entspricht den folgenden UInt32-Dauern (in Sekunden):

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