Ereignisse sind asynchron und werden von Google Cloud Pub/Sub in einem einzelnen Thema pro Projectverwaltet. Ereignisse liefern Updates für alle Geräte und Strukturen. Der Empfang von Ereignissen ist sichergestellt, solange das Zugriffstoken nicht vom Nutzer widerrufen wurde und die Ereignisnachrichten nicht abgelaufen sind.
Veranstaltungen aktivieren
Ereignisse sind eine optionale Funktion der SDM API. Weitere Informationen finden Sie unter Ereignisse aktivieren Project.
Google Cloud Pub/Sub
Weitere Informationen zur Funktionsweise von Pub/Sub finden Sie in der Google Cloud Pub/Sub-Dokumentation. Wichtig ist insbesondere:
- Anleitungen für die Grundlagen von Pub/Sub
- Weitere Informationen zur Authentifizierung
- Wählen Sie eine der bereitgestellten Clientbibliotheken aus oder schreiben Sie Ihre eigene und verwenden Sie die REST-/HTTP- oder gRPC-API-Oberflächen.
Ereignisabo
Vor Januar 2025 wurde Ihnen, wenn Ereignisse für Ihre Projectaktiviert waren, ein Thema für diese Project ID zur Verfügung gestellt, das so aussah:
projects/gcp-project-name/subscriptions/topic-id
Wenn Sie Ereignisse empfangen möchten, erstellen Sie je nach Anwendungsfall ein Pull-- oder Push-Abo für dieses Thema. Es werden mehrere Abos für das SDM-Thema unterstützt. Weitere Informationen finden Sie unter Abos verwalten.
Ereignisse auslösen
Um Ereignisse zum ersten Mal zu initiieren, nachdem das Pub/Sub-Abo erstellt wurde, führen Sie einen
devices.list-API-Aufruf als einmaligen Trigger aus. Ereignisse für alle Strukturen und Geräte werden nach diesem Aufruf veröffentlicht.
Ein Beispiel finden Sie auf der Seite Autorisieren in der Kurzanleitung.
Reihenfolge der Ereignisse
Pub/Sub garantiert keine geordnete Zustellung von Ereignissen. Die Reihenfolge, in der Ereignisse empfangen werden, entspricht möglicherweise nicht der Reihenfolge, in der die Ereignisse tatsächlich aufgetreten sind. Verwenden Sie das Feld timestamp, um die Reihenfolge von Ereignissen abzugleichen. Ereignisse können auch einzeln oder in einer einzigen Ereignisnachricht kombiniert eintreffen.
Weitere Informationen finden Sie unter Nachrichten sortieren.
Nutzer-IDs
Wenn Ihre Implementierung auf Nutzern (und nicht auf Struktur oder Gerät) basiert, verwenden Sie das Feld userID aus der Ereignis-Payload, um Ressourcen und Ereignisse zu verknüpfen. Dieses Feld enthält eine verschleierte ID, die einen bestimmten Nutzer darstellt.
Die userID ist auch im HTTP-Antwortheader jedes API-Aufrufs verfügbar.
Beziehung zwischen Ereignissen
Beziehungselemente stellen eine relationale Aktualisierung für eine Ressource dar. Zum Beispiel, wenn ein Gerät einer Struktur hinzugefügt oder aus einer Struktur gelöscht wird.
Es gibt drei Arten von Beziehungsereignissen:
- CREATED
- GELÖSCHT
- AKTUALISIERT
Die Nutzlast für ein Beziehungsereignis sieht so aus:
Nutzlast
{
"eventId" : "e73314bd-eb36-42c6-86a5-bb3d2706ccb3",
"timestamp" : "2019-01-01T00:00:01Z",
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
},
"userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"
}Bei einem Beziehungsevent ist object die Ressource, die das Ereignis ausgelöst hat, und subject die Ressource, mit der object jetzt eine Beziehung hat. Im obigen Beispiel hat ein user einem developerZugriff auf dieses bestimmte Gerät gewährt und das autorisierte Gerät des userist jetzt mit seiner autorisierten Struktur verknüpft, was das Ereignis auslöst.
Eine subject kann nur ein Raum oder ein Gebäude sein. Wenn a developer keine Berechtigung zum Aufrufen der Struktur von userhat, ist subject immer leer.
Felder
| Feld | Beschreibung | Datentyp |
|---|---|---|
eventId |
Die eindeutige Kennung für das Ereignis. | stringBeispiel: „551277d3-a144-4d69-a3c8-1dfd86c16017“ |
timestamp |
Die Zeit, in der das Ereignis aufgetreten ist. | stringBeispiel: „2019-01-01T00:00:01Z“ |
relationUpdate |
Ein Objekt mit Informationen zur Aktualisierung der Beziehung. | object |
userId |
Eine eindeutige, verschleierte Kennung, die den Nutzer repräsentiert. | stringBeispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“ |
Weitere Informationen zu den verschiedenen Arten von Ereignissen und ihrer Funktionsweise finden Sie unter Ereignisse.
Beispiele
Die Ereignis-Payloads unterscheiden sich für die einzelnen Arten von Beziehungsereignissen:
ERSTELLT
Struktur erstellt
"relationUpdate" : {
"type" : "CREATED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Gerät erstellt
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Gerät erstellt
"relationUpdate" : {
"type" : "CREATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}AKTUALISIERT
Gerät verschoben
"relationUpdate" : {
"type" : "UPDATED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}GELÖSCHT
Gebäude gelöscht
"relationUpdate" : {
"type" : "DELETED",
"subject" : "",
"object" : "enterprises/project-id/structures/structure-id"
}Gerät gelöscht
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id",
"object" : "enterprises/project-id/devices/device-id"
}Gerät gelöscht
"relationUpdate" : {
"type" : "DELETED",
"subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
"object" : "enterprises/project-id/devices/device-id"
}Beziehungsereignisse werden in folgenden Fällen nicht gesendet:
- Ein Raum wird gelöscht
Ressourcenereignisse
Ein Ressourcenereignis stellt eine Aktualisierung dar, die sich auf eine bestimmte Ressource bezieht. Dies kann als Reaktion auf eine Änderung des Werts eines Attributfelds erfolgen, z. B. wenn der Modus eines Thermostats geändert wird. Sie kann auch eine Geräteaktion darstellen, die kein Attributfeld ändert, z. B. das Drücken einer Gerätetaste.
Ein Ereignis, das als Reaktion auf eine Änderung des Werts eines Attributfelds generiert wird, enthält ein traits-Objekt, ähnlich wie bei einem GET-Aufruf für ein Gerät:
Nutzlast
{
"eventId" : "ec33a442-8b89-449a-a438-6c6229937434",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"traits" : {
"sdm.devices.traits.ThermostatMode" : {
"mode" : "COOL"
}
}
},
"userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}In der Dokumentation zu den einzelnen Attributen finden Sie Informationen zum Nutzlastformat für Ereignisse vom Typ „Ressource für Attributfeldänderung“.
Ein Ereignis, das als Reaktion auf eine Geräteaktion generiert wird, die kein Attributfeld ändert, hat auch eine Nutzlast mit einem resourceUpdate-Objekt, aber mit einem events-Objekt anstelle eines traits-Objekts:
Nutzlast
{
"eventId" : "ea1090ee-c801-4532-87eb-1f43bf640693",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "k-rZHyK3y6wE5Uub8IQKPwpdf4...",
}
}
}
"userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [
"enterprises/project-id/devices/device-id"
]
}Diese Arten von Ressourcenereignissen werden in bestimmten Traits definiert. Das Motion-Event wird beispielsweise im CameraMotion -Trait definiert. In der Dokumentation der einzelnen Eigenschaften finden Sie Informationen zum Nutzlastformat für diese Arten von Ressourcenereignissen.
Felder
| Feld | Beschreibung | Datentyp |
|---|---|---|
eventId |
Die eindeutige Kennung für das Ereignis. | stringBeispiel: „ea1090ee-c801-4532-87eb-1f43bf640693“ |
timestamp |
Die Zeit, in der das Ereignis aufgetreten ist. | stringBeispiel: „2019-01-01T00:00:01Z“ |
resourceUpdate |
Ein Objekt mit Details zum Update der Ressource. | object |
userId |
Eine eindeutige, verschleierte Kennung, die den Nutzer repräsentiert. | stringBeispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“ |
eventThreadId |
Die eindeutige Kennung für den Ereignis-Thread. | stringBeispiel: „d67cd3f7-86a7-425e-8bb3-462f92ec9f59“ |
eventThreadState |
Der Status des Ereignis-Threads. | stringWerte: „STARTED“, „UPDATED“, „ENDED“ |
resourceGroup |
Ein Objekt, das Ressourcen angibt, die möglicherweise ähnliche Aktualisierungen wie dieses Ereignis haben. Die Ressource des Ereignisses selbst (aus dem resourceUpdate-Objekt) ist immer in diesem Objekt vorhanden. |
object |
Weitere Informationen zu den verschiedenen Arten von Ereignissen und ihrer Funktionsweise finden Sie unter Ereignisse.
Aktualisierbare Benachrichtigungen
Benachrichtigungen, die auf Ressourcenereignissen basieren, können in einer App implementiert werden, z. B. für Android oder iOS. Um die Anzahl der gesendeten Benachrichtigungen zu reduzieren, kann eine Funktion namens aktualisierbare Benachrichtigungen implementiert werden. Dabei werden vorhandene Benachrichtigungen basierend auf nachfolgenden Ereignissen im selben Ereignis-Thread mit neuen Informationen aktualisiert.Wählen Sie Ereignisse aus, die aktualisierbare Benachrichtigungen unterstützen und in der Dokumentation mit Aktualisierbar eventThreadId. Mit diesem Feld können Sie einzelne Ereignisse verknüpfen, um eine bestehende Benachrichtigung zu aktualisieren, die einem Nutzer angezeigt wurde.
Ein Ereignis-Thread ist nicht dasselbe wie eine Ereignissitzung. Der Ereignis-Thread gibt einen aktualisierten Status für ein vorheriges Ereignis im selben Thread an. Die Ereignissitzung kennzeichnet separate Ereignisse, die miteinander in Verbindung stehen. Für eine bestimmte Ereignissitzung kann es mehrere Ereignis-Threads geben.
Für Benachrichtigungen werden verschiedene Arten von Ereignissen in unterschiedlichen Threads gruppiert.
Die Logik für die Gruppierung und das Timing von Threads wird von Google verwaltet und kann sich jederzeit ändern. A developer sollte Benachrichtigungen basierend auf den Ereignis-Threads und ‑Sitzungen aktualisieren, die von der SDM API bereitgestellt werden.
Thread-Status
Ereignisse, die aktualisierbare Benachrichtigungen unterstützen, haben auch ein Feld eventThreadState, das den Status des Ereignis-Threads zu diesem Zeitpunkt angibt. Dieses Feld kann die folgenden Werte haben:
- STARTED: Das erste Ereignis in einem Ereignis-Thread.
- AKTUALISIERT: Ein Ereignis in einem laufenden Ereignis-Thread. In einem einzelnen Thread kann es null oder mehr Ereignisse mit diesem Status geben.
- ENDED: Das letzte Ereignis in einem Ereignis-Thread. Je nach Thread-Typ kann es sich um ein Duplikat des letzten UPDATED-Ereignisses handeln.
Mit diesem Feld kann der Fortschritt eines Ereignis-Threads verfolgt werden und es wird angegeben, wann er beendet wurde.
Ereignisfilterung
In einigen Fällen werden von einem Gerät erkannte Ereignisse möglicherweise herausgefiltert, bevor sie in einem SDM Pub/Sub-Thema veröffentlicht werden. Dieses Verhalten wird als Ereignisfilterung bezeichnet. Mit der Ereignisfilterung soll verhindert werden, dass in kurzer Zeit zu viele ähnliche Ereignisnachrichten veröffentlicht werden.
Beispielsweise kann eine Nachricht für ein erstes Motion-Event in einem SDM-Thema veröffentlicht werden. Andere Nachrichten für „Bewegung“ werden danach bis zu einem bestimmten Zeitraum herausgefiltert. Danach kann wieder eine Ereignismeldung für diesen Ereignistyp veröffentlicht werden.
In der Google Home App (GHA) werden gefilterte Ereignisse weiterhin im Ereignisverlauf des userangezeigt. Solche Ereignisse lösen jedoch keine App-Benachrichtigung aus, auch wenn dieser Benachrichtigungstyp aktiviert ist.
Jeder Ereignistyp hat seine eigene Ereignisfilterlogik, die von Google definiert wird und sich jederzeit ändern kann. Diese Logik zum Filtern von Ereignissen ist unabhängig vom Ereignis-Thread und der Sitzungslogik.
Dienstkonten
Dienstkonten werden für die Verwaltung von SDM API-Abos und Ereignismeldungen empfohlen. Ein Dienstkonto wird von einer Anwendung oder einer virtuellen Maschine und nicht von einer Person verwendet und hat einen eigenen eindeutigen Kontoschlüssel.
Für die Autorisierung von Dienstkonten für die Pub/Sub API wird das zweibeinige OAuth (2LO) verwendet.
Im 2LO-Autorisierungsvorgang:
- Der developer fordert mit einem Serviceschlüssel ein Zugriffstoken an.
- Die developer verwendet das Zugriffstoken bei Aufrufen der API.
Weitere Informationen zu Google 2LO und zur Einrichtung finden Sie unter OAuth 2.0 für Server-zu-Server-Anwendungen verwenden.
Autorisierung
Das Dienstkonto muss für die Verwendung mit der Pub/Sub API autorisiert sein:
- Cloud Pub/Sub API in Google Cloud aktivieren
- Erstellen Sie ein Dienstkonto und einen Dienstkontoschlüssel, wie unter Dienstkonto erstellen beschrieben. Wir empfehlen, ihr nur die Rolle Pub/Sub-Abonnent zuzuweisen. Laden Sie den Dienstkontoschlüssel auf den Computer herunter, auf dem die Pub/Sub API verwendet wird.
- Stellen Sie die Authentifizierungsanmeldedaten (Dienstkontoschlüssel) für Ihren Anwendungscode bereit, indem Sie der Anleitung auf der Seite im vorherigen Schritt folgen. Alternativ können Sie ein Zugriffstoken manuell mit
oauth2labrufen, wenn Sie den API-Zugriff schnell testen möchten. - Verwenden Sie Dienstkontoanmeldedaten oder das Zugriffstoken mit der Pub/Sub-API
project.subscriptions, um Nachrichten abzurufen und zu bestätigen.
oauth2l
oauth2l ist ein Befehlszeilentool für OAuth, das in Go geschrieben wurde. Sie können es für Mac oder Linux mit Go installieren.
- Wenn Go nicht auf Ihrem System installiert ist, laden Sie es zuerst herunter und installieren Sie es.
- Nachdem Go installiert wurde, installieren Sie
oauth2lund fügen Sie den Speicherort der UmgebungsvariablenPATHhinzu:go install github.com/google/oauth2l@latestexport PATH=$PATH:~/go/bin - Verwenden Sie
oauth2l, um mit den entsprechenden OAuth-Bereichen ein Zugriffstoken für die API abzurufen: Wenn sich Ihr Serviceschlüssel beispielsweise unteroauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform~/myServiceKey-eb0a5f900ee3.jsonbefindet:oauth2l fetch --credentials ~/myServiceKey-eb0a5f900ee3.json --scope https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platformya29.c.Elo4BmHXK5...
Weitere Informationen zur Verwendung finden Sie in der README-Datei zu oauth2l.
Google API-Clientbibliotheken
Für Google-APIs, die OAuth 2.0 verwenden, sind mehrere Clientbibliotheken verfügbar. Weitere Informationen zur Sprache Ihrer Wahl finden Sie unter Google API-Clientbibliotheken.
Wenn Sie diese Bibliotheken mit der Pub/Sub APIverwenden, nutzen Sie die folgenden Bereichsstrings:
https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloud-platform
Fehler
Die folgenden Fehlercodes können im Zusammenhang mit diesem Leitfaden zurückgegeben werden:
| Fehlermeldung | RPC | Fehlerbehebung |
|---|---|---|
| Kamerabilder können nicht mehr heruntergeladen werden. | DEADLINE_EXCEEDED |
Eventbilder laufen 30 Sekunden nach der Veröffentlichung des Events ab. Laden Sie das Bild vor Ablauf des Gültigkeitszeitraums herunter. |
| Die Ereignis-ID gehört nicht zur Kamera. | FAILED_PRECONDITION |
Verwenden Sie die richtige eventID, die vom Kamera-Ereignis zurückgegeben wird. |
Eine vollständige Liste der API-Fehlercodes finden Sie in der API-Fehlercode-Referenz.