Как добавить новые устройства Matter в дом

Home API для iOS используют концентратор Matter, чтобы ввести устройство в эксплуатацию в сети. Во время ввода в эксплуатацию приложение отправляет команду в SDK, а затем в хаб.

Конфигурация проекта Xcode

   Реализовано в примере приложения для iOS   

Прежде чем внедрять Commissioning API, добавьте необходимые возможности, разрешения и свойства Info.plist в целевые объекты Xcode:

Права на использование

Добавьте следующие записи в файлы .entitlements основной цели приложения и расширения:

  • Управление учетными данными сети Thread:

    <key>com.apple.developer.networking.manage-thread-network-credentials</key>
    <true/>
    

    Чтобы использовать это право в распределенной сборке, необходимо отправить в Apple форму запроса на получение права. Apple требует, чтобы вы подтвердили свое участие в Thread Group и что ваше Thread Border Router (TBR) сертифицировано Thread Group.

  • Информация о Wi-Fi:

    <key>com.apple.developer.networking.wifi-info</key>
    <true/>
    
  • Группы приложений. Добавьте общую группу приложений, чтобы основное приложение и расширение Matter Add Device могли обмениваться данными (например, group.com.yourdomain.appgroupname). Этот идентификатор создается и регистрируется разработчиком в Apple Developer Console и должен соответствовать группе приложений, настроенной в целевых возможностях в Xcode. Google Home SDK использует этот идентификатор в обеих целях, чтобы автоматически синхронизировать состояние ввода в эксплуатацию, учетные данные сети и списки комнат с помощью общего контейнера UserDefaults.

Общий доступ к Связке ключей (необязательно)

Если расширению приложения нужно получить учетные данные или токены доступа, сохраненные основным приложением с помощью UserInfo.authorizationToken(), необходимо настроить общую группу доступа к связке ключей для основного приложения и расширения в их файлах plist:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)your.shared.keychain.group</string>
</array>

Свойства Info.plist

Добавьте в файл Info.plist основной цели приложения следующие ключи описания:

  • Описание использования местоположения:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Your custom message explaining why location access is needed to read the current Wi-Fi SSID</string>
    
  • Сервисы Bonjour: В разделе NSBonjourServices укажите сервисы, необходимые для локального обнаружения Matter и Thread:

    <key>NSBonjourServices</key>
    <array>
        <string>_matter._tcp</string>
        <string>_matterc._udp</string>
        <string>_matterd._udp</string>
        <string>_meshcop._udp</string>
    </array>
    
  • Описание использования локальной сети. Добавьте ключ NSLocalNetworkUsageDescription с сообщением, объясняющим разрешения на обнаружение локальной сети.

Как настроить устройство

Чтобы настроить устройство Matter:

  1. Уведомите Home APIs iOS SDK о том, что нужно подготовиться к запросам на ввод в эксплуатацию Matter с помощью structure.prepareForMatterCommissioning(). Эта команда выполнит следующие действия:

    • Убедитесь, что разрешение предоставлено.
    • Убедитесь, что контроллер подключен к интернету и доступен.
    • Убедитесь, что в данный момент не выполняется другой сеанс ввода в эксплуатацию.
    do {
      try await structure.prepareForMatterCommissioning()
    } catch {
      // Failed to prepare for Matter Commissioning
      return
    }
    
  2. Создайте запрос с помощью MatterAddDeviceRequest(), чтобы начать процесс поддержки Matter от Apple.

    let topology = MatterAddDeviceRequest.Topology(
      ecosystemName: "Google Home",
      homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
    )
    
    let request = MatterAddDeviceRequest(topology: topology)
    
  3. Выполните запрос с помощью perform(). Если произойдет ошибка, отмените запрос на ввод в эксплуатацию с помощью structure.cancelMatterCommissioning().

    do {
      // Starting MatterAddDeviceRequest.
      try await request.perform()
      // Successfully completed MatterAddDeviceRequest.
      let commissionedDeviceIDs = try structure.completeMatterCommissioning()
      // Commissioned device IDs.
    } catch let error {
      structure.cancelMatterCommissioning()
      // Failed to complete MatterAddDeviceRequest.
    }
    
  4. Создайте App Group ID в Apple Developer Console, чтобы приложение могло взаимодействовать с расширением MatterAddDevice при вводе устройства в эксплуатацию.

    Вам также потребуется обновить идентификатор пакета приложения и профили инициализации, чтобы использовать этот идентификатор группы.

  5. При инициализации настройте экземпляр Home так, чтобы он использовал идентификатор группы.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions
    launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
      Home.configure {
        $0.sharedAppGroup = "group.com.sample.app.commissioning"
      }
    
      return true
    }
    
  6. Реализуйте расширение приложения Matter для iOS от Apple.

    В примере кода показана реализация подкласса MatterAddDeviceExtensionRequestHandler API от Apple.

    Как минимум, добавьте фреймворк GoogleHomeMatterCommissionerSDK в целевое расширение и переопределите три метода для вызова API Google Home platform (GHP)HomeMatterCommissioner.

    • commissionDevice
    • rooms
    • configureDevice
    import MatterSupport
    import GoogleHomeSDK
    import OSLog
    
    final class RequestHandler: MatterAddDeviceExtensionRequestHandler {
      // The App Group ID defined by the application to share information between the extension and main app.
      private static var appGroup = "group.com.sample.app.commissioning"
    
      ...
    
      // MARK: - Home API commissioning handlers
    
      /// Commissions a device to the Google Home ecosystem.
      /// - Parameters:
      ///   - home: The home that the device will be added to
      ///   - onboardingPayload: The payload to be sent to the Matter Commissioning SDK to commission the device.
      ///   - commissioningID: An identifier not used by the Home API SDK.
      override func commissionDevice(in home: MatterAddDeviceRequest.Home?, onboardingPayload: String, commissioningID: UUID) async throws {
        // Commission Matter device with payload.
    
        var onboardingPayloadForHub = onboardingPayload
        let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
        try await homeMatterCommissioner.commissionMatterDevice(
        onboardingPayload: onboardingPayloadForHub)
      }
    
      /// Obtains rooms from the Home Ecosystem to present to the user during the commissioning flow.
      /// - Parameter home: The home that the device will be added to.
      /// - Returns: A list of rooms if obtained from the Google Home ecosystem or an empty list if there was an error in getting them.
      override func rooms(in home: MatterAddDeviceRequest.Home?) async -> [MatterAddDeviceRequest.Room] {
        do {
          let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
          let fetchedRooms = try homeMatterCommissioner.fetchRooms()
          // Returning fetched rooms.
          return fetchedRooms
        } catch {
          // Failed to fetch rooms with error
          return []
        }
      }
    
      /// Pushes the device's configurations to the Google Home Ecosystem.
      /// - Parameters:
      ///   - name: The friendly name the user chose to set on the device.
      ///   - room: The room identifier that the user chose to put the device in.
      override func configureDevice(named name: String, in room: MatterAddDeviceRequest.Room?) async {
        // Configure Device name: room
        do {
          let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
          await homeMatterCommissioner.configureMatterDevice(
            deviceName: name, roomName: room?.displayName)
        } catch {
          // Configure Device failed with error
        }
      }
    }