Auf Geräte und Gerätemetadaten für Android zugreifen

Der Zugriff auf Geräte-APIs ist über die Smart-Home-APIs für Android 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 auf Android-Geräten.

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.

Nicht behandelte Ausnahmen führen zum Absturz Ihrer App.

Weitere Informationen finden Sie unter Fehlerbehandlung.

Ein Beispiel finden Sie unter Befehl an ein Gerät senden.

Beispielanrufe

Liste der Geräte 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 Klasse standardTraits 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-Funktion „flow“ finden Sie unter distinctUntilChanged.

Status in einem Merkmal-Abo ungültig machen

Über die TraitStateInvalidation-Schnittstelle können Sie einen Status ungültig machen, der über Abos für das Zielgerät abgerufen wurde, 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 Merkmale für Gerätetypen abrufen

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

Außerdem werden Attributen Kollisionen berücksichtigt, wenn ein Gerät zwei Gerätetypen hat, die beide dasselbe Attribut haben. Wenn ein Gerät beispielsweise sowohl ein Lautsprecher als auch eine dimmbare Lampe 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 für Google-Attribute googleTraits:

// 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, müssen Sie es direkt referenzieren:

// 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 im 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-Benutzeroberfläche.

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

So rufen Sie eine Liste der Geräte auf, 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önnen, 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 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 auf herstellerspezifische Weise erstellt wird: "matterUniqueId": "matter-device-id",

Verwenden Sie beim Eingeben dieser Stringfelder Ihre Matter-Anbieter- und Produkt-IDs, sofern 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 Merkmalsmetadaten

Geräten und Merkmalen in den Home APIs sind Metadaten zugeordnet, die bei der Verwaltung der Nutzerfreundlichkeit in einer App helfen 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 Haupttyp ist:

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

Prüfen, ob ein Merkmal online ist

Verwenden Sie die Methode connectivityState(), um die Konnektivität eines Merkmals zu 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 Verbindung für ein Gerät 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. Die dataSourceLocality gibt an, 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 „Unbekannter Ort“ 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 Konnektivität 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 Automatisierungen 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 die aggregierten 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