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

Auf Geräte-APIs kann über die Home-APIs für Android zugegriffen werden. Importieren Sie diese 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-Merkmal „Ein/Aus“ und den Gerätetyp „Ein/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 unter Android.

Fehlerbehandlung

Jede Methode in den Home APIs kann eine HomeException auslösen. Wir empfehlen daher, einen try-catch-Block zu verwenden, um HomeException bei allen Aufrufen abzufangen.

Prüfen Sie beim Verarbeiten von HomeException die Felder code und message, um herauszufinden, was schiefgelaufen ist.

Nicht abgefangene 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

Geräteliste abrufen

Wenn eine Struktur verfügbar ist, gibt ein devices()-Aufruf einen Flow von Geräten zurück, auf die 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 verfügbar 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 On/Off-Trait des Geräts an. Mit dem Datenmodell für Merkmale der Home APIs, in dem dieses Merkmal als OnOff identifiziert wird, können Sie Merkmalsdaten ü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-Flow-Funktion finden Sie unter distinctUntilChanged.

Status in einem Trait-Abo ungültig machen

Über die TraitStateInvalidation-Schnittstelle kann ein über Abonnements abgerufener Status für das Zielgerät ungültig gemacht werden, wenn der Status nicht korrekt gemeldet wird. Beispiele dafür, wann der Status möglicherweise nicht korrekt gemeldet wird: Verwendung von Attributen in Matter-Traits mit der Qualitätsstufe „C“ oder aufgrund einer Geräteimplementierung, die das Problem unerwartet verursacht.

Mit dieser API wird ein erzwungenes Lesen des aktuellen Trait-Status ausgelöst und das Ergebnis über vorhandene Trait-Abläufe zurückgegeben.

Rufen Sie das Attribut ab und führen Sie dann einen forceRead-Befehl für das Attribut aus:

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

Liste der Geräte-Traits abrufen

Gerätetypen sollten als Einstiegspunkt zum Lesen von Attributen verwendet werden, da sie ein Gerät in seine funktionalen Teile zerlegen (z. B. Endpunkte in Matter).

Außerdem werden Attributkonflikte berücksichtigt, falls 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 On/Off- und zwei Level Control-Traits.

So rufen Sie die Liste der verfügbaren Traits für den Gerätetyp „Dimmable Light“ (Dimmbare Lampe) auf:

// 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 Trait-Konflikt kann auftreten, wenn ein Gerät zwei Traits mit demselben Namen hat. onOff kann sich beispielsweise auf eine Instanz des Standard-OnOff-Traits oder auf eine Instanz eines vom Hersteller definierten OnOff-Traits beziehen. Um potenzielle Unklarheiten hinsichtlich des beabsichtigten Attributs zu vermeiden, muss einer Trait-Instanz, auf die über ein Gerät verwiesen wird, ein qualifizierender Namespace vorangestellt werden. Verwenden Sie für Standardmerkmale, die analogen Matter-Standardclustern entsprechen, standardTraits. Verwenden Sie für Google-Merkmale googleTraits:

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

So greifen Sie auf ein herstellerspezifisches Attribut zu:

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

Liste von Geräten mit einem bestimmten Merkmal abrufen

Die Funktion filter in Kotlin kann verwendet werden, um API-Aufrufe weiter zu optimieren. So erhalten Sie beispielsweise eine Liste der Geräte im Zuhause, die alle das Attribut „Ein/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 Traits finden Sie im Trait-Interface.

Liste von Geräten 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)
val lightDevices =
  home.devices().map { devices ->
    devices.filter {
      it.has(DimmableLightDevice) ||
        it.has(OnOffLightDevice) ||
        it.has(ColorTemperatureLightDevice) ||
        it.has(ExtendedColorLightDevice)
    }
  }

Es gibt mehrere Gerätetypen in den Home-APIs, die einen Kerngerätetyp darstellen können. 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 den Gerätetyp auf höherer Ebene in einem Zuhause zu erhalten, müssen daher mehrere Gerätetypen in gefilterte Abläufe aufgenommen werden.

Eine vollständige Liste der in den Home APIs verfügbaren Gerätetypen finden Sie in der DeviceType-Schnittstelle.

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

Das Merkmal 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äteidentifizierung für Gerätehersteller

Wenn Sie Gerätehersteller sind und Cloud-to-cloud-Geräte entwickeln, können Sie Ihre Cloud-to-cloud-Geräte über das BasicInformation-Attribut identifizieren. Dazu können Sie diese Stringfelder in die SYNC-Antwort einfügen:

  • 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 erstellt wird: "matterUniqueId": "matter-device-id",

Verwenden Sie beim Eingeben dieser String-Felder 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.

Im Beispiel für die SYNC-Antwort wird die Verwendung dieser Felder gezeigt:

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

Geräte- und Attributmetadaten

Geräten und Attributen in den Home-APIs sind Metadaten zugeordnet, die bei der Verwaltung der Nutzerfreundlichkeit in einer App hilfreich sein können.

Jedes Merkmal in den Home APIs enthält die Property sourceConnectivity, die Informationen zum Onlinestatus und zur Lokalität (lokales oder Remote-Routing) eines Merkmals enthält.

Primären Typ eines Geräts abrufen

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

Rufen Sie zuerst den/die Gerätetyp(en) mit type() ab und bestimmen Sie dann den/die primären Typ(en):

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

Prüfen, ob ein Attribut online ist

Verwenden Sie die Methode connectivityState(), um die Verbindung eines Traits zu prüfen:

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

Einige Merkmale, in der Regel smart home-Merkmale von Google, 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 für ein Gerät prüfen

Die Verbindung für ein Gerät wird tatsächlich 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 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-Standardmerkmale sind aufgrund des lokalen Routings möglicherweise weiterhin online, cloudbasierte Merkmale sind jedoch offline.

Netzwerkrouting eines Attributs prüfen

Der Ort für ein Merkmal ist auch in den Home APIs verfügbar. Die dataSourceLocality gibt an, ob das Attribut remote (über die Cloud), lokal (über einen lokalen Hub) oder Peer-to-Peer (direkt vom Gerät zum Gerät, ohne Hub) weitergeleitet wird.

Der unbekannte Lokalitätswert 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

Netzwerkrouting für ein Gerät prüfen

Wie die Konnektivität wird die Lokalität auf Geräteebene geprüft. Der zurückgegebene Status ist eine Kombination aus der Lokalität für alle Merkmale auf diesem Gerät.

val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality

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

Name eines Geräts ändern

Rufen Sie die Methode setName() auf, um den Namen eines Geräts zu ändern:

mixerDevice.setName("Grendel")

Namen werden abgeschnitten, wenn sie das Limit von 60 Unicode-Codepunkten (Zeichen) überschreiten. Es werden keine Fehler ausgegeben. Entwickler sind dafür verantwortlich, lange Namen zu verarbeiten. Sie können beispielsweise entscheiden, ob sie Nutzer darüber informieren möchten, dass Namen gekürzt werden.

API-Liste

Nachdem eine Instanz von Home erstellt wurde, sind die folgenden Geräte-APIs darüber zugänglich:

API Beschreibung
devices() Alle Geräte in allen Strukturen müssen im Google-Konto vorhanden sein. Gibt ein HomeObjectsFlow zurück, das weitere Abruf- und Filteroptionen bietet.

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

API Beschreibung
allCandidates() Gibt alle Automatisierungskandidaten für das Gerät und seine untergeordneten Elemente zurück.
candidates() Gibt alle Automatisierungskandidaten für das Gerät zurück.
connectivityStateChanged Der Zeitpunkt der letzten Änderung des Gerätestatus.
events(event) Ruft einen Ablauf eines bestimmten Ereignisses ab.
events(trait) Ruft einen Stream aller Ereignisse für dieses Attribut ab.
events(traits) Ruft einen Stream aller Ereignisse nach diesen Attributen ab.
getSourceConnectivity(trait) Metadaten für ein bestimmtes Merkmal abrufen. Gibt SourceConnectivity zurück.
has(trait) Prüft, ob das aktuell angeforderte Attribut vom Gerät unterstützt wird.
has(type) Gibt an, ob das Gerät den angegebenen Typ unterstützt.
id Die eindeutige System-ID des Geräts.
isInRoom Gibt an, ob sich das Gerät in einem Raum befindet.
isInStructure Gibt an, ob sich das Gerät in einem Gebäude befindet.
isMatterDevice Gibt an, ob 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 Raums, dem das Gerät zugewiesen ist. Gibt ein Id zurück.
sourceConnectivity Die Quellverbindung des Geräts, die aggregierte Verbindungsstatus und die Netzwerk-Lokalität der Geräteattribute darstellt.
structure() Die Struktur, der das Gerät zugewiesen ist. Gibt Structure zurück.
structureId Die ID des Gebäudes, dem das Gerät zugewiesen ist. Gibt ein Id zurück.
type(type) Rufen Sie die Typdefinition mit den (falls verfügbar) ausgefüllten Attributen für den direkten Zugriff ab. Gibt immer einen aktuellen Snapshot der Eigenschaften zurück.
types() Rufen Sie eine Liste aller auf dem Gerät verfügbaren Typen ab.