Ereignisse

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.

Veranstaltungen aktivieren

Ereignisse sind eine optionale Funktion der SDM API. 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:

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
Projekte, die nach Januar 2025 erstellt werden, müssen ihre Pub/Sub-Themen selbst hosten. Sie müssen Ihre eigene Themen-ID angeben. 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 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 Gebäude und Geräte werden nach diesem Aufruf veröffentlicht.

Ein Beispiel finden Sie auf der Seite Autorisieren in der Kurzanleitung.

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 von Ereignissen abzugleichen. Ereignisse können auch einzeln oder kombiniert in einer einzigen Ereignisnachricht eingehen.

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

Beziehungsereignisse stellen eine relationale Aktualisierung für eine Ressource dar. Beispielsweise, wenn ein Gerät einer Struktur hinzugefügt oder aus einer Struktur gelöscht wird.

Es gibt drei Arten von Ereignissen für Beziehungen:

  • CREATED
  • GELÖSCHT
  • AKTUALISIERT

Die Nutzlast für ein Beziehungsereignis sieht so aus:

Nutzlast

{
  "eventId" : "81688b62-4f69-432f-bbe0-5270032f5466",
  "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 object die Ressource, die das Ereignis ausgelöst hat, und subject die Ressource, mit der object jetzt eine Beziehung hat. Im Beispiel oben hat ein user einem developerZugriff auf dieses bestimmte Gerät gewährt. Das autorisierte Gerät des userist jetzt mit seiner autorisierten Struktur verknüpft, was das Ereignis auslöst.

Ein subject kann nur ein Raum oder eine Struktur 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. string
Beispiel: „4ec221c5-4cbc-4fd5-ae2e-6eebd1311876“
timestamp Die Zeit, zu der das Ereignis aufgetreten ist. string
Beispiel: „2019-01-01T00:00:01Z“
relationUpdate Ein Objekt mit detaillierten Informationen zur Aktualisierung der Beziehung. object
userId Eine eindeutige, verschleierte Kennung, die den Nutzer darstellt. string
Beispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“

Weitere Informationen zu den verschiedenen Arten von Ereignissen und ihrer Funktionsweise finden Sie unter Ereignisse.

Beispiele

Die Ereignis-Nutzlasten 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

Struktur 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 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" : "b5a3cb32-3ca8-4b0b-9510-c6a9e70f00f4",
  "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, bei der kein Attributfeld geändert wird, hat ebenfalls eine Nutzlast mit einem resourceUpdate-Objekt, aber mit einem events-Objekt anstelle eines traits-Objekts:

Nutzlast

{
  "eventId" : "803821e5-2626-41d5-8ea2-04b6fdb88f8c",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "HEQiFiTuneH7NJVZ-kHxnbZyU9...", } } } "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 Bewegungsereignis wird beispielsweise im CameraMotion -Trait definiert. Informationen zum Nutzlastformat für diese Arten von Ressourcenereignissen finden Sie in der Dokumentation der einzelnen Traits.

Felder

Feld Beschreibung Datentyp
eventId Die eindeutige Kennung für das Ereignis. string
Beispiel: „803821e5-2626-41d5-8ea2-04b6fdb88f8c“
timestamp Die Zeit, zu der das Ereignis aufgetreten ist. string
Beispiel: „2019-01-01T00:00:01Z“
resourceUpdate Ein Objekt mit Details zur Ressourcenaktualisierung. object
userId Eine eindeutige, verschleierte Kennung, die den Nutzer darstellt. string
Beispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“
eventThreadId Die eindeutige Kennung für den Ereignis-Thread. string
Beispiel: „d67cd3f7-86a7-425e-8bb3-462f92ec9f59“
eventThreadState Der Status des Ereignis-Threads. string
Werte: „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 aktualisiert, die auf nachfolgenden Ereignissen im selben Ereignis-Thread basieren.

Wählen Sie Ereignisse aus, die aktualisierbare Benachrichtigungen unterstützen und in der Dokumentation mit Aktualisierbar  gekennzeichnet sind. Diese Ereignisse haben in ihren Nutzlasten ein zusätzliches Feld namens eventThreadId. Mit diesem Feld können Sie einzelne Ereignisse verknüpfen, um eine vorhandene Benachrichtigung zu aktualisieren, die einem Nutzer angezeigt wurde.

Ein Event-Thread ist nicht dasselbe wie eine Event-Sitzung. Der Ereignis-Thread gibt einen aktualisierten Status für ein vorheriges Ereignis im selben Thread an. Die Ereignissitzung identifiziert 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 verschiedenen Threads gruppiert.

Die Logik für die Gruppierung und das Timing von Threads 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 kann die folgenden Werte enthalten:

  • STARTED: Das erste Ereignis in einem Ereignis-Thread.
  • AKTUALISIERT: 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. Je nach Thread-Typ 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.

Ereignisse filtern

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 Ereignismeldungen 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 bis zum Ablauf eines bestimmten Zeitraums aus der Veröffentlichung herausgefiltert. Nach Ablauf dieses Zeitraums kann wieder eine Ereignisbenachrichtigung für diesen Ereignistyp veröffentlicht werden.

In der Google Home App (GHA) werden gefilterte Ereignisse weiterhin im Ereignisverlauf des userangezeigt. Bei solchen Ereignissen wird jedoch keine App-Benachrichtigung generiert, auch wenn dieser Benachrichtigungstyp aktiviert ist.

Für jeden Ereignistyp gibt es eine eigene Logik zum Filtern von Ereignissen, 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 Ereignisnachrichten empfohlen. Ein Dienstkonto wird von einer Anwendung oder einer VM verwendet, nicht von einer Person, und hat einen eigenen eindeutigen Kontoschlüssel.

Die Dienstkontoautorisierung für die Pub/Sub API verwendet Two-legged OAuth (2LO).

Im 2LO-Autorisierungsablauf:

  • Der developer fordert ein Zugriffstoken mit einem Dienstkontoschlü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:

  1. Cloud Pub/Sub API in Google Cloud aktivieren
  2. 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.
  3. 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 oauth2l abrufen, wenn Sie den API-Zugriff schnell testen möchten.
  4. Verwenden Sie Dienstkontoanmeldedaten oder das Zugriffstoken mit der Pub/Sub-API project.subscriptions, 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.

  1. Wenn Go noch nicht auf Ihrem System installiert ist, laden Sie es herunter und installieren Sie es.
  2. Nachdem Go installiert wurde, installieren Sie oauth2l und fügen Sie den Speicherort zur Umgebungsvariable PATH hinzu:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Verwenden Sie oauth2l, um mit den entsprechenden OAuth-Bereichen ein Zugriffstoken für die API abzurufen:
    oauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub
    https://www.googleapis.com/auth/cloud-platform
    Wenn sich Ihr Dienstschlüssel beispielsweise unter ~/myServiceKey-eb0a5f900ee3.json befindet:
    oauth2l fetch --credentials ~/myServiceKey-eb0a5f900ee3.json --scope https://www.googleapis.com/auth/pubsub
    https://www.googleapis.com/auth/cloud-platform
    ya29.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, 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
Das Kamerabild kann nicht mehr heruntergeladen werden. DEADLINE_EXCEEDED Veranstaltungsbilder laufen 30 Sekunden nach der Veröffentlichung der Veranstaltung ab. Laden Sie das Bild vor Ablauf des Zeitraums herunter.
Die Ereignis-ID gehört nicht zur Kamera. FAILED_PRECONDITION Verwenden Sie die richtige eventID, die vom Kameraereignis zurückgegeben wird.

Eine vollständige Liste der API-Fehlercodes finden Sie in der API-Fehlercode-Referenz.