1. Introducción
¿Qué son las APIs de Home?
Las APIs de Google Home proporcionan un conjunto de bibliotecas para que los desarrolladores aprovechen el ecosistema de Google Home. Con las APIs de Home, los desarrolladores pueden compilar apps que comisionen y controlen dispositivos de casa inteligente sin problemas.
Componentes de las APIs de Home
Las APIs de Home se componen de lo siguiente:
- APIs de Device y Structure: Interactúa con la casa de un usuario. Las apps pueden usar estas APIs para leer información sobre dispositivos, habitaciones y estructuras (por ejemplo, ver la temperatura actual del termostato) y controlar dispositivos (por ejemplo, cambiar el punto de ajuste del termostato).
- API de comisión: Comisiona (configura) nuevos dispositivos Matter en el tejido con el mínimo esfuerzo.
- API de Automation: Crea, borra y consulta automatizaciones que se ejecutan en la casa de un usuario.
Requisitos previos
- La versión estable más reciente de Xcode
- Una Cuenta de Google que tenga al menos una estructura en la casa
- Un dispositivo iOS con iOS 16.4 o versiones posteriores configurado con la cuenta de prueba
- Un ID de Apple inscrito en el Programa para Desarrolladores de Apple para generar el perfil de aprovisionamiento
- Un conmutador de Google que admita las APIs de Home
Qué aprenderás
- Cómo compilar una app para iOS con las APIs de Home y las prácticas recomendadas
- Cómo usar las APIs de Device y Structure para representar y controlar una casa inteligente
- Cómo usar la API de Commissioning para agregar dispositivos al ecosistema de Google Home
- Cómo usar la API de Automation para crear una automatización básica
2. Cómo configurar tu casa
Prepara los dispositivos
Google Home Playground ofrece una variedad de dispositivos inteligentes para la casa emulados y precompilados, y se recomienda para explorar todo el potencial de las APIs de Home, especialmente si tienes una cantidad limitada de dispositivos en tu casa.
Sigue las instrucciones para acceder a Google Home Playground y completar la vinculación de la cuenta en la app de Google Home. Después de completar este proceso, deberías poder ver los dispositivos en la pestaña "Dispositivos" de la app de Google Home.
3. Cómo prepararte
Obtén el código de la app de ejemplo
Comienza por clonar el código fuente de GitHub:
git clone https://github.com/google-home/google-home-api-sample-app-ios.git
El directorio de ejemplo contiene dos ramas, start
y finished
, para este codelab.
start
: Es el código de partida para este proyecto, en el que realizarás cambios para completar el codelab.finished
: Es el código completo de este codelab, que se usa para verificar tu trabajo.
Explora el código de inicio
Para comenzar este codelab, cambia a la rama start
de tu repositorio clonado:
git checkout start
Esta rama contiene el código de partida del proyecto. Modificarás este código a lo largo del codelab para implementar la funcionalidad completa. La app de ejemplo del codelab proporciona una estructura básica compilada en Swift para interactuar con el SDK de iOS de las APIs de Home. Echemos un vistazo rápido a los componentes clave del proyecto start
:
Main Entry (GoogleHomeAPISampleIOSApp)
: Se encuentra enGoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift
y es el punto de entrada principal de la app. Configura e inicializa el SDK y establece la interfaz de usuario principal.Core Views (View/)
:MainView.swift
: La vista raíz después del inicio, que contiene elNavigationView
principal. Controla la selección de la estructura activa de Google Home y muestra elStructureView
correspondiente.StructureView.swift
: Muestra el contenido de la estructura seleccionada actualmente. Usa pestañas para cambiar entre una cuadrícula de Dispositivos y la lista de Automatizaciones. También proporciona menús para agregar habitaciones o dispositivos.DeviceView.swift
: Representa la tarjeta interactiva de un solo dispositivo dentro de la cuadrículaStructureView
.AutomationsView.swift
: Muestra la lista de automatizaciones existentes para la estructura y proporciona navegación para crear o ver los detalles de la automatización.
ViewModels (ViewModel/)
: Estas clases administran el estado y la lógica de las vistas.AccountViewModel.swift
: Controla la conexión con el objetoHome
y administra el estado de autenticación.MainViewModel.swift
: Administra la lista de objetosStructure
disponibles y realiza un seguimiento de la estructura seleccionada.StructureViewModel.swift
: Administra la visualización de habitaciones y objetosDeviceControl
dentro de la estructura seleccionada.AutomationList.swift
,AutomationViewModel.swift
, etcétera: Controla la recuperación, la visualización, la creación y la administración de automatizaciones.
Device Controls (ViewModel/Device/)
:DeviceControl.swift
: Es una clase base para representar dispositivos controlables en la IU.- Subclases específicas (
LightControl.swift
,FanControl.swift
,OnOffPlugInUnitControl.swift
, etcétera): Implementa la lógica de la IU, el control de dispositivos y la asignación de estado para diferentes tipos de dispositivos según sus atributos. DeviceControlFactory.swift
: Es responsable de crear la subclaseDeviceControl
adecuada para unHomeDevice
determinado.
Commissioning (Commissioning/)
:CommissioningManager.swift
: Contiene la lógica para administrar el flujo de comisión de dispositivos Matter.
Utilities & UX (Utils/, UX/, Storage/)
: Contiene código de ayuda para elementos de la IU (colores, dimensiones), control de errores, almacenamiento de datos (SelectedStructureStorage.swift
) y otras utilidades.
A lo largo de este codelab, encontrarás comentarios como TODO
o bloques de código y alertas comentados dentro del proyecto start
. Estos marcan las secciones en las que agregarás o quitarás comentarios del código para implementar la funcionalidad requerida siguiendo los pasos proporcionados.
Crea archivos de configuración de implementación de Apple
Para configurar App Attest, sigue las instrucciones para crear archivos de configuración de implementación de Apple. Ten en cuenta que, después de la configuración, la app solo se puede implementar en un dispositivo real, no en un simulador.
Configura la autenticación
Para obtener el ID de cliente de OAuth y habilitar las APIs de Home, primero accede a Google Cloud y crea un proyecto nuevo o selecciona uno existente. Luego, sigue los pasos que se proporcionan para generar el ID de cliente de OAuth y habilitar las APIs de Home, y agrega tu cuenta a la lista de entidades permitidas.
Configura el SDK
Obtén el SDK de las APIs de Home para iOS y configúralo. Para ello, consulta las instrucciones de configuración que se proporcionan en Cómo configurar el SDK. Recuerda reemplazar HOME_API_TODO_ADD_APP_GROUP
por tu propio grupo de apps.
Compila y ejecuta el proyecto
Después de compilar y ejecutar el proyecto con la rama start
, debería aparecer un diálogo TODO
y una pantalla que muestre el mensaje "Se requiere acceso". La interacción con las APIs de Home se implementará en las siguientes secciones.
Nota: Para encontrar el código que se debe modificar, busca en el proyecto el texto que se muestra en el diálogo. Por ejemplo, busca "TODO: inicializar Home".
4. Inicialización
Inicializa la página principal
Antes de usar cualquiera de las APIs de Home para iOS, debes inicializar Home
en tu app. Home
es la entrada de nivel superior al SDK y proporciona acceso a todas las entidades de la estructura del usuario. Cuando solicitas todas las entidades de un tipo en particular, la API muestra un objeto Query
que te permite elegir cómo recibir los resultados. En GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift
, quita el comentario y la alerta en connect()
para implementar la inicialización de la 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).")
}
}
}
Permiso para usar las APIs de Home
La pantalla de consentimiento aparecerá cuando ejecutes la app. Elige la estructura de Google Home y selecciona la cuenta que se encuentra en la lista de entidades permitidas de tu proyecto de Google Cloud.
5. Dispositivos y estructuras
Cómo obtener habitaciones y dispositivos
En GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
, quita el comentario y la alerta en getRoomsAndDevices()
para obtener las habitaciones y los dispositivos de la estructura seleccionada con home.rooms()
y home.devices()
, respectivamente.
/// 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 función process()
primero se asegura de que los dispositivos estén en la misma habitación antes de hacer que interactúen como HomeDevices
con DeviceControl
y DeviceControlFactory
.
Nota: Si tu dispositivo no aparece en DeviceControlFactory
, aparecerá como “No compatible”. Para obtener más información sobre los dispositivos compatibles, consulta la página Tipos de dispositivos compatibles en iOS.
Interactuar con un dispositivo
Inicialmente, el enchufe outlet1
está inactivo cuando se presiona o se desliza en los dispositivos. Para habilitar la interacción con él, busca GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift
y quita el comentario y la alerta dentro de la función 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 función primaryAction()
, que se encuentra dentro de la clase OnOffPlugInUnitControl
, activa o desactiva el estado de encendido o apagado de un enchufe inteligente o cualquier dispositivo representado por OnOffPluginUnitDeviceType
.
Hay ejemplos adicionales de control de dispositivos disponibles en GoogleHomeAPISampleIOS/ViewModel/Device
.
Cómo crear una nueva habitación
La API de Structure permite crear y borrar habitaciones, así como transferir dispositivos entre ellas.
En GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
, quita el comentario y la alerta en 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)")
}
}
}
Para crear una habitación nueva con structure.createRoom()
, navega a la esquina superior izquierda y selecciona el ícono “+” > Agregar habitación. Ingresa el nombre de la sala nueva y haz clic en “Crear sala”. La habitación nueva aparecerá después de unos segundos.
Cómo mover el dispositivo a otra habitación
En GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
, quita el comentario y la alerta en 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)")
}
}
}
Para cambiar la ubicación del dispositivo con structure.move()
, mantén presionado el dispositivo, selecciona "Mover a otra habitación" y elige la habitación nueva.
Cómo borrar una habitación vacía
En GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
, quita el comentario y la alerta en 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)")
}
}
}
Para borrar una sala vacía con structure.deleteRoom()
, haz clic en el ícono de papelera que se encuentra a la derecha del nombre de la sala y confirma la acción. Ten en cuenta que solo se pueden borrar las habitaciones vacías.
Nota: Vuelve a colocar el dispositivo para crear una habitación vacía.
6. Puesta en marcha
Nota: Esta sección requiere una unidad central de Google y un dispositivo Matter. Asegúrate de que el concentrador de Google de tu estructura esté en línea y sea accesible. Si no tienes un dispositivo Matter, prueba con la app de dispositivo virtual de Matter.
Cómo agregar un dispositivo Matter
La API de Commissioning permite que tu app agregue dispositivos Matter nuevos a la casa y la Cuenta de Google del usuario. Esto proporciona una experiencia de configuración fluida directamente en tu app.
En GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift
, quita el comentario y la alerta en 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
}
}
Para crear una habitación nueva con structure.prepareForMatterCommissioning()
, navega a la esquina superior izquierda y selecciona el ícono “+” > Agregar dispositivo a Google Fabric. Usa MatterAddDeviceRequest
para agregar el dispositivo Matter a tu habitación. Después de seleccionar la habitación y el nombre del dispositivo, este se mostrará en la pantalla "Dispositivos".
7. Automatización
Consulta todas las automatizaciones de la estructura
Presiona Automatizaciones en la barra de navegación en la parte inferior. Se mostrarán todas las automatizaciones de tu estructura con structure.listAutomations()
.
Nota: Si no tienes ninguna automatización de la casa configurada, verás el mensaje "Agrega una automatización para comenzar".
Crea una automatización
Ahora que conoces las APIs de Device y Structure, y sabes cómo agregar un dispositivo nuevo, es hora de crear una automatización nueva con la API de Automation.
En GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift
, quita el comentario, la alerta y la automatización vacía en 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()
}
}
}
Para crear una automatización que apague la luz cinco segundos después de que se encienda, ve a la vista de automatización y haz clic en el botón “+ Agregar”. Luego, selecciona "Apagar la luz después de 5 segundos". Aparecerán los detalles de la automatización, incluidos starter
, condition
y action
. Haz clic en "Guardar" para crear la automatización de structure.createAutomation()
.
Nota: Las automatizaciones disponibles dependen de los dispositivos que tengas en tu casa. Si no ves ninguna automatización disponible, cambia el nombre de tu dispositivo de luz a "luz2".
Regresa a la pestaña "Dispositivos" y enciende la luz llamada "luz2". Se apagará automáticamente después de cinco segundos.
Los componentes de una automatización son los siguientes:
- Activador: Es un evento que inicia la automatización. En este ejemplo, la automatización se iniciaría una vez que haya un cambio en
OnOffTrait
. - Condición: Verifica si el dispositivo de activación cumple con requisitos específicos. En este caso, la automatización se ejecutaría si la luz está encendida.
- Acción: Esta es la automatización que deseas realizar, pero solo si el activador cumple con los requisitos. Si se cumplen las condiciones, la luz se apagará.
Para ver ejemplos adicionales, consulta la página Ejemplos de automatizaciones.
Cómo borrar una automatización
El método structure.deleteAutomation()
se invoca cuando deslizas el dedo hacia la izquierda en una automatización existente y presionas el ícono de la papelera para quitarla de tu estructura.
8. Felicitaciones
¡Felicitaciones! Creaste correctamente una app de casa inteligente básica con las APIs de Home para iOS.
Logros:
- Inicialización: Conectaste tu app al ecosistema de Google Home con
Home.connect()
. - Permisos: Se controló la autenticación y autorización del usuario para acceder a los datos de la casa.
- Dispositivos y estructuras: Se recuperaron y mostraron habitaciones y dispositivos con
home.rooms()
yhome.devices()
. - Control de dispositivos: Se implementó la interacción con el dispositivo, como activar o desactivar el estado de un
OnOffPluginUnitDeviceType
llamando a comandos en sus atributos. - Administración de estructuras: Se agregó la funcionalidad para crear habitaciones nuevas (
structure.createRoom()
), mover dispositivos entre habitaciones (structure.move()
) y borrar habitaciones vacías (structure.deleteRoom()
). - Comisión: Se integró el flujo de comisión del SDK para agregar nuevos dispositivos Matter (
MatterAddDeviceRequest
). - Automatización: Se analizó cómo enumerar, crear (
structure.createAutomation()
) y borrar (structure.deleteAutomation()
) automatizaciones dentro de una estructura.
Ahora tienes conocimientos básicos sobre cómo aprovechar las APIs de Home para crear experiencias de control de casa inteligente enriquecidas en iOS.
Próximos pasos:
- Explora el control de otros tipos de dispositivos que se proporcionan en la app de ejemplo (luces, ventiladores, persianas, etcétera).
- Analiza en detalle los diferentes atributos y comandos disponibles para varios dispositivos.
- Experimenta con la creación de automatizaciones más complejas con diferentes activadores, condiciones y acciones.
- Consulta la documentación de las APIs de Home para obtener más detalles y funciones avanzadas.
¡Bien hecho!