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 Beheben von HomeException die Felder
error.code und
error.message, um herauszufinden, was schiefgelaufen ist. Es kann auch Unterfehlercodes geben. Rufen Sie daher die Methode
getSubErrorCodes() auf und prüfen Sie das Ergebnis.
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.
Beispielaufrufe
Geräteliste abrufen
Sobald Sie eine Referenz zur Structure-Instanz haben, gibt ein devices()-Aufruf eine 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 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 von der API darstellen zu lassen. Dazu müssen Sie den Parameter enableMultipartDevices der Methode devices() auf true setzen. Weitere Informationen finden Sie unter Multipart-Geräte unter Android.
Gerätestatus lesen
Hier sehen Sie ein Beispiel für die Prüfung des Attributs OnOff aus dem On/Off-Trait des Geräts. Mit dem Datenmodell für Home APIs-Traits, in dem dieser Trait als OnOff identifiziert wird, können Sie Trait-Daten ü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, sind die Verwendung von Attributen in Matter-Traits mit der Qualität „C“ oder eine Geräteimplementierung, die unerwartet das Problem 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 für das Attribut aus:
val onOffTrait = device.?type(DimmableLightDevice)?.map{it.trait(OnOff)}.first()
onOffTrait.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 andere 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 der Geräte 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 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) } }
Es gibt mehrere Gerätetypen in den Home APIs, die einen Kerngerätetyp darstellen könnten. Es gibt beispielsweise keinen Gerätetyp „Light“. Stattdessen gibt es vier verschiedene Gerätetypen, die ein Licht darstellen können, wie im vorherigen Beispiel gezeigt. Um eine umfassende Ansicht des Gerätetyps auf höherer Ebene in einem Zuhause zu erhalten, müssen 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-to-Cloud-Geräteidentifizierung für Gerätehersteller
Wenn Sie Gerätehersteller sind und Cloud-to-cloud-Geräte entwickeln, können Sie die folgenden Stringfelder in die SYNC-Antwort aufnehmen, um Ihre Cloud-to-cloud-Geräte über das BasicInformation-Attribut zu identifizieren:
Die vom 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 beim Eingeben dieser String-Felder Ihre MatterAnbieter- und Produkt-IDs, sofern Sie sie haben. Wenn Sie kein Alliance-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 Dokumentation zu Cloud-to-cloud SYNC.
Geräte- und Attributmetadaten
Geräten und Merkmalen in den Home-APIs sind Metadaten zugeordnet, die bei der Verwaltung der Nutzerfreundlichkeit in einer App helfen können.
Jedes Merkmal in den Home APIs enthält die Property sourceConnectivity mit Informationen zum Onlinestatus und zur Lokalität (lokales oder Remote-Routing) eines Merkmals.
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 für ein Gerät zu prüfen.
Rufen Sie zuerst den/die Typ(en) des Geräts 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 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.
IP-Adresse des Geräts ermitteln
Verwende das Attribut networkInterfaces des Traits 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 Attributs prüfen
Der Standort für ein Merkmal ist auch in den Home APIs verfügbar. Das dataSourceLocality gibt an, ob das Merkmal 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 auch die Lokalität auf Geräteebene geprüft. Der zurückgegebene Status ist eine Kombination aus der Lokalität für alle Eigenschaften 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.
Gerätenamen ä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.
Gruppenmitgliedschaft eines Geräts prüfen
Ein physisches Gerät kann einer oder mehreren Gerätegruppen angehören. So sehen Sie, zu welchen
Gruppen ein Gerät gehört
GroupMembership:
val groupIds = device.trait(GroupMembershipTrait)?.groupObjectIds.orEmpty()
for (groupId in groupIds) {
println("HomeAPI", "Device belongs to group: $groupId")
}
Umgekehrt können Sie alle Mitgliedsgeräte, die zu einem DeviceGroup gehören, aufrufen, indem Sie den devices()-Ablauf auf einem DeviceGroup aufrufen:
group.devices(enableMultipartDevices = true).collect { members ->
println("HomeAPI", "Group contains ${members.size} devices")
}