Auf Geräte und Gerätemetadaten zugreifen

Der Zugriff auf Geräte-APIs ist über die Smart-Home-APIs möglich. Importieren Sie die folgenden Pakete in Ihre App:

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

Wenn Sie bestimmte Gerätetypen oder -merkmale mit den Geräte-APIs verwenden möchten, müssen sie einzeln importiert werden.

Wenn Sie beispielsweise das Matter-Attribut „An/Aus“ und den Gerätetyp „An/Aus-Steckdose“ verwenden möchten, importieren Sie die folgenden Pakete in Ihre Anwendung:

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

Weitere Informationen finden Sie unter Datenmodell.

Fehlerbehandlung

Bei jeder Methode in den Home APIs kann eine HomeException geworfen werden. Wir empfehlen daher, einen try-catch-Block zu verwenden, um HomeException bei allen Aufrufen zu fangen.

Prüfen Sie bei der Verarbeitung von HomeException die Felder code und message, um herauszufinden, was schiefgelaufen ist.

Alle nicht behandelten Ausnahmen führen zum Absturz Ihrer App.

Weitere Informationen finden Sie unter Fehlerbehandlung.

Ein Beispiel finden Sie unter Befehl an Geräte senden.

Beispielanrufe

Geräteliste abrufen

Wenn die Struktur verfügbar ist, gibt ein devices()-Aufruf einen Geräte-Stream zurück, auf den Sie über diese Struktur zugreifen können:

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

Dort sind die Status für jedes Gerät zugänglich und unterstützte Befehle können an das Gerät gesendet werden.

Gerätestatus lesen

Sehen wir uns ein Beispiel für die Prüfung des Attributs OnOff aus dem Attribut „An/Aus“ des Geräts an. Mit dem Datenmodell für Merkmale der Home APIs, in dem dieses Merkmal als OnOff gekennzeichnet ist, können Sie Merkmaldaten über die standardTraits-Klasse des Gerätetyps abrufen:

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

Weitere Informationen zur Kotlin-Flow-Funktion finden Sie unter distinctUntilChanged.

Status in einem Merkmal-Abo ungültig machen

Über die TraitStateInvalidation-Schnittstelle können Sie einen Status, der über Abos für das Zielgerät abgerufen wurde, ungültig machen, wenn der Status nicht korrekt gemeldet wird. Beispiele für Fälle, in denen der Status möglicherweise nicht korrekt gemeldet wird: Verwendung von Attributen in Matter-Attributen mit der Qualität „C“ oder eine Geräteimplementierung, die das Problem unerwartet verursacht.

Diese API erzwingt ein Lesen des aktuellen Merkmalstatus und gibt das Ergebnis über vorhandene Merkmalflüsse zurück.

Rufen Sie das Merkmal ab und führen Sie dann eine forceRead für das Merkmal aus:

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

Liste der Gerätetypmerkmale abrufen

Gerätetypen sollten als Ausgangspunkt für das Lesen von Merkmalen verwendet werden, da sie ein Gerät in seine funktionalen Teile zerlegen (wie Endpunkte in Matter).

Außerdem werden Kollisionen von Merkmalen berücksichtigt, wenn ein Gerät zwei Gerätetypen hat, die beide dasselbe Merkmal haben. Wenn ein Gerät beispielsweise sowohl ein Lautsprecher als auch ein dimmbares Licht ist, hat es zwei „An/Aus“- und zwei „Steuerung der Helligkeit“-Attribute.

So rufen Sie eine Liste der verfügbaren Eigenschaften für den Gerätetyp „Dimmbares Licht“ ab:

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

Eine weitere Art von Attributüberschneidung kann auftreten, wenn ein Gerät zwei Attribute mit demselben Namen hat. onOff kann sich beispielsweise auf eine Instanz des standardmäßigen OnOff-Attributs oder auf eine Instanz eines vom Hersteller definierten OnOff-Attributs beziehen. Um mögliche Unklarheiten darüber zu vermeiden, welche Eigenschaft gemeint ist, sollte einer Trait-Instanz, auf die über ein Gerät verwiesen wird, ein qualifizierender Namespace vorangestellt werden. Verwenden Sie für Standardmerkmale, also solche, die den Matter-Standardclustern entsprechen, standardTraits. Verwenden Sie googleTraits für Google-Attribute:

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

Wenn Sie auf ein herstellerspezifisches Attribut zugreifen möchten, verweisen Sie direkt darauf:

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

Liste der Geräte mit einer bestimmten Eigenschaft abrufen

Mit der Funktion filter in Kotlin können API-Aufrufe weiter optimiert werden. So rufen Sie beispielsweise eine Liste der Geräte in Ihrem Zuhause ab, die alle die Eigenschaft „An/Aus“ haben:

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

Eine vollständige Liste der in den Home APIs verfügbaren Merkmale finden Sie in der Trait-Oberfläche.

Liste der Geräte mit ähnlichen Gerätetypen abrufen

So rufen Sie eine Liste der Geräte ab, die alle Lampen in einem Zuhause repräsentieren:

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

In den Smart-Home-APIs gibt es mehrere Gerätetypen, die einen Hauptgerätetyp darstellen könnten. Es gibt beispielsweise keinen Gerätetyp „Lampe“. Stattdessen gibt es vier verschiedene Gerätetypen, die eine Lampe darstellen könnten, wie im vorherigen Beispiel gezeigt. Um also einen umfassenden Überblick über die Gerätetypen auf höherer Ebene in einem Zuhause zu erhalten, müssen mehrere Gerätetypen in gefilterten Datenflüssen enthalten sein.

Eine vollständige Liste der Gerätetypen, die in den Smart-Home-APIs verfügbar sind, finden Sie in der DeviceType-Benutzeroberfläche.

Anbieter-ID oder Produkt-ID für ein Gerät abrufen

Das Attribut BasicInformation enthält Informationen wie die Anbieter-ID, die Produkt-ID, den Produktnamen und die Seriennummer eines Geräts:

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

Cloud-zu-Cloud-Geräte identifizieren

Wenn Sie ein Gerätehersteller sind und Cloud-to-cloud-Geräte herstellen, können Sie die folgenden Stringfelder in die SYNC-Antwort aufnehmen, um Ihre Cloud-to-cloud-Geräte über das BasicInformation-Attribut zu identifizieren:

  • Von der Connectivity Standards Alliance (CSA) 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 aufgebaut ist: "matterUniqueId": "matter-device-id",

Verwenden Sie bei der Eingabe dieser Stringfelder Ihre MatterAnbieter- und Produkt-IDs, falls vorhanden. Wenn Sie kein CSA-Mitglied sind und Ihnen diese IDs nicht zugewiesen wurden, können Sie die Felder matterOriginalVendorId und matterOriginalProductId leer lassen und matterUniqueId als Kennung angeben.

In der Beispiel-SYNC-Antwort wird die Verwendung dieser Felder veranschaulicht:

{
  "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 Cloud-to-cloud SYNC-Dokumentation.

Geräte- und Merkmalmetadaten

Geräten und Merkmalen in den Home APIs sind Metadaten zugeordnet, die die Nutzerfreundlichkeit in einer App verbessern können.

Jede Eigenschaft in den Home APIs enthält eine sourceConnectivity-Property mit Informationen zum Onlinestatus und zur Lokalität einer Eigenschaft (lokales oder Remote-Routing).

Primären Typ eines Geräts abrufen

Einige Geräte können über die Smart-Home-APIs mehrere Gerätetypen präsentieren. Damit Nutzern in einer App die richtigen Optionen für ihre Geräte angezeigt werden (z. B. Gerätesteuerung und vorgeschlagene Automatisierungen), ist es hilfreich, den primären Gerätetyp für ein Gerät zu prüfen.

Rufe zuerst den Gerätetyp mit type() ab und finde dann heraus, welcher der primäre Typ ist:

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

Prüfen, ob ein Merkmal online ist

Mit der Methode connectivityState() können Sie die Konnektivität eines Merkmals prüfen:

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

Einige Merkmale, in der Regel Google smart home-Merkmale, werden möglicherweise als offline angezeigt, wenn das Gerät keine Internetverbindung hat. Das liegt daran, dass diese Merkmale cloudbasiert sind und kein lokales Routing haben.

Verbindung eines Geräts prüfen

Die Konnektivität eines Geräts wird tatsächlich auf Gerätetypebene geprüft, da einige Geräte mehrere Gerätetypen unterstützen. Der zurückgegebene Status ist eine Kombination der Verbindungsstatus für alle Merkmale auf diesem Gerät.

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

Der Status PARTIALLY_ONLINE kann bei gemischten Gerätetypen auftreten, wenn keine Internetverbindung besteht. Matter-Standardeigenschaften sind aufgrund des lokalen Routings möglicherweise weiterhin online, aber cloudbasierte Eigenschaften sind offline.

Netzwerk-Routing eines Merkmals prüfen

Die Region für ein Merkmal ist auch in den Home APIs verfügbar. Mit der dataSourceLocality wird angegeben, ob das Attribut per Fernzugriff (über die Cloud), lokal (über einen lokalen Hub) oder Peer-to-Peer (direkt von Gerät zu Gerät, kein Hub) weitergeleitet wird.

Der Wert „Unbekannt“ (UNSPECIFIED) ist beispielsweise möglich, wenn 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 im Ermessen des Kunden, wie er mit solchen Geräten umgeht.

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

Netzwerk-Routing für ein Gerät prüfen

Wie bei der Verbindung wird auch die Lokalität auf Gerätetypebene geprüft. Der zurückgegebene Status ist eine Kombination aus der Lokalität aller Merkmale auf diesem Gerät.

val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality

Ein Status von MIXED kann in einem ähnlichen Szenario wie bei der PARTIALLY_ONLINE-Verbindung auftreten: Einige Merkmale sind cloudbasiert, andere lokal.

API-Liste

Sobald eine Instanz von Home erstellt wurde, können über sie die folgenden Geräte-APIs aufgerufen werden:

API Beschreibung
devices() Alle Geräte in allen Gebäuden im Google-Konto abrufen Gibt einen HomeObjectsFlow zurück, der weitere Abruf- und Filteroptionen bietet.

Sobald Sie eine HomeDevice haben, können Sie über diese auf die folgenden APIs zugreifen:

API Beschreibung
allCandidates() Gibt alle Kandidaten für automatisierte Abläufe für das Gerät und seine untergeordneten Elemente zurück.
candidates() Gibt alle Kandidaten für die Automatisierung für das Gerät zurück.
connectivityStateChanged Der Zeitpunkt, zu dem sich der Status des Geräts zuletzt geändert hat.
events(event) Ruft einen Ablauf eines bestimmten Ereignisses ab.
events(trait) Hiermit wird ein Stream aller Ereignisse nach diesem Attribut abgerufen.
events(traits) Hiermit wird ein Stream aller Ereignisse nach diesen Merkmalen abgerufen.
getSourceConnectivity(trait) Metadaten für ein bestimmtes Merkmal abrufen Gibt SourceConnectivity zurück.
has(trait) Prüfen, ob das aktuell angeforderte Merkmal vom Gerät unterstützt wird
has(type) Ob das Gerät den angegebenen Typ unterstützt.
id Die eindeutige System-ID des Geräts.
isInRoom Ob sich das Gerät in einem Raum befindet.
isInStructure Ob sich das Gerät in einem Gebäude befindet.
isMatterDevice Wenn das Gerät von Matter unterstützt wird.
name Der vom Nutzer angegebene Name des Geräts.
room() Der Raum, dem das Gerät zugewiesen ist. Gibt Room zurück.
roomId Die ID des Zimmers, dem das Gerät zugewiesen ist. Gibt eine Id zurück.
sourceConnectivity Die Quellverbindung des Geräts, die aggregierte Verbindungsstatus und die Netzwerklokalität der Merkmale des Geräts darstellt.
structure() Das Gebäude, dem das Gerät zugewiesen ist. Gibt Structure zurück.
structureId Die ID des Gebäudes, dem das Gerät zugewiesen ist. Gibt eine Id zurück.
type(type) Rufen Sie die Typdefinition mit den ausgefüllten Merkmalen ab (falls verfügbar), um direkten Zugriff zu erhalten. Gibt immer einen aktuellen Snapshot der Merkmale zurück.
types() Liste aller auf dem Gerät verfügbaren Typen abrufen