iOS용 초인종 기기 가이드

초인종 기기 유형은 푸시 기반 프로토콜을 사용하여 오디오 및 동영상 스트림 전송을 처리하는 PushAvStreamTransportTrait과 라이브 스트림 및 인터콤을 제어하는 기능을 제공하는 WebRtcLiveViewTrait의 두 가지 특성을 사용하여 구현됩니다.

기능을 사용하거나 속성을 업데이트하려고 시도하기 전에 항상 기기의 속성 및 명령어 지원을 확인하세요. 자세한 내용은 iOS에서 기기 제어를 참고하세요.

Home API 기기 유형 특성 Swift 샘플 앱 사용 사례

초인종

GoogleDoorbellDeviceType

home.matter.6006.types.0113

문 밖에 있는 버튼으로 작동하며, 문 반대편에 있는 사람의 주의를 끌기 위해 사용되는 청각 및/또는 시각 신호를 내는 장치입니다. 초인종에는 접근 가능한 라이브 스트림, 양방향 TalkBack 또는 감지 활동이 포함될 수 있습니다.

필수 특성
     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]

기기 클라우드 연락의 가장 최근 시간 가져오기

기기가 클라우드와 마지막으로 통신한 시간을 찾으려면 ExtendedGeneralDiagnostics 특성의 lastContactTimestamp 속성을 사용하세요.

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

기기의 연결 확인

일부 기기는 여러 기기 유형을 지원하므로 기기의 연결은 실제로 기기 유형 수준에서 확인됩니다. 반환된 상태는 해당 기기의 모든 특성의 연결 상태를 조합한 것입니다.

let lightConnectivity =
  dimmableLightDeviceType.metadata.sourceConnectivity
  .connectivityState

인터넷 연결이 없는 경우 혼합 기기 유형에서 partiallyOnline 상태가 관찰될 수 있습니다. Matter 표준 특성은 로컬 라우팅으로 인해 온라인 상태일 수 있지만 클라우드 기반 특성은 오프라인 상태가 됩니다.

라이브 스트림 시작

라이브 스트림을 시작하려면 세션 설명 프로토콜 (SDP) 문자열을 WebRtcLiveViewTrait 특성의 startLiveView(offerSdp:) 메서드에 전송합니다. 이 메서드는 다음 세 값을 반환합니다.

  • 세션의 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
  }
}

TalkBack 시작 및 중지

토크백을 시작하려면 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을 전달합니다. 다음 예에서는 Boolean를 사용하여 녹화 기능을 전환하는 단일 호출로 이러한 호출을 래핑합니다.

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

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

카메라의 녹화 기능을 사용 설정하거나 사용 중지하는 것은 카메라 동영상을 켜거나 끄는 것과 같습니다. 카메라 동영상이 켜져 있으면 활동 및 관련 클립을 위해 녹화됩니다.

녹화 기능이 사용 중지된 경우 (카메라 동영상이 꺼져 있음):

  • 카메라가 기기 유형의 connectivityState에 따라 온라인으로 표시될 수 있습니다.
  • 실시간 스트림에 액세스할 수 없으며 카메라에서 클라우드 활동을 감지하지도 않습니다.

녹화 기능이 사용 설정되어 있는지 확인

카메라의 녹화 기능이 사용 설정되어 있는지 확인하려면 연결이 활성 상태인지 확인하세요. 다음 예에서는 이를 수행하는 두 함수를 정의합니다.

public func isDeviceRecording() -> Bool {
  guard let pushAvStreamTransportTrait else {
    // PushAvStreamTransportTrait not found.
    return false
  }
  guard
    let hasActiveConnection =
      pushAvStreamTransportTrait
      .attributes
      .currentConnections?
      .contains(where: { $0.transportStatus == .active })
  else {
    return false
  }
  return hasActiveConnection
}

배터리 설정

Home API를 통해 다양한 배터리 설정을 제어할 수 있습니다.

배터리 사용량 환경설정 설정

에너지 균형을 설정하면 기기의 배터리 수명과 성능 간의 절충을 구성할 수 있습니다. '확장', '균형', '성능'과 같은 다양한 배터리 프로필을 만들고 프로필 간에 전환할 수 있습니다.

이 기능은 EnergyPreference 특성의 currentEnergyBalance 속성을 업데이트하여 구현됩니다. 이 속성은 기기의 energyBalances 목록에 정의된 특정 프로필에 해당하는 정수 색인을 허용합니다 (예: EXTENDED의 경우 0, BALANCED의 경우 1, PERFORMANCE의 경우 2).

currentEnergyBalancenull 값은 기기에서 맞춤 프로필을 사용하고 있음을 나타냅니다. 읽기 전용 상태입니다.

다음은 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)
  }
}

자동 절전 모드 사용 설정하기

이 기능을 구성하려면 EnergyPreference 특성의 currentLowPowerModeSensitivity 속성을 업데이트하세요. 이 속성은 색인을 사용하여 민감도 수준을 선택합니다. 여기서 0은 일반적으로 Disabled을 나타내고 1Enabled 또는 Automatic을 나타냅니다.

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

배터리 충전 상태 가져오기

기기의 현재 충전 상태 (충전 중, 완전 충전, 충전 안 함)를 가져오려면 PowerSource 특성의 batChargeState 속성을 사용하세요.

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

배터리 잔량 가져오기

현재 배터리 잔량을 가져오려면 PowerSource 특성의 batChargeLevel 속성을 사용합니다. 수준은 OK, Warning (낮음) 또는 Critical입니다.

self.batteryLevel = powerSourceTrait.attributes.batChargeLevel

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

전원 가져오기

기기에서 사용하는 전원 소스를 확인하려면 PowerSource 특성의 BatPresentwiredPresent 속성을 사용합니다.

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

오디오 설정

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을 제공합니다.

활동 감지 구역 확인

활동 감지 구역을 표시하려면 ZoneManagement 특성의 zones 속성을 확인하세요.

let zoneManagementTrait: Google.ZoneManagementTrait

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

활동 감지 구역 추가

새 영역을 만들려면 createTwoDCartesianZone 명령어를 사용합니다. 이 명령어는 영역의 이름, 꼭짓점, 색상, 사용을 정의하는 TwoDCartesianZoneStruct를 사용합니다.

다음 예에서는 4개의 꼭짓점이 있고, 색상이 연어색 (#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을 사용한 소리 감지에는 다음 트리거 유형을 사용할 수 있습니다.

모드 enum 값 설명
소리 Sound 일반적인 소리 감지입니다.
말소리 PersonTalking 음성을 감지합니다.
개 짖는 소리 DogBark 개 소리를 감지합니다.
유리 깨지는 소리 GlassBreak 유리 깨지는 소리를 감지합니다.
연기 경보 SmokeAlarm 연기 경보를 감지합니다. T3 청각 패턴 (짧은 경고음 3회 후 일시중지)으로 인식되는 경우가 많습니다.
일산화탄소 경보 CoAlarm 일반적으로 T4 청각 패턴 (짧은 경고음 4회 후 일시중지)으로 인식되는 일산화탄소 (CO) 경보를 감지합니다.

소리 감지 상태 확인

사용자에게 소리 감지의 현재 상태를 표시하려면 기기에서 지원하는 기능과 기기 하드웨어에서 사용 설정된 기능을 확인해야 합니다. 확인할 두 가지 속성은 다음과 같습니다.

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

사용 설정된 트리거 집합 업데이트

사용 설정된 트리거 집합을 업데이트하려면 EventTriggerEnablement 구조 목록을 사용하는 SetOrUpdateEventDetectionTriggers 명령어를 사용합니다.

// 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은 사용 가능한 녹화 전략을 정의합니다.

모드 enum 값 설명
사용 중지됨 Disabled 녹화가 완전히 사용 중지됩니다. 주로 기존 기기에서 사용됩니다.
CVR (연속 동영상 녹화) Cvr 동영상은 연중무휴로 녹화됩니다. 구독이 필요합니다(예: Google 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)
}

기타 설정

Home API를 통해 다양한 기타 설정을 제어할 수 있습니다.

야간 적외선 조명 사용 또는 사용 중지하기

카메라의 야간 모드를 사용 설정 또는 사용 중지하려면 TriStateAutoEnum를 사용하여 내장 setNightVision 함수를 통해 CameraAvStreamManagementTrait 특성의 nightVision 속성을 업데이트합니다.

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

카메라 표시 영역 변경

카메라 뷰포트는 Nest 카메라 동영상 확대/축소 및 개선 지원 도움말에 설명된 확대/축소 및 자르기 기능과 동일합니다.

뷰포트는 뷰포트의 좌표로 사용되는 네 개의 값이 포함된 ViewportStruct에 정의됩니다. 좌표는 다음과 같이 정의됩니다.

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

ViewportStruct 값을 결정하는 것은 앱의 UI와 카메라 구현에 따라 다릅니다. 매우 기본적인 수준에서 카메라 동영상의 뷰포트를 설정하려면 내장 setViewport 함수를 사용하여 ViewportStructCameraAvStreamManagementTrait 특성의 viewport 속성을 업데이트합니다.

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
}

기기 절전 해제 민감도 조정

기기의 절전 모드 해제 감도는 기기가 활동을 감지할 수 있는 범위를 줄이고 활동을 감지한 후 절전 모드를 해제하는 시간을 늘려 배터리를 절약하는 데 사용됩니다.

Home API에서 이는 기기의 transportOptions에 있는 triggerOptionsmotionSensitivity 속성을 사용하여 설정할 수 있습니다. 이러한 옵션은 각 기기의 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
  }
}

최대 이벤트 길이 조정

최대 활동 길이는 카메라가 활동의 클립을 녹화하는 시간입니다. Home API를 통해 기기별로 Google Home app (GHA)를 통해 설정하는 것과 동일한 길이로 초 단위 간격으로 구성할 수 있습니다.

  • 10초
  • 15초
  • 30초
  • 60초(1분)
  • 120초(2분)
  • 180초 (3분)

Home API에서 이는 기기의 transportOptions에 있는 triggerOptionsmotionTimeControl 속성을 사용하여 설정할 수 있습니다. 이러한 옵션은 각 기기의 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 클라우드로 전송하도록 개별적으로 선택할 수 있습니다 (Home API용 클라우드 모니터링 참고).

기기의 분석을 사용 설정하려면 ExtendedGeneralDiagnosticsTraitanalyticsEnabled 속성을 true로 설정합니다. analyticsEnabled를 설정하면 분석 로그 파일을 Google Home 클라우드에 업로드할 수 있는 다른 속성인 logUploadEnabled이 자동으로 true로 설정됩니다.

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

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

차임벨 설정

Home API를 통해 다양한 초인종 차임벨 설정을 제어할 수 있습니다.

차임벨 소리 변경

초인종 차임벨 소리를 변경하려면 먼저 ChimeTrait 특성의 installedChimeSounds 속성을 사용하여 기기에 설치된 차임벨 소리 목록을 가져옵니다.

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

그런 다음 기본 제공 setSelectedChime 함수를 사용하여 ChimeTrait 특성의 selectedChime 속성을 업데이트합니다.

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

외부 차임벨 사용

초인종은 집 내부에 설치된 기계식 벨과 같은 외부 차임벨을 사용하도록 구성할 수 있습니다. 외부 차임벨의 손상을 방지하려면 초인종 설치 중에 이를 구성해야 합니다.

설치된 외부 차임벨의 유형을 나타내려면 ExternalChimeType를 사용하여 내장 setExternalChime 함수를 사용하여 ChimeTrait 특성의 externalChime 속성을 업데이트합니다.

// Indicate the external chime is mechanical
func setExternalChime(to value: Google.ChimeTrait.ExternalChimeType) async {
  do {
    _ = try await doorbellChimeTrait.update {
      $0.setExternalChime(value)
    }
  } catch {
    // Error
  }
}

외부 차임벨 지속 시간 변경

외부 초인종이 울리는 시간(초)은 Home API를 통해 구성할 수 있습니다. 외부 차임벨이 차임벨 지속 시간을 지원하는 경우 사용자가 이를 구성할 수 있습니다.

여기에서 설정된 값은 외부 초인종 자체의 사양과 권장 초인종 지속 시간에 따라 다릅니다.

외부 차임벨 소리 지속 시간을 변경하려면 내장 setExternalChimeDurationSeconds 함수를 사용하여 ChimeTrait 특성의 externalChimeDurationSeconds 속성을 업데이트합니다.

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

차임벨 테마 사용 설정

일부 초인종에는 사용자가 제한된 시간 동안만 사용할 수 있는 차임벨이 있을 수 있습니다. 예를 들어 휴일에 맞는 차임벨이 있습니다. 이를 차임벨 테마라고 합니다.

사용자가 사용할 수 있는 차임벨 테마를 확인하려면 시간 상자 필터를 만들고 이를 사용하여 ChimeThemes 특성에서 getAvailableThemes 명령어의 결과를 필터링합니다. 그러면 테마 이름을 비롯한 사용 가능한 테마 목록이 반환됩니다.

다음 예는 목록을 필터링하는 방법을 보여줍니다. 현재 시간이 테마의 시작 시간과 종료 시간 (각각 startTimeSecondsendTimeSeconds 값) 내에 있으면 테마가 활성 상태로 간주됩니다. 시작 시간이 설정되지 않은 경우 시작 시간부터 활성 상태로 간주됩니다. 종료 시간이 설정되지 않으면 무기한 활성 상태로 유지됩니다. 둘 다 누락된 경우 테마는 항상 활성 상태입니다.

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

원하는 테마의 이름(예: Christmas)을 알면 ChimeThemes ChimeThemes 특성에서 setSelectedTimeboxedThemeName() 함수를 사용하여 선택할 수 있습니다.

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