ドアホン デバイスタイプは、2 つのトレイトを使用して実装されます。PushAvStreamTransportTrait は、プッシュベースのプロトコルを使用して音声と動画のストリーム転送を処理します。WebRtcLiveViewTrait は、ライブ ストリームとトークバックを制御する機能を提供します。
機能を使用したり、属性を更新しようとしたりする前に、デバイスの属性とコマンドのサポートを必ず確認してください。詳しくは、iOSでデバイスを制御するをご覧ください。
| Google Home の API のデバイスタイプ | トレイト | Swift サンプルアプリ | ユースケース |
|---|---|---|---|
|
ドアホン
ドアの外側のボタンを押すと、音や視覚信号を発するデバイス。ドアの向こう側にいる人の注意を引くために使用されます。ドアホンには、アクセシビリティ対応のライブ配信、双方向のトークバック、検出イベントなどの機能が搭載されている場合があります。 |
必須のトレイト 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]
デバイスの接続を確認する
一部のデバイスは複数のデバイスタイプをサポートしているため、デバイスの接続は実際にはデバイスタイプ レベルでチェックされます。返される状態は、そのデバイスのすべてのトレイトの接続状態の組み合わせです。
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
}
}
TalkBack の開始と停止
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)")
}
}
録画機能を有効または無効にする
カメラの録画機能を有効にするには、PushAvStreamTransportTrait トレイトの setTransportStatus(transportStatus:optionalArgsProvider:) メソッドに TransportStatusEnum.Active を渡します。録画機能を無効にするには、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
}
}
}
カメラの録画機能を有効または無効にすることは、カメラの動画のオンとオフを切り替えることと同じです。カメラの動画がオンになっている場合、イベントと関連するクリップの目的で録画が行われます。
録画機能が無効になっている場合(カメラの動画がオフの場合):
- カメラは、デバイスタイプの
connectivityStateに従ってオンラインとして表示されることがあります。 - ライブ ストリームにアクセスできず、カメラでクラウド イベントも検出されません。
録画機能が有効になっているかどうかを確認する
カメラの録画機能が有効になっているかどうかを確認するには、接続がアクティブかどうかを確認します。次の例では、これを行う 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
}
バッテリーの設定
さまざまなバッテリー設定は、Home API を介して制御できます。
バッテリー使用量の設定
エネルギー バランスを設定すると、デバイスのバッテリー寿命とパフォーマンスのトレードオフを構成できます。「延長」、「バランス」、「パフォーマンス」などのさまざまなバッテリー プロファイルを作成して、切り替えることができます。
この機能は、EnergyPreference トレイトの currentEnergyBalance 属性を更新することで実装されます。この属性は、デバイスの energyBalances リストで定義された特定のプロファイルに対応する整数インデックスを受け取ります(たとえば、EXTENDED の場合は 0、BALANCED の場合は 1、PERFORMANCE の場合は 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) } }
自動バッテリー セーバーをオンにする
この機能を構成するには、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 }
音声設定
さまざまな音声設定は、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
}
}
その他の設定
その他のさまざまな設定は、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
}
}
カメラのビューポートを変更する
カメラのビューポートは、Google Nest カメラの動画でズーム機能や補正機能を使用するのサポート記事で説明されているズームと切り抜き機能と同じです。
ビューポートは、ビューポートの座標として使用される 4 つの値を含む ViewportStruct で定義されます。座標は次のように定義されます。
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
ViewportStruct の値を決定するには、アプリの UI とカメラの実装に依存します。基本的なレベルでは、カメラ動画のビューポートを設定するには、組み込みの setViewport 関数を使用して、CameraAvStreamManagementTrait トレイトの viewport 属性を ViewportStruct で更新します。
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 の triggerOptions の motionSensitivity プロパティを使用して設定できます。これらのオプションは、各デバイスの 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 の triggerOptions の motionTimeControl プロパティを使用して設定できます。これらのオプションは、各デバイスの 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
}
}
チャイムの設定
ドアホンのチャイムのさまざまな設定は、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)
}
}```