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 Gebäude. Der Empfang von Ereignissen ist sichergestellt, solange das Zugriffstoken nicht vom Nutzer widerrufen wurde und die Ereignisnachrichten nicht abgelaufen sind.
Ereignisse aktivieren
Ereignisse sind eine optionale Funktion der SDM API. Unter Ereignisse aktivieren erfahren Sie, wie Sie sie für Ihr 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:
- Grundlagen von Pub/Sub mit den Anleitungen kennenlernen.
- Funktionsweise der Authentifizierung verstehen
- Eine bereitgestellte Clientbibliothek auswählen oder eine eigene schreiben und die REST/HTTP- oder gRPC-API-Oberflächen verwenden.
Ereignisabo
Vor Januar 2025 wurde Ihnen, wenn Ereignisse für Ihr Projectaktiviert waren, ein Thema speziell für diese Project ID zur Verfügung gestellt, und zwar in folgendem Format:
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 initiieren
Wenn Sie Ereignisse zum ersten Mal initiieren möchten, nachdem das Pub/Sub-Abo erstellt wurde, führen Sie einen
devices.list
API-Aufruf als einmaligen Trigger aus. Nach diesem
Aufruf werden Ereignisse für alle Gebäude und Geräte veröffentlicht.
Ein Beispiel finden Sie auf der SeiteAutorisieren im Schnellstart leitfaden.
Ereignisreihenfolge
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 der Ereignisse abzugleichen. Ereignisse können auch einzeln oder kombiniert
in einer einzigen Ereignisnachricht eintreffen.
Weitere Informationen finden Sie unter Nachrichten sortieren.
Nutzer-IDs
Wenn Ihre Implementierung auf Nutzern basiert (und nicht auf Gebäuden oder Geräten), verwenden Sie das
userID Feld aus der Ereignisnutzlast, um Ressourcen und Ereignisse zu korrelieren. Dieses Feld ist
eine verschleierte ID, die einen bestimmten Nutzer darstellt.
Die userID ist auch im HTTP-Antwortheader jedes API-Aufrufs verfügbar.
Beziehungsereignisse
Beziehungsereignisse stellen eine relationale Aktualisierung für eine Ressource dar. Beispielsweise wenn ein Gerät einem Gebäude hinzugefügt oder daraus gelöscht wird.
Es gibt drei Arten von Beziehungsereignissen:
- ERSTELLT
- GELÖSCHT
- AKTUALISIERT
Die Nutzlast für ein Beziehungsereignis sieht so aus:
Nutzlast
{
"eventId" : "84527b4c-13ed-479c-a756-21b9bb4111b5",
"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 Beziehungsereignis ist das object die Ressource, die das Ereignis ausgelöst hat, und das
subject ist die Ressource, mit der das object jetzt eine Beziehung hat. Im
obigen Beispiel hat ein user einem Zugriff auf dieses bestimmte Gerät gewährt, und das user's autorisierte Gerät des
developerist jetzt mit seinem autorisierten
Gebäude verknüpft, wodurch das Ereignis ausgelöst wird.
Ein subject kann nur ein Raum oder ein Gebäude sein. Wenn a developer keine
Berechtigung hat, das userGebäude des' anzusehen, ist das subject immer
leer.
Felder
| Feld | Beschreibung | Datentyp |
|---|---|---|
eventId |
Die eindeutige Kennung für das Ereignis. | stringBeispiel: „d3c2bcb3-6588-4747-a65c-07c7f50a482d“ |
timestamp |
Die Zeit, in der das Ereignis aufgetreten ist. | stringBeispiel: „2019-01-01T00:00:01Z“ |
relationUpdate |
Ein Objekt mit Details zur Aktualisierung der Beziehung. | object |
userId |
Eine eindeutige, verschleierte Kennung, die den Nutzer darstellt. | stringBeispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“ |
Weitere Informationen zu den verschiedenen Arten von Ereignissen und ihrer Funktionsweise finden Sie unter Ereignisse.
Beispiele
Die Ereignisnutzlasten unterscheiden sich für die einzelnen Arten von Beziehungsereignissen:
ERSTELLT
Gebäude 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 nicht gesendet, wenn:
- Ein Raum gelöscht wird
Ressourcenereignisse
Ein Ressourcenereignis stellt eine Aktualisierung dar, die sich auf eine bestimmte Ressource bezieht. Es kann als Reaktion auf eine Änderung des Werts eines Merkmalsfelds erfolgen, z. B. wenn der Modus eines Thermostats geändert wird. Es kann auch eine Geräteaktion darstellen, die kein Merkmalsfeld ändert, z. B. wenn eine Gerätetaste gedrückt wird.
Ein Ereignis, das als Reaktion auf eine Änderung des Werts eines Merkmalsfelds generiert wird, enthält ein
traits Objekt, ähnlich einem GET-Aufruf für ein Gerät:
Nutzlast
{
"eventId" : "be30516f-e855-49fb-b50d-cbf031c81c30",
"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 Merkmalen finden Sie Informationen zum Nutzlastformat für Ressourcenereignisse, die durch Änderungen von Merkmalsfeldern ausgelöst werden.
Ein Ereignis, das als Reaktion auf eine Geräteaktion generiert wird, die kein Merkmalsfeld ändert, hat ebenfalls eine
Nutzlast mit einem resourceUpdate Objekt, aber mit einem events Objekt
anstelle eines traits Objekts:
Nutzlast
{
"eventId" : "8e70e14f-bf37-4be0-bc85-8fd56b93b412",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "Qah4OySZOSvtiUbdpFWafiRTfI...",
}
}
}
"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 Merkmalen definiert. Das Ereignis „Bewegung“ wird beispielsweise im Merkmal CameraMotion definiert. In der Dokumentation zu den einzelnen Merkmalen finden Sie Informationen zum Nutzlastformat für diese Arten von Ressourcenereignissen.
Felder
| Feld | Beschreibung | Datentyp |
|---|---|---|
eventId |
Die eindeutige Kennung für das Ereignis. | stringBeispiel: „8e70e14f-bf37-4be0-bc85-8fd56b93b412“ |
timestamp |
Die Zeit, in der das Ereignis aufgetreten ist. | stringBeispiel: „2019-01-01T00:00:01Z“ |
resourceUpdate |
Ein Objekt mit Details zur Aktualisierung der Ressource. | object |
userId |
Eine eindeutige, verschleierte Kennung, die den Nutzer darstellt. | 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 ähnliche Aktualisierungen wie dieses Ereignis haben könnten. 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 mit neuen Informationen aktualisiert, die auf nachfolgenden Ereignissen im selben Ereignis-Thread basieren.Ereignisse, die aktualisierbare Benachrichtigungen unterstützen, sind in der Dokumentation als
Aktualisierbar eventThreadId. Mit diesem Feld können einzelne Ereignisse verknüpft werden, um eine vorhandene Benachrichtigung zu aktualisieren, die für einen 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 identifiziert separate Ereignisse, die miteinander in Beziehung stehen. Für eine bestimmte Ereignissitzung kann es mehrere Ereignis-Threads geben.
Für Benachrichtigungen werden verschiedene Arten von Ereignissen in verschiedenen Threads gruppiert.
Diese Threadgruppierung und Timinglogik wird von Google verwaltet und kann jederzeit geändert werden. 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 hat die folgenden Werte:
- STARTED – Das erste Ereignis in einem Ereignis-Thread.
- UPDATED – 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 Threadtyp kann es sich um ein Duplikat des letzten UPDATED-Ereignisses handeln.
Mit diesem Feld lässt sich der Fortschritt eines Ereignis-Threads verfolgen und feststellen, wann er beendet wurde.
Ereignisfilterung
In einigen Fällen werden Ereignisse, die von einem Gerät erkannt wurden, möglicherweise herausgefiltert, sodass sie nicht in einem SDM Pub/Sub-Thema veröffentlicht werden. Dieses Verhalten wird als Ereignisfilterung bezeichnet. Der Zweck der Ereignisfilterung besteht darin, zu vermeiden, dass in kurzer Zeit zu viele ähnliche Ereignisnachrichten veröffentlicht werden.
Beispielsweise kann eine Nachricht für ein anfängliches Bewegungsereignis in einem SDM-Thema veröffentlicht werden. Andere Nachrichten für Bewegungen werden danach so lange herausgefiltert, bis ein bestimmter Zeitraum verstrichen ist. Nach Ablauf dieses Zeitraums kann wieder eine Ereignisnachricht für diesen Ereignistyp veröffentlicht werden.
In der Google Home App werden gefilterte Ereignisse weiterhin im userEreignisverlauf des angezeigt. 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 jederzeit geändert werden kann. Diese Ereignisfilterlogik ist unabhängig von der Logik für Ereignis-Threads und ‑Sitzungen.
Dienstkonten
Dienstkonten werden für die Verwaltung von SDM API-Abos und Ereignisnachrichten empfohlen. Ein Dienstkonto wird von einer Anwendung oder einer virtuellen Maschine und nicht von einer Person verwendet und hat einen eigenen eindeutigen Kontoschlüssel.
Die Dienstkontoautorisierung für die Pub/Sub API verwendet OAuth mit zwei Beinen (2LO).
Im 2LO-Autorisierungsablauf gilt Folgendes:
- fordert mit einem Dienstkontoschlüssel ein Zugriffstoken an. developer
- verwendet das Zugriffstoken für Aufrufe der API. developer
Weitere Informationen zu Google 2LO und zur Einrichtung finden Sie unter OAuth 2.0 für Server-zu-Server Anwendungen verwenden.
Autorisierung
Das Dienstkonto sollte für die Verwendung mit der Pub/Sub API autorisiert sein:
- Aktivieren Sie die Cloud Pub/Sub API in Google Cloud.
- Erstellen Sie ein Dienstkonto und einen Dienstkontoschlüssel, wie unter Dienstkonto erstellen beschrieben. Wir empfehlen, ihm nur die Rolle Pub/Sub-Abonnent zuzuweisen. Laden Sie den Dienstkontoschlüssel auf den Computer herunter, der die Pub/Sub API verwenden soll.
- Geben Sie Ihre Anmeldedaten (Dienstkontoschlüssel) in Ihrem
Anwendungscode an. Folgen Sie dazu der Anleitung auf der Seite im vorherigen
Schritt. Wenn Sie den API-Zugriff schnell testen möchten, können Sie auch manuell ein Zugriffstoken mit
oauth2labrufen, wenn Sie den API-Zugriff schnell testen möchten. - Verwenden Sie die Anmeldedaten des Dienstkontos oder das Zugriffstoken mit der
Pub/Sub
project.subscriptionsAPI um Nachrichten abzurufen und zu bestätigen.
oauth2l
oauth2l von Google ist ein Befehlszeilentool für OAuth, das in Go geschrieben wurde. Installieren Sie es für Mac oder Linux mit Go.
- Wenn Sie Go nicht auf Ihrem System haben, laden Sie es herunter und installieren Sie es zuerst.
- Installieren Sie nach der Installation von Go
oauth2lund fügen Sie den Speicherort der UmgebungsvariablePATHhinzu:go install github.com/google/oauth2l@latestexport PATH=$PATH:~/go/bin - Verwenden Sie
oauth2l, um ein Zugriffstoken für die API mit den entsprechenden OAuth-Bereichen abzurufen: Wenn sich Ihr Dienstkontoschlü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 oauth2l READMEDatei.
Google API-Clientbibliotheken
Es gibt mehrere Clientbibliotheken für Google APIs, die OAuth 2.0 verwenden. Weitere Informationen zu der Sprache Ihrer Wahl finden Sie unter Google API-Clientbibliotheken.
Wenn Sie diese Bibliotheken mit der Pub/Sub APIverwenden, verwenden 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 |
|---|---|---|
| Das Kamerabild kann nicht mehr heruntergeladen werden. | DEADLINE_EXCEEDED |
Ereignisbilder laufen 30 Sekunden nach der Veröffentlichung des Ereignisses ab. Laden Sie das Bild vor Ablauf herunter. |
| Die Ereignis-ID gehört nicht zur Kamera. | FAILED_PRECONDITION |
Verwenden Sie die richtige eventID, die vom Kameraereignis zurückgegeben wurde. |
Eine vollständige Liste der API-Fehlercodes finden Sie in der API-Fehlercode-Referenz.