門鈴裝置類型是使用三種特徵實作:PushAvStreamTransportTrait,使用推送通訊協定處理音訊和影片串流傳輸;WebRtcLiveViewTrait,提供控制直播和對講功能的能力;以及 CameraSnapshotTrait,提供快取預覽快照和即時快照擷取。
使用任何功能或嘗試更新屬性前,請務必確認裝置是否支援該屬性和指令。詳情請參閱「在iOS上控制裝置」。
| Home API 裝置類型 | 特徵 | Swift 範例應用程式 | 用途 |
|---|---|---|---|
|
門鈴
一種裝置,由門外的按鈕啟動,會發出聲音和/或視覺訊號,用於引起門內人員的注意。門鈴可能提供無障礙直播、雙向對講或偵測事件。 |
必要特徵 google PushAvStreamTransportTrait google WebRtcLiveViewTrait |
門鈴 |
取得裝置的基本資訊
BasicInformation 特性包含裝置的供應商名稱、供應商 ID、產品 ID、產品名稱 (包含型號資訊) 和軟體版本等資訊:
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!
取得序號
如要取得裝置序號,請使用 ExtendedBasicInformation 特性的 GetSerialNumber 指令。以下範例會將序號儲存在名為 serialNumber 的變數中:
// Assuming extendedBasicInformationTrait: Google.ExtendedBasicInformationTrait let response = try await extendedBasicInformationTrait.getSerialNumber() let serialNumber = response.serialNumber
應答短訊
「應答短訊」功能可讓使用者傳送預先定義的訊息給門鈴裝置。
這項功能僅適用於門鈴裝置。合作夥伴應用程式可取得預先定義的訊息清單,並向使用者顯示這些訊息供其選擇。使用者無法編輯預先定義的訊息。
應答短訊是透過 PresetMessage 特性實作。
播放預設訊息
如要播放預設訊息,請呼叫 playPresetMessage 方法,並傳遞 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)")
}
}
設定使用的語言
設定使用的語言
使用 LocalizationConfiguration 特性的 setActiveLocale 方法,將裝置的有效口語語言設為特定語言代碼 (例如「en_US」)。
// Setting the active language // Assuming localizationConfigurationTrait: Matter.LocalizationConfigurationTrait let selectedLocale = "en_US" try await localizationConfigurationTrait.update { $0.setActiveLocale(selectedLocale) }
取得裝置最近一次與雲端通訊的時間
如要找出裝置最近一次與雲端通訊的時間,請使用 ExtendedGeneralDiagnostics 特性的 lastContactTimestamp 屬性:
if let lastContactTimeStamp = extendedGeneralDiagnosticsTrait.attributes.lastContactTimestamp { self.lastContactTime = Date(timeIntervalSince1970: Double(lastConnectedTimeStamp)) }
攝影機安裝類型設定
Mount 特性包含攝影機固定座設定和狀態資訊。您可以讀取掛接狀態、偵測類型和掛接類型名稱等屬性。此外,您可以使用 Mount 特徵覆寫預設的掛接類型設定。
// 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) }
檢查裝置的連線能力
系統實際上會檢查裝置類型層級的裝置連線能力,因為部分裝置支援多種裝置類型。傳回的狀態是該裝置所有特性的連線狀態組合。
let doorbellConnectivity = doorbellDeviceType.metadata.sourceConnectivity.connectivityState
如果裝置類型不一,且沒有網際網路連線,可能會看到 partiallyOnline 狀態。由於本機路由,Matter 標準特徵可能仍會上線,但雲端式特徵會離線。
取得裝置的 IP 位址
如要找出裝置的 IP 位址,請使用 GeneralDiagnosticsTrait 的 networkInterfaces 屬性。位址會以 Data 物件的形式傳回,您可以使用 Network 架構將其格式化為標準 IPv4 或 IPv6 字串:
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
}
開始直播
如要開始直播,請將工作階段描述通訊協定 (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
}
}
啟動及停止對講
如要啟動對講功能,請呼叫 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)")
}
}
管理直播
調整直播畫質,可根據用戶端的觀看情境,最佳化頻寬用量 (例如在顯示較小的預覽圖塊、格狀檢視或子母畫面模式時,切換至較低解析度)。
使用 WebRtcLiveView 特性動態變更畫質,可專門管理特定用戶端上進行中直播工作階段的解析度。這與直接在裝置上設定裝置層級的頻寬用量不同,後者會影響所有同時觀看者,以及儲存到雲端的歷史錄影畫質。
以下範例說明如何擷取及更新裝置的直播畫質:
擷取支援的畫質選項:取得裝置支援的串流解析度。程式碼會查詢
WebRtcLiveView特性,並使用supportedQualityHints屬性,將支援的串流畫質顯示為QualityHint值清單 (例如.sd、.hd、.fhd、.qhd或.uhd)。變更直播畫質:套用所選
QualityHint,變更進行中直播的串流解析度 (例如從標準畫質切換為高畫質)。updateQualityHint函式會使用WebRtcLiveView特性的changeLiveViewQuality方法,將所選QualityHint設定套用至使用中的媒體工作階段。
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 } }
啟用及停用錄製功能
如要啟用攝影機的錄影功能,請將 TransportStatusEnum.Active 傳遞至 PushAvStreamTransportTrait 特性的 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
}
擷取攝影機快照
使用 CameraSnapshot 特性,從攝影機擷取靜態圖片快照。這類快照適用於多種情境:
CameraSnapshot 特性提供兩種擷取快照的方式,取決於您需要快取快照以快速算繪,還是需要隨選即時快照。
取得快照預覽
預覽快照是快取圖片,SDK 無需喚醒相機即可擷取。這是擷取靜態圖片最快的方法,非常適合用於攝影機總覽頁面或資訊主頁格線。
如要取得預覽快照,請讀取 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 }
視攝影機設定和活動而定,預覽網址會指向根據近期影片片段 (最新影片片段的第一個 I 影格) 產生的快取圖片,或是攝影機定期上傳的快照。
為表示圖片的新鮮度,Google Home 雲端會在提供的 JPEG/PNG 圖片中嵌入 X-Home-Image-Captured-At 標頭,格式為世界標準時間。您可以在用戶端剖析這個標頭,在應用程式中顯示快照的時間。
取得隨選即時快照
如果使用者歷程需要攝影機目前的即時監控畫面 (例如設定活動區),可以要求即時快照。觸發即時快照會指示攝影機喚醒、擷取新影格,並上傳到雲端。
如要要求即時快照,請使用 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)") }
驗證快照要求
所有快照網址都會指向安全媒體,且需要 Home API v2 範圍的 OAuth 2.0 權杖。如要下載及算繪圖片,必須將 OAuth 權杖做為不記名權杖,插入 HTTP 要求的 Authorization 標頭。
以下範例說明如何設定安全的網路要求,以便下載快照:
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 } }
電池設定
你可以透過 Home API 控制各種電池設定。
設定電池用量偏好設定
設定能源平衡,即可在裝置的電池續航力和效能之間取得平衡。您可以建立不同的電池設定檔,例如「延長」、「平衡」和「效能」,並在這些設定檔之間切換。
如要實作這項功能,請更新 EnergyPreference 特性的 currentEnergyBalance 屬性。這個屬性接受整數索引,對應到裝置 energyBalances 清單中定義的特定設定檔 (例如 0 對應 EXTENDED、1 對應 BALANCED、2 對應 PERFORMANCE)。
null 的 currentEnergyBalance 值表示裝置使用的是自訂設定檔。這是唯讀狀態。
以下範例說明 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,1 則代表 Enabled 或 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 特性的 BatPresent 和 wiredPresent 屬性。
if powerSourceTrait.attributes.wiredPresent ?? false { self.powerSourceType = .wired } else if powerSourceTrait.attributes.batPresent ?? false { self.powerSourceType = .battery } else { self.powerSourceType = nil }
檢查是否需要更換電池
batReplaceability 屬性會指出電池是否不可更換、可由使用者更換,或可由原廠更換。
如果電池可更換,PowerSource 特性的 batReplacementNeeded 屬性會指出是否需要更換電池。
// Get the battery replacement status var batteryStatus = powerSourceTrait.attributes.batReplacementNeeded if batteryStatus { print("Replace the battery.") }
如果電池可由使用者更換,batReplacementDescription 會描述電池,包括外型規格、化學成分和偏好製造商等資訊。
音訊設定
你可以透過 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,定義區域的名稱、頂點、顏色和用途。
以下範例說明如何建立名為「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 }
刪除活動區
如要移除可用區,請使用 removeZone 指令並指定 zoneId。
let zoneManagementTrait: Google.ZoneManagementTrait let zoneID: UInt16 do { _ = try await zoneManagementTrait.removeZone(zoneID: zoneID) } catch { // Error }
聲響偵測事件觸發條件
AvStreamAnalysis 特性提供介面,可用於管理攝影機和門鈴裝置上的事件偵測觸發條件。雖然影像觸發條件 (例如人或車輛) 可以限定在特定區域,但聲音相關觸發條件通常是裝置層級的設定。
EventTriggerTypeEnum 的聲響偵測功能提供下列觸發條件類型:
| 模式 | 列舉值 | 說明 |
|---|---|---|
| 音效 | Sound |
一般聲響偵測。 |
| 有人說話 | PersonTalking |
偵測語音。 |
| 狗吠 | DogBark |
偵測狗叫聲。 |
| 玻璃碎裂 | GlassBreak |
偵測玻璃碎裂聲。 |
| 煙霧警報 | SmokeAlarm |
偵測煙霧警報器,通常會辨識 T3 音訊模式 (三次短嗶聲後暫停)。 |
| 一氧化碳警報 | CoAlarm |
偵測一氧化碳 (CO) 警報,通常會發出 T4 聲響模式 (四聲短嗶聲後暫停)。 |
查看聲響偵測狀態
如要向使用者顯示聲響偵測功能的目前狀態,請務必檢查裝置支援的功能,以及裝置硬體啟用的功能。要檢查的兩個屬性如下:
在 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 |
全天候錄影。須訂閱 (例如 Google Home Premium。 |
| EBR (事件錄影) | Ebr |
錄影功能是由事件 (人物、動作) 觸發。 影片長度取決於事件時間長度和訂閱方案。 |
| ETR (事件觸發錄影) | Etr |
由事件觸發的短暫預覽錄影 (例如 10 秒)。 |
| 實景 | LiveView |
錄製功能已停用,但使用者仍可觀看直播。 |
| 靜態圖片 | Images |
發生事件時,系統會拍攝快照,而非錄製影像。 |
查看錄製模式
如要顯示目前的錄製設定,請檢查 RecordingMode 特性的屬性:
supportedRecordingModes:所有潛在模式availableRecordingModes- 可選模式selectedRecordingMode:啟用模式
// 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, ) ) } }
變更錄製模式
更新前,請確認 availableRecordingModes 屬性中包含從 supportedRecordingModes 屬性選擇的索引。
如要更新所選模式,請使用 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 函式,以 ViewportStruct 更新 CameraAvStreamManagementTrait 特性的 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,則必須先產生這個結構,才能更新任何屬性。
使用這個輔助函式產生 struct,以便用於下列設定變更:
- 調整裝置喚醒靈敏度
- 調整事件錄影時間上限
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 雲端 (請參閱「Home API 的 Cloud Monitoring」)。
如要啟用裝置的數據分析功能,請將 ExtendedGeneralDiagnosticsTrait 的 analyticsEnabled) 屬性設為 true。設定 analyticsEnabled 時,另一個屬性 logUploadEnabled 會自動設為 true,以便將數據分析記錄檔上傳至 Google Home 雲端。
// Enable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(true)
}
// Disable analytics
_ = try await extendedGeneralDiagnosticsTrait.update {
$0.setAnalyticsEnabled(false)
}
傳輸和錄製設定
本節說明與攝影機串流影像畫質和事件觸發相關的設定。這些設定是由 PushAvStreamTransport 特性管理。
讀取傳輸設定
本節說明如何從攝影機或門鈴裝置擷取目前的設定。它會擷取 PushAvStreamTransport 特性,找出用於錄製的特定連線,然後擷取頻寬品質、喚醒靈敏度和事件長度上限的目前值。
// 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
更新傳輸設定
本節說明如何變更傳輸設定。它會建立包含新值的新 TransportOptionsStruct,然後使用 modifyPushTransport 指令將這些更新後的設定傳回裝置,並套用至上一步找到的錄製連線。
如要修改這些設定,請使用 modifyPushTransport 指令和 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 )
判斷頻寬品質
TransportOptionsStruct 的 videoStreamId 屬性對應至特定影片串流設定。
如要取得支援的影片串流,請參閱 allocatedVideoStreams 屬性,這是 VideoStreamStructs 的清單。CameraAvStreamManagement。
調整裝置喚醒靈敏度
TransportTriggerOptionsStruct 的 motionSensitivity 屬性對應下列值:
| 標籤 | 值 (UInt8) |
|---|---|
| 低 | 1 |
| 中 | 5 |
| 高 | 10 |
調整事件錄影時間上限
TransportMotionTriggerTimeControlStruct 的 maxDuration 屬性對應下列 UInt32 持續時間 (以秒為單位):
- 10、15、30、60、120、180
電鈴設定
你可以透過 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 指令結果。這會傳回可用主題清單,包括主題名稱。
以下範例說明如何篩選清單。如果目前時間介於主題的開始和結束時間 (分別為 startTimeSeconds 和 endTimeSeconds 值) 之間,系統就會將主題視為有效。如未設定開始時間,則視為從一開始就啟用。如未設定結束時間,則會無限期持續啟用。如果兩者皆未設定,主題就會一律啟用。
let chimeThemes = try await chimeThemeTrait.getAvailableThemes().themes
if !chimeThemes.isEmpty {
var chimeThemeSettings = []
for chimeTheme in chimeThemes {
let currentDateTime = UInt64(Date().timeIntervalSince1970)
// Only show chime themes that are active.
if chimeTheme.startTimeSeconds ?? 0 <= currentDateTime
&& chimeTheme.endTimeSeconds ?? UInt64.max >= currentDateTime
{
self.chimeThemeSettings.append(chimeTheme.name)
}
}
}
取得所需主題的名稱 (例如 Christmas) 後,您可以使用 ChimeThemes ChimeThemes 特徵上的 setSelectedTimeboxedThemeName() 函式選取該主題。
private func setChimeTheme(to value: String) async throws {
_ = try await chimeThemeTrait.update {
$0.setSelectedTimeboxedThemeName(value)
}
}
訪客通報設定
您可以使用 Home API 的 VisitorAnnouncement 特性,查詢及管理門鈴的訪客通報設定。這項特性能控制是否要在有人按門鈴時,透過 Google 智慧音箱或螢幕通報訪客到來。
以下範例說明如何檢查是否已啟用訪客通報功能,以及如何更新這項設定:
let visitorAnnouncementsEnabled: Bool = visitorAnnouncementTrait.attributes.visitorAnnouncementsEnabled let value: Bool _ = try await self.visitorAnnouncementTrait?.update { $0.setVisitorAnnouncementsEnabled(value) }
停用裝置
如要從結構體中移除門鈴,請呼叫 device.decommission()。停用時,系統會向使用者顯示 Google 管理的確認畫面,警告所有記錄的全天候錄影記錄、事件記錄、剪輯片段和熟面孔資料庫資料,都會從住家中永久刪除。
如需詳細操作說明和程式碼範例,請參閱「移除裝置」。