Vous pouvez accéder aux API d'appareil via les API Home pour iOS. Importez les packages suivants dans votre application :
import GoogleHomeSDK
import GoogleHomeTypes
Pour en savoir plus, consultez la page Modèle de données sur iOS.
Gestion des exceptions
Certaines méthodes des API Home génèrent une
HomeError. Nous vous recommandons donc d'utiliser un do-catch block pour intercepter
HomeError lors de ces appels.
Lorsque vous gérez HomeError, vérifiez ses champs code et message
pour savoir ce qui s'est mal passé.
Toutes les erreurs non gérées entraîneront le plantage de votre application.
Pour en savoir plus, consultez la page Gestion des erreurs.
Pour obtenir un exemple, consultez la page Envoyer une commande à un appareil.
Exemples d'appels
Obtenir une liste d'appareils
Avec une référence à l'Home
objet, appelez
devices() pour obtenir une
Query des appareils accessibles.
Appelez la méthode Query's
batched(), qui émet un ensemble reflétant l'état actuel de la maison à chaque
modification des métadonnées de l'appareil. Vous pouvez également appeler
Query.list() pour obtenir un
instantané des appareils disponibles. Il s'agit d'une méthode pratique qui s'abonne au flux batched() et renvoie la première valeur émise.
Query.stream()
produit un flux qui émet de nouvelles valeurs lors des modifications des métadonnées de l'appareil, telles que son nom, sa pièce ou sa structure. En interne, cette méthode utilise batched() et n'émet que les propriétés modifiées.
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
Vous pouvez ensuite accéder aux états de chaque appareil et leur envoyer des commandes.
Avec la version 1.8 des API Home, vous avez la possibilité de faire en sorte que l'API représente chaque appareil multipartite comme un seul appareil en définissant le paramètre enableMultipartDevices de la méthode devices() sur true. Pour en savoir plus, consultez la page
Appareils multipartites sur iOS.
Obtenir les types d'appareils
Pour obtenir les types d'appareils associés à un appareil, lisez la
propriété types
de l'appareil, qui renvoie un
DeviceTypeController.
Appelez DeviceTypeController.subscribe(_:) pour vous abonner aux mises à jour d'un type d'appareil spécifique :
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 l'appareil n'est pas compatible avec le type d'appareil spécifié, il renvoie un Empty
Publisher qui se termine immédiatement.
Si l'appareil est compatible avec un type d'appareil spécifique, vous pouvez obtenir un handle pour ce type en appelant get() :
if let device = devices.first(where: { $0.id == myDeviceId }) { let _ = await device.types.get(OnOffLightDeviceType.self) }
Si l'appareil n'est pas compatible avec le type spécifié, il renvoie nil.
Appelez
DeviceTypeController.subscribeAll()
pour obtenir un Publisher de
DeviceTypeCollection.
Cette classe vous permet de vérifier si l'appareil possède un type d'appareil particulier :
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] } }
Obtenir une caractéristique de type d'appareil
Les types d'appareils sont le point d'entrée pour la lecture des caractéristiques, car ils décomposent un appareil en ses éléments fonctionnels (comme les points de terminaison dans Matter).
Ils tiennent également compte des conflits de caractéristiques dans le cas où un appareil comporte deux types d'appareils, qui peuvent tous deux avoir la même caractéristique. Par exemple, si un appareil est à la fois un haut-parleur et une lumière à intensité variable, il aura deux caractéristiques On/Off et deux caractéristiques de contrôle du niveau.
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 à la caractéristique visée, référencez une caractéristique via l'une des deux collections de caractéristiques de chaque type d'appareil.
Pour les caractéristiques standards, c'est-à-dire celles qui sont analogues aux
Matter clusters standards, utilisez matterTraits. Par exemple, pour obtenir un trait spécifique pour le type d'appareil "Lumière à intensité variable" :
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
Pour les caractéristiques Google, utilisez googleTraits :
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.traits[Google.DoorbellPressTrait.self] }
Pour accéder à une caractéristique spécifique au fabricant, référencez-la via la propriété traits, mais faites-la précéder du nom du package du fabricant :
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 }
Lire l'état d'un appareil
Consultez cet exemple de vérification de l'attribut OnOff de la caractéristique On/Off de l'appareil :
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 }
Obtenir une liste d'appareils avec une caractéristique spécifique
Pour obtenir une liste d'appareils dotés d'une caractéristique spécifique, vous devez parcourir les appareils, les types d'appareils de chaque appareil et les caractéristiques de chaque type d'appareil. Par exemple, pour obtenir une liste des appareils de la maison qui ont tous la caractéristique On/Off :
// Get all light devices that support levelControl var levelControlDevices: [HomeDevice] = [] let 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) } } }
Pour obtenir la liste complète des caractéristiques disponibles dans les API Home, consultez la page Index des caractéristiques sur iOS.
Obtenir une liste d'appareils avec des types d'appareils similaires
Pour obtenir une liste des appareils qui représentent toutes les lumières d'une maison :
// 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) }
Plusieurs types d'appareils dans les API Home peuvent représenter un type d'appareil de base. Par exemple, il n'existe pas de type d'appareil "Lumière". Au lieu de cela, il existe quatre types d'appareils différents qui peuvent représenter une lumière, comme illustré dans l'exemple précédent. Par conséquent, pour obtenir une vue complète du type d'appareil de niveau supérieur dans une maison, plusieurs types d'appareils doivent être inclus.
Pour obtenir la liste complète des types d'appareils et de leurs caractéristiques disponibles dans les API Home, consultez la page Types d'appareils compatibles sur iOS.
Obtenir le nom du fournisseur, l'ID du fournisseur ou l'ID du produit pour un appareil
La BasicInformationTrait
caractéristique 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 :
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") }
Identification des appareils cloud-to-cloud pour les fabricants d'appareils
Si vous êtes fabricant d'appareils et que vous créez des Cloud-to-cloud appareils,
pour identifier vos
Cloud-to-cloud appareils via la
BasicInformation caractéristique, vous pouvez inclure ces champs de chaîne dans
leur SYNC réponse :
ID de fournisseur émis par Connectivity Standards Alliance (Alliance) :
"matterOriginalVendorId": "0xfff1",Identifiant de produit qui identifie de manière unique un produit d'un fournisseur :
"matterOriginalProductId": "0x1234",Identifiant unique de l'appareil, construit d'une manière spécifique au fabricant :
"matterUniqueId": "matter-device-id",
Lorsque vous saisissez ces champs de chaîne, utilisez vos Matter
ID de fournisseur et de produit si vous en avez. Si vous n'êtes pas membre et que ces ID ne vous ont pas été attribués, vous pouvez laisser les champs matterOriginalVendorId et matterOriginalProductId vides et fournir matterUniqueId comme identifiant.Alliance
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
Cloud-to-cloud SYNC.
Métadonnées d'appareil et de caractéristique
Les appareils et les caractéristiques des API Home sont associés à des métadonnées, ce qui peut vous aider à gérer l'expérience utilisateur dans une application.
Chaque caractéristique des API Home contient une
sourceConnectivity
propriété, qui fournit des informations sur l'état en ligne et la localité
(routage local ou à distance).
Obtenir le type principal d'un appareil
Certains appareils peuvent présenter plusieurs types d'appareils via les API Home. Pour s'assurer que les utilisateurs disposent des options appropriées dans une application (telles que le contrôle de l'appareil et les automatisations suggérées) pour leurs appareils, il est utile de vérifier si un type d'appareil est le type principal de l'appareil.
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.") } }
Vérifier si une caractéristique est en ligne
Lisez la propriété connectivityState pour vérifier la connectivité d'un trait :
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Certaines caractéristiques, généralement les caractéristiques smart home Google, peuvent s'afficher hors connexion si l'appareil n'est pas connecté à Internet. En effet, ces caractéristiques sont basées sur 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.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Un état partiallyOnline peut être observé dans le cas de types d'appareils mixtes lorsqu'il n'y a pas de connectivité Internet. Matter caractéristiques standard
peuvent toujours être en ligne en raison du routage local, mais les caractéristiques basées sur le cloud seront
hors connexion.
Obtenir l'adresse IP de l'appareil
Pour trouver l'adresse IP de l'appareil, utilisez l'networkInterfaces attribut de
l'
GeneralDiagnosticsTrait.
Les adresses sont renvoyées en tant qu'objets Data, que vous pouvez mettre au format de chaînes IPv4 ou IPv6 standards à l'aide du framework Network :
func getIpAddresses(trait: Matter.GeneralDiagnosticsTrait) -> [String] {
let interfaces = trait.attributes.networkInterfaces ?? []
var ipAddresses: [String] = []
for interface in interfaces {
for data in interface.iPv4Addresses {
if let ipv4 = IPv4Address(data) {
ipAddresses.append(String(describing: ipv4))
}
}
for data in interface.iPv6Addresses {
if let ipv6 = IPv6Address(data) {
ipAddresses.append(String(describing: ipv6))
}
}
}
return ipAddresses
}
Vérifier le routage réseau d'une caractéristique
La localité d'une caractéristique est également disponible dans les API Home. dataSourceLocality indique si la caractéristique est routée à distance (via le cloud), localement (via un hub local) ou en peer-to-peer (directement d'appareil à appareil, sans hub).
La valeur de localité inconnue unspecified est possible, par exemple, lorsqu'une application démarre et n'a pas encore atteint un hub ou un 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. Il appartient au client de déterminer comment gérer ces appareils.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Vérifier le routage réseau d'un appareil
Comme la connectivité, la localité est vérifiée au niveau du type d'appareil. L'état renvoyé est une combinaison de la localité de toutes les caractéristiques de cet appareil.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
Un état mixed peut être observé dans un scénario similaire à celui de la connectivité partiallyOnline : certaines caractéristiques sont basées sur le cloud, tandis que d'autres sont locales.
Modifier le nom d'un appareil
Appelez la
setName(_:)
méthode pour modifier le nom d'un appareil :
let updatedDevice = try await theDevice.setName("new device name")
Lorsque vous modifiez le nom d'un appareil, la structure HomeDevice d'origine reste la même et la modification est reflétée dans l'objet HomeDevice mis à jour renvoyé.
Les noms seront tronqués s'ils dépassent la limite de 60 points de code Unicode (caractères) et aucune erreur ne sera générée. Les développeurs sont responsables de la gestion des noms longs et peuvent, par exemple, décider s'ils souhaitent informer les utilisateurs que les noms seront tronqués.