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 Merkmal „Matter On/Off“ und den Gerätetyp „On/Off Plug-in Unit“ 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.

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 Behandeln von HomeException die Felder error.code und error.message, um herauszufinden, was falsch gelaufen ist. Es können auch Unterfehlercodes vorhanden sein. Rufen Sie daher die getSubErrorCodes() Methode auf und prüfen Sie das Ergebnis.

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

Weitere Informationen finden Sie unter Fehlerbehandlung.

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

Beispielaufrufe

Geräteliste abrufen

Sobald Sie einen Verweis auf die Structure-Instanz haben, 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()

Von dort aus können Sie auf die Status der einzelnen Geräte zugreifen und Befehle an Geräte senden.

Mit Version 1.8 der Home APIs haben Sie die Möglichkeit, jedes mehrteilige Gerät als einzelnes Gerät darzustellen, indem Sie den Parameter enableMultipartDevices der Methode devices() auf true setzen. Weitere Informationen finden Sie unter Mehrteilige Geräte auf Android.

Gerätestatus lesen

Hier sehen Sie ein Beispiel für das Prüfen des Attributs OnOff aus dem Merkmal „On/Off“ des Geräts. 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 Merkmalabo ungültig machen

Über die Schnittstelle TraitStateInvalidation kann ein Status ungültig gemacht werden, der über Abos für das Zielgerät abgerufen wurde, wenn der Status nicht korrekt gemeldet wird. Das kann beispielsweise der Fall sein, wenn Attribute in Matter Merkmalen mit der Qualitätsstufe „C“ verwendet werden oder wenn eine Geräteimplementierung unerwartet das Problem verursacht.

Diese API erzwingt das Lesen des aktuellen Merkmalsstatus und gibt das Ergebnis über vorhandene Merkmals-Flows zurück.

Rufen Sie das Merkmal ab und führen Sie dann einen forceRead-Vorgang für das Merkmal aus:

val onOffTrait = device.?type(DimmableLightDevice)?.map{it.trait(OnOff)}.first()
onOffTrait.forceRead()

Liste der Merkmale des Gerätetyps abrufen

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

Sie berücksichtigen auch Merkmalskollisionen, falls ein Gerät zwei Gerätetypen hat, die beide dasselbe Merkmal haben. Wenn ein Gerät beispielsweise sowohl ein Lautsprecher als auch eine dimmbare Lampe ist, hat es zwei Merkmale für „On/Off“ und zwei für „Level Control“.

So rufen Sie die Liste der verfügbaren Merkmale für den Gerätetyp „Dimmable Light“ 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 andere Art von Merkmalskollision kann auftreten, wenn ein Gerät zwei Merkmale mit demselben Namen hat. Beispielsweise kann sich onOff auf eine Instanz des Standardmerkmals OnOff oder auf eine Instanz eines vom Hersteller definierten OnOff-Merkmals beziehen. Um potenzielle Unklarheiten hinsichtlich des beabsichtigten Merkmals 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 den 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

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

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

Liste der Geräte mit einem bestimmten Merkmal abrufen

Die filter Funktion in Kotlin kann verwendet werden, um API-Aufrufe weiter zu verfeinern. So rufen Sie beispielsweise eine Liste der Geräte im Zuhause ab, die alle das Merkmal „On/Off“ 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 Schnittstelle.

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

In den Home APIs gibt es mehrere Gerätetypen, die einen Kerngerätetyp darstellen können. Es gibt beispielsweise keinen Gerätetyp „Light“. Stattdessen gibt es vier verschiedene Gerätetypen, die eine Lampe darstellen können, wie im vorherigen Beispiel gezeigt. Wenn Sie also eine umfassende Übersicht über den Gerätetyp auf höherer Ebene in einem Zuhause erhalten möchten, müssen mehrere Gerätetypen in gefilterte Flows 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 BasicInformation Merkmal 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äteidentifikation für Gerätehersteller

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

  • Die von der Connectivity Standards Alliance (Alliance) ausgegebene Anbieter-ID: "matterOriginalVendorId": "0xfff1",

  • Eine Produkt-ID, die ein Produkt eines Anbieters eindeutig identifiziert: "matterOriginalProductId": "0x1234",

  • Eine eindeutige ID 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, falls vorhanden. Wenn Sie kein Alliance Mitglied sind und diese IDs nicht zugewiesen wurden, können Sie die matterOriginalVendorId und matterOriginalProductId Felder leer lassen und matterUniqueId als ID 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 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 Nutzererfahrung in einer App hilfreich sein können.

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

Primären Typ eines Geräts abrufen

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

Rufen Sie zuerst die Typen des Geräts mit type() ab und bestimmen Sie dann die primären Typen:

val types = device.types().first()
val primaryTypes = types.filter { 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.

Konnektivität für ein Gerät prüfen

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

val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState

Bei gemischten Gerätetypen kann der Status PARTIALLY_ONLINE auftreten, wenn keine Internetverbindung besteht. Matter Standardmerkmale sind aufgrund des lokalen Routings möglicherweise weiterhin online, cloudbasierte Merkmale sind jedoch offline.

IP-Adresse des Geräts abrufen

Verwenden Sie das Attribut networkInterfaces des Merkmals GeneralDiagnostics, um die IP-Adresse des Geräts zu ermitteln. Die Adressen werden als Byte-Arrays zurückgegeben, die Sie in Standard-IPv4- oder IPv6-Strings formatieren können:

val ipAddresses =
  trait.networkInterfaces?.flatMap { networkInterface ->
    (networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
      try {
        java.net.InetAddress.getByAddress(bytes).hostAddress
      } catch (e: java.net.UnknownHostException) {
        null
      }
    }
  } ?: emptyList()

Netzwerkrouting eines Merkmals prüfen

Die Lokalität für ein Merkmal ist auch in den Home APIs verfügbar. dataSourceLocality gibt an, ob das Merkmal remote (über die Cloud), lokal (über einen lokalen Hub) oder Peer-to-Peer (direkt von Gerät zu Gerät, kein Hub) geroutet 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ätekonnektivität erreicht hat. Diese Geräte sind nicht erreichbar und bei Interaktionsanfragen von Befehlen oder Ereignissen tritt ein Fehler auf. Es liegt am Client, zu entscheiden, wie mit solchen Geräten umgegangen werden soll.

val onOffLocality = onOffTrait?.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 der Lokalität für alle 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-Konnektivität auftreten: Einige Merkmale sind cloudbasiert, andere lokal.

Namen eines Geräts ändern

Rufen Sie die setName() Methode 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 für die Verarbeitung langer Namen verantwortlich und können beispielsweise entscheiden, ob sie Nutzer darüber informieren möchten, dass Namen abgeschnitten werden.