Przewodnik po routerze granicznym na Androida

Deweloperzy aplikacji na Androida mogą używać interfejsów Home API do zarządzania Thread Border Router (TBR).

Element GoogleBorderRouterDevice jest implementowany za pomocą 2 głównych cech urządzenia: ThreadNetworkCapabilities, która udostępnia atrybuty tylko do odczytu umożliwiające sprawdzanie funkcji border router, oraz ThreadNetworkManagement, która obsługuje polecenia dotyczące cyklu życia sieci i udostępniania danych logowania za pomocą tymczasowego klucza wstępnego dla komisarza (ePSKc). Zasady dostępu do internetu na poziomie struktury są zarządzane za pomocą ThreadNetworkSettings cechy.

Zanim zaczniesz korzystać z jakichkolwiek funkcji lub spróbujesz zaktualizować atrybuty, zawsze sprawdź, czy urządzenie obsługuje atrybuty i polecenia. Więcej informacji znajdziesz w artykule Sterowanie urządzeniami w Google Home Android.

Typ urządzenia w interfejsach Home API Cechy Przykładowa aplikacja w Kotlinie Przypadek użycia

Router graniczny

GoogleBorderRouterDevice

home.matter.6006.types.0161

Wymagane cechy
     google ThreadNetworkCapabilities
     google ThreadNetworkManagement

Router graniczny

Pobieranie podstawowych informacji o urządzeniu

   Zaimplementowane w przykładowej aplikacji na Androida   

Cechy BasicInformation obejmują informacje takie jak nazwa dostawcy, identyfikator dostawcy, identyfikator produktu, nazwa produktu (w tym informacje o modelu) i wersja oprogramowania urządzenia:

// 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}")
    }

Sprawdzanie możliwości routera granicznego

Za pomocą cechy ThreadNetworkCapabilities możesz sprawdzić możliwości border router's tylko do odczytu (takie jak obsługa ePSKc i konfiguracja ustawienia dostępu do internetu).

suspend fun checkBorderRouterCapabilities(device: HomeDevice) {
    // Filter for GoogleBorderRouterDevice device type
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    if (gtbrDevice == null) {
        println("Device is not a Google border router.")
        return
    }

    // Retrieve the ThreadNetworkCapabilities trait
    val capabilitiesTrait = gtbrDevice.trait(ThreadNetworkCapabilities)
    if (capabilitiesTrait == null) {
        println("ThreadNetworkCapabilities trait not found on device.")
        return
    }

    val isEpskcSupported = capabilitiesTrait.epskcSupported ?: false
    val internetAccessOption = capabilitiesTrait.internetAccessOption?.name ?: "None"
    val isIasSupported = !internetAccessOption.equals("None", ignoreCase = true)

    println("ePSKc Supported: $isEpskcSupported")
    println("Internet Access Setting Supported: $isIasSupported")
}

Zarządzanie udostępnianiem danych logowania do sieci Thread (ePSKc)

Udostępnianie danych logowania do sieci Thread odbywa się za pomocą tymczasowego klucza wstępnego dla komisarza (ePSKc). Tryb ePSKc generuje tymczasowy, bezpieczny klucz dostępu, którego urządzenia zewnętrzne lub komisarze mogą używać do bezpiecznego uzyskiwania zbioru danych sieci Thread.

Aktywowanie trybu ePSKc

suspend fun startEpskcSession(device: HomeDevice, durationSeconds: Short): ActivateEpskcModeCommand.Response? {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    if (mgmtTrait == null) {
        println("ThreadNetworkManagement trait not found.")
        return null
    }

    return try {
        val response = mgmtTrait.activateEpskcMode(
            optionalArgs = { this.requestedDurationSeconds = durationSeconds }
        )

        println("ePSKc Session Activated!")
        println("Status: ${response.status}")
        println("Ephemeral PSKc: ${response.epskc}")
        println("Valid Duration (s): ${response.validDurationSeconds}")

        response
    } catch (e: Exception) {
        println("Failed to activate ePSKc mode: ${e.message}")
        null
    }
}

Dezaktywowanie trybu ePSKc

suspend fun stopEpskcSession(device: HomeDevice) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    mgmtTrait?.deactivateEpskcMode()
    println("ePSKc mode deactivated.")
}

Obserwowanie zdarzeń dezaktywacji ePSKc

TBR emitują zdarzenia, gdy sesja ePSKc się kończy (np. z powodu użycia klucza, wygaśnięcia sesji lub ręcznego anulowania).

suspend fun observeEpskcEvents(device: HomeDevice) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    mgmtTrait?.epskcModeDeactivatedEventFlow()?.collect { event ->
        println("ePSKc Session Ended. Reason: ${event.reason}")
        when (event.reason?.name) {
            "KeyUsed" -> println("Key was successfully used to commission a device.")
            "Expired" -> println("Session timed out before the key was used.")
            "Cancelled" -> println("Session was manually cancelled.")
        }
    }
}

Zarządzanie członkostwem w sieci Thread

Możesz wysłać do TBR polecenie dołączenia do nowej sieci Thread, podając aktywne TLV zbioru danych operacyjnych, lub polecenie opuszczenia bieżącej sieci.

suspend fun joinNetwork(device: HomeDevice, datasetTlvs: ByteArray) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    try {
        val response = mgmtTrait?.joinNetwork(operationalDatasetTlvs = datasetTlvs)
        println("Join network command sent. Status: ${response?.status}")
    } catch (e: Exception) {
        println("Join network failed: ${e.message}")
    }
}

suspend fun leaveNetwork(device: HomeDevice) {
    val gtbrDevice = device.type(GoogleBorderRouterDevice).firstOrNull()
    val mgmtTrait = gtbrDevice?.trait(ThreadNetworkManagement)

    try {
        mgmtTrait?.leaveNetwork()
        println("Leave network command sent successfully.")
    } catch (e: Exception) {
        println("Leave network failed: ${e.message}")
    }
}

Konfigurowanie dostępu do internetu na poziomie struktury

Cechy ThreadNetworkSettings to cechy, które można aktualizować i które są powiązane ze strukturą (Structure) reprezentującą dom lub budynek. Umożliwiają one deweloperom konfigurowanie zasad dostępu do internetu w całej strukturze dla TBRów.

suspend fun updateStructureInternetAccess(structure: Structure, enableInternetAccess: Boolean) {
    // Retrieve the ThreadNetworkSettings trait for the structure
    val settingsTrait = structure.trait(ThreadNetworkSettings).firstOrNull()
    if (settingsTrait == null) {
        println("ThreadNetworkSettings trait not found on structure.")
        return
    }

    val option = if (enableInternetAccess) {
        InternetAccessOption.InternetAccessOptionAll
    } else {
        InternetAccessOption.InternetAccessOptionNone
    }

    try {
        settingsTrait.update {
            setInternetAccessOption(option)
        }
        println("Successfully updated Thread internet access policy to: ${option.name}")
    } catch (e: Exception) {
        println("Failed to update Thread internet access policy: ${e.message}")
    }
}