iOS 向けボーダー ルーター デバイスガイド

iOS アプリのデベロッパーは、Home API を使用して Thread ボーダー ルーターを管理できます。

GoogleBorderRouterDevice は、2 つのプライマリ デバイス トレイト(ThreadNetworkCapabilitiesTraitThreadNetworkManagementTrait)を使用して実装されます。ThreadNetworkCapabilitiesTrait は、ボーダー ルーターの機能を検査するための読み取り専用の属性を提供します。ThreadNetworkManagementTrait は、コミッショナー(ePSKc)の一時的な事前共有キーを使用して、ネットワーク ライフサイクル コマンドと認証情報の共有を処理します。構造レベルのインターネット アクセス ポリシーは、ThreadNetworkSettingsTrait トレイトを使用して管理されます。

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

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

ボーダー ルーター

GoogleBorderRouterDeviceType

home.matter.6006.types.0161

必須のトレイト
     google ThreadNetworkCapabilitiesTrait
     google ThreadNetworkManagementTrait

ボーダー ルーター

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

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

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!

境界ルーターの機能を調べる

ThreadNetworkCapabilitiesTrait トレイトを使用すると、ボーダー ルーターの読み取り専用機能(ePSKc のサポートやインターネット アクセス設定の構成など)を調べることができます。

func checkBorderRouterCapabilities(device: HomeDevice) async {
    // Filter for GoogleBorderRouterDevice device type
    guard let gtbrDevice = device.type(Google.GoogleBorderRouterDevice.self) else {
        print("Device is not a Google border router.")
        return
    }

    // Retrieve the ThreadNetworkCapabilitiesTrait
    guard let capabilitiesTrait = gtbrDevice.traits(Google.ThreadNetworkCapabilitiesTrait.self) else {
        print("ThreadNetworkCapabilitiesTrait not found on device.")
        return
    }

    do {
        let isEpskcSupported = try await capabilitiesTrait.epskcSupported.read()
        let internetAccessOption = try await capabilitiesTrait.internetAccessOption.read()
        let isIasSupported = internetAccessOption != .none

        print("ePSKc Supported: \(isEpskcSupported)")
        print("Internet Access Setting Supported: \(isIasSupported)")
    } catch {
        print("Failed to read capabilities: \(error)")
    }
}

Thread 認証情報の共有を管理する(ePSKc)

Thread 認証情報の共有は、コミッショナーの一時的な事前共有鍵(ePSKc)を使用して実現されます。ePSKc モードでは、外部デバイスまたはコミッショナーが Thread ネットワーク データセットを安全に取得するために使用できる、一時的な安全なパスキーが生成されます。

ePSKc モードを有効にする

func startEpskcSession(device: HomeDevice, durationSeconds: Int16) async -> Google.ThreadNetworkManagementTrait.ActivateEpskcModeResponse? {
    guard let gtbrDevice = device.type(Google.GoogleBorderRouterDevice.self),
          let mgmtTrait = gtbrDevice.traits(Google.ThreadNetworkManagementTrait.self) else {
        print("ThreadNetworkManagementTrait not found.")
        return nil
    }

    do {
        var request = Google.ThreadNetworkManagementTrait.ActivateEpskcModeRequest()
        request.requestedDurationSeconds = durationSeconds

        let response = try await mgmtTrait.activateEpskcMode(request)

        print("ePSKc Session Activated!")
        print("Status: \(response.status)")
        print("Ephemeral PSKc: \(response.epskc)")
        print("Valid Duration (s): \(response.validDurationSeconds)")

        return response
    } catch {
        print("Failed to activate ePSKc mode: \(error)")
        return nil
    }
}

ePSKc モードを無効にする

func stopEpskcSession(device: HomeDevice) async {
    guard let gtbrDevice = device.type(Google.GoogleBorderRouterDevice.self),
          let mgmtTrait = gtbrDevice.traits(Google.ThreadNetworkManagementTrait.self) else {
        return
    }

    do {
        try await mgmtTrait.deactivateEpskcMode(Google.ThreadNetworkManagementTrait.DeactivateEpskcModeRequest())
        print("ePSKc mode deactivated.")
    } catch {
        print("Failed to deactivate ePSKc mode: \(error)")
    }
}

ePSKc の無効化イベントをモニタリングする

Thread ボーダー ルーターは、ePSKc セッションが終了したときにイベントを発行します(キーが使用された、セッションの有効期限が切れた、手動でキャンセルされたなど)。

func observeEpskcEvents(device: HomeDevice) async {
    guard let gtbrDevice = device.type(Google.GoogleBorderRouterDevice.self),
          let mgmtTrait = gtbrDevice.traits(Google.ThreadNetworkManagementTrait.self) else {
        return
    }

    do {
        for try await event in mgmtTrait.epskcModeDeactivatedEvent.stream() {
            print("ePSKc Session Ended. Reason: \(event.reason)")
            switch event.reason {
            case .keyUsed:
                print("Key was successfully used to commission a device.")
            case .expired:
                print("Session timed out before the key was used.")
            case .cancelled:
                print("Session was manually cancelled.")
            @unknown default:
                print("Unknown deactivation reason.")
            }
        }
    } catch {
        print("Error streaming ePSKc events: \(error)")
    }
}

Thread ネットワークのメンバーシップを管理する

アクティブな Operational Dataset TLV を指定して新しい Thread ネットワークに参加するよう Thread ボーダー ルーターにコマンドを送信したり、現在のネットワークから離脱するようコマンドを送信したりできます。

func joinNetwork(device: HomeDevice, datasetTlvs: Data) async {
    guard let gtbrDevice = device.type(Google.GoogleBorderRouterDevice.self),
          let mgmtTrait = gtbrDevice.traits(Google.ThreadNetworkManagementTrait.self) else {
        return
    }

    do {
        var request = Google.ThreadNetworkManagementTrait.JoinNetworkRequest()
        request.operationalDatasetTlvs = datasetTlvs

        let response = try await mgmtTrait.joinNetwork(request)
        print("Join network command sent. Status: \(response.status)")
    } catch {
        print("Join network failed: \(error)")
    }
}

func leaveNetwork(device: HomeDevice) async {
    guard let gtbrDevice = device.type(Google.GoogleBorderRouterDevice.self),
          let mgmtTrait = gtbrDevice.traits(Google.ThreadNetworkManagementTrait.self) else {
        return
    }

    do {
        try await mgmtTrait.leaveNetwork(Google.ThreadNetworkManagementTrait.LeaveNetworkRequest())
        print("Leave network command sent successfully.")
    } catch {
        print("Leave network failed: \(error)")
    }
}

構造レベルのインターネット アクセスを構成する

ThreadNetworkSettings トレイトは、Structure(家や建物を表す)に付加される更新可能なトレイトです。これにより、デベロッパーは Thread ボーダー ルーターの構造全体のインターネット アクセス ポリシーを構成できます。

func updateStructureInternetAccess(structure: Structure, enableInternetAccess: Bool) async {
    guard let settingsTrait = structure.traits(Google.ThreadNetworkSettingsTrait.self) else {
        print("ThreadNetworkSettingsTrait not found on structure.")
        return
    }

    let option: Google.ThreadNetworkSettingsTrait.InternetAccessOption = enableInternetAccess ? .internetAccessOptionAll : .internetAccessOptionNone

    do {
        try await settingsTrait.update { mutator in
            mutator.internetAccessOption = option
        }
        print("Successfully updated Thread internet access policy.")
    } catch {
        print("Failed to update Thread internet access policy: \(error)")
    }
}