Matter 用の Android アプリを構築する

1. ようこそ

IoT 標準の統一を目的として構築された Matter は、Google Home、Zigbee、Bluetooth Mesh、Z-Wave などのさまざまなエコシステムでスマートホーム デバイスを接続します。

モバイル デバイスは、スマートホーム デバイスとの中心的なやり取りのポイントです。Matter 対応デバイスをサポートする独自の Android アプリを構築したい場合は、迅速に開始できるようサポートいたします。

Matter 向け Google Home サンプルアプリ(Matter 向け GHSA)は、Home Mobile SDK API を紹介するもので、ユーザーはデバイスのコミッショニングと共有を行うことができます。また、このサンプルアプリは、Matter の主なコンセプトを理解するための学習ツールとして、Matter デバイスとのやり取りをデバッグしてトラブルシューティングするためのツールとしても使用できます。

演習内容

この Codelab では、サンプルアプリのソースコードをダウンロードし、Home Mobile SDK を使用してデバイスをコミッショニングして共有する方法を学びます。また、Matter リポジトリ(connectedhomeipのコミッショニング ライブラリとクラスタ ライブラリの使用方法についても説明します。

サンプルアプリをダウンロードしたら、Android Studio でソースコードを確認し、次の Home Mobile SDK API を実装します。

また、コミッショニングのコンセプト、Matter ファブリック、Matter デバイスの制御方法についても詳しく説明します。

必要なもの

始める前に、次の手順を完了してください。

サンプルアプリでデバイスをコミッショニングして制御するために、ハブ(Google Nest Hub(第 2 世代)など)は必要ありません。

2. セットアップする

Codelab スターター アプリは codelab ブランチにあります。Codelab のソースコードの操作を開始するには、ZIP ファイルをダウンロードします。

この codelab ZIP ファイルを使用して、動作するサンプルをビルドします。

Codelab のバージョン

codelab ブランチには、サンプルアプリの 2.0.0 リリースのタグが付けられています。各ステップを進めながら更新を比較するには、このリリースの完成したソースコードをダウンロードします。

GitHub リポジトリのクローンを作成する場合は、サンプルアプリの README の手順に沿って操作してください。

依存関係

デバイスの共有とコミッショニングに必要なソースコードについては、ガイドで説明しますが、始める前に次の依存関係について把握しておくとよいでしょう。これらの依存関係は libs.versions.toml ファイルで宣言され、その使用方法は build.gradle.kts ファイルで指定されています。

ソースコード

ユーザー インターフェースとほとんどの機能はすでに作成されています。

この Codelab では、次のファイルに Matter の機能を追加します。

  • java/com/google/homesampleapp/commissioning/AppCommissioningService: デバイスを開発ファブリックにコミッショニングできます
  • java/com/google/homesampleapp/screens/home/HomeScreenjava/com/google/homesampleapp/screens/home/HomeViewModel.kt: Home Mobile SDK のコミッショニング機能が含まれます
  • java/com/google/homesampleapp/screens/device/DeviceScreenjava/com/google/homesampleapp/screens/device/DeviceViewModel: Share Device API 呼び出しが含まれます

各ファイルには、変更するコードブロックのコメントが付けられています。例:

// CODELAB: add commissioningFunction()

これにより、コードラボの対応するセクションをすばやく見つけることができます。

3. Google への手数料

デバイスを制御し、同じファブリック内でデバイス同士が通信できるようにするには、コミッショナー(この場合は、このサンプル アプリケーションである Google Home Sample App for Matter)によるコミッショニングが必要です。

Matter のコミッショニングについては、次のコンセプトを理解することが重要です。

  • ファブリックを使用すると、デバイス間で通信できます。
  • ファブリックは、一意の認証情報の共有セットを維持します。
  • エコシステムは、信頼できるルート証明書の発行、ファブリック ID の割り当て、一意のノード ID の割り当てを行います。エコシステムは、コミッショナーのバックエンド サービスです(Google Home エコシステムの Home Graph など)。
  • デバイスは複数のファブリックにコミッショニングできます(マルチ管理者機能)。

デバイスをコミッショニングするには、CommissioningClient API を使用する必要があります。.commissionDevice() の呼び出しは IntentSender を返し、Google Play 開発者サービスで適切なアクティビティを起動します。

interface CommissioningClient {
  Task<IntentSender> commissionDevice(CommissioningRequest request);
}

次のセクションでは、デバイスを Google ファブリックにコミッショニングするために必要な最小限のコードについて説明します。

ステップ 1: アクティビティ ランチャー

CommissioningClient からの IntentSender を処理するには、ActivityResultLauncher を使用します。

val commissioningLauncher = registerForActivityResult(
    StartIntentSenderForResult()
) { result: ActivityResult ->
    if (result.resultCode == RESULT_OK) {
        Timber.d(TAG, "Commissioning succeeded.")
    } else {
        Timber.d(TAG, "Commissioning failed. " + result.resultCode)
    }
}

ステップ 2: 試運転機能

CommissioningClient API を使用してデバイスを Google ファブリックにコミッショニングする基本的な例を次に示します。

  1. コミッショニング プロセスは commissionDevice() 関数から始まります。まず、CommissioningRequest が定義されます。このデフォルト構成では、デバイスはローカル Android ファブリックにのみコミッショニングされます。
  2. Matter は、Home Mobile SDK のエントリ ポイントです。次の呼び出しで、.getCommissioningClientthis(アクティビティ)によって CommissioningClient を取得します。
  3. .commissionDevice()CommissioningRequest を受け入れます。
  4. 最後に、.addOnSuccessListener が呼び出されて CommissioningResult が処理され、Google Play 開発者サービス(GPS)の Commission Device アクティビティが起動します。
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

ローカル Android ファブリックは、Android の設定から利用して、デバイスを他のファブリックにコミッショニングするプロセスを簡素化できます。

次に、デバイスを開発ファブリックにコミッショニングする方法について説明します。

コミッショニング プロセス中のユーザー インターフェースの概要については、Matter 向け Google Home サンプルアプリガイドを参照してください。

4. 開発ファブリックへのコミッション

デバイスは複数のファブリックにコミッショニングできます。信頼できるペア設定を管理するために、デバイスはさまざまな FabricInfo メンバーを含む FabricTable を保存します。例:

  • ファブリックの識別
  • ファブリックによってデバイスに割り当てられたノード ID
  • Vendor Id
  • ファブリック ID
  • デバイスのオペレーション認証情報

管理ドメイン マネージャー(ADM)はファブリック認証情報を定義します。前のシナリオでは、Google Play 開発者サービスが信頼できるルート認証局(CA)として機能するエコシステムです。デバイスをローカル Android ファブリックにコミッショニングすると、すべてのデバイスに同じファブリック認証情報と CA のセットが含まれます。

カスタム コミッショニング サービス

ローカル Android ファブリックにコミッショニングするために、デフォルトのパラメータを使用して CommissioningClient API で CommissioningRequest をビルドしました。

val request: CommissioningRequest = CommissioningRequest.builder().build()

アプリから新しいデバイスを制御、管理するには、ローカル開発ファブリックを作成し、デバイスをコミッショニングするためのオペレーション認証情報を取得する必要があります。このシナリオでは、アプリはデバイスに適切なノード認証情報を割り当てる、一意の独立したエコシステムになります。

カスタム サービスを CommissioningRequest に渡すことで、デバイスを独自のファブリックにコミッショニングすることを Home Mobile SDK に通知できます。

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

  class Builder {
    Builder setCommissioningService(@Nullable ComponentName commissioningService);

    CommissioningRequest build();
  }
}

次のステップでは、カスタム サービスを使用するように commissionDevice() 関数を変更します。また、ホーム フラグメントにアクティビティ ランチャーを追加し、LiveData オブジェクトを使用して API フローを管理します。

ステップ 1: GPS アクティビティ ランチャーを作成する

まず、CommissioningClient API からの IntentSender を処理するアクティビティ ランチャーを作成します。

  1. java/com/google/homesampleapp/screens/home/ フォルダで HomeScreen を開きます。
  2. // CODELAB: commissionDeviceLauncher definition コメントを次のコードに置き換えて、コミッショニング アクティビティの結果を登録して処理します。
    val commissionDeviceLauncher =
      rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartIntentSenderForResult()
      ) { result ->
        // Commission Device Step 5.
        // The Commission Device activity in GPS (step 4) has completed.
        val resultCode = result.resultCode
        if (resultCode == Activity.RESULT_OK) {
          Timber.d("CommissionDevice: Success")
          // We let the ViewModel know that GPS commissioning has completed successfully.
          // The ViewModel knows that we still need to capture the device name and will\
          // update UI state to trigger the NewDeviceAlertDialog.
          homeViewModel.gpsCommissioningDeviceSucceeded(result)
        } else {
          homeViewModel.commissionDeviceFailed(resultCode)
        }
      }
    

ステップ 2: コミッショニング デバイス アクションをトリガーする

このステップでは、ユーザーがホーム画面の右下にある [+] ボタンをクリックして、[デバイスのコミッショニング] アクションをトリガーします。その後、commissionDevice() が呼び出されます。

val onCommissionDevice = {
  ...
  commissionDevice(activity!!.applicationContext, commissionDeviceLauncher)
}

ステップ 3: API を呼び出す

  1. 引き続き java/com/google/homesampleapp/screens/home フォルダの HomeScreen.kt に移動します。
  2. // CODELAB: commissionDevice コメントを次の commissionDeviceRequest に置き換えます。setCommissioningServiceAppCommissioningServiceCommissioningService インスタンスにバインドし、コールバック関数で返します。カスタム サービスを渡すと、Home Mobile SDK はまずデバイスを Android ローカル ファブリックにコミッショニングしてから、オンボーディング ペイロードを AppCommissioningService に送り返します。
    val commissionDeviceRequest =
        CommissioningRequest.builder()
            .setCommissioningService(ComponentName(
                context, AppCommissioningService::class.java))
            .build()
    
  3. .getCommissioningClient() を呼び出し、次に .commissionDevice() を呼び出します。
Matter.getCommissioningClient(context)
    .commissionDevice(commissionDeviceRequest)

commissionDevice 関数を完成させるには、addOnSuccessListeneraddOnFailureListener を追加します。

    .addOnSuccessListener { result ->
      commissionDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
    }
    .addOnFailureListener { error ->
      Timber.e(error)
    }

5. コミッショニング サービスを作成する

commissionDevice() 関数では、CommissioningClient API から CommissioningService を取得するようリクエストしました。このフローでは、CommissioningClient API はまずデバイスをローカル Android ファブリックにコミッショニングし、CommissioningRequestMetadata オブジェクトを含むコールバックを返します。

public interface CommissioningService {
interface Callback {
    void onCommissioningRequested(CommissioningRequestMetadata metadata);
  }
}

次に、CommissioningService.Callback を継承し、デバイスをサンプルアプリにコミッショニングするために必要な機能を提供する必要があります。基本的な CommissioningService 実装の例を次に示します。

class MatterCommissioningService : Service(), CommissioningService.Callback {
   private val commissioningServiceDelegate =
     CommissioningService.Builder(this)
       .setCallback(this)
       .build()

   override fun onBind(intent: Intent) = commissioningServiceDelegate.asBinder()

   override fun onCommissioningRequested(metadata: CommissioningRequestMetadata) {
     // perform commissioning

     commissioningServiceDelegate
       .sendCommissioningComplete(CommissioningCompleteMetadata.builder().build())
   }
 }

ステップ 1: カスタム AppCommissioningService を確認する

作業を開始するにあたり、カスタム CommissioningService の基本クラス構造をすでに定義しています。サービスの機能の概要は次のとおりです。このガイドを続けるには、java/commissioningAppCommissioningService を開いてください。

Home Mobile SDK API に次のインポートを追加しました。

import com.google.android.gms.home.matter.commissioning.CommissioningCompleteMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningRequestMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningService

AppCommissioningService には、Matter リポジトリ(connectedhomeipのライブラリも含まれています。

import com.google.homesampleapp.chip.ChipClient

最後に、このサービスには HiltKotlin コルーチンをサポートするためのインポートが含まれています。

次に、コンストラクタを作成し、commissioningServiceDelegate などのいくつかの設定を行います。この commissioningServiceDelegate は、コミッショニングが完了したことを Google Play 開発者サービスに通知するために使用します。

private lateinit var commissioningServiceDelegate: CommissioningService
...
commissioningServiceDelegate = CommissioningService.Builder(this).setCallback(this).build()

ここで、コミッショニング関数を追加します。

ステップ 2: onCommissioningRequested をオーバーライドする

デバイスをアプリの開発ファブリックにコミッショニングする手順は次のとおりです。

  1. java/commissioningAppCommissioningServiceを開きます。
  2. onCommissioningRequested() 関数を見つけます。CommissioningRequestMetadata を出力するログメッセージを提供しました。// CODELAB: onCommissioningRequested() コメントを置き換えて、serviceScope コルーチンを開始し、deviceId を取得します。
    // Perform commissioning on custom fabric for the sample app.
    serviceScope.launch {
      val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
    
  3. コミッショニングを実施します。このステップでは、CommissioningRequestMetadata オブジェクトで返されたデバイス情報を渡すことができます。ChipClient はこのメタデータ情報を使用して、GHSA for Matter アプリとデバイスの間に安全なチャネルを作成します。
    try {
      Timber.d(
          "Commissioning: App fabric -> ChipClient.establishPaseConnection(): deviceId [${deviceId}]")
      chipClient.awaitEstablishPaseConnection(
          deviceId,
          metadata.networkLocation.ipAddress.hostAddress!!,
          metadata.networkLocation.port,
          metadata.passcode)
      Timber.d(
          "Commissioning: App fabric -> ChipClient.commissionDevice(): deviceId [${deviceId}]")
      chipClient.awaitCommissionDevice(deviceId, null)
    } catch (e: Exception) {
      Timber.e(e, "onCommissioningRequested() failed")
      // No way to determine whether this was ATTESTATION_FAILED or DEVICE_UNREACHABLE.
      commissioningServiceDelegate
          .sendCommissioningError(CommissioningError.OTHER)
          .addOnSuccessListener {
            Timber.d(
                "Commissioning: commissioningServiceDelegate.sendCommissioningError() succeeded")
          }
          .addOnFailureListener { e2 ->
            Timber.e(e2, "Commissioning: commissioningServiceDelegate.sendCommissioningError() failed")
          }
      return@launch
    }
    
  4. commissioningServiceDelegate を使用して、コミッショニングが完了したことを Google Play 開発者サービスに通知します。.sendCommissioningComplete() で、CommissioningCompleteMetadata を渡します。
    commissioningServiceDelegate
        .sendCommissioningComplete(
            CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build())
        .addOnSuccessListener {
          Timber.d("Commissioning: commissioningServiceDelegate.sendCommissioningComplete() succeeded")
        }
        .addOnFailureListener { e ->
          Timber.e(e, "Commissioning: commissioningServiceDelegate.sendCommissioningComplete() failed")
        }
    }
    

アプリを実行する

ローカル ファブリックにコミッショニングするために必要なコードがすべて揃ったので、テストを行います。Android デバイスを選択してアプリを実行します。ホーム画面で [デバイスを追加] をタップし、手順に沿ってデバイスをコミッショニングします。

コミッショニングが完了すると、デバイスはローカル Android ファブリックとローカル開発ファブリックの 2 つのファブリックに参加します。各ファブリックには、独自の認証情報セットと一意の 64 ビット ファブリック ID があります。

6. デバイスを操作する

開発ファブリックへのコミッショニングにより、Matter リポジトリ(connectedhomeipのライブラリを使用して、サンプルアプリからデバイスを制御できます。

デバイス クラスタへのアクセスとコマンドの送信を簡単にするためのヘルパークラスを作成しました。詳しくは、java/clustersClustersHelper を開いてください。この Singleton ヘルパーは、デバイス情報にアクセスするために次のライブラリをインポートします。

import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipStructs

このクラスを使用してデバイスのオン/オフ クラスタを取得し、.toggle を呼び出すことができます。

suspend fun toggleDeviceStateOnOffCluster(deviceId: Long, endpoint: Int) {
  Timber.d("toggleDeviceStateOnOffCluster())")
  val connectedDevicePtr =
      try {
        chipClient.getConnectedDevicePointer(deviceId)
      } catch (e: IllegalStateException) {
        Timber.e("Can't get connectedDevicePointer.")
        return
      }
  return suspendCoroutine { continuation ->
    getOnOffClusterForDevice(connectedDevicePtr, endpoint)
        .toggle(
            object : ChipClusters.DefaultClusterCallback {
              override fun onSuccess() {
                continuation.resume(Unit)
              }
              override fun onError(ex: Exception) {
                Timber.e("readOnOffAttribute command failure: $ex")
                continuation.resumeWithException(ex)
              }
            })
  }
}

デバイスを切り替える

デバイスをコミッショニングすると、CommissioningResult で返されたペイロードが DataStore に追加されます。これにより、アプリはコマンドの送信に使用できるデバイス情報にアクセスできるようになります。

Matter アプリはイベント ドリブンです。Matter スタックが初期化されると、クラスタ サービスは受信メッセージをリッスンします。デバイスがコミッショニングされると、Matter クライアントはデバイスのコミッショニング中に確立された安全な運用チャネルを介してコマンドを送信します。

デバイスでは、パケットの検証と復号が行われ、コールバックとともにディスパッチされます。コールバック関数には、attributePath からアクセス可能な EndpointId、ClusterId、AttributeId が含まれます。たとえば、このコードは Matter デバイスに実装できます。

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type,
                                       uint16_t size, uint8_t * value)
{
    // handle callback
    ClusterId clusterId     = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
}

次のステップでは、Matter SDK と ClustersHelper を使用してデバイスを切り替えます。

  1. java/screens/deviceDeviceViewModel に移動します。
  2. updateDeviceStateOn 関数を見つけます。
  3. // CODELAB: toggle コメントを clustersHelper を呼び出すコードに置き換え、デバイス リポジトリを更新します。
    Timber.d("Handling real device")
        try {
          clustersHelper.setOnOffDeviceStateOnOffCluster(deviceUiModel.device.deviceId, isOn, 1)
          devicesStateRepository.updateDeviceState(deviceUiModel.device.deviceId, true, isOn)
        } catch (e: Throwable) {
          Timber.e("Failed setting on/off state")
        }
    

この関数は DeviceScreen から呼び出されます。

// On/Off Switch click.
val onOnOffClick: (value: Boolean) -> Unit = { value ->
  deviceViewModel.updateDeviceStateOn(deviceUiModel!!, value)
}

アプリを実行する

アプリを実行して、更新を再読み込みします。ホーム画面で、デバイスのオンとオフを切り替えます。

7. 他のエコシステムとデバイスを共有する

デバイスの共有は、Matter 仕様ではマルチ管理者フローと呼ばれます。

前の手順で、Home Mobile SDK を使用すると、デバイスをローカル Android ファブリックとサンプルアプリの開発ファブリックにコミッショニングできることを学びました。これは、デバイスを複数のファブリックにコミッショニングできるマルチ管理者フローの例です。

アプリやプラットフォームに関してユーザーごとに好みが異なる家庭では、さらに多くのファブリックでデバイスを共有したい場合もあるでしょう。

Home Mobile SDK は、ShareDeviceRequest API でこの機能を提供します。これにより、次のことが可能になります。

  1. デバイスの一時的なコミッショニング ウィンドウを開きます。
  2. デバイスの状態を変更して、別のファブリックにコミッショニングできるようにします。
  3. 他のアプリやエコシステムからデバイスを操作する。

次の手順では、Home Mobile SDK を使用してデバイスを共有します。

ステップ 1: GPS アクティビティ ランチャーを作成する

開発ファブリックにコミッショニングしたときに作成した Commissioning Activity Launcher と同様に、CommissioningClient API からの IntentSender を処理する Share Device Activity Launcher を作成しました。

  1. java/com/google/homesampleapp/screens/device/ フォルダで DeviceScreen を開きます。
  2. // CODELAB: shareDeviceLauncher definition コメントを次のコードに置き換えて、.shareDevice() アクティビティの結果を登録して処理します。
    val shareDeviceLauncher = rememberLauncherForActivityResult(
      contract = ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
      // Commission Device Step 5.
      // The Share Device activity in GPS (step 4) has completed.
      val resultCode = result.resultCode
      if (resultCode == Activity.RESULT_OK) {
        deviceViewModel.shareDeviceSucceeded()
      } else {
        deviceViewModel.shareDeviceFailed(resultCode)
      }
    }
    

ステップ 2: デバイスの共有アクションをトリガーする

このステップでは、ユーザーがデバイス画面の [共有] ボタンをクリックして [デバイスを共有] アクションをトリガーします。その後、deviceViewModel が呼び出され、デバイス共有用のペア設定ウィンドウが開きます。

// Share Device button click.
val onShareDevice: () -> Unit = remember {
 {
   deviceViewModel.openPairingWindow(deviceUiModel!!.device.deviceId)
 }
}

ペア設定ウィンドウが正常に開くと、deviceViewModel はその事実を UI に伝えます。ViewModel と UI 間の通信は StateFlow オブジェクトを介して行われます。

// Communicate to the UI that the pairing window is open.
// UI can then launch the GPS activity for device sharing.
_pairingWindowOpenForDeviceSharing.value = true

StateFlow オブジェクトの変更を確認すると、DeviceScreen は次の呼び出しを行います。

shareDevice(activity!!.applicationContext, shareDeviceLauncher, deviceViewModel)

ステップ 3: API を呼び出す

デバイスの共有タスクを開始します。

  1. java/com/google/homesampleapp/screens/device/ フォルダで DeviceScreen.kt を開きます。
  2. shareDevice() 関数を見つけます。// CODELAB: shareDevice コメントを ShareDeviceRequest に置き換えます。DeviceDescriptor は、ベンダー ID、プロダクト ID、deviceType など、デバイスに関する具体的な情報を提供します。この例では、値をハードコードしています。
    val shareDeviceRequest =
      ShareDeviceRequest.builder()
        .setDeviceDescriptor(DeviceDescriptor.builder().build())
        .setDeviceName("GHSAFM temp device name")
    
  3. CommissioningWindowパラメータを設定します。
        .setCommissioningWindow(
            CommissioningWindow.builder()
                .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR))
                .setPasscode(SETUP_PIN_CODE)
                .setWindowOpenMillis(SystemClock.elapsedRealtime())
                .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong())
                .build())
        .build()
    
  4. .getCommissioningClient() を呼び出します。ただし、今回は .shareDevice() API を使用します。
    Matter.getCommissioningClient(context)
        .shareDevice(shareDeviceRequest)
    

commissioningClient.shareDevice() API の成功コールバックは、Google Play 開発者サービスでデバイス共有アクティビティを起動するために使用される IntentSender を提供します。

  1. shareDevice 関数を完成させるため、addOnSuccessListeneraddOnFailureListener を追加します。成功すると、shareDeviceLauncherlaunch が呼び出され、デバイス共有の GPS アクティビティが起動します。
        .addOnSuccessListener { result ->
          Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]")
          shareDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
        .addOnFailureListener { error ->
          Timber.e(error)
          deviceViewModel.showMsgDialog("Share device failed", error.toString())
        }
    

アプリを実行する

Matter 対応デバイスを他のエコシステムと共有するには、Android デバイスに別のプラットフォームがインストールされている必要があります。ターゲット コミッショナーとして使用できるサンプルアプリの別のインスタンスを作成しました。

Android デバイスにターゲット コミッショナーをインストールしたら、Matter デバイスを共有できることを確認します。ターゲットのコミッショナー アプリには GHSAFM-TC というラベルが付いています。

デバイスが 3 つのファブリックに参加できるようになりました。

  1. ローカル Android ファブリック。
  2. 開発ファブリック(このアプリ)。
  3. デバイスを共有したばかりの 3 つ目のファブリック。

8. 次のステップ

完了

これで、この Codelab は終了です。Home Mobile SDK を使用してデバイスをコミッショニングし、共有する方法を学びました。

サンプルアプリで問題が発生した場合は、次の手順に沿って環境を確認してください。

サンプルアプリの使用について質問がある場合や、コードのバグを発見した場合は、GitHub リポジトリの Issue Tracker に問題を送信できます。

技術的な質問について Google から公式なガイダンスを得るには、スマートホーム デベロッパー フォーラムをご利用ください。

コミュニティからテクニカル サポートを受けるには、Stack Overflow で google-smart-home タグを使用します。