Se puede acceder a las APIs de dispositivos a través de las APIs de Home para iOS. Importa los siguientes paquetes a tu app:
import GoogleHomeSDK
import GoogleHomeTypes
Para obtener más información, consulta Modelo de datos en iOS.
Manejo de errores
Algunos métodos de las APIs de Home arrojan un HomeError
, por lo que te recomendamos que uses un bloque do-catch
para detectar HomeError
en esas llamadas.
Cuando manejes HomeError
, verifica sus campos code
y message
para saber qué ocurrió.
Cualquier error no controlado provocará que falle la app.
Para obtener más información, consulta Control de errores.
Consulta Enviar un comando a un dispositivo para ver un ejemplo.
Llamadas de muestra
Obtén una lista de dispositivos
Con una referencia al objeto Home
, invoca devices()
para obtener un Query
de dispositivos accesibles.
Llama al método batched()
de Query
, que emite un conjunto que refleja el estado actual de la casa con cada cambio en los metadatos del dispositivo. O llama a Query.list()
para obtener una instantánea de los dispositivos disponibles. Este es un método de conveniencia que se suscribe a la transmisión batched()
y devuelve el primer valor emitido.
Query.stream()
produce un flujo que emite valores nuevos en los cambios de metadatos del dispositivo, como su nombre, habitación o estructura. Internamente, usa batched()
y solo emite las propiedades que cambiaron.
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
Desde allí, se puede acceder a los estados de cada dispositivo y enviar comandos compatibles.
Obtén los tipos de dispositivos
Para obtener los tipos de dispositivos asociados con un dispositivo, lee la propiedad types
del dispositivo, que devuelve un DeviceTypeController
.
Llama a DeviceTypeController.subscribe(_:)
para suscribirte a las actualizaciones de un tipo de dispositivo en particular:
let devices = try await self.home.devices().list() if let device = devices.first(where: { $0.id == myDeviceId }) { var receivedUpdate1 = false var receivedUpdate2 = false device.types.subscribe(OnOffLightDeviceType.self) .assertNoFailure() .sink { device in if !receivedUpdate1 { receivedUpdate1 = true Task { try await device.matterTraits.onOffTrait?.on() } return } if !receivedUpdate2 { receivedUpdate2 = true return } fatalError("Received unexpected update") } }
Si el dispositivo no admite el tipo de dispositivo especificado, devuelve un Empty
Publisher
que se completa de inmediato.
Si el dispositivo admite un tipo de dispositivo específico, puedes obtener un identificador para ese tipo llamando a get()
:
if let device = devices.first(where: { $0.id == myDeviceId }) { let deviceType = await device.types.get(OnOffLightDeviceType.self) }
Si el dispositivo no admite el tipo especificado, se devuelve nil
.
Llama a DeviceTypeController.subscribeAll()
para obtener un Publisher
de DeviceTypeCollection
.
Esta clase te permite verificar si el dispositivo tiene un tipo de dispositivo en particular:
if let device = devices.first(where: { $0.id == myDeviceId }) { device.types.subscribeAll() .assertNoFailure() .sink { types in let lightDeviceType = types[OnOffLightDeviceType.self] let fanDeviceType = types[FanDeviceType.self] } }
Obtén un rasgo de tipo de dispositivo
Los tipos de dispositivos son el punto de entrada para leer rasgos, ya que descomponen un dispositivo en sus partes funcionales (como los extremos en Matter).
También tienen en cuenta las colisiones de rasgos en el caso de que un dispositivo tenga dos tipos de dispositivos, ambos con el mismo rasgo. Por ejemplo, si un dispositivo es tanto una bocina como una luz regulable, tendría dos rasgos de encendido/apagado y dos de control de nivel.
Otro tipo de conflicto de rasgos puede ocurrir cuando un dispositivo tiene dos rasgos con el mismo nombre. Por ejemplo, onOff
podría hacer referencia a una instancia del rasgo OnOff
estándar o a una instancia de un rasgo OnOff
definido por el fabricante. Para eliminar cualquier posible ambigüedad sobre qué rasgo se pretende, haz referencia a un rasgo a través de una de las dos colecciones de rasgos en cada tipo de dispositivo.
Para los rasgos estándar, es decir, aquellos que son análogos a los clústeres estándar de Matter, usa matterTraits
. Por ejemplo, para obtener un rasgo específico del tipo de dispositivo Luz regulable, haz lo siguiente:
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
Para los rasgos de Google, usa googleTraits
:
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.googleTraits.doorbellPressTrait.self }
Para acceder a un rasgo específico del fabricante, haz referencia a él a través de la propiedad traits
, pero anteponle el nombre del paquete del fabricante:
let deviceType = await device1?.types.get(OnOffLightDeviceType.self) // Accessing custom trait on the type. if let spinnerTrait = deviceType?.traits[ExampleOrganization.SpinnerTrait.self] { let rpmVal = spinnerTrait.attributes.rpm }
Cómo leer el estado de un dispositivo
Observa este ejemplo de cómo verificar el atributo OnOff
del rasgo On/Off del dispositivo:
let lightDevices = devices.filter { $0.types.contains(OnOffLightDeviceType.self) } let light1 = lightDevices.first let lightDeviceTypeOptional = await light1?.types.get(OnOffLightDeviceType.self) if let onOffTrait = lightDeviceTypeOptional?.matterTraits.onOffTrait { let onOffVal = onOffTrait.attributes.onOff }
Obtén una lista de dispositivos con un rasgo específico
Para obtener una lista de los dispositivos que tienen un rasgo específico, debes iterar sobre los dispositivos, los tipos de dispositivos de cada dispositivo y los rasgos de cada tipo de dispositivo. Por ejemplo, para obtener una lista de los dispositivos de la casa que tienen el rasgo Encendido/Apagado, haz lo siguiente:
// Get all light devices that support levelControl var levelControlDevices: [HomeDevice] = [] var allDevices = try await home.devices().list() for device in allDevices { if let deviceType = await device.types.get(OnOffLightDeviceType.self) { if deviceType.traits.contains(Matter.LevelControlTrait.self) { levelControlDevices.append(device) } } }
Consulta el índice de rasgos en iOS para obtener una lista completa de los rasgos disponibles en las APIs de Home.
Obtén una lista de dispositivos con tipos de dispositivos similares
Para obtener una lista de los dispositivos que representan todas las luces de una casa, haz lo siguiente:
// Get a list of devices with similar device types (lights) let lightDevices = try await self.home.devices().list().compactMap { $0.types.contains(DimmableLightDeviceType.self) || $0.types.contains(OnOffLightDeviceType.self) || $0.types.contains(ColorTemperatureLightDeviceType.self) || $0.types.contains(ExtendedColorLightDeviceType.self) }
En las APIs de Home, hay varios tipos de dispositivos que podrían representar un tipo de dispositivo principal. Por ejemplo, no existe el tipo de dispositivo "Luz". En cambio, hay cuatro tipos de dispositivos diferentes que podrían representar una luz, como se muestra en el ejemplo anterior. Por lo tanto, para obtener una vista integral de los tipos de dispositivos de nivel superior en una casa, se deben incluir varios tipos de dispositivos.
Consulta la lista completa de tipos de dispositivos compatibles con iOS y sus características disponibles en las APIs de Home.
Cómo obtener el nombre del proveedor, el ID del proveedor o el ID del producto de un dispositivo
El rasgo BasicInformationTrait
incluye información como el ID del proveedor, el ID del producto, el nombre del producto y el número de serie de un dispositivo:
guard let vendorName = basicInfoTrait.attributes.vendorName else { fatalError("Failed to get vendorName") } guard let vendorID = basicInfoTrait.attributes.vendorID else { fatalError("Failed to get vendorID") } guard let productID = basicInfoTrait.attributes.productID else { fatalError("Failed to get productID") }
Identificación de dispositivos de nube a nube para fabricantes de dispositivos
Si eres fabricante de dispositivos y compilas dispositivos Cloud-to-cloud, para identificar tus dispositivos Cloud-to-cloud a través del rasgo BasicInformation
, puedes incluir estos campos de cadena en su respuesta SYNC
:
ID del proveedor emitido por la Connectivity Standards Alliance (CSA):
"matterOriginalVendorId": "0xfff1",
Es un identificador de producto que identifica de forma única un producto de un proveedor:
"matterOriginalProductId": "0x1234",
Es un identificador único para el dispositivo, que se construye de una manera específica del fabricante:
"matterUniqueId": "matter-device-id",
Cuando ingreses estos campos de cadena, usa tus IDs de Matterproveedor y producto si los tienes. Si no eres miembro de la CSA y no se te asignaron estos IDs, puedes dejar los campos matterOriginalVendorId
y matterOriginalProductId
en blanco y proporcionar el matterUniqueId
como identificador.
En la respuesta de SYNC de ejemplo, se muestra el uso de estos campos:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"agentUserId": "1836.15267389",
"devices": [
{
"id": "456",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.Brightness",
"action.devices.traits.ColorSetting",
],
"willReportState": true,
"deviceInfo": { ... },
"matterOriginalVendorId": "0xfff1",
"matterOriginalProductId": "0x1234",
"matterUniqueId": "matter-device-id",
"otherDeviceIds": [
{
"deviceId": "local-device-id",
}
]
}
]
}
}
Para obtener más información, consulta la documentación de Cloud-to-cloud SYNC
.
Metadatos del dispositivo y del rasgo
Los dispositivos y los rasgos de las APIs de Home tienen metadatos asociados, lo que puede ayudar a administrar la experiencia del usuario en una app.
Cada rasgo de las APIs de Home contiene una propiedad sourceConnectivity
, que incluye información sobre el estado en línea y la localidad de un rasgo (enrutamiento local o remoto).
Obtiene el tipo principal de un dispositivo.
Algunos dispositivos pueden presentar varios tipos de dispositivos a través de las APIs de Home. Para garantizar que los usuarios vean las opciones adecuadas en una app (como el control de dispositivos y las automatizaciones sugeridas) para sus dispositivos, es útil verificar si un tipo de dispositivo es el tipo principal del dispositivo.
if let deviceType = await device?.types.get(HumiditySensorDeviceType.self) { if deviceType.metadata.isPrimaryType { print("Humidity Sensor is the primary type on this device.") } else { print("Humidity Sensor isn't the primary type on this device.") } }
Cómo verificar si un rasgo está en línea
Lee la propiedad connectivityState
para verificar la conectividad de un rasgo:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Algunos rasgos, por lo general, los rasgos de Google smart home, pueden mostrarse sin conexión si el dispositivo no tiene conectividad a Internet. Esto se debe a que estos rasgos son basados en la nube y no tienen enrutamiento local.
Cómo verificar la conectividad de un dispositivo
En realidad, la conectividad de un dispositivo se verifica a nivel del tipo de dispositivo, ya que algunos dispositivos admiten varios tipos. El estado que se devuelve es una combinación de los estados de conectividad de todas las características del dispositivo.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Se puede observar un estado de partiallyOnline
en el caso de tipos de dispositivos mixtos cuando no hay conectividad a Internet. Es posible que los rasgos Matter estándar sigan en línea debido al enrutamiento local, pero los rasgos basados en la nube estarán sin conexión.
Cómo verificar el enrutamiento de red de un rasgo
La localidad de un rasgo también está disponible en las APIs de Home. El dataSourceLocality
indica si el rasgo se enruta de forma remota (a través de la nube), local (a través de un concentrador local) o de punto a punto (directamente de dispositivo a dispositivo, sin concentrador).
Por ejemplo, es posible que el valor de localidad desconocido unspecified
se devuelva mientras una app se inicia y aún no llega a un centro o servidor para la conectividad del dispositivo. No se puede acceder a estos dispositivos y fallarán las solicitudes de interacción de comandos o eventos. Corresponde al cliente determinar cómo controlar esos dispositivos.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Cómo verificar el enrutamiento de red de un dispositivo
Al igual que la conectividad, la localidad se verifica a nivel del tipo de dispositivo. El estado que se devuelve es una combinación de la localidad de todos los rasgos del dispositivo.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
Se puede observar un estado de mixed
en una situación similar a la de la conectividad partiallyOnline
: algunos rasgos se basan en la nube, mientras que otros son locales.
Cómo cambiar el nombre de un dispositivo
Llama al método setName(_:)
para cambiar el nombre de un dispositivo:
let updatedDevice = try await theDevice.setName("new device name")
Cuando se cambia el nombre de un dispositivo, la estructura HomeDevice
original permanece igual y el cambio se refleja en el objeto HomeDevice
actualizado que se devuelve.
Lista de APIs
Una vez que se crea una instancia de Home
, se puede acceder a las siguientes APIs de Device a través de ella:
API | Descripción |
---|---|
device(id:) |
Devuelve un Publisher para el dispositivo especificado que emite el estado del dispositivo cada vez que cambia. |
devices() |
Obtiene todos los dispositivos en todas las estructuras de la Cuenta de Google. Devuelve un Query<HomeDevice> que proporciona más opciones de recuperación y filtrado. |
Una vez que tengas un objeto HomeDevice
, podrás acceder a las siguientes APIs a través de él:
API | Descripción |
---|---|
id |
Es el ID único del sistema del dispositivo. |
name |
Es el nombre del dispositivo proporcionado por el usuario. |
structureID |
Es el ID de la estructura a la que está asignado el dispositivo. Muestra un objeto String? . |
roomID |
Es el ID de la habitación a la que está asignado el dispositivo. Muestra un objeto String? . |
types |
Obtiene un tipo específico o todos los tipos disponibles en el dispositivo. |
isMatterDevice |
Si el dispositivo está respaldado por Matter |
sourceConnectivity |
Es la conectividad de origen del dispositivo, que representa los estados de conectividad agregados y la localidad de red de los rasgos del dispositivo. |