Creare un'app mobile utilizzando le API Home su iOS

1. Introduzione

f154e30306882c74.png

Che cosa sono le API Home?

Le API Google Home forniscono un insieme di librerie che consentono agli sviluppatori di accedere all'ecosistema Google Home. Con le API Home, gli sviluppatori possono creare app che eseguono il provisioning e controllano senza problemi i dispositivi per la smart home.

3e11583c779a2cec.png

Questo video fornisce una breve panoramica dell'app mobile che creerai, quindi segui il video mentre svolgi il codelab.

Componenti delle API Home

Le API Home sono composte da:

  • API Device e Structure: interagisci con la casa di un utente. Le app possono utilizzare queste API per leggere informazioni su dispositivi, stanze e strutture (ad esempio, visualizzare la temperatura attuale del termostato) e controllare i dispositivi (ad esempio, modificare il setpoint del termostato).
  • API Commissioning: esegui la messa in servizio (configura) di nuovi dispositivi Matter nell'infrastruttura con il minimo sforzo.
  • API Automation: crea, elimina ed esegui query sulle automazioni in esecuzione nella casa di un utente.

Prerequisiti

Obiettivi didattici

  • Come creare un'app per iOS utilizzando le API Home con le best practice.
  • Come utilizzare le API Device e Structure per rappresentare e controllare una smart home.
  • Come utilizzare l'API Commissioning per aggiungere dispositivi all'ecosistema Google Home.
  • Come utilizzare l'API Automation per creare un'automazione di base.

2. Configurare La tua casa

Prepara i dispositivi

Il playground di Google Home offre una serie di dispositivi per la smart home emulati predefiniti ed è consigliato per esplorare tutto il potenziale delle API Home, soprattutto se hai un numero limitato di dispositivi in casa.

Segui le istruzioni per accedere a Google Home Playground e completare il collegamento dell'account nell'app Google Home. Al termine, dovresti essere in grado di vedere i dispositivi nella scheda "Dispositivi" dell'app Google Home.

c892afce113abe8f.png

3. Preparazione

Ottieni il codice dell'app di esempio

Inizia clonando il codice sorgente da GitHub:

git clone https://github.com/google-home/google-home-api-sample-app-ios.git

La directory di esempio contiene due rami, start e finished, per questo codelab.

  • start: Il codice iniziale di questo progetto in cui apporterai le modifiche per completare il codelab.
  • finished: il codice completato per questo codelab, utilizzato per controllare il tuo lavoro.

Esplora il codice "start"

Inizia questo codelab passando al ramo start del repository clonato:

git checkout start

Questo ramo contiene il codice iniziale del progetto. Modificherai questo codice durante il codelab per implementare la funzionalità completa. L'app di esempio del codelab fornisce una struttura di base creata in Swift per interagire con l'SDK iOS delle API Home. Diamo una rapida occhiata ai componenti chiave del progetto start:

  • Main Entry (GoogleHomeAPISampleIOSApp): situato in GoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift, è il punto di accesso principale dell'app. Configura e inizializza l'SDK e imposta l'interfaccia utente principale.
  • Core Views (View/):
    • MainView.swift: La visualizzazione principale dopo l'avvio, contenente il NavigationView principale. Gestisce la selezione della casa Google Home attiva e mostra il StructureView corrispondente.
    • StructureView.swift: mostra i contenuti della struttura attualmente selezionata, utilizzando le schede per passare da una griglia di Dispositivi all'elenco Automazioni. Fornisce anche menu per aggiungere stanze o dispositivi.
    • DeviceView.swift: rappresenta il riquadro interattivo per un singolo dispositivo all'interno della griglia StructureView.
    • AutomationsView.swift: mostra l'elenco delle automazioni esistenti per la struttura e fornisce la navigazione per creare o visualizzare i dettagli dell'automazione.
  • ViewModels (ViewModel/): Queste classi gestiscono lo stato e la logica delle visualizzazioni.
    • AccountViewModel.swift: gestisce la connessione all'oggetto Home e lo stato di autenticazione.
    • MainViewModel.swift: gestisce l'elenco degli oggetti Structure disponibili e tiene traccia della struttura selezionata.
    • StructureViewModel.swift: gestisce la visualizzazione delle camere e degli oggetti DeviceControl all'interno della struttura selezionata.
    • AutomationList.swift, AutomationViewModel.swift e così via: gestisce il recupero, la visualizzazione, la creazione e la gestione delle automazioni.
  • Device Controls (ViewModel/Device/):
    • DeviceControl.swift: una classe base per rappresentare i dispositivi controllabili nella UI.
    • Sottoclassi specifiche (LightControl.swift, FanControl.swift, OnOffPlugInUnitControl.swift e così via): implementa la logica della UI, il controllo del dispositivo e la mappatura dello stato per diversi tipi di dispositivi in base alle loro caratteristiche.
    • DeviceControlFactory.swift: responsabile della creazione della sottoclasse DeviceControl appropriata per un determinato HomeDevice.
  • Commissioning (Commissioning/):
    • CommissioningManager.swift: contiene la logica per la gestione del flusso di provisioning del dispositivo Matter.
  • Utilities & UX (Utils/, UX/, Storage/): contiene codice helper per gli elementi della UI (colori, dimensioni), la gestione degli errori, l'archiviazione dei dati (SelectedStructureStorage.swift) e altre utilità.

In questo codelab troverai commenti come TODO o blocchi di codice e avvisi commentati all'interno del progetto start. Questi segni indicano le sezioni in cui aggiungere o decommentare il codice per implementare la funzionalità richiesta, seguendo i passaggi forniti.

Crea file di configurazione del deployment Apple

Per configurare App Attest, segui le istruzioni per creare file di configurazione del deployment Apple. Tieni presente che dopo la configurazione, l'app può essere implementata solo su un dispositivo reale, non in un simulatore.

Configura l'autenticazione

Per ottenere l'ID client OAuth e abilitare le API per la casa, accedi prima a Google Cloud e crea un nuovo progetto o selezionane uno esistente. Poi, segui i passaggi forniti per generare l'ID client OAuth e attivare le API per la casa e aggiungi il tuo account alla lista consentita.

Configura l'SDK

Ottieni l'SDK per iOS delle API Home e configuralo seguendo le istruzioni di configurazione fornite in Configurare l'SDK. Ricordati di sostituire HOME_API_TODO_ADD_APP_GROUP con il tuo gruppo di app.

Crea ed esegui il progetto

Dopo aver creato ed eseguito il progetto con il ramo start, dovrebbero essere visualizzati una finestra di dialogo TODO e una schermata con il messaggio "Accesso richiesto". L'interazione con le API Home verrà implementata nelle sezioni seguenti.

bd56b7080037e38a.png 9c0f08a3f4197a77.png

Nota: individua il codice da modificare cercando nel progetto il testo visualizzato nella finestra di dialogo. Ad esempio, cerca "TODO: initialize Home".

4. Inizializzazione

Inizializzare la casa

Prima di utilizzare una delle API Home per iOS, devi inizializzare Home nella tua app. Home è il punto di accesso di primo livello all'SDK e fornisce l'accesso a tutte le entità nella struttura dell'utente. Quando richiedi tutte le entità di un determinato tipo, l'API restituisce un oggetto Query che ti consente di scegliere come ricevere i risultati. In GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift, rimuovi il commento e l'avviso in connect() per implementare l'inizializzazione della casa.

  /// TODO: initialize Home
  /// Remove comments to initialize Home and handling permission.
  private func connect() {
    Task {
      do {
        self.home = try await Home.connect()
      } catch {
        Logger().error("Auth error: \(error).")
      }
    }
  }

Autorizzazione a utilizzare le API Home

La schermata del consenso viene visualizzata quando esegui l'app. Scegli la struttura di Google Home e seleziona l'account presente nella lista consentita del tuo progetto Google Cloud.

47310f458c0094d9.png 4a571dbd9979a88c.png e29c75891a3a67af.png

5. Dispositivi e strutture

Ottenere stanze e dispositivi

In GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, rimuovi il commento e l'avviso in getRoomsAndDevices() per ottenere le stanze e i dispositivi nella struttura selezionata con home.rooms() e home.devices(), rispettivamente.

  /// TODO: get rooms and devices
  /// Remove comments to get the rooms and devices from home entry
  private func getRoomsAndDevices(){
    self.home.rooms().batched()
      .combineLatest(self.home.devices().batched())
      .receive(on: DispatchQueue.main)
      .catch { error in
        Logger().error("Failed to load rooms and devices: \(error)")
        return Just((Set<Room>(), Set<HomeDevice>()))
      }
      .map { [weak self] rooms, devices in
        guard let self = self else { return [] }
        self.hasLoaded = true
        return self.process(rooms: rooms, devices: devices)
      }
      /// receive from .map and .assign() to publisher entries
      .assign(to: &self.$entries)
  }

La funzione process() si assicura innanzitutto che i dispositivi si trovino nella stessa stanza prima di farli interagire come HomeDevices utilizzando DeviceControl e DeviceControlFactory.

4c677c4c294e67ca.png

Nota: se il tuo dispositivo non è elencato in DeviceControlFactory, verrà visualizzato come "Non supportato". Per scoprire di più sui dispositivi supportati, consulta la pagina Tipi di dispositivi supportati su iOS.

Interagire con un dispositivo

Il plug-in outlet1 è inizialmente inattivo quando tocchi o scorri sui dispositivi. Per attivare l'interazione, individua GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift e rimuovi il commento e l'avviso all'interno della funzione primaryAction().

  /// TODO: primary action of OnOffPlug
  /// Toggles the plug; usually provided as the `action` callback on a Button.
  public override func primaryAction() {
    self.updateTileInfo(isBusy: true)
    Task { @MainActor [weak self] in
      guard
        let self = self,
        let onOffPluginUnitDeviceType = self.onOffPluginUnitDeviceType,
        let onOffTrait = onOffPluginUnitDeviceType.matterTraits.onOffTrait
      else { return }

      do {
        try await onOffTrait.toggle()
      } catch {
        Logger().error("Failed to to toggle OnOffPluginUnit on/off trait: \(error)")
        self.updateTileInfo(isBusy: false)
      }
    }
  }

La funzione primaryAction(), che si trova all'interno della classe OnOffPlugInUnitControl, attiva/disattiva una presa intelligente o qualsiasi dispositivo rappresentato da OnOffPluginUnitDeviceType.

Altri esempi di controllo dei dispositivi sono disponibili in GoogleHomeAPISampleIOS/ViewModel/Device.

Creare una nuova stanza

L'API Structure consente la creazione e l'eliminazione di stanze, nonché il trasferimento di dispositivi tra le stanze.

In GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, rimuovi il commento e l'avviso in addRoom().

  /// TODO: add room
  /// Add a new room in a given structure.
  func addRoom(name: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.createRoom(name: name)
      } catch {
        Logger().error("Failed to create room: \(error)")
      }
    }
  }

Per creare una nuova stanza con structure.createRoom(), vai nell'angolo in alto a sinistra e seleziona l'icona "+" > Aggiungi stanza. Inserisci il nuovo nome della stanza e fai clic su "Crea stanza". La nuova stanza verrà visualizzata dopo alcuni secondi.

b122ae6642b7da1c.png a45f785e1d51938e.png 7753b56cbdcff8d6.png

Spostare il dispositivo in un'altra stanza

In GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, rimuovi il commento e l'avviso in moveDevice().

  /// TODO: move device
  /// Move a device into a different room.
  func moveDevice(device deviceID: String, to roomID: String, structure: Structure) {
    Task {
      do {
        _ = try await structure.move(device: deviceID, to: roomID)
      } catch {
        Logger().error("Failed to move to room: \(error)")
      }
    }
  }

Per spostare il dispositivo con structure.move(), tieni premuto, seleziona "Sposta in un'altra stanza" e scegli la nuova stanza.

f9627592af44163d.png fd126fabb454f2bf.png 813e1e23e50cd9f6.png

Eliminare una stanza vuota

In GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, rimuovi il commento e l'avviso in removeRoom().

  /// TODO: delete room
  /// Delete an empty room in a given structure.
  func removeRoom(id: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.deleteRoom(id: id)
      } catch {
        Logger().error("Failed to remove room: \(error)")
      }
    }
  }

Per eliminare una stanza vuota con structure.deleteRoom(), fai clic sull'icona del cestino a destra del nome della stanza e conferma l'azione. Tieni presente che è possibile eliminare solo le stanze vuote.

4f129262ad67f564.png

Nota: sposta il dispositivo indietro per creare una stanza vuota.

6. Commissioning

Nota: questa sezione richiede un hub Google e un dispositivo Matter. Assicurati che l'hub Google nella tua struttura sia online e raggiungibile. Se non hai un dispositivo Matter, prova a utilizzare l'app Matter Virtual Device.

Aggiungere un dispositivo Matter

L'API Commissioning consente alla tua app di aggiungere nuovi dispositivi Matter alla casa e all'Account Google dell'utente. In questo modo, l'esperienza di configurazione è fluida e avviene direttamente all'interno dell'app.

In GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift, rimuovi il commento e l'avviso in addMatterDevice().

  /// TODO: add Matter Device
  /// Starts the Matter device commissioning flow to add the device to the user's home.
  /// - Parameters:
  ///   - structure: The structure to add the device to.
  ///   - add3PFabricFirst: Whether to add the device to a third party fabric first.
  public func addMatterDevice(to structure: Structure, add3PFabricFirst: Bool) {
    self.isCommissioning = true

    /// pass if it's 1p or 3p commissioning
    let userDefaults = UserDefaults(
      suiteName: CommissioningManager.appGroup)
    userDefaults?.set(
    add3PFabricFirst, forKey: CommissioningUserDefaultsKeys.shouldPerform3PFabricCommissioning)

    Task {
      do {
        try await structure.prepareForMatterCommissioning()
      } catch {
        Logger().error("Failed to prepare for Matter Commissioning: \(error).")
        self.isCommissioning = false
        return
      }

      // Prepare the Matter request by providing the ecosystem name and home to be added to.
      let topology = MatterAddDeviceRequest.Topology(
        ecosystemName: "Google Home",
        homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
      )
      let request = MatterAddDeviceRequest(topology: topology)

      do {
        Logger().info("Starting MatterAddDeviceRequest.")
        try await request.perform()
        Logger().info("Completed MatterAddDeviceRequest.")
        let commissionedDeviceIDs = try structure.completeMatterCommissioning()
        Logger().info("Commissioned device IDs: \(commissionedDeviceIDs).")
      } catch let error {
        structure.cancelMatterCommissioning()
        Logger().error("Failed to complete MatterAddDeviceRequest: \(error).")
      }

      self.isCommissioning = false
    }
  }

Per creare una nuova stanza con structure.prepareForMatterCommissioning(), vai nell'angolo in alto a sinistra e seleziona l'icona "+" > Aggiungi dispositivo a Google Fabric. Utilizza MatterAddDeviceRequest per aggiungere il dispositivo Matter alla stanza. Dopo aver selezionato la stanza e il nome del dispositivo, quest'ultimo viene visualizzato nella schermata "Dispositivi".

adf6cbb531787aaf.png f002bd6320bc480d.png

7. Automazione

Visualizzare tutte le automazioni nella struttura

Tocca Automazioni nella barra di navigazione in basso. Verranno elencate tutte le automazioni nella tua struttura con structure.listAutomations().

cc6d50f72f812c24.png

Nota: se non hai configurato automazioni della casa, vedrai il messaggio "Aggiungi un'automazione per iniziare".

Crea un'automazione

Ora che hai familiarità con le API Device e Structure e con l'aggiunta di un nuovo dispositivo, è il momento di creare una nuova automazione utilizzando l'API Automation.

In GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift, rimuovi il commento, l'avviso e l'automazione vuota in lightAutomation().

  /// TODO: create automation
  /// - Parameter devices: devices in current selected structure
  /// - Returns: the automation object to be created
  /// This automation will turn off the light after 5 seconds.
  public func lightAutomation(devices: Set<HomeDevice>) async throws -> any DraftAutomation {
    let light = devices.first { $0.name == "light2" }
    
    guard let light else {
      Logger().error("Unable to find light device with name light2")
      throw HomeError.notFound("No devices support OnOffLightDeviceType")
    }
    
    return automation(
      name: "Turn off light after 5 seconds",
      description:
        """
        Turns off light2 after it has been on for 5 seconds.
        """
    ) {
      let onOffStarter = starter(light, OnOffLightDeviceType.self, OnOffTrait.self)
      onOffStarter
      condition {
        onOffStarter.onOff.equals(true)
      }
      delay(for: Duration.seconds(5))
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.off()
      }
    }
  }

Per creare un'automazione che spegne la luce cinque secondi dopo l'accensione, vai alla visualizzazione delle automazioni e fai clic sul pulsante "+ Aggiungi". Poi seleziona "Spegni la luce dopo 5 secondi". Verranno visualizzati i dettagli dell'automazione, tra cui starter, condition e action. Fai clic su "Salva" per creare l'automazione entro il giorno structure.createAutomation().

21c1f8ea2a29134b.png 4bd36f6ed9c5f6e9.png

Nota: le automazioni disponibili dipendono dai dispositivi presenti in casa. Se non vedi automazioni disponibili, prova a rinominare il dispositivo di illuminazione in "light2".

Torna alla scheda "Dispositivi" e accendi la luce denominata "light2". Si spegnerà automaticamente dopo cinque secondi.

I componenti di un'automazione sono:

  • Comando iniziale:un evento che avvia l'automazione. In questo esempio, l'automazione si avvierà una volta che si verifica una modifica il giorno OnOffTrait.
  • Condizione:verifica se il dispositivo iniziale soddisfa requisiti specifici. In questo caso, l'automazione verrà eseguita se la luce è accesa.
  • Azione:l'automazione che vuoi eseguire, ma solo se il comando iniziale soddisfa i requisiti. Se le condizioni sono soddisfatte, la luce viene spenta.

Per altri esempi, consulta la pagina Automazioni di esempio.

Eliminare un'automazione

Il metodo structure.deleteAutomation() viene richiamato quando scorri il dito verso sinistra su un'automazione esistente e tocchi l'icona del cestino per rimuoverla dalla tua casa.

dc678cd9e16f89a5.png

8. Complimenti

Complimenti! Hai creato correttamente un'app per la smart home di base utilizzando le API Home per iOS.

Obiettivi raggiunti:

  • Inizializzazione: hai connesso la tua app all'ecosistema Google Home utilizzando Home.connect().
  • Autorizzazioni: gestisce l'autenticazione e l'autorizzazione degli utenti per l'accesso ai dati della casa.
  • Dispositivi e strutture: stanze e dispositivi recuperati e visualizzati utilizzando home.rooms() e home.devices().
  • Controllo dei dispositivi: implementa l'interazione con i dispositivi, ad esempio l'attivazione/disattivazione dello stato di un OnOffPluginUnitDeviceType chiamando i comandi sulle relative caratteristiche.
  • Gestione della struttura: è stata aggiunta la funzionalità per creare nuove stanze (structure.createRoom()), spostare i dispositivi tra le stanze (structure.move()) ed eliminare le stanze vuote (structure.deleteRoom()).
  • Provisioning: è stato integrato il flusso di provisioning dell'SDK per aggiungere nuovi dispositivi Matter (MatterAddDeviceRequest).
  • Automazione: è stato esaminato come elencare, creare (structure.createAutomation()) ed eliminare (structure.deleteAutomation()) le automazioni all'interno di una struttura.

Ora hai una conoscenza di base di come sfruttare le API Home per creare esperienze di controllo della smart home avanzate su iOS.

Passaggi successivi:

  • Esplora il controllo di altri tipi di dispositivi forniti nell'app di esempio (luci, ventilatori, tapparelle e così via).
  • Scopri di più sulle diverse caratteristiche e sui diversi comandi disponibili per vari dispositivi.
  • Prova a creare automazioni più complesse utilizzando comandi iniziali, condizioni e azioni diversi.
  • Per funzionalità e dettagli più avanzati, consulta la documentazione delle API per la casa.

Ben fatto!