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 gewährleistet, solange das Zugriffstoken nicht vom Nutzer widerrufen wird und die Ereignisnachrichten nicht abgelaufen sind.
Veranstaltungen aktivieren
Ereignisse sind eine optionale Funktion der SDM API. Unter Ereignisse aktivieren erfahren Sie, wie Sie sie für Ihre Projectaktivieren.
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
- Wählen Sie eine bereitgestellte Clientbibliothek aus oder schreiben Sie eine eigene und verwenden Sie die REST/HTTP- oder gRPC-API-Oberflächen.
Ereignisabo
Wenn Ereignisse vor Januar 2025 für Ihre Projectaktiviert waren, wurde Ihnen ein von Google gehostetes Thema speziell für diese Project -ID in folgendem Format bereitgestellt:
projects/sdm-prod/topics/enterprise-project-id
Alle Projekte müssen ihre Pub/Sub-Themen jetzt in ihrem eigenen Google Cloud-Projekt selbst hosten (obligatorisch für neue Projekte seit Januar 2025 und erforderlich für alle bestehenden Projekte bis zum 30. November 2026). Das Format ist:
projects/gcp-project-name/subscriptions/topic-id
Wenn Ihr project bereits ein selbst gehostetes Thema in Ihrem eigenen Google Cloud-Projekt verwendet, müssen Sie nichts weiter tun. Durch die Migration Ihrer Pub/Sub-Themenkonfiguration werden vorhandene Nutzerzugriffstokens oder OAuth-Berechtigungen nicht ungültig. Für selbst gehostete Themen und Abos gelten die standardmäßigen Google Cloud Pub/Sub-Preise (einschließlich einer kostenlosen Stufe von 10 GB pro Monat). Weitere Informationen finden Sie unter Thema erstellen.
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 Seite Autorisieren in der Kurzanleitung.
Ereignisreihenfolge
Pub/Sub garantiert nicht, dass Ereignisse in der richtigen Reihenfolge zugestellt werden. 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 eingehen.
Weitere Informationen finden Sie unter Nachrichten sortieren.
Nutzer-IDs
Wenn deine Implementierung auf Nutzern (und nicht auf Gebäuden oder Geräten) basiert, verwende das Feld userID 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 Aktualisierung der Beziehung 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:
- CREATED
- GELÖSCHT
- AKTUALISIERT
Die Nutzlast für ein Beziehungsereignis sieht so aus:
Nutzlast
{
"eventId" : "1a2e13bc-c23c-4bc4-8366-6b5669607f0e",
"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"
}In einem Beziehungsereignis ist die object die Ressource, die das Ereignis ausgelöst hat, und die subject die Ressource, zu der die object jetzt eine Beziehung hat. Im obigen Beispiel hat ein user einem developerZugriff auf dieses bestimmte Gerät gewährt. Das autorisierte Gerät des userist 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 nicht berechtigt ist, die Struktur von useranzusehen, istsubjectimmer leer.
Felder
| Feld | Beschreibung | Datentyp |
|---|---|---|
eventId |
Die eindeutige Kennung für das Ereignis. | stringBeispiel: „a121b435-e3bb-4ba1-9dea-945686b7dabf“ |
timestamp |
Die Zeit, in der das Ereignis aufgetreten ist. | stringBeispiel: „2019-01-01T00:00:01Z“ |
relationUpdate |
Ein Objekt mit detaillierten Informationen zur Beziehungsaktualisierung. | 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 je nach Art des Beziehungsereignisses:
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 in folgenden Fällen nicht gesendet:
- Ein Chatroom wird gelöscht
Ressourcenereignisse
Ein Ressourcenereignis stellt eine Aktualisierung dar, die für eine Ressource spezifisch ist. Sie kann als Reaktion auf eine Änderung des Werts eines Attributfelds erfolgen, z. B. wenn der Modus eines Thermostats geändert wird. Es 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 Funktionsfelds generiert wird, enthält ein traits-Objekt, ähnlich einem GET-Aufruf für ein Gerät:
Nutzlast
{
"eventId" : "caec1000-1cab-43d3-946f-bc3c5f8615c9",
"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 findest du Informationen zum Nutzlastformat für alle Ereignisse zur Änderung von Attributfeldern.
Ein Ereignis, das als Reaktion auf eine Geräteaktion generiert wird, die kein Attributfeld ändert, hat ebenfalls eine Nutzlast mit einem resourceUpdate-Objekt, aber mit einem events-Objekt anstelle eines traits-Objekts:
Nutzlast
{
"eventId" : "0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : {
"name" : "enterprises/project-id/devices/device-id",
"events" : {
"sdm.devices.events.CameraMotion.Motion" : {
"eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
"eventId" : "jOvQqNOSL76837k_JxTR4BJ6nw...",
}
}
}
"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 Attributen definiert. Das Bewegungsereignis wird beispielsweise im Merkmal CameraMotion definiert. In der Dokumentation zu den einzelnen Attributen findest du Informationen zum Nutzlastformat für diese Arten von Ressourcenereignissen.
Felder
| Feld | Beschreibung | Datentyp |
|---|---|---|
eventId |
Die eindeutige Kennung für das Ereignis. | stringBeispiel: „0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c“ |
timestamp |
Die Zeit, in der das Ereignis aufgetreten ist. | stringBeispiel: „2019-01-01T00:00:01Z“ |
resourceUpdate |
Ein Objekt mit detaillierten Informationen zur Ressourcenaktualisierung. | 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 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 mit neuen Informationen basierend auf nachfolgenden Ereignissen im selben Ereignisthread aktualisiert.Ausgewählte Ereignisse unterstützen aktualisierbare Benachrichtigungen und sind in der Dokumentation mit Aktualisierbar eventThreadId in ihren Nutzlasten. Verwende dieses Feld, um einzelne Ereignisse miteinander zu verknüpfen, um eine vorhandene 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 identifiziert separate Ereignisse, die miteinander zusammenhängen. Für eine bestimmte Ereignissitzung kann es mehrere Ereignisthreads geben.
Für Benachrichtigungen werden verschiedene Arten von Ereignissen in unterschiedliche Threads gruppiert.
Diese Threadgruppierung und die Timing-Logik werden von Google verwaltet und können sich jederzeit ändern. Ein developer sollte Benachrichtigungen basierend auf den Ereignisthreads und ‑sitzungen aktualisieren, die von der SDM API bereitgestellt werden.
Thread-Status
Ereignisse, die aktualisierbare Benachrichtigungen unterstützen, haben auch ein eventThreadState-Feld, 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 können null oder mehr Ereignisse mit diesem Status vorhanden sein.
- ENDED – Das letzte Ereignis in einem Ereignis-Thread, das je nach Thread-Typ ein Duplikat des letzten UPDATED-Ereignisses sein kann.
Mit diesem Feld kann der Fortschritt eines Ereignisthreads und dessen Ende verfolgt werden.
Ereignisfilterung
In einigen Fällen werden von einem Gerät erkannte Ereignisse möglicherweise herausgefiltert und nicht in einem SDM-Pub/Sub-Thema veröffentlicht. 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 Bewegungsereignis in einem SDM-Thema veröffentlicht werden. Andere Nachrichten für Motion werden danach erst nach Ablauf eines bestimmten Zeitraums veröffentlicht. Nach Ablauf dieses Zeitraums kann eine Ereignisnachricht für diesen Ereignistyp wieder veröffentlicht werden.
In der Google Home App werden gefilterte Ereignisse weiterhin im Ereignisverlauf von userangezeigt. Solche Ereignisse generieren jedoch keine App-Benachrichtigung, auch wenn dieser Benachrichtigungstyp aktiviert ist.
Jeder Ereignistyp hat eine eigene Logik für die Ereignisfilterung, die von Google definiert wird und sich jederzeit ändern kann. Diese Logik zum Filtern von Ereignissen ist unabhängig von der Ereignisthread- und Sitzungslogik.
Dienstkonten
Dienstkonten werden für die Verwaltung von SDM API-Abos und Ereignisnachrichten empfohlen. Ein Dienstkonto wird von einer Anwendung oder einer virtuellen Maschine verwendet, nicht von einer Person, und hat einen eigenen eindeutigen Kontoschlüssel.
Für die Dienstkontoautorisierung für die Pub/Sub API wird zweibeiniges OAuth (2LO) verwendet.
Im 2LO-Autorisierungsablauf:
- developer fordert ein Zugriffstoken mit einem Dienstschlüssel 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:
- 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, auf dem die Pub/Sub API verwendet wird.
- Stellen Sie Ihrem Anwendungscode Ihre Authentifizierungsdaten (Dienstkontoschlüssel) zur Verfügung. Folgen Sie dazu der Anleitung auf der Seite im vorherigen Schritt. Wenn Sie den API-Zugriff schnell testen möchten, können Sie ein Zugriffstoken auch manuell mit
oauth2labrufen. - Verwenden Sie Dienstkonto-Anmeldedaten oder das Zugriffstoken mit der Pub/Sub
project.subscriptionsAPI, um Nachrichten abzurufen und zu bestätigen.
oauth2l
Google oauth2l ist ein in Go geschriebenes Befehlszeilentool für OAuth. Installieren Sie es für Mac oder Linux mit Go.
- Wenn Go nicht auf Ihrem System installiert ist, laden Sie es zuerst herunter und installieren Sie es.
- 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 Dienstschlü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-README-Datei.
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, 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 Image vor Ablauf herunter. |
| Die Ereignis-ID gehört nicht zur Kamera. | FAILED_PRECONDITION |
Verwende die richtige eventID, die vom Kamera-Ereignis zurückgegeben wird. |
Eine vollständige Liste der API-Fehlercodes finden Sie in der API-Fehlercode-Referenz.