iOS 向けカメラ デバイス ガイド

カメラ デバイスタイプは、2 つのトレイトを使用して実装されます: PushAvStreamTransportTraitプッシュベースのプロトコルを使用して音声と動画のストリーム転送を処理します。 WebRtcLiveViewTraitライブ ストリームとトークバックを制御する機能を提供します。

機能を使用したり、属性を更新したりする前に、デバイスの属性とコマンドのサポートを必ず確認してください。詳しくは、でデバイスを制御する iOSをご覧ください。

Google Home の API デバイスタイプ トレイト Swift サンプルアプリ ユースケース

カメラ

GoogleCameraDeviceType

home.matter.6006.types.0158

静止画像や動画を撮影するデバイス。カメラには、アクセス可能なライブ ストリーム、双方向トークバック、アクティビティ検出などの機能があります。

必須トレイト
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

カメラ

デバイスに関する基本情報を取得する

BasicInformation トレイトには、ベンダー名、ベンダー ID、商品 ID、 商品名(モデル情報を含む)、ソフトウェア バージョン、 デバイスのシリアル番号などの情報が含まれます。

// [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!
let serialNumber = basicInfoTrait.attributes.serialNumber!
// [END get_device_information]

デバイスがクラウドに接続した最新の時刻を取得する

デバイスがクラウドに接続した最新の時刻を確認するには、 lastContactTimestamp 属性を ExtendedGeneralDiagnostics 使用します。

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

デバイスの接続を確認する

一部のデバイスは複数のデバイスタイプをサポートしているため、デバイスの接続は実際にはデバイスタイプ レベルで確認されます。返される状態は、そのデバイスのすべてのトレイトの接続状態の組み合わせです。

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

インターネットに接続されていない場合、デバイスタイプが混在していると partiallyOnline の状態になることがあります。Matter 標準 トレイトはローカル ルーティングによりオンラインのままですが、クラウドベースのトレイトは オフラインになります。

ライブ配信を開始する

ライブ配信を開始するには、セッション記述プロトコル(SDP)文字列を WebRtcLiveViewTrait トレイトの startLiveView(offerSdp:) メソッドに送信します。このメソッドは次の 3 つの値を返します。

  • セッションの SDP。
  • セッション継続時間(秒単位)。
  • セッション ID。セッションの延長または終了に使用できます。
public func sendOffer(offerSdp: String) async throws
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval)
{
  do {
    // Sending StartLiveView command
    let response = try await liveViewTrait.startLiveView(
      offerSdp: offerSdp
    )
    // Received StartLiveView response
    return (
      answerSdp: response.answerSdp,
      mediaSessionId: response.mediaSessionId,
      liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
    )
  } catch {
    // Failed to send StartLiveView command
    throw error
  }
}

ライブ配信を延長する

ライブストリームには、期限切れになるまでの事前設定された期間があります。アクティブなストリームの期間を延長するには、 メソッドを使用して延長リクエストを発行します。extendLiveView(mediaSessionId:optionalArgsProvider:)

public func extendLiveView(mediaSessionId: String) async throws {
  do {
    // Extending live view
    let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
  } catch {
    // Failed to extend live view
    throw error
  }
}

トークバックを開始 / 停止する

トークバックを開始するには、 WebRtcLiveViewTrait トレイトの startTalkback(mediaSessionId:optionalArgsProvider:) メソッドを呼び出します。 停止するには、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)")
  }
}

録画機能を有効または無効にする

カメラの録画機能を有効にするには、 TransportStatusEnum.ActivePushAvStreamTransportTrait トレイトの setTransportStatus(transportStatus:optionalArgsProvider:) メソッドに渡します。録画機能を無効にするには、 TransportStatusEnum.Inactive を渡します。 次の例では、これらの呼び出しを 1 つの呼び出しでラップし、Boolean を使用して録画機能を切り替えます。

public func toggleIsRecording(isOn: Bool) {
  self.uiState = .loading

  guard let pushAvStreamTransportTrait else {
    // PushAvStreamTransportTrait not found.
    return
  }
  Task {
    do {
      try await pushAvStreamTransportTrait.setTransportStatus(
        transportStatus: isOn ? .active : .inactive)
      if isOn {
        do {
          self.player = try self.createWebRtcPlayer()
        } catch {
          // Failed to initialize WebRtcPlayer
          self.uiState = .disconnected
          return
        }
        await self.player?.initialize()
        self.uiState = .live
      } else {
        self.player = nil
        self.uiState = .off
      }
    } catch {
      // Failed to toggle onOff
    }
  }
}

カメラの録画機能を有効または無効にすることは、カメラの動画をオンまたはオフにすることと同じです。カメラの動画がオンになっている場合、録画が行われます(アクティビティと関連クリップの場合)。

録画機能が無効になっている場合(カメラの動画がオフの場合):

録画機能が有効になっているかどうかを確認する

カメラの録画機能が有効になっているかどうかを確認するには、接続がアクティブかどうかを確認します。次の例では、これを行うための 2 つの関数を定義しています。

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
}

バッテリーの設定

さまざまなバッテリー設定は、Google Home の API で制御できます。

バッテリー使用量の優先度を設定する

エネルギー バランスを設定すると、デバイスのバッテリー寿命とパフォーマンスのトレードオフを構成できます。「拡張」、「バランス」、「パフォーマンス」など、さまざまなバッテリー プロファイルを作成して切り替えることができます。

この機能は、 currentEnergyBalance 属性 を更新することで、EnergyPreference トレイトに実装されます。この属性は、デバイスの energyBalances リストで定義された特定のプロファイルに対応する整数インデックスを受け取ります(例: EXTENDED の場合は 0BALANCED の場合は 1PERFORMANCE の場合は 2)。

currentEnergyBalance の値が null の場合、デバイスはカスタム プロファイルを使用しています。これは読み取り専用の状態です。

次は、currentEnergyBalance 属性が使用する構造の例と、その属性を使用する実際のコード スニペットを示しています。

// Example energyBalances list
{
  "energy_balances": [
    {
      "step": 0,
      "label": "EXTENDED"
    },
    {
      "step": 50,
      "label": "BALANCED"
    },
    {
      "step": 100,
      "label": "PERFORMANCE"
    }
  ]
}
private func setBatteryUsage(to option: UInt8) async throws {
  _ = try await energyPreferenceTrait.update {
    $0.setCurrentEnergyBalance(option)
  }
}

バッテリー セーバーを自動的にオンにする

この機能を構成するには、 currentLowPowerModeSensitivity 属性 の EnergyPreference トレイトを更新します。この属性はインデックスを使用して感度レベルを選択します。通常、0Disabled を表し、1Enabled または Automatic を表します。

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

バッテリーの充電状態を取得する

デバイスの現在の充電状態(充電中、フル充電、充電なし)を取得するには、 トレイトの batChargeState 属性を使用します。PowerSource

self.chargingState = powerSourceTrait.attributes.batChargeState

var description: String
switch self.chargingState {
case .isCharging:
  description = "Charging"
case .isAtFullCharge:
  description = "Full"
case .isNotCharging:
  description = "Not Charging"
default:
  description = "Unknown"
}

バッテリー残量を取得する

現在のバッテリー残量を取得するには、 batChargeLevel 属性の PowerSource トレイトを使用します。レベルは OKWarning(低)、Critical のいずれかです。

self.batteryLevel = powerSourceTrait.attributes.batChargeLevel

var description: String
switch self.batteryLevel {
case .ok:
  description = "OK"
case .warning:
  description = "Warning"
case .critical:
  description = "Critical"
default:
  description = "Unknown"
}

電源を取得する

デバイスが使用している電源を確認するには、 BatPresent 属性と wiredPresent 属性を PowerSource トレイトで使用します。

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

音声設定

さまざまな音声設定は、Google Home の API で制御できます。

マイクのオンとオフを切り替える

デバイスのマイクのオンとオフを切り替えるには、組み込みの setMicrophoneMuted 関数を使用して、CameraAvStreamManagementTrait トレイトの microphoneMuted 属性を更新します。

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

音声録音のオンとオフを切り替える

デバイスの音声録音のオンとオフを切り替えるには、組み込みの setRecordingMicrophoneMuted 関数を使用して、CameraAvStreamManagementTrait トレイトの recordingMicrophoneMuted 属性を更新します。

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

スピーカーの音量を調整する

デバイスのスピーカーの音量を調整するには、組み込みの setSpeakerVolumeLevel 関数を使用して、CameraAvStreamManagementTrait トレイトの speakerVolumeLevel 属性を更新します。

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

アクティビティ エリアの設定

ZoneManagement トレイトは、カメラとドアホン デバイスのカスタム関心領域(アクティビティ エリア)を管理するためのインターフェースを提供します。これらのゾーンは、デバイスの画角内の特定のエリアに対するイベント検出(人物や車両の動きなど)をフィルタするために使用されます。

アクティビティ エリアは、パートナー アプリケーション内でユーザーが構成します。これにより、カメラの画角内の特定のエリアにエリアを描画できます。ユーザー定義のエリアは、このトレイトで使用される構造に変換されます。 アクティビティ エリアの仕組みについて詳しくは、 アクティビティ エリアを設定して使用するをご覧ください。

アクティビティ エリアは通常、2D デカルト座標を使用して定義されます。 このトレイトは、頂点に TwoDCartesianVertexStruct、ゾーン定義(名前、頂点、色、使用状況)に TwoDCartesianZoneStruct を提供します。

アクティビティ エリアを確認する

アクティビティ エリアを表示するには、 zones トレイトの ZoneManagement属性を確認します。

let zoneManagementTrait: Google.ZoneManagementTrait

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

アクティビティ エリアを追加する

新しいゾーンを作成するには、 createTwoDCartesianZone コマンドを使用します。このコマンドは、TwoDCartesianZoneStruct、 エリアの名前、頂点、色、使用状況を定義するを受け取ります。

次の例では、4 つの頂点を持つ「Front Porch」という名前のエリアを作成し、サーモン色(#F439A0)で、モーション検知に使用します。

import GoogleHomeSDK
import GoogleHomeTypes

func createFrontPorchZone(trait: Google.ZoneManagementTrait) async {
  // 1. Define the vertices for the zone (2D Cartesian coordinates)
  // Values are UInt16, typically scaled to the device's twoDCartesianMax.
  let vertices = [
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 260, y = 422),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1049, y = 0),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048, y = 0),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 2048, y = 950),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 1630, y = 1349),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 880, y = 2048),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 0, y = 2048),
    Google.ZoneManagementTrait.TwoDCartesianVertexStruct(x = 638, y = 1090)
  ]

  // 2. Define the zone structure using the given SDK struct
  let newZone = Google.ZoneManagementTrait.TwoDCartesianZoneStruct(
    name: "Front Porch",
    use: [.motion], // ZoneUseEnum.motion
    vertices: vertices,
    // Color is a hex string (for example, Salmon/Pink)
    color: "#F439A0"
  )

  do {
    // 3. Execute the raw command to add the zone to the device
    // This returns the created zone's ID (UInt16).
    var newZoneID = try await trait.createTwoDCartesianZone(zone: newZone)
  } catch {
    // Error
  }
}

アクティビティ エリアを更新する

既存のゾーンを更新するには、 updateTwoDCartesianZone コマンドを使用します。このコマンドには、zoneId と更新された TwoDCartesianZoneStructが必要です。

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

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

アクティビティ エリアを削除する

ゾーンを削除するには、特定の zoneId を指定して removeZone コマンドを使用します。

let zoneManagementTrait: Google.ZoneManagementTrait
let zoneID: UInt16

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

サウンド アクティビティ トリガー

AvStreamAnalysis トレイトは、カメラとドアホン デバイスのアクティビティ検出トリガーを管理するためのインターフェースを提供します。ビジョンベースのトリガー(人物や車両など)はエリア固有にできますが、サウンド関連のトリガーは通常、デバイスレベルの構成です。

EventTriggerTypeEnum を使用すると、サウンド検知に次のトリガータイプを使用できます。

モード 列挙値 説明
サウンド Sound 一般的なサウンド検知。
話し声 PersonTalking 音声を検出します。
犬の鳴き声 DogBark 犬の鳴き声を検出します。
ガラスの割れる音 GlassBreak ガラスの割れる音を検出します。
煙警報 SmokeAlarm 煙警報を検出します。多くの場合、T3 可聴 パターン(短いビープ音 3 回の後に一時停止)で認識されます。
一酸化炭素警報 CoAlarm 一酸化炭素(CO)警報を検出します。通常、T4 可聴パターン(短いビープ音 4 回の後に一時停止)で認識されます。

サウンド検知のステータスを確認する

サウンド検知の現在の状態をユーザーに表示するには、デバイスがサポートしている機能と、デバイス ハードウェアで有効になっている機能を確認する必要があります。確認する属性は次の 2 つです。

iOS 開発では通常、デバイスから AvStreamAnalysis トレイトにアクセスしてこれらの属性を読み取ります。

// Example struct to store event triggers
public struct EventTrigger: Equatable {
  public var id: Google.AvStreamAnalysisTrait.EventTriggerTypeEnum
  public var enabled: Bool
}

let avStreamAnalysisTrait: Google.AvStreamAnalysisTrait

let possibleEventTriggers = avStreamAnalysisTrait.attributes.supportedEventTriggers ?? []
let enabledEventTriggers = avStreamAnalysisTrait.attributes.enabledEventTriggers ?? []

let eventTriggers [EventTrigger] = []
for trigger in possibleEventTriggers {
  self.eventTriggers.append(
    EventTrigger(
      id: trigger,
      enabled: enabledEventTriggers.contains(trigger)
    )
  )
}

有効なトリガーのセットを更新する

有効なトリガーのセットを更新するには、 SetOrUpdateEventDetectionTriggers コマンドを使用します。このコマンドは、EventTriggerEnablement 構造のリストを受け取ります。

// Example struct to store event triggers
public struct EventTrigger: Equatable {
  public var id: Google.AvStreamAnalysisTrait.EventTriggerTypeEnum
  public var enabled: Bool
}

let avStreamAnalysisTrait: Google.AvStreamAnalysisTrait
let eventTriggers: [EventTrigger]

let enabledEventTriggers = eventTriggers.map {
  Google.AvStreamAnalysisTrait.EventTriggerEnablement(
    eventTriggerType: $0.id,
    enablementStatus: $0.enabled ? .enabled : .disabled
  )
}

try await avStreamAnalysisTrait.setOrUpdateEventDetectionTriggers(
  eventTriggerEnablements: enabledEventTriggers
)

録画モード

RecordingMode トレイトは、カメラとドアホン デバイスの動画と画像の録画動作を管理するためのインターフェースを提供します。ユーザーは、連続録画、アクティビティ検出時の録画、録画の完全無効化(ライブビューのみ)を選択できます。

RecordingModeEnum は、使用可能な録画方法を定義します。

モード 列挙値 説明
無効 Disabled 録画は完全に無効になっています。主にレガシー デバイスで使用されます。
CVR (連続録画) Cvr 動画は 24 時間 365 日録画されます。定期購入が必要です (例: Google Home Premium)。
EBR (アクティビティ検出時の録画) Ebr アクティビティ(人物、動き)によって録画がトリガーされます。 動画の長さは、アクティビティの長さと定期購入によって異なります。
ETR (アクティビティ トリガー録画) Etr アクティビティによってトリガーされる短いプレビュー録画(10 秒など) 。
ライブビュー LiveView 録画は無効になっていますが、ユーザーはライブ配信にアクセスできます。
静止画像 Images アクティビティが発生すると、動画ではなくスナップショットが録画されます。

録画モードを確認する

現在の録画構成を表示するには、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,
      )
    )
  }
}

録画モードを変更する

更新する前に、supportedRecordingModes 属性から選択したインデックスが availableRecordingModes 属性に存在することを確認してください。

選択したモードを更新するには、選択したモードのインデックスを渡して setSelectedRecordingMode 関数を使用します。

let recordingModeTrait: Google.RecordingModeTrait
let recordingModeID: UInt8

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

その他の設定

さまざまなその他の設定は、Google Home の API で制御できます。

画像の向きを変更する

カメラ画像(動画)の向きを回転させることができます。動画は 180 度しか回転できません。

カメラの画像の向きを変更するには、組み込みの setImageRotation 関数を使用して、CameraAvStreamManagementTrait トレイトの imageRotation 属性を更新します。

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

ナイトビジョン機能をオンまたはオフにする

カメラのナイトビジョン機能をオンまたはオフにするには、TriStateAutoEnum を使用して、 nightVision 属性をCameraAvStreamManagementTrait トレイトの組み込みの setNightVision 関数を使用して更新します。

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

ステータス LED の明るさを変更する

ステータス LED の明るさを変更するには、 ThreeLevelAutoEnum を使用して、組み込みの setStatusLightBrightness 関数を使用して、CameraAvStreamManagementTrait トレイトの statusLightBrightness 属性を更新します。

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

カメラのビューポートを変更する

カメラのビューポートは、Google Nest カメラの動画でズーム機能や補正機能を使用するサポート記事で説明されているズームとトリミングの機能と同じです。

ビューポートは、ビューポートの座標として使用される 4 つの値を含む ViewportStruct で定義されます。座標は次のように定義されます。

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

ViewportStruct の値を決定するには、アプリの UI とカメラの実装によって異なります。基本的なレベルでは、カメラの 動画のビューポートを設定するには、 viewport トレイトの CameraAvStreamManagementTrait 属性を ViewportStruct で更新します。 組み込みの setViewport 関数を使用します。

func setCrop(x1: UInt16, y1: UInt16, x2: UInt16, y2: UInt16) {

  let viewport = Google.CameraAvStreamManagementTrait.ViewportStruct(
    x1: x1,
    y1: y1,
    x2: x2,
    y2: y2
  )

  Task {
    do {
      try await cameraAvStreamManagementTrait.update {
        $0.setViewport(viewport)
      }
    } catch {
      // Error
    }
  }

}

TransportOptionsStruct を生成する

一部の設定では、TransportOptionsStruct のプロパティを変更する必要があります。このプロパティは、ストリーミング接続のトランスポート オプションに渡されます。Swift の場合、プロパティを更新する前にこの構造体を生成する必要があります。

次の設定変更で使用する構造体を生成するには、次のヘルパー関数を使用します。

func getTransportOptions(
  transportOptions: Google.PushAvStreamTransportTrait.TransportOptionsStruct,
  wakeUpSensitivity: UInt8?,
  maxEventLength: UInt32?
) async throws
  -> Google.PushAvStreamTransportTrait.TransportOptionsStruct
{

  var newMotionTimeControl:
    Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct? = nil
  if let maxEventLength {
    guard let motionTimeControl = transportOptions.triggerOptions.motionTimeControl else {
      throw HomeError.failedPrecondition(
        // Error - cannot update max event length without motion time control
    }
    newMotionTimeControl =
      Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct(
        initialDuration: motionTimeControl.initialDuration,
        augmentationDuration: motionTimeControl.augmentationDuration,
        maxDuration: maxEventLength,
        blindDuration: motionTimeControl.blindDuration
      )
  }

  return Google.PushAvStreamTransportTrait.TransportOptionsStruct(
    streamUsage: .recording,
    videoStreamID: nil,
    audioStreamID: nil,
    tlsEndpointID: transportOptions.tlsEndpointID,
    url: transportOptions.url,
    triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct(
      triggerType: .motion,
      motionZones: nil,
      motionSensitivity: wakeUpSensitivity,
      motionTimeControl: newMotionTimeControl,
      maxPreRollLen: nil
    ),
    ingestMethod: .cmafIngest,
    containerOptions: Google.PushAvStreamTransportTrait.ContainerOptionsStruct(
      containerType: .cmaf,
      cmafContainerOptions: nil
    ),
    expiryTime: nil
  )
}

private func getRecordingConnection() async throws
  -> Google.PushAvStreamTransportTrait.TransportConfigurationStruct?
{
  guard let pushAvStreamTransportTrait else {
    // Error - PushAvStreamTransport trait not available
    return nil
  }

  let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations

  for connection in connections {
    guard let transportOptions = connection.transportOptions,
      transportOptions.streamUsage == .recording
    else {
      continue
    }

    return connection
  }

  return nil
}

デバイスの復帰感度を調整する

デバイスの復帰感度は、デバイスがアクティビティを検知できる範囲を狭め、アクティビティを検出してから復帰するまでの時間を長くすることで、バッテリーを節約するために使用されます。

Google Home の API では、デバイスの transportOptionstriggerOptionsmotionSensitivity プロパティを使用して設定できます。これらのオプションは、デバイスごとに PushAvStreamTransportTrait トレイト内で定義されます。

復帰感度は、次の値にのみ設定できます。

  • 1 = 低
  • 5 = 中
  • 10 = 高

更新プロセスでは、アクティブな 録画ストリームのトランスポート構成を findTransport コマンドを使用して見つけ、 modifyPushTransport コマンドを使用して新しい感度値で構成を変更します。

modifyPushTransport コマンドでは、完全な TransportOptionsStruct を渡す必要があるため、まず現在の構成から既存の値をコピーする必要があります。これを行うための ヘルパー関数については、を生成するTransportOptionsStructをご覧ください。

func setWakeUpSensitivity(to value: UInt8) async {
  do {
    let connection = try await getRecordingConnection()
    guard let connection,
      let transportOptions = connection.transportOptions
    else {
      // Error - Transport options not available
      return
    }

    guard transportOptions.triggerOptions.motionSensitivity != nil else {
      // Error - Motion sensitivity not available to be updated for this device
      return
    }

    try await pushAvStreamTransportTrait.modifyPushTransport(
      connectionID: connection.connectionID,
      transportOptions: self.getTransportOptions(
        transportOptions: transportOptions,
        wakeUpSensitivity: value,
        maxEventLength: nil
      )
    )

  } catch {
    // Error
  }
}

最長アクティビティ時間を調整する

最長アクティビティ時間は、カメラがアクティビティのクリップを録画する時間の長さです。Google Home の API では、 と同じ長さで、秒単位でデバイスごとに構成できます。Google Home app (GHA)

  • 10 秒
  • 15 秒
  • 30 秒
  • 60 秒(1 分)
  • 120 秒(2 分)
  • 180 秒(3 分)

Google Home の API では、デバイスの transportOptionstriggerOptionsmotionTimeControl プロパティを使用して設定できます。これらのオプションは、デバイスごとに PushAvStreamTransportTrait トレイト内で定義されます。

更新プロセスでは、アクティブな 録画ストリームのトランスポート構成を findTransport コマンドを使用して見つけ、新しいアクティビティ時間の値で構成を modifyPushTransport コマンドを使用して変更します。

modifyPushTransport コマンドでは、完全な TransportOptionsStruct を渡す必要があるため、まず現在の構成から既存の値をコピーする必要があります。これを行うための ヘルパー関数については、を生成するTransportOptionsStructをご覧ください。

func setMaxEventLength(to value: UInt32) async {
  do {
    let connection = try await getRecordingConnection()
    guard let connection,
      let transportOptions = connection.transportOptions
    else {
      // Error - Transport options not available
      return
    }

    guard transportOptions.triggerOptions.motionTimeControl != nil else {
      // Error - Motion time control not available to be updated for this device
      return
    }

    try await pushAvStreamTransportTrait.modifyPushTransport(
      connectionID: connection.connectionID,
      transportOptions: self.getTransportOptions(
        transportOptions: transportOptions,
        wakeUpSensitivity: nil,
        maxEventLength: value
      )
    )

  } catch {
    // Error
  }
}

分析を有効または無効にする

各デバイスは、詳細な分析データを Google Home クラウドに送信することを個別にオプトインできます(Google Home の API の Cloud Monitoring をご覧ください)。

デバイスの分析を有効にするには、 analyticsEnabled) の ExtendedGeneralDiagnosticsTraittrue に設定します。analyticsEnabled を設定すると、別のプロパティ logUploadEnabled が自動的に true に設定され、分析ログファイルを Google Home クラウドにアップロードできるようになります。

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

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