1. Introduzione
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 commissionano e controllano facilmente i dispositivi per la smart home.
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 set-point del termostato).
- API di messa in servizio: esegui la messa in servizio (configura) dei nuovi dispositivi Matter nell'Infrastruttura con il minimo sforzo.
- API Automation: crea, elimina e esegui query sulle automazioni in esecuzione nella casa di un utente.
Prerequisiti
- La versione stabile più recente di Xcode.
- Un Account Google con almeno una casa.
- Un dispositivo iOS con iOS 16.4 o versioni successive configurato con l'account di test.
- Un ID Apple registrato al programma Apple Developer per generare il profilo di provisioning.
- Un hub Google che supporta le API Home.
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 casa
Prepara i dispositivi
Google Home Playground 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 riuscire a vedere i dispositivi nella scheda "Dispositivi" dell'app Google Home.
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 branch, start
e finished
, per questo codelab.
start
: il codice di avvio di questo progetto in cui apporterai modifiche per completare il codelab.finished
: il codice completo di questo codelab, utilizzato per controllare il tuo lavoro.
Esplora il codice "start"
Per iniziare questo codelab, passa al ramo start
del repository clonato:
git checkout start
Questo ramo contiene il codice di avvio 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 per iOS delle API Home. Diamo un'occhiata ai componenti chiave del progetto start
:
Main Entry (GoogleHomeAPISampleIOSApp)
: si trova inGoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift
ed è il punto di contatto principale dell'app. Configura e inizializza l'SDK e imposta l'interfaccia utente principale.Core Views (View/)
:MainView.swift
: la visualizzazione principale dopo il lancio, contenente ilNavigationView
principale. Gestisce la selezione della casa Google Home attiva e mostra ilStructureView
corrispondente.StructureView.swift
: mostra i contenuti della struttura attualmente selezionata, utilizzando le schede per passare da una griglia di Dispositivi all'elenco di Automazioni. Fornisce inoltre menu per l'aggiunta di stanze o dispositivi.DeviceView.swift
: rappresenta il riquadro interattivo di un singolo dispositivo all'interno della grigliaStructureView
.AutomationsView.swift
: mostra l'elenco delle automazioni esistenti per la struttura e consente di creare o visualizzare i dettagli delle automazioni.
ViewModels (ViewModel/)
: questi classi gestiscono lo stato e la logica delle visualizzazioni.AccountViewModel.swift
: gestisce la connessione all'oggettoHome
e gestisce lo stato di autenticazione.MainViewModel.swift
: gestisce l'elenco degli oggettiStructure
disponibili e tiene traccia della struttura selezionata.StructureViewModel.swift
: gestisce la visualizzazione delle camere e degli oggettiDeviceControl
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 di base per rappresentare i dispositivi controllabili nell'interfaccia utente.- Classi secondarie specifiche (
LightControl.swift
,FanControl.swift
,OnOffPlugInUnitControl.swift
e così via): implementano la logica dell'interfaccia utente, 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 sottoclasseDeviceControl
appropriata per un determinatoHomeDevice
.
Commissioning (Commissioning/)
:CommissioningManager.swift
: contiene la logica per la gestione del flusso di messa in servizio del dispositivo Matter.
Utilities & UX (Utils/, UX/, Storage/)
: contiene codice di supporto per gli elementi dell'interfaccia utente (colori, dimensioni), la gestione degli errori, lo stoccaggio 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
. Segnalano le sezioni in cui aggiungere o rimuovere il commento del codice per implementare la funzionalità richiesta, seguendo i passaggi indicati.
Creare file di configurazione del deployment Apple
Per configurare App Attest, segui le istruzioni per la creazione dei 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 attivare le API Home, accedi prima a Google Cloud e crea un nuovo progetto o selezionane uno esistente. Poi, segui i passaggi indicati per generare l'ID client OAuth e attivare le API Home e aggiungi il tuo account alla lista consentita.
Configura l'SDK
Ottieni l'SDK per iOS delle API Home e configuralo facendo riferimento alle istruzioni di configurazione riportate in Configurare l'SDK. Ricorda di sostituire HOME_API_TODO_ADD_APP_GROUP
con il tuo gruppo di app.
Crea ed esegui il progetto
Dopo aver compilato ed eseguito il progetto con il ramo start
, dovrebbe apparire una finestra di dialogo TODO
e una schermata con il messaggio "Accesso richiesto". L'interazione con le API Home verrà implementata nelle sezioni seguenti.
Nota: individua il codice che deve essere modificato cercando nel progetto il testo visualizzato nella finestra di dialogo. Ad esempio, cerca "DA FARE: inizializza Home".
4. Inizializzazione
Inizializzare la casa
Prima di utilizzare una delle API Home per iOS, devi inizializzare Home
nella tua app. Home
è l'elemento di primo livello dell'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 per utilizzare le API Home
La schermata del consenso viene visualizzata quando esegui l'app. Scegli la struttura di Google Home e seleziona l'account che si trova nella lista consentita del tuo progetto Google Cloud.
5. Strutture e dispositivi
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
.
Nota: se il tuo dispositivo non è elencato nel 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 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 lo stato di una presa smart o di 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 ed 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 all'angolo in alto a sinistra e seleziona l'icona "+" > Aggiungi stanza. Inserisci il nome della nuova stanza e fai clic su "Crea stanza". La nuova stanza verrà visualizzata dopo alcuni secondi.
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 cambiare la posizione del dispositivo con structure.move()
, tieni premuto il pulsante, seleziona "Sposta in un'altra stanza" e scegli la nuova stanza.
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 puoi eliminare solo le stanze vuote.
Nota: sposta il dispositivo indietro per creare una stanza vuota.
6. Messa in servizio
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 di messa in servizio consente alla tua app di aggiungere nuovi dispositivi Matter alla casa e all'Account Google dell'utente. In questo modo, la configurazione 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 tua stanza. Dopo aver selezionato la stanza e il nome del dispositivo, il dispositivo viene visualizzato nella schermata "Dispositivi".
7. Automazione
Visualizzare tutte le automazioni nella struttura
Tocca Automazioni nella barra di navigazione in basso. Verranno elencate tutte le automazioni della tua struttura con structure.listAutomations()
.
Nota: se non hai configurato alcuna automazione per la casa, viene visualizzato 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 spenga la luce cinque secondi dopo l'accensione, vai alla visualizzazione delle automazioni e fai clic sul pulsante "+ Aggiungi". Quindi 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 per structure.createAutomation()
.
Nota: le automazioni disponibili dipendono dai dispositivi presenti in casa. Se non vedi automazioni disponibili, prova a rinominare il dispositivo di illuminazione in "lampada2".
Torna alla scheda "Dispositivi" e accendi la luce denominata "luce2". Si spegnerà automaticamente dopo cinque secondi.
I componenti di un'automazione sono:
- Comando iniziale:si tratta di un evento che avvia l'automazione. In questo esempio, l'automazione si avvia quando si verifica una modifica in
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 spia viene spenta.
Per altri esempi, consulta la pagina Automazioni di esempio.
Eliminare un'automazione
Il metodo structure.deleteAutomation()
viene invocato quando scorri verso sinistra su un'automazione esistente e tocchi l'icona del cestino per rimuoverla dalla struttura.
8. Complimenti
Complimenti! Hai creato un'app per la smart home di base utilizzando le API Home per iOS.
Che cosa hai realizzato:
- Iniziale: hai collegato la tua app all'ecosistema Google Home utilizzando
Home.connect()
. - Autorizzazioni: gestite l'autenticazione e l'autorizzazione degli utenti per accedere ai dati della casa.
- Dispositivi e strutture: stanze e dispositivi recuperati e visualizzati utilizzando
home.rooms()
ehome.devices()
. - Controllo dispositivo: è stata implementata l'interazione con il dispositivo, ad esempio l'attivazione/la disattivazione dello stato di un
OnOffPluginUnitDeviceType
chiamando i comandi sui relativi tratti. - Gestione della struttura: sono state aggiunte funzionalità per creare nuove stanze (
structure.createRoom()
), spostare i dispositivi da una stanza all'altra (structure.move()
) ed eliminare le stanze vuote (structure.deleteRoom()
). - Commissioning: è stato integrato il flusso di messa in servizio dell'SDK per aggiungere nuovi dispositivi Matter (
MatterAddDeviceRequest
). - Automazione: è stato illustrato come elencare, creare (
structure.createAutomation()
) ed eliminare (structure.deleteAutomation()
) le automazioni all'interno di una struttura.
Ora hai una conoscenza di base su come sfruttare le API Home per creare esperienze di controllo della smart home complete su iOS.
Passaggi successivi:
- Esplora il controllo di altri tipi di dispositivi forniti nell'app di esempio (lampade, ventilatori, tende e così via).
- Approfondisci i diversi tratti e 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 Home.
Ben fatto!