Auf Geräte-APIs kann über die Home APIs für iOS zugegriffen werden. Importieren Sie die folgenden Pakete in Ihre App:
import GoogleHomeSDK
import GoogleHomeTypes
Weitere Informationen finden Sie unter Datenmodell unter iOS.
Fehlerbehandlung
Einige Methoden in den Home APIs geben einen HomeError zurück. Wir empfehlen daher, einen do-catch-Block zu verwenden, um HomeError bei diesen Aufrufen abzufangen.
Wenn Sie HomeError verarbeiten, prüfen Sie die Felder code und message, um herauszufinden, was schiefgelaufen ist.
Nicht behandelte Fehler führen zum Absturz der App.
Weitere Informationen finden Sie unter Fehlerbehandlung.
Ein Beispiel finden Sie unter Befehl an ein Gerät senden.
Beispielaufrufe
Liste der Geräte abrufen
Rufen Sie mit einem Verweis auf das Home-Objekt devices() auf, um eine Query der verfügbaren Geräte zu erhalten.
Rufe die Methode batched() von Query auf, die bei jeder Änderung der Gerätemetadaten ein Set ausgibt, das den aktuellen Status des Zuhauses widerspiegelt. Oder rufen Sie Query.list() auf, um eine Übersicht der verfügbaren Geräte zu erhalten. Dies ist eine einfache Methode, die den batched()-Stream abonniert und den ersten ausgegebenen Wert zurückgibt.
Query.stream() erzeugt einen Stream, der neue Werte ausgibt, wenn sich die Metadaten des Geräts ändern, z. B. der Name, der Raum oder das Gebäude. Intern wird dafür batched() verwendet und es werden nur die geänderten Properties ausgegeben.
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
Dort kannst du auf die Status der einzelnen Geräte zugreifen und Befehle an Geräte senden.
Mit Version 1.8 der Home APIs kannst du die API so konfigurieren, dass jedes mehrteilige Gerät als einzelnes Gerät dargestellt wird. Dazu musst du den Parameter enableMultipartDevices der Methode devices() auf true setzen. Weitere Informationen finden Sie unter Mehrteilige Geräte unter iOS.
Gerätetypen abrufen
Wenn du die Gerätetypen abrufen möchtest, die mit einem Gerät verknüpft sind, lies das Attribut types des Geräts, das ein DeviceTypeController zurückgibt.
Rufen Sie DeviceTypeController.subscribe(_:) auf, um Updates für einen bestimmten Gerätetyp zu abonnieren:
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") } }
Wenn das Gerät den angegebenen Gerätetyp nicht unterstützt, wird ein Empty
Publisher zurückgegeben, das sofort abgeschlossen wird.
Wenn das Gerät einen bestimmten Gerätetyp unterstützt, kannst du durch Aufrufen von get() ein Handle für diesen Typ abrufen:
if let device = devices.first(where: { $0.id == myDeviceId }) { let _ = await device.types.get(OnOffLightDeviceType.self) }
Wenn das Gerät den angegebenen Typ nicht unterstützt, wird nil zurückgegeben.
Rufen Sie DeviceTypeController.subscribeAll() auf, um eine Publisher von DeviceTypeCollection zu erhalten.
Mit dieser Klasse können Sie prüfen, ob das Gerät einen bestimmten Gerätetyp hat:
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] } }
Gerätetyp-Attribut abrufen
Gerätetypen sind der Einstiegspunkt zum Lesen von Attributen, da sie ein Gerät in seine funktionalen Teile zerlegen (wie Endpunkte in Matter).
Sie berücksichtigen auch Attributkonflikte, falls ein Gerät zwei Gerätetypen hat, die beide dasselbe Attribut haben können. Wenn ein Gerät beispielsweise sowohl ein Lautsprecher als auch eine dimmbare Lampe ist, hat es zwei OnOff- und zwei LevelControl-Attribute.
Eine andere Art von Attributkonflikt kann auftreten, wenn ein Gerät zwei Attribute mit demselben Namen hat. onOff könnte sich beispielsweise auf eine Instanz des Standard-OnOff-Attributs oder auf eine Instanz eines vom Hersteller definierten OnOff-Attributs beziehen. Um mögliche Unklarheiten darüber zu vermeiden, welches Attribut gemeint ist, verweise auf ein Attribut über eine der beiden Attributsammlungen für jeden Gerätetyp.
Verwenden Sie für Standardmerkmale, d. h. Merkmale, die den Standardclustern von Matter entsprechen, matterTraits. So rufen Sie beispielsweise ein bestimmtes Attribut für den Gerätetyp „Dimmable Light“ ab:
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
Verwenden Sie für Google-Attribute googleTraits:
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.traits[Google.DoorbellPressTrait.self] }
Wenn du auf ein herstellerspezifisches Attribut zugreifen möchtest, verweise über die Property traits darauf, stelle aber den Paketnamen des Herstellers voran:
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 }
Gerätestatus lesen
Hier ist ein Beispiel für die Prüfung des Attributs OnOff des Gerätemerkmals „An/Aus“:
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 }
Liste der Geräte mit einem bestimmten Attribut abrufen
Wenn du eine Liste der Geräte mit einem bestimmten Attribut abrufen möchtest, musst du die Geräte, die Gerätetypen der einzelnen Geräte und die Attribute der einzelnen Gerätetypen durchgehen. So kannst du beispielsweise eine Liste der Geräte im Zuhause abrufen, die alle das Attribut „An/Aus“ haben:
// 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) } } }
Eine vollständige Liste der in den Home APIs verfügbaren Eigenschaften findest du im Index der Eigenschaften für iOS.
Liste der Geräte mit ähnlichen Gerätetypen abrufen
So rufen Sie eine Liste der Geräte ab, die alle Lampen in einem Zuhause darstellen:
// 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) }
In den Home APIs gibt es mehrere Gerätetypen, die einen Hauptgerätetyp darstellen könnten. Es gibt beispielsweise keinen Gerätetyp „Licht“. Stattdessen gibt es vier verschiedene Gerätetypen, die eine Lampe darstellen können, wie im vorherigen Beispiel gezeigt. Um einen umfassenden Überblick über die übergeordneten Gerätetypen in einem Zuhause zu erhalten, müssen daher mehrere Gerätetypen berücksichtigt werden.
Eine vollständige Liste der Gerätetypen und ihrer Eigenschaften, die in den Home-APIs verfügbar sind, findest du unter Unterstützte Gerätetypen unter iOS.
Anbietername, Anbieter-ID oder Produkt-ID für ein Gerät abrufen
Das Attribut BasicInformationTrait enthält Informationen wie die Anbieter-ID, die Produkt-ID, den Produktnamen und die Seriennummer eines Geräts:
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") }
Cloud-zu-Cloud-Geräteidentifikation für Gerätehersteller
Wenn du ein Gerätehersteller bist und Cloud-to-cloud-Geräte herstellst, kannst du diese Stringfelder in die SYNC-Antwort aufnehmen, um deine Cloud-to-cloud-Geräte über das Attribut BasicInformation zu identifizieren:
Die von Connectivity Standards Alliance (Alliance) ausgestellte Anbieter-ID:
"matterOriginalVendorId": "0xfff1",Eine Produktkennzeichnung, die ein Produkt eines Anbieters eindeutig identifiziert:
"matterOriginalProductId": "0x1234",Eine eindeutige Kennung für das Gerät, die herstellerspezifisch erstellt wird:
"matterUniqueId": "matter-device-id",
Verwenden Sie bei der Eingabe dieser Stringfelder Ihre Matter-Anbieter- und Produkt-IDs, falls vorhanden. Wenn Sie kein Alliance-Mitglied sind und Ihnen diese IDs nicht zugewiesen wurden, können Sie die Felder matterOriginalVendorId und matterOriginalProductId leer lassen und die matterUniqueId als Kennung angeben.
Die Beispiel-SYNC-Antwort zeigt die Verwendung dieser Felder:
{
"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",
}
]
}
]
}
}
Weitere Informationen finden Sie in der Dokumentation zu Cloud-to-cloud SYNC.
Geräte- und Attributmetadaten
Geräte und Eigenschaften in den Home APIs sind mit Metadaten verknüpft, die bei der Verwaltung der Nutzererfahrung in einer App hilfreich sein können.
Jedes Attribut in den Home APIs enthält eine sourceConnectivity-Property, die Informationen zum Onlinestatus und zur Lokalität (lokales oder Remote-Routing) eines Attributs enthält.
Primären Typ eines Geräts abrufen
Einige Geräte können über die Home APIs mehrere Gerätetypen darstellen. Damit Nutzer in einer App die passenden Optionen für ihre Geräte sehen (z. B. Gerätesteuerung und vorgeschlagene automatisierte Abläufe), ist es hilfreich, zu prüfen, ob ein Gerätetyp der primäre Typ des Geräts ist.
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.") } }
Prüfen, ob ein Merkmal online ist
Lies das Attribut connectivityState, um die Konnektivität eines Merkmals zu prüfen:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Einige Eigenschaften, in der Regel Google smart home-Eigenschaften, werden möglicherweise als offline angezeigt, wenn das Gerät keine Internetverbindung hat. Das liegt daran, dass diese Attribute cloudbasiert sind und kein lokales Routing haben.
Verbindung eines Geräts prüfen
Die Konnektivität eines Geräts wird auf der Ebene des Gerätetyps geprüft, da einige Geräte mehrere Gerätetypen unterstützen. Der zurückgegebene Status ist eine Kombination der Verbindungsstatus aller Attribute auf diesem Gerät.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Der Status partiallyOnline kann bei gemischten Gerätetypen auftreten, wenn keine Internetverbindung besteht. Matter-Standard-Traits sind aufgrund des lokalen Routings möglicherweise noch online, cloudbasierte Traits sind jedoch offline.
IP-Adresse des Geräts abrufen
Verwenden Sie das Attribut networkInterfaces von GeneralDiagnosticsTrait, um die IP-Adresse des Geräts zu ermitteln.
Die Adressen werden als Data-Objekte zurückgegeben, die Sie mit dem Network-Framework in IPv4- oder IPv6-Standardstrings formatieren können:
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
}
Netzwerkrouting eines Merkmals prüfen
Die Lokalität für ein Trait ist auch in den Home APIs verfügbar. dataSourceLocality gibt an, ob das Attribut remote (über die Cloud), lokal (über einen lokalen Hub) oder Peer-to-Peer (direkt von Gerät zu Gerät, ohne Hub) weitergeleitet wird.
Der unbekannte Standortwert unspecified ist beispielsweise möglich, während eine App gestartet wird und noch keinen Hub oder Server für die Geräteverbindung erreicht hat. Diese Geräte sind nicht erreichbar und Interaktionsanfragen von Befehlen oder Ereignissen schlagen fehl. Es liegt am Client, zu entscheiden, wie mit solchen Geräten umgegangen werden soll.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Netzwerkrouting für ein Gerät prüfen
Wie die Konnektivität wird auch die Lokalität auf Gerätetypebene geprüft. Der zurückgegebene Status ist eine Kombination aus der Lokalität für alle Attribute auf diesem Gerät.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
Der Status mixed kann in einem ähnlichen Szenario wie bei der partiallyOnline-Verbindung beobachtet werden: Einige Eigenschaften sind cloudbasiert, andere lokal.
Gerätenamen ändern
Rufen Sie die Methode setName(_:) auf, um den Namen eines Geräts zu ändern:
let updatedDevice = try await theDevice.setName("new device name")
Wenn du den Namen eines Geräts änderst, bleibt die ursprüngliche HomeDevice-Struktur unverändert und die Änderung wird im zurückgegebenen aktualisierten HomeDevice-Objekt widergespiegelt.
Namen werden abgeschnitten, wenn sie das Limit von 60 Unicode-Codepunkten (Zeichen) überschreiten. Es werden keine Fehler ausgegeben. Entwickler sind für den Umgang mit langen Nutzernamen verantwortlich und können beispielsweise entscheiden, ob sie Nutzer darüber informieren möchten, dass Nutzernamen gekürzt werden.
Gruppenmitgliedschaft für ein Gerät prüfen
Ein physisches Gerät kann zu einer oder mehreren Gerätegruppen gehören. Wenn Sie wissen möchten, zu welchen Gruppen ein Gerät gehört, prüfen Sie die GroupMembershipTrait auf dem Gerät:
if let trait = await device.traits.get(Google.GroupMembershipTrait.self) {
for groupId in trait.attributes.groupObjectIdsArray {
print("Device belongs to group: \(groupId)")
}
}
Wenn du die von einer DeviceGroup unterstützten Gerätetypen prüfen und Befehle an die Gruppe als einzelne Entität senden möchtest, lies den Hilfeartikel Gerätegruppe steuern.