สร้างแอป Android สําหรับกรณี

1. ยินดีต้อนรับ

Matter สร้างขึ้นโดยมีเป้าหมายที่จะผสานรวมมาตรฐาน IoT เข้าด้วยกัน เพื่อเชื่อมต่ออุปกรณ์ในบ้านอัจฉริยะกับระบบนิเวศที่หลากหลาย เช่น Google Home, Zigbee, Bluetooth Mesh, Z-Wave และอีกมากมาย

อุปกรณ์เคลื่อนที่เป็นจุดโต้ตอบส่วนกลางพร้อมด้วยอุปกรณ์ในบ้านอัจฉริยะ หากคุณต้องการสร้างแอป Android ของคุณเองเพื่อรองรับอุปกรณ์ Matter เราช่วยให้คุณเริ่มต้นใช้งานได้อย่างรวดเร็ว

แอปตัวอย่าง Google Home สำหรับ Matter (GHSA สำหรับ Matter) แสดง API ของ Home Mobile SDK เพื่อให้ผู้ใช้มอบหมายและแชร์อุปกรณ์ได้ นอกจากนี้ คุณยังสามารถใช้แอปตัวอย่างเป็นเครื่องมือเรียนรู้เพื่อทำความเข้าใจแนวคิดหลักของ Matter ให้ดียิ่งขึ้น รวมถึงเป็นเครื่องมือในการแก้ไขข้อบกพร่องและแก้ปัญหาการโต้ตอบกับอุปกรณ์ Matter

สิ่งที่คุณจะต้องทำ

ใน Codelab นี้ คุณจะดาวน์โหลดซอร์สโค้ดของแอปตัวอย่างและดูวิธีใช้ Home Mobile SDK เพื่อค่าคอมมิชชันและแชร์อุปกรณ์ นอกจากนี้ คุณยังจะได้ดูวิธีใช้ไลบรารีการมอบหมายและไลบรารีคลัสเตอร์จากที่เก็บ Matter (connectedhomeip)

หลังจากดาวน์โหลดแอปตัวอย่างแล้ว เราจะตรวจสอบซอร์สโค้ดใน Android Studio และติดตั้ง API ของ Home Mobile SDK ต่อไปนี้

นอกจากนี้ คุณยังจะได้ดูข้อมูลเพิ่มเติมเกี่ยวกับแนวคิดการว่าจ้าง โครงสร้าง Matter และวิธีควบคุมอุปกรณ์ Matter

สิ่งที่ต้องมี

โปรดทำตามขั้นตอนต่อไปนี้ก่อนเริ่มดำเนินการ

คุณไม่จำเป็นต้องใช้ฮับ เช่น Google Nest Hub (รุ่นที่ 2) เพื่อสั่งงานและควบคุมอุปกรณ์ด้วยแอปตัวอย่าง

2. ตั้งค่า

แอปเริ่มต้นของ Codelab อยู่ในสาขา codelab หากต้องการเริ่มทํางานกับซอร์สโค้ดของ Codelab คุณสามารถดาวน์โหลดไฟล์ ZIP ได้

คุณจะใช้ไฟล์ ZIP codelab นี้เพื่อสร้างตัวอย่างที่ใช้งานได้

เวอร์ชันของ Codelab

สาขา codelab ติดแท็กด้วยรุ่น 2.0.0 ของแอปตัวอย่าง หากต้องการเปรียบเทียบการอัปเดตระหว่างที่ดำเนินการในแต่ละขั้นตอน คุณสามารถดาวน์โหลดซอร์สโค้ดที่เสร็จสมบูรณ์แล้วสำหรับรุ่นนี้

หากต้องการโคลนที่เก็บ GitHub ให้ทำตามวิธีการในตัวอย่างแอป README

การอ้างอิง

เราจะแนะนำซอร์สโค้ดที่จำเป็นในการแชร์และจัดเตรียมอุปกรณ์ให้แก่คุณ แต่การตระหนักถึงทรัพยากร Dependency ต่อไปนี้ก่อนเริ่มต้นใช้งานอาจช่วยคุณได้ โปรดทราบว่ามีการประกาศทรัพยากร Dependency เหล่านี้ไว้ในไฟล์ libs.versions.toml และการใช้งานที่ระบุในไฟล์ build.gradle.kts

ซอร์สโค้ด

มีการสร้างอินเทอร์เฟซผู้ใช้และฟังก์ชันส่วนใหญ่สําหรับคุณไว้แล้ว

สำหรับ Codelab นี้ เราจะเพิ่มฟังก์ชัน Matter ลงในไฟล์ต่อไปนี้

  • java/commissioning/AppCommissioningService: ให้คุณมอบหมายอุปกรณ์ให้กับโครงสร้างการพัฒนา
  • java/screens/home/HomeScreen และ java/screens/home/HomeViewModel.kt: มีฟังก์ชันการสั่งงาน Home Mobile SDK
  • java/screens/device/DeviceScreen และ java/screens/device/DeviceViewModel: รวมการเรียก Share Device API

แต่ละไฟล์จะมีความคิดเห็นด้วยโค้ดบล็อกที่คุณกำลังจะแก้ไข เช่น

// CODELAB: add commissioningFunction()

ซึ่งจะช่วยให้คุณค้นหาส่วนที่เกี่ยวข้องใน Codelab ได้อย่างรวดเร็ว

3. ค่าคอมมิชชันต่อ Google

ก่อนที่จะควบคุมอุปกรณ์และอนุญาตให้อุปกรณ์สื่อสารกันได้ภายในเครื่องเดียวกัน อุปกรณ์ดังกล่าวต้องได้รับมอบหมายจากเจ้าหน้าที่ ซึ่งในกรณีนี้คือแอปพลิเคชันตัวอย่าง Google Home สำหรับ Matter

คุณควรทำความเข้าใจแนวคิดต่อไปนี้เกี่ยวกับการว่าจ้าง Matter

  • ผ้าช่วยให้อุปกรณ์สื่อสารกันได้
  • Fabrics จะมีชุดข้อมูลเข้าสู่ระบบที่ไม่ซ้ำกันซึ่งใช้ร่วมกัน
  • ระบบนิเวศมีหน้าที่ในการออกใบรับรองรูทที่เชื่อถือได้ กำหนดรหัสผ้า และการกำหนดรหัสโหนดที่ไม่ซ้ำกัน ระบบนิเวศคือบริการแบ็กเอนด์ของเจ้าหน้าที่ เช่น กราฟหน้าแรก สำหรับระบบนิเวศของ Google Home
  • สามารถมอบหมายอุปกรณ์ให้กับผ้าได้มากกว่า 1 อย่าง (ฟีเจอร์สำหรับผู้ดูแลระบบหลายคน)

คุณจะต้องใช้ CommissioningClient API หากต้องการชำระค่าอุปกรณ์ การเรียก .commissionDevice() แสดงผล IntentSender ซึ่งเปิดกิจกรรมที่เหมาะสมในบริการ Google Play ดังนี้

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

ในส่วนถัดไป เราจะพูดถึงโค้ดขั้นต่ำที่จำเป็นต้องใช้ในการคอมมิชชันอุปกรณ์กับ Google

ขั้นตอนที่ 1: ตัวเรียกใช้งานกิจกรรม

ในการจัดการ IntentSender จาก CommissioningClient คุณสามารถใช้ Activity ResultsLauncher ได้ดังนี้

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 Fabric

  1. กระบวนการจัดเตรียมจะเริ่มต้นด้วยฟังก์ชัน commissionDevice() ก่อนอื่นมีการกำหนด CommissioningRequest ด้วยการกำหนดค่าเริ่มต้นนี้ อุปกรณ์จะมอบหมายให้กับผ้า Android ท้องถิ่นเท่านั้น
  2. Matter คือจุดแรกเข้าของ Home Mobile SDK ในการโทรครั้งถัดไป .getCommissioningClient จะได้รับ CommissioningClient จาก this (Activity)
  3. .commissionDevice() ยอมรับ CommissioningRequest
  4. และสุดท้าย .addOnSuccessListener จะได้รับคำขอให้ประมวลผล CommissioningResult และเปิดตัวกิจกรรมอุปกรณ์แบบค่าคอมมิชชันของบริการ Google Play (GPS)
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

คุณสามารถใช้ประโยชน์จากผ้า Android ท้องถิ่นผ่านการตั้งค่า Android เพื่อลดความซับซ้อนของกระบวนการจัดเตรียมอุปกรณ์ไปยังผ้าอื่นๆ

ถัดไป คุณจะได้เรียนรู้วิธีมอบหมายอุปกรณ์ให้กับโครงสร้างการพัฒนา

สำหรับภาพรวมของอินเทอร์เฟซผู้ใช้ในระหว่างกระบวนการจัดเตรียม โปรดดูแอปตัวอย่างของ Google Home สำหรับคู่มือ Matter

4. ดำเนินการในฐานะสิ่งทอเพื่อการพัฒนา

สามารถสั่งงานอุปกรณ์ให้กับผ้าได้มากกว่า 1 เครื่อง หากต้องการจัดการการจับคู่ที่เชื่อถือได้ อุปกรณ์จะจัดเก็บ FabricTable ที่มีสมาชิก FabricInfo หลายคน เช่น

  • การระบุเนื้อผ้า
  • รหัสโหนดที่ผ้ากำหนดให้กับอุปกรณ์
  • รหัสผู้ให้บริการ
  • รหัส Fabric
  • ข้อมูลเข้าสู่ระบบด้านการปฏิบัติงานของอุปกรณ์

เครื่องมือจัดการโดเมนการดูแลระบบ (ADM) จะกำหนดข้อมูลเข้าสู่ระบบ Fabric ในสถานการณ์ก่อนหน้านี้ บริการ Google Play คือระบบนิเวศที่ทำหน้าที่เป็นผู้ออกใบรับรองรูท (CA) ที่เชื่อถือได้ เมื่อคุณว่าจ้างให้อุปกรณ์ใช้ Local Android Fabric อุปกรณ์ทั้งหมดจะรวมข้อมูลเข้าสู่ระบบ Fabric ชุดเดียวกันและ CA ชุดเดียวกัน

บริการจัดหาอุปกรณ์ตามความต้องการของลูกค้า

เราใช้พารามิเตอร์เริ่มต้นในการสร้าง CommissioningRequest ใน CommissioningClient API เพื่อรับค่าคอมมิชชันสำหรับ Local Android Fabric

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

หากต้องการควบคุมและจัดการอุปกรณ์ใหม่จากแอป คุณต้องสร้างแนวทางการพัฒนาในเครื่องและรับข้อมูลเข้าสู่ระบบด้านการปฏิบัติงานเพื่อจัดเตรียมอุปกรณ์ ในสถานการณ์นี้ แอปของคุณจะกลายเป็นระบบนิเวศอิสระที่ไม่เหมือนใคร ซึ่งกําหนดข้อมูลเข้าสู่ระบบของโหนดที่เหมาะสมให้กับอุปกรณ์

คุณสามารถแจ้ง Home Mobile SDK ว่าต้องการค่าคอมมิชชันให้กับอุปกรณ์ของคุณเอง โดยผ่านบริการที่กำหนดเองไปยัง CommissioningRequest ดังนี้

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

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

    CommissioningRequest build();
  }
}

ในขั้นตอนถัดไป เราจะแก้ไขฟังก์ชัน commissionDevice() เพื่อใช้บริการที่กำหนดเอง นอกจากนี้เราจะเพิ่ม Launcher กิจกรรมลงในส่วนย่อยของ Home และใช้ออบเจ็กต์ LiveData เพื่อจัดการโฟลว์ API

ขั้นตอนที่ 1: สร้าง Launcher กิจกรรม GPS

ก่อนอื่น เรามาสร้าง Launcher กิจกรรมเพื่อจัดการ IntentSender จาก CommissioningClient API กัน

  1. เปิด HomeScreen ในโฟลเดอร์ java/screens/home/
  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. ยังคงอยู่ใน HomeScreen.kt ในโฟลเดอร์ java/screens/home/
  2. แทนที่ความคิดเห็น // CODELAB: commissionDevice ด้วย commissionDeviceRequest ต่อไปนี้ setCommissioningService จะเชื่อมโยง AppCommissioningService กับอินสแตนซ์ CommissioningService โดยแสดงผลในฟังก์ชันเรียกกลับ เมื่อคุณส่งผ่านบริการที่กำหนดเอง 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 เสร็จสมบูรณ์ ให้เพิ่ม addOnSuccessListener และ addOnFailureListener:

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

5. สร้าง CommissioningService

ในฟังก์ชัน commissionDevice() เราขอรับ CommissioningService จาก CommissioningClient API ในขั้นตอนนี้ CommissioningClient API จะกำหนดค่าอุปกรณ์ไปยัง Fabric Android Fabric ก่อน จากนั้นแสดงผลโค้ดเรียกกลับที่มีออบเจ็กต์ 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 ที่กำหนดเองของเราไว้แล้ว ภาพรวมคร่าวๆ เกี่ยวกับฟังก์ชันการทำงานของบริการมีดังนี้ หากต้องการติดตาม โปรดเปิด AppCommissioningService ใน java/commissioning

เราได้เพิ่มการนำเข้าต่อไปนี้สำหรับ API ของ Home Mobile SDK

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.home_sample_app_for_matter.chip.ChipClient

สุดท้าย บริการจะมีการนําเข้าเพื่อรองรับ Hilt และโครูทีนของ Kotlin

ถัดไป เราจะสร้างตัวสร้างและตั้งค่าบางอย่าง รวมถึง commissioningServiceDelegate ซึ่งเราจะใช้เพื่อแจ้งให้บริการ Google Play ทราบเมื่อการมอบหมายเสร็จสมบูรณ์

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

ถึงเวลาเพิ่มฟังก์ชันการจัดเตรียม

ขั้นตอนที่ 2: ลบล้าง onCommissioningRequested

หากต้องการจัดเตรียมอุปกรณ์ให้กับการพัฒนาแอป ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิด AppCommissioningService ใน java/commissioning
  2. ค้นหาฟังก์ชัน onCommissioningRequested() เราได้มีข้อความบันทึกที่พิมพ์ CommissioningRequestMetadata ออกมาแล้ว แทนที่ความคิดเห็น // CODELAB: onCommissioningRequested() เพื่อเริ่ม Coroutine serviceScope และรับ deviceId
    // Perform commissioning on custom fabric for the sample app.
    serviceScope.launch {
      val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
    
  3. จัดเตรียมอุปกรณ์ ในขั้นตอนนี้ เราจะส่งข้อมูลอุปกรณ์ที่ส่งกลับมาในออบเจ็กต์ CommissioningRequestMetadata ChipClient จะใช้ข้อมูลเมตานี้เพื่อสร้างช่องทางที่ปลอดภัยระหว่างแอป GHSA สำหรับ 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 แล้วเรียกใช้แอป จากหน้าจอหลัก ให้แตะเพิ่มอุปกรณ์และทำตามขั้นตอนให้เสร็จสิ้นเพื่อจัดเตรียมอุปกรณ์

เมื่อดำเนินการเสร็จแล้ว ปัจจุบันอุปกรณ์จะมีส่วนร่วมใน 2 ผ้า ได้แก่ ผ้า Android ท้องถิ่นและผ้าสำหรับการพัฒนาในท้องถิ่น Fabric แต่ละผ้าจะมีชุดข้อมูลเข้าสู่ระบบที่ไม่ซ้ำกันและรหัส Fabric 64 บิตที่ไม่ซ้ำกัน

6. ควบคุมอุปกรณ์

การกำหนดโครงสร้างในอุปกรณ์การพัฒนาจะช่วยให้คุณใช้ไลบรารีจากที่เก็บ Matter (connectedhomeip) เพื่อควบคุมอุปกรณ์จากแอปตัวอย่างได้

เราได้สร้างคลาสผู้ช่วยเพื่อให้คุณเข้าถึงคลัสเตอร์อุปกรณ์และส่งคำสั่งได้ง่ายขึ้น เปิด ClustersHelper ใน java/clusters เพื่อดูข้อมูลเพิ่มเติม ตัวช่วย 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 จะส่งคำสั่งผ่านช่องทางการดำเนินการที่ปลอดภัยซึ่งสร้างขึ้นระหว่างการจัดเตรียมอุปกรณ์

ในอุปกรณ์จะมีการตรวจสอบแพ็กเก็ต ถอดรหัส แล้วนำส่งพร้อมการเรียกกลับ ฟังก์ชันเรียกกลับประกอบด้วย EndpointId, ClusterId และ AttributeId ซึ่งเข้าถึงได้จาก attributePath เช่น โค้ดนี้นําไปใช้กับอุปกรณ์ 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. ไปที่ DeviceViewModel ใน java/screens/device
  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

ในขั้นตอนที่ผ่านมา เราได้เรียนรู้ว่า SDK ของ Home Mobile ทำให้สามารถมอบหมายอุปกรณ์ให้กับผ้า Android ท้องถิ่นและสิ่งทอเพื่อการพัฒนาสำหรับแอปตัวอย่างได้ นี่คือตัวอย่างขั้นตอนสำหรับผู้ดูแลระบบหลายคน ซึ่งสามารถมอบหมายอุปกรณ์ให้กับผ้าได้มากกว่า 1 เครื่อง

ตอนนี้คุณอาจต้องการแชร์อุปกรณ์กับผ้าจำนวนมากขึ้น โดยเฉพาะอย่างยิ่งหากเป็นครอบครัวที่ผู้คนมีความชอบในเรื่องแอปพลิเคชันและแพลตฟอร์มเป็นของตนเอง

Home Mobile SDK มีฟังก์ชันการทำงานนี้ใน ShareDeviceRequest API ซึ่งช่วยให้คุณทำสิ่งต่อไปนี้ได้

  1. เปิดหน้าต่างการจัดเตรียมอุปกรณ์ชั่วคราว
  2. เปลี่ยนสถานะของอุปกรณ์เพื่อให้คุณสามารถสั่งการไปยังเนื้อผ้าอื่นได้
  3. ควบคุมอุปกรณ์จากแอปและระบบนิเวศอื่นๆ

ในขั้นตอนถัดไป คุณจะใช้ Home Mobile SDK เพื่อแชร์อุปกรณ์

ขั้นตอนที่ 1: สร้าง Launcher กิจกรรม GPS

เราได้สร้าง Share Device Activity Launcher สำหรับจัดการ IntentSender จาก CommissioningClient API ซึ่งคล้ายกับ Launcher กิจกรรมค่าคอมมิชชันที่เราสร้างขึ้นเมื่อสั่งงานให้กับเทคโนโลยีการพัฒนา

  1. เปิด DeviceScreen ในโฟลเดอร์ java/screens/device/
  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 = {
 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. เปิด DeviceScreen.kt ในโฟลเดอร์ java/screens/device/
  2. ค้นหาฟังก์ชัน shareDevice() แทนที่ความคิดเห็น // CODELAB: shareDevice ด้วย ShareDeviceRequest DeviceDescriptor จะให้ข้อมูลที่เฉพาะเจาะจงเกี่ยวกับอุปกรณ์ เช่น รหัสผู้ให้บริการ รหัสผลิตภัณฑ์ และประเภทอุปกรณ์ ในตัวอย่างนี้ เราฮาร์ดโค้ดค่า
    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 จะทำให้ระบบใช้ IntentSender เพื่อเปิดใช้กิจกรรม Share Device ในบริการ Google Play

  1. เพื่อให้ฟังก์ชัน shareDevice เสร็จสมบูรณ์ ให้เพิ่ม addOnSuccessListener และ addOnFailureListener เมื่อสำเร็จ launch จะถูกเรียกใช้ใน shareDeviceLauncher เพื่อเปิดกิจกรรม 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 ได้โดยทำดังนี้

หากต้องการคำแนะนำอย่างเป็นทางการจาก Google สำหรับคำถามทางเทคนิค โปรดใช้ฟอรัมนักพัฒนาสมาร์ทโฮมต่อไปนี้

หากต้องการรับการสนับสนุนด้านเทคนิคจากชุมชน ให้ใช้แท็ก google-smart-home ใน Stack Overflow ดังนี้