Se puede acceder a las APIs de dispositivos a través de las APIs de Home. Importa estos paquetes a tu app:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Para usar tipos o atributos de dispositivos específicos con las APIs de dispositivos, se deben importar individualmente.
Por ejemplo, para usar el atributo de encendido/apagado Matter y el tipo de dispositivo de unidad de complemento de encendido/apagado, importa los siguientes paquetes a tu aplicación:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
Para obtener más información, consulta Modelo de datos.
Manejo de errores
Cualquier método de las APIs de Home puede generar una HomeException
, por lo que te recomendamos que uses un bloque try-catch
para capturar HomeException
en todas las llamadas.
Cuando controles HomeException
, verifica sus campos code
y message
para saber qué salió mal.
Cualquier excepción no controlada hará que la app falle.
Para obtener más información, consulta Manejo de errores.
Consulta Cómo enviar un comando a un dispositivo para ver un ejemplo.
Llamadas de muestra
Cómo obtener una lista de dispositivos
Con la estructura disponible, una llamada a devices()
muestra un flujo de dispositivos a los que puedes acceder desde esa estructura:
// Get a flow of all devices accessible to the user val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices() // Calling list() on a HomeObjectsFlow returns the first Set of elements. val allDevices: Set<HomeDevice> = allDevicesFlow.list()
Desde allí, se puede acceder a los estados de cada dispositivo y se pueden enviar comandos compatibles al dispositivo.
Cómo leer el estado de un dispositivo
Veamos un ejemplo de cómo verificar el atributo OnOff
desde el atributo On/Off del dispositivo. Con el modelo de datos de atributos de las APIs de Home, en el que este atributo se identifica como OnOff
, puedes recuperar datos de atributos a través de la clase standardTraits
del tipo de dispositivo:
// Assuming we have a device. val deviceFlow = home.devices().itemFlow(myDeviceId) val device = deviceFlow.first() // Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger // on the specific trait changes and not the whole type. val onOffTraitFlow: Flow<OnOff?> = device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged() val onOffTrait: OnOff = onOffTraitFlow.first()!!
Consulta distinctUntilChanged
para obtener más información sobre la función de flujo de Kotlin.
Cómo invalidar el estado en una suscripción de rasgo
La interfaz TraitStateInvalidation
proporciona la capacidad de invalidar un estado recuperado a través de suscripciones al dispositivo de destino en los casos en que el estado no se informa correctamente.
Algunos ejemplos de casos en los que es posible que el estado no se informe correctamente son el uso de atributos en los atributos Matter con la calidad "C" o debido a una implementación de dispositivo que causa el problema de forma inesperada.
Esta API emite una lectura forzada del estado del rasgo actual y muestra el resultado a través de los flujos de rasgos existentes.
Obtén el atributo y, luego, ejecuta un forceRead
en él:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Cómo obtener una lista de atributos de tipo de dispositivo
Los tipos de dispositivos deben usarse como punto de entrada para leer atributos, ya que descomponen un dispositivo en sus partes funcionales (como los extremos en Matter).
También tienen en cuenta las colisiones de atributos en caso de que un dispositivo tenga dos tipos de dispositivos, ambos con el mismo atributo. Por ejemplo, si un dispositivo es una bocina y una luz regulable, tendrá dos atributos de encendido/apagado y dos de control de nivel.
Para obtener la lista de atributos disponibles para el tipo de dispositivo de luz regulable, haz lo siguiente:
// Get all types available on this device. Requires the types to be part of the registry during // SDK initialization. val typesFlow: Flow<Set<DeviceType>> = device.types() // Get a snapshot of all types. val types: Set<DeviceType> = typesFlow.first() // Get the DimmableLightDevice instance from the set of types. val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull() // Get all traits in the type + traits registered val allTraits: Set<Trait> = dimmableLightDevice!!.traits()
Otro tipo de colisión de atributos puede ocurrir cuando un dispositivo tiene dos atributos con el
mismo nombre. Por ejemplo, onOff
podría referirse a una instancia del atributo OnOff
estándar o a una instancia de un atributo OnOff
definido por el fabricante. Para eliminar cualquier ambigüedad sobre qué atributo se pretende, una instancia de Trait
a la que se hace referencia a través de un dispositivo debe ir precedida por un espacio de nombres de calificación. Para los atributos estándar, es decir, aquellos que son análogos a los clústeres estándar de Matter, usa standardTraits
. Para los atributos de Google, usa googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
Para acceder a un atributo específico del fabricante, haz referencia a él directamente:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Cómo obtener una lista de dispositivos con una característica específica
La función filter
en Kotlin se puede usar para definir mejor las llamadas a la API. Por ejemplo, para obtener una lista de los dispositivos de la casa que tienen el atributo de encendido/apagado, haz lo siguiente:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Consulta la interfaz Trait
para obtener una lista completa de los atributos disponibles en las APIs de Home.
Cómo obtener 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) val lightDevices = home.devices().map { devices -> devices.filter { it.has(DimmableLightDevice) || it.has(OnOffLightDevice) || it.has(ColorTemperatureLightDevice) || it.has(ExtendedColorLightDevice) } }
Existen varios tipos de dispositivos en las APIs de Home que podrían representar un tipo de dispositivo principal. Por ejemplo, no hay un 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 del tipo de dispositivo de nivel superior en una casa, se deben incluir varios tipos de dispositivos en los flujos filtrados.
Consulta la interfaz de DeviceType
para obtener una lista completa de los tipos de dispositivos disponibles en las APIs de Home.
Cómo obtener el ID del proveedor o el ID del producto de un dispositivo
El atributo BasicInformation
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:
// Get device basic information. All general information traits are on the RootNodeDevice type. val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!! println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.productId}")
Identifica dispositivos de nube a nube
Si eres fabricante de dispositivos y compilas dispositivos Cloud-to-cloud, para identificar tus dispositivos Cloud-to-cloud a través del atributo BasicInformation
, puedes incluir estos campos de cadena en su respuesta SYNC
:
El ID del proveedor emitido por la Connectivity Standards Alliance (CSA):
"matterOriginalVendorId": "0xfff1",
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 crea de una manera específica del fabricante:
"matterUniqueId": "matter-device-id",
Cuando ingreses estos campos de cadena, usa los IDs de proveedor y producto de Matter si los tienes. Si no eres miembro de CSA y no se te asignaron estos IDs, puedes dejar los campos matterOriginalVendorId
y matterOriginalProductId
en blanco y proporcionar matterUniqueId
como identificador.
En la respuesta de ejemplo de SYNC, 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 SYNC
de Cloud-to-cloud.
Metadatos de dispositivos y atributos
Los dispositivos y atributos de las APIs de Home tienen metadatos asociados que pueden ayudar a administrar la experiencia del usuario en una app.
Cada atributo de las APIs de Home contiene una propiedad sourceConnectivity
, que tiene información sobre el estado en línea y la localidad de un atributo (enrutamiento local o remoto).
Cómo obtener 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 a los usuarios se les presenten las opciones adecuadas en una app (como el control de dispositivos y las automatizaciones sugeridas) para sus dispositivos, es útil verificar cuál es el tipo de dispositivo principal de un dispositivo.
Primero, obtén los tipos del dispositivo con type()
y, luego, determina cuál es el tipo principal:
val types = device.types().first() val primaryType = types.first { it.metadata.isPrimaryType }
Cómo comprobar si un atributo está en línea
Usa el método connectivityState()
para verificar la conectividad de un atributo:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
Es posible que algunos atributos, por lo general, los atributos smart home de Google, aparezcan sin conexión si el dispositivo no tiene conectividad a Internet. Esto se debe a que estos atributos se basan en la nube y no tienen enrutamiento local.
Cómo verificar la conectividad de un dispositivo
La conectividad de un dispositivo se verifica a nivel del tipo de dispositivo porque algunos dispositivos admiten varios tipos de dispositivos. El estado que se muestra es una combinación de los estados de conectividad de todos los atributos de ese dispositivo.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Se puede observar un estado de PARTIALLY_ONLINE
en el caso de tipos de dispositivos mixtos cuando no hay conectividad a Internet. Es posible que los atributos estándar de Matter aún estén en línea debido al enrutamiento local, pero los atributos basados en la nube no estarán disponibles.
Cómo comprobar el enrutamiento de red de un atributo
La localidad de un atributo también está disponible en las APIs de Home. dataSourceLocality
indica si el atributo se enruta de forma remota (a través de la nube), de forma local (a través de un concentrador local) o de igual a igual (directo de dispositivo a dispositivo, sin concentrador).
El valor de localidad desconocida UNSPECIFIED
es posible, por ejemplo, mientras se inicia una app y aún no se ha conectado a un concentrador 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. Depende del cliente determinar cómo controlar esos dispositivos.
val onOffLocality = onOffTrait?.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 muestra es una combinación de la localidad de todos los atributos de ese dispositivo.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
Se puede observar un estado de MIXED
en una situación similar a la de la conectividad PARTIALLY_ONLINE
: algunos atributos se basan en la nube, mientras que otros son locales.
Lista de APIs
Una vez que se crea una instancia de Home
, se puede acceder a las siguientes APIs de dispositivos a través de ella:
API | Descripción |
---|---|
devices() |
Obtén todos los dispositivos de todas las estructuras de la Cuenta de Google. Devuelve un HomeObjectsFlow que proporciona más opciones de recuperación y filtrado. |
Una vez que tengas un HomeDevice
, podrás acceder a las siguientes APIs a través de él:
API | Descripción |
---|---|
allCandidates() |
Muestra todos los candidatos de automatización para el dispositivo y sus elementos secundarios. |
candidates() |
Muestra todos los candidatos de automatización para el dispositivo. |
connectivityStateChanged |
Es la última vez que cambió el estado del dispositivo. |
events(event) |
Obtiene un flujo de un evento específico. |
events(trait) |
Obtiene un flujo de todos los eventos por este atributo. |
events(traits) |
Obtiene un flujo de todos los eventos según estos atributos. |
getSourceConnectivity(trait) |
Obtén metadatos de un atributo en particular. Muestra un objeto SourceConnectivity . |
has(trait) |
Comprueba si el dispositivo admite el atributo solicitado actual. |
has(type) |
Si el dispositivo admite el tipo proporcionado. |
id |
Es el ID de sistema único del dispositivo. |
isInRoom |
Si el dispositivo está en una habitación |
isInStructure |
Si el dispositivo está en una estructura. |
isMatterDevice |
Si el dispositivo está respaldado por Matter. |
name |
Es el nombre del dispositivo que proporcionó el usuario. |
room() |
Es la habitación a la que se asignó el dispositivo. Muestra un objeto Room . |
roomId |
Es el ID de la habitación a la que está asignado el dispositivo. Muestra un Id . |
sourceConnectivity |
La conectividad de origen del dispositivo, que representa los estados de conectividad agregados y la localidad de red de los atributos del dispositivo. |
structure() |
Es la estructura a la que se asigna el dispositivo. Muestra un objeto Structure . |
structureId |
Es el ID de la estructura a la que está asignado el dispositivo. Muestra un Id . |
type(type) |
Obtén la definición del tipo con los atributos propagados (cuando estén disponibles) para el acceso directo. Siempre muestra una instantánea actualizada de los atributos. |
types() |
Obtén una lista de todos los tipos disponibles en el dispositivo. |