Accéder aux appareils et aux métadonnées des appareils

Vous pouvez accéder aux API de l'appareil via les API Home. Importez ces packages dans votre application:

import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id

Pour utiliser des types ou des caractéristiques d'appareils spécifiques avec les API Device, ils doivent être importés individuellement.

Par exemple, pour utiliser le trait Matter Marche/Arrêt et le type d'appareil Unité de plug-in Marche/Arrêt, importez les packages suivants dans votre application:

import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice

Pour en savoir plus, consultez la section Modèle de données.

Gestion des exceptions

Toute méthode des API Home peut générer une exception HomeException. Nous vous recommandons donc d'utiliser un bloc try-catch pour intercepter les exceptions HomeException sur tous les appels.

Lorsque vous gérez HomeException, vérifiez ses champs code et message pour savoir ce qui s'est mal passé.

Toute exception non gérée entraînera le plantage de votre application.

Pour en savoir plus, consultez la section Gestion des erreurs.

Pour obtenir un exemple, consultez Envoyer une commande à un appareil.

Exemples d'appels

Obtenir la liste des appareils

Une fois la structure disponible, un appel devices() renvoie un flux d'appareils auxquels vous pouvez accéder à partir de cette structure:

// 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()

À partir de là, les états de chaque appareil sont accessibles et les commandes compatibles peuvent être envoyées à l'appareil.

Lire l'état d'un appareil

Examinons un exemple de vérification de l'attribut OnOff à partir du trait "Marche/Arrêt" de l'appareil. À l'aide du modèle de données de caractéristique des API Home, où cette caractéristique est identifiée comme OnOff, vous pouvez récupérer des données de caractéristique via la classe standardTraits du type d'appareil:

// 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()!!

Pour en savoir plus sur la fonction de flux Kotlin, consultez distinctUntilChanged.

Invalider l'état dans un abonnement de trait

L'interface TraitStateInvalidation permet d'invalider un état récupéré via des abonnements à l'appareil cible lorsque l'état n'est pas correctement signalé. Par exemple, l'état peut ne pas être correctement signalé si vous utilisez des attributs dans des traits Matter avec la qualité "C" ou en raison d'une implémentation d'appareil qui provoque le problème de manière inattendue.

Cette API émet une lecture forcée de l'état actuel de la caractéristique et renvoie le résultat via les flux de caractéristiques existants.

Obtenez le trait, puis exécutez une forceRead sur le trait:

val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()

Obtenir la liste des caractéristiques des types d'appareils

Les types d'appareils doivent être utilisés comme point d'entrée pour lire les traits, car ils décomposent un appareil en ses éléments fonctionnels (comme les points de terminaison dans Matter).

Ils prennent également en compte les collisions de traits au cas où un appareil comporte deux types d'appareils, qui peuvent tous deux avoir le même trait. Par exemple, si un appareil est à la fois une enceinte et une lumière à intensité réglable, il comporte deux attributs Marche/Arrêt et deux attributs de contrôle du niveau.

Pour obtenir la liste des caractéristiques disponibles pour le type d'appareil "Lumière à intensité variable" :

// 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()

Un autre type de conflit de caractéristiques peut se produire lorsqu'un appareil comporte deux caractéristiques portant le même nom. Par exemple, onOff peut faire référence à une instance de la caractéristique OnOff standard ou à une instance d'une caractéristique OnOff définie par le fabricant. Pour éliminer toute ambiguïté potentielle quant au trait visé, une instance Trait référencée via un appareil doit être précédée d'un espace de noms qualificatif. Pour les traits standards, c'est-à-dire ceux qui sont analogues aux clusters standards Matter, utilisez standardTraits. Pour les traits Google, utilisez googleTraits:

// Accessing standard traits on the type.
val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff
val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl

Pour accéder à une caractéristique spécifique au fabricant, faites-en référence directement:

// Accessing a custom trait on the type.
val customTrait = dimmableLightDevice.trait(MyCustomTrait)

Obtenir la liste des appareils avec une caractéristique spécifique

La fonction filter en Kotlin peut être utilisée pour affiner davantage les appels d'API. Par exemple, pour obtenir la liste des appareils de la maison qui ont tous la caractéristique Marche/Arrêt:

// Get all devices that support OnOff
val onOffDevices: Flow<List<HomeDevice>> =
  home.devices().map { devices -> devices.filter { it.has(OnOff) } }

Consultez l'interface Trait pour obtenir la liste complète des traits disponibles dans les API Home.

Obtenir la liste des appareils avec des types d'appareils similaires

Pour obtenir la liste des appareils représentant toutes les ampoules d'une maison:

// 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)
    }
  }

Dans les API Home, plusieurs types d'appareils peuvent représenter un type d'appareil de base. Par exemple, il n'existe pas de type d'appareil "Ampoule". Au lieu de cela, quatre types d'appareils différents peuvent représenter une lumière, comme illustré dans l'exemple précédent. Par conséquent, pour obtenir une vue complète des types d'appareils de niveau supérieur dans une maison, plusieurs types d'appareils doivent être inclus dans les flux filtrés.

Consultez l'interface DeviceType pour obtenir la liste complète des types d'appareils disponibles dans les API Home.

Obtenir l'ID du fournisseur ou l'ID produit d'un appareil

La caractéristique BasicInformation inclut des informations telles que l'ID du fournisseur, l'ID du produit, le nom du produit et le numéro de série d'un appareil:

// 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}")

Identifier les appareils cloud-to-cloud

Si vous êtes fabricant d'appareils et que vous créez des appareils Cloud-to-cloud, afin d'identifier vos appareils Cloud-to-cloud via la caractéristique BasicInformation, vous pouvez inclure ces champs de chaîne dans leur réponse SYNC:

  • L'ID du fournisseur délivré par la Connectivity Standards Alliance (CSA) : "matterOriginalVendorId": "0xfff1",

  • Code produit qui identifie de manière unique un produit d'un fournisseur : "matterOriginalProductId": "0x1234",

  • Identifiant unique de l'appareil, qui est construit de manière spécifique au fabricant :"matterUniqueId": "matter-device-id",

Lorsque vous saisissez ces champs de chaîne, utilisez vos ID de fournisseur et de produit Matter, le cas échéant. Si vous n'êtes pas membre d'une CSA et que vous n'avez pas reçu ces ID, vous pouvez laisser les champs matterOriginalVendorId et matterOriginalProductId vides et indiquer matterUniqueId comme identifiant.

L'exemple de réponse SYNC montre l'utilisation de ces champs:

{
  "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",
          }
        ]
      }
    ]
  }
}

Pour en savoir plus, consultez la documentation SYNC Cloud-to-cloud.

Métadonnées de l'appareil et des traits

Les appareils et les caractéristiques des API Home sont associés à des métadonnées, ce qui peut aider à gérer l'expérience utilisateur dans une application.

Chaque caractéristique des API Home contient une propriété sourceConnectivity, qui contient des informations sur l'état en ligne et la localité d'une caractéristique (routage local ou distant).

Obtenir le type principal d'un appareil

Certains appareils peuvent présenter plusieurs types d'appareils via les API Home. Pour vous assurer que les utilisateurs voient les options appropriées dans une application (telles que le contrôle de l'appareil et les suggestions d'automatisation) pour leurs appareils, il est utile de vérifier le type d'appareil principal.

Commencez par obtenir le ou les types d'appareils à l'aide de type(), puis déterminez le type principal:

val types = device.types().first()
val primaryType = types.first { it.metadata.isPrimaryType }

Vérifier si un trait est en ligne

Utilisez la méthode connectivityState() pour vérifier la connectivité d'un trait:

val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState

Certains traits, en particulier les traits Google smart home, peuvent s'afficher hors connexion si l'appareil n'est pas connecté à Internet. En effet, ces traits sont basés dans le cloud et ne disposent pas de routage local.

Vérifier la connectivité d'un appareil

La connectivité d'un appareil est en fait vérifiée au niveau du type d'appareil, car certains appareils sont compatibles avec plusieurs types d'appareils. L'état renvoyé est une combinaison des états de connectivité de toutes les caractéristiques de cet appareil.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

Un état PARTIALLY_ONLINE peut être observé en cas de types d'appareils mixtes en l'absence de connexion Internet. Les caractéristiques standards Matter peuvent toujours être en ligne en raison du routage local, mais les caractéristiques basées sur le cloud seront hors connexion.

Vérifier le routage réseau d'un trait

La localité d'un trait est également disponible dans les API Home. dataSourceLocality indique si la caractéristique est acheminée à distance (via le cloud), localement (via un hub local) ou en pair à pair (directement d'un appareil à un autre, sans hub).

La valeur de localité inconnue UNSPECIFIED est possible, par exemple, lorsqu'une application démarre et qu'elle n'a pas encore atteint de hub ou de serveur pour la connectivité de l'appareil. Ces appareils ne sont pas accessibles et les requêtes d'interaction provenant de commandes ou d'événements échoueront. C'est au client de déterminer comment gérer ces appareils.

val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality

Vérifier le routage réseau d'un appareil

Comme pour la connectivité, la localité est vérifiée au niveau du type d'appareil. L'état renvoyé est une combinaison de la localité pour toutes les caractéristiques de cet appareil.

val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality

Un état MIXED peut être observé dans un scénario semblable à celui de la connectivité PARTIALLY_ONLINE: certains traits sont basés dans le cloud, tandis que d'autres sont locaux.

Liste des API

Une fois une instance de Home créée, les API Device suivantes sont accessibles via celle-ci:

API Description
devices() Récupérez tous les appareils de toutes les structures du compte Google. Affiche un objet HomeObjectsFlow qui fournit d'autres options de récupération et de filtrage.

Une fois que vous disposez d'un HomeDevice, les API suivantes sont accessibles via celui-ci:

API Description
allCandidates() Renvoie toutes les automatisations candidates pour l'appareil et ses enfants.
candidates() Renvoie toutes les automatisations candidates pour l'appareil.
connectivityStateChanged Date et heure de la dernière modification de l'état de l'appareil.
events(event) Récupère un flux d'un événement spécifique.
events(trait) Récupère un flux de tous les événements de ce trait.
events(traits) Récupère un flux de tous les événements en fonction de ces caractéristiques.
getSourceConnectivity(trait) Obtenir les métadonnées d'un trait spécifique Renvoie un objet SourceConnectivity.
has(trait) Vérifiez si la caractéristique actuellement demandée est compatible avec l'appareil.
has(type) Si l'appareil est compatible avec le type fourni.
id Identifiant système unique de l'appareil.
isInRoom Si l'appareil se trouve dans une pièce.
isInStructure Si l'appareil se trouve dans une structure
isMatterDevice Si l'appareil est sauvegardé par Matter.
name Nom de l'appareil fourni par l'utilisateur.
room() Pièce à laquelle l'appareil est attribué. Renvoie un objet Room.
roomId ID de la chambre à laquelle l'appareil est attribué. Renvoie un Id.
sourceConnectivity Connectivité source de l'appareil, représentant les états de connectivité agrégés et la localité réseau des caractéristiques de l'appareil.
structure() Structure à laquelle l'appareil est attribué. Renvoie un objet Structure.
structureId ID de la structure à laquelle l'appareil est attribué. Renvoie un Id.
type(type) Obtenez la définition du type avec les traits renseignés (le cas échéant) pour un accès direct. Renvoie toujours un instantané à jour des traits.
types() Obtenez la liste de tous les types disponibles sur l'appareil.