Android 向けドアベル デバイスガイド

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

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

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

ドアホン

GoogleDoorbellDevice

home.matter.6006.types.0113

ドアの外側のボタンを押すと、音や視覚信号を発するデバイス。ドアの向こう側にいる人の注意を引くために使用されます。ドアホンには、アクセシビリティ対応のライブ配信、双方向のトークバック、検出イベントなどの機能が搭載されている場合があります。

必須のトレイト
     google PushAvStreamTransport
     google WebRtcLiveView

ドアホン

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

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

// Get device basic information. All general information traits are on the RootNodeDevice type.
    device.type(RootNodeDevice).first().standardTraits.basicInformation?.let { basicInformation ->
        println("vendorName ${basicInformation.vendorName}")
        println("vendorId ${basicInformation.vendorId}")
        println("productId ${basicInformation.productId}")
        println("productName ${basicInformation.productName}")
        println("softwareVersion ${basicInformation.softwareVersion}")
        println("serialNumber ${basicInformation.serialNumber}")
    }

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

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

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

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

ライブ配信を開始する

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

  • セッションの SDP。
  • セッションの長さ(秒単位)。
  • セッション ID。セッションの延長または終了に使用されることがあります。
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) {
 return cameraDevice.type(GoogleDoorbellDevice).trait(WebRtcLiveView).first {
    it?.metadata?.sourceConnectivity?.connectivityState == ConnectivityState.ONLINE
  }

}

// Start the live view
suspend fun startCameraStream(trait: WebRtcLiveView, offerSdp: String) {
  val response = trait.startLiveView(offerSdp)
  // Response contains three fields (see below)
  return response
}
  ...

// This is used to manage the WebRTC connection
val peerConnection: RTCPeerConnection = ...

   ...

val startResponse = startCameraStream(sdp)
val answerSdp = startResponse?.answerSdp
val sessionDuration = startResponse?.liveSessionDurationSeconds
val mediaSessionId = startResponse?.mediaSessionId

peerConnection.setRemoteDescription(SessionDescription.Type.ANSWER,
                                    answerSdp)

ライブ配信を延長する

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

// Assuming camera stream has just been started
suspend fun scheduleExtension(trait: WebRtcLiveView, mediaSessionId: String, liveSessionDurationSeconds: UShort ) {
  delay(liveSessionDurationSeconds - BUFFER_SECONDS * 1000)
  val response = trait.extendLiveView(mediaSessionId)
  // returns how long the session will be live for
  return response.liveSessionDurationSeconds
}

TalkBack の開始と停止

TalkBack を開始するには、WebRtcLiveView トレイトの startTalkback() メソッドを呼び出します。停止するには、stopTalkback() を使用します。

// Make sure camera stream is on
suspend fun setTalkback(isOn: Boolean, trait: WebRtcLiveView, mediaSessionId: String) {
  if(isOn) {
    trait.startTalkback(mediaSessionId)
  } else {
    trait.stopTalkback(mediaSessionId)
  }
}

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

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

// Start or stop recording for all connections.
suspend fun setCameraRecording(trait: PushAvStreamTransport, isOn: Boolean) {
  if(isOn) {
    trait.setTransportStatus(TransportStatusEnum.Active)
  } else {
    trait.setTransportStatus(TransportStatusEnum.Inactive)
  }
}

カメラの録画機能を有効または無効にすることは、カメラの動画のオンとオフを切り替えることと同じです。カメラの動画がオンになっている場合、イベントと関連するクリップの目的で録画が行われます。

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

  • カメラは、デバイスタイプの connectivityState に従ってオンラインとして表示されることがあります。
  • ライブ ストリームにアクセスできず、カメラでクラウド イベントも検出されません。

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

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

// Get the on/off state
suspend fun onOffState(pushAvStreamTransport: PushAvStreamTransport) {
  return pushAvStreamTransport
    .currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

// Check if the camera's recording capability is enabled
fun PushAvStreamTransport.recordModeActive(): Boolean {
  return currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

別の方法として、述語を使用して findTransport() 関数を使用することもできます。

// Fetch the current connections
suspend fun queryRecordModeState(trait: PushAvStreamTransport) {
  return trait.findTransport().let {
      it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active
    }
}

バッテリーの設定

さまざまなバッテリー設定は、Home API を介して制御できます。

バッテリー使用量の設定

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

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

currentEnergyBalancenull 値は、デバイスがカスタム プロファイルを使用していることを示します。読み取り専用の状態です。

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

// Example energyBalances list
energy_balances: [
  {
    step: 0,
    label: "EXTENDED"
  },
  {
    step: 50,
    label: "BALANCED"
  },
  {
    step: 100,
    label: "PERFORMANCE"
  }
]
// The index parameter must be within the UByte range (0-255).
suspend fun setEnergyBalance(trait: EnergyPreference, index: Int) {
  trait.update { setCurrentEnergyBalance(index.toUByte()) }
}

// Setting the battery usage to more recording ie performance
setEnergyBalance(energyPreference, 2)

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

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

suspend fun setAutomaticBatterySaver(enable: Boolean, trait: EnergyPreference) {
  // 0 is Disabled, 1 is Enabled
  val value = if (enable) 1.toUByte() else 0.toUByte()
  trait.update { setCurrentLowPowerModeSensitivity(value) }
}

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

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

// Get the battery charging state
val batteryChargeState = powerSource.batChargeState

when (batteryChargeState) {
    PowerSourceTrait.BatChargeStateEnum.IsCharging -> "Charging"
    PowerSourceTrait.BatChargeStateEnum.IsAtFullCharge -> "Full"
    PowerSourceTrait.BatChargeStateEnum.IsNotCharging -> "Not Charging"
    else -> "Unknown"
}

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

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

// Get the battery charge level
val batteryLevel = powerSourceTrait.batChargeLevel

when (batteryLevel) {
    PowerSourceTrait.BatChargeLevelEnum.OK -> "OK"
    PowerSourceTrait.BatChargeLevelEnum.Warning -> "Warning"
    PowerSourceTrait.BatChargeLevelEnum.Critical -> "Critical"
    else -> "Unknown"
}

電源を取得する

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

  val trait: PowerSource
  val isWired = trait.wiredPresent
  val hasBattery = trait.batPresent

音声設定

さまざまな音声設定は、Home API を介して制御できます。

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

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

// Turn the device's microphone on or off
suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setMicrophoneMuted(disableMicrophone) }
}

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

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

// Turn audio recording on or off for the device
suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setRecordingMicrophoneMuted(disableAudioRecording) }
}

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

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

// Adjust the camera speaker volume
suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) {
  trait.update { setSpeakerVolumeLevel(volume.toUbyte()) }
}

その他の設定

その他のさまざまな設定は、Home API を介して制御できます。

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

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

// Turn night vision on
cameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On)
}

// Turn night vision off
CameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off)
}

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

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

// Set the LED brightness to high
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High)
}

// Set the LED brightness to low
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low)
}

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

カメラのビューポートは、Google Nest カメラの動画でズーム機能や補正機能を使用するのサポート記事で説明されているズームと切り抜き機能と同じです。

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

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

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

cameraAvStreamManagement
  .update { setViewport(
    CameraAvStreamManagementTrait.ViewportStruct(
      x1 = horizontalRange.rangeStart.roundToInt().toUShort(),
      x2 = horizontalRange.rangeEnd.roundToInt().toUShort(),
      y1 = verticalRange.rangeStart.roundToInt().toUShort(),
      y2 = verticalRange.rangeEnd.roundToInt().toUShort(),
    )
) }

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

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

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

ウェイクアップ感度は、次の値にのみ設定できます。

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

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

// Create a struct with the new wake-up sensitivity
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionSensitivity =
        OptionalValue.present(wakeUpSensitivity.toUByte())
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }

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

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

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

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

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

// Create a struct with the new max event length
// where maxDuration is the length in seconds
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionTimeControl =
        OptionalValue.present(
          TransportMotionTriggerTimeControlStruct(maxDuration = it.toUInt())
        )
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }

チャイムの設定

ドアホンのチャイムのさまざまな設定は、Home API を介して制御できます。

チャイムの音を変更する

ドアホンのチャイム音を変更するには、まず Chime トレイトの installedChimeSounds 属性を使用して、デバイスにインストールされているチャイム音のリストを取得します。

// Get a list of chimes and identify the currently selected one
private val doorbellChimeTraitFlow: Flow =
    device.traitFromType(Chime, GoogleDoorbellDevice)
val chimeSounds = doorbellChimeTraitFlow.first().installedChimeSounds ?: emptyList()

次に、組み込みの setSelectedChime Kotlin 関数を使用して、Chime トレイトの selectedChime 属性を更新します。

// Set the chime using the chimeId from the installed list
chimeSounds.firstOrNull { it.name == name }?.let { setSelectedChime(it.chimeId) }

外部チャイムを使用する

ドアホンは、家の中に設置された機械式ベルなどの外部チャイムを使用するように構成できます。外部チャイムの損傷を防ぐため、ドアホンの設置時に設定する必要があります。

設置されている外部チャイムの種類を示すには、ExternalChimeType を使用して、組み込みの setExternalChime Kotlin 関数を使用して Chime トレイトの externalChime 属性を更新します。

// Indicate the external chime is mechanical
chime.update {
  setExternalChime(ChimeTrait.ExternalChimeType.Mechanical)
}

外部チャイムの鳴動時間を変更する

外部チャイムが鳴る時間(秒単位)は、Home API で設定できます。外部チャイムがチャイム音の長さをサポートしている場合、ユーザーはこれを設定できます。

ここで設定する値は、外部チャイム自体の仕様と、推奨されるチャイムの長さによって異なります。

外部チャイムの再生時間を変更するには、組み込みの setExternalChimeDurationSeconds Kotlin 関数を使用して、Chime トレイトの externalChimeDurationSeconds 属性を更新します。

// Change the external chime duration
chime.update {
  setExternalChimeDurationSeconds(newDuration.toUShort())
}

チャイムのテーマを有効にする

一部のドアベルには、ユーザーが期間限定で利用できるチャイムが用意されている場合があります。たとえば、祝日固有のチャイムなどです。これらはチャイムのテーマと呼ばれます。

ユーザーが使用できるチャイムテーマを確認するには、タイムボックス フィルタを作成し、それを使用して ChimeThemes トレイトの getAvailableThemes() コマンドの結果をフィルタします。テーマ名など、利用可能なテーマのリストが返されます。

次の例は、リストをフィルタする方法を示しています。現在の時刻がテーマの開始時刻と終了時刻(それぞれ startTimeSecondsendTimeSeconds の値)の間にある場合、そのテーマは有効と見なされます。開始時刻が設定されていない場合、最初から有効と見なされます。終了時刻が設定されていない場合、無期限で有効になります。両方ともない場合、テーマは常に有効です。

// Get themes from the ChimeThemes trait
fun List<ChimeThemesTrait.ThemeStruct>.filterTimeboxedThemes():
    List<ChimeThemesTrait.ThemeStruct> {
  val now = timeSource.instant().epochSecond.toULong()
  return filter { chimeStruct: ChimeThemesTrait.ThemeStruct ->
    val startTime: ULong = chimeStruct.startTimeSeconds.getOrNull() ?: 0UL
    val endTime: ULong = chimeStruct.endTimeSeconds.getOrNull() ?: MAX_VALUE
    startTime <= now && now <= endTime
  }
}

val availableThemes =
  doorbellChimeThemesTraitFlow
    .first()
    .getAvailableThemes()
    .themes
    .filterTimeboxedThemes()

Christmas などの目的のテーマの名前を取得したら、ChimeThemes トレイトの setSelectedTimeboxedThemeName() 関数を使用して選択できます。

// Select a theme using the ChimeThemes trait
val themeToSelect = "Christmas"
if (themeToSelect in availableThemeNames) {
  doorbellChimeThemesTraitFlow.first().setSelectedTimeboxedThemeName(themeToSelect)
}