Ereignisse

Ereignisse sind asynchron und werden von Google Cloud Pub/Sub in einem einzigen Thema pro Projectverwaltet. Ereignisse liefern Updates für alle Geräte und Gebäude und der Empfang von Ereignissen wird sichergestellt, 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 Projectaktivieren.

Google Cloud Pub/Sub

Weitere Informationen zur Funktionsweise von Pub/Sub finden Sie in der Google Cloud Pub/Sub-Dokumentation. Wichtig ist insbesondere:

Ereignisabo

Wenn Ereignisse für Projectaktiviert sind, wird dir ein Thema speziell für diese Project -ID in folgendem Format zur Verfügung gestellt:

projects/sdm-prod/topics/enterprise-project-id

Wenn Sie Ereignisse empfangen möchten, erstellen Sie je nach Anwendungsfall ein pull oder push 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 zum ersten Mal Ereignisse auslösen möchten, nachdem das Pub/Sub-Abo erstellt wurde, führen Sie einen API-Aufruf vom Typ devices.list als einmaligen Trigger aus. Ereignisse für alle Gebäude und Geräte werden nach diesem Aufruf veröffentlicht.

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

Ereignisreihenfolge

Pub/Sub garantiert nicht die geordnete Zustellung von Ereignissen und die Eingangsreihenfolge der Ereignisse entspricht möglicherweise nicht der Reihenfolge, in der die Ereignisse tatsächlich eingetreten sind. Verwenden Sie das Feld timestamp, um den Abgleich der Ereignisreihenfolge zu erleichtern. Ereignisse können auch einzeln oder in einer einzigen Ereignisnachricht ankommen.

Weitere Informationen finden Sie unter Nachrichten sortieren.

Nutzer-IDs

Wenn Ihre Implementierung auf Nutzern basiert und nicht auf Struktur oder Gerät, verwenden Sie das Feld userID aus der Ereignisnutzlast, um Ressourcen und Ereignisse zu korrelieren. Dieses Feld ist eine verschleierte ID, die einen bestimmten Nutzer repräsentiert.

Die userID ist auch im HTTP-Antwortheader jedes API-Aufrufs verfügbar.

Beziehungsereignisse

Beziehungsereignisse stellen eine relationale Aktualisierung einer Ressource dar. Dies ist beispielsweise der Fall, wenn ein Gerät einem Gebäude hinzugefügt oder aus einem Gebäude gelöscht wird.

Es gibt drei Arten von Beziehungsereignissen:

  • ERSTELLT
  • GELÖSCHT
  • AKTUALISIERT

Die Nutzlast für ein Beziehungsereignis lautet wie folgt:

Nutzlast

{
  "eventId" : "3d498951-e011-453f-b4a4-8f0f3025490b",
  "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 die object die Ressource, die das Ereignis ausgelöst hat, und die subject ist die Ressource, mit der die object jetzt eine Beziehung hat. Im Beispiel oben hat ein user einer developerZugriff auf dieses spezifische Gerät gewährt. Das autorisierte Gerät der usersteht jetzt in Verbindung mit der autorisierten Struktur, die das Ereignis auslöst.

Ein subject kann nur ein Raum oder ein Gebäude sein. Wenn a developer keine Berechtigung zum Ansehen der user-Struktur hat, ist subject immer leer.

Felder

Field Beschreibung Datentyp
eventId Die eindeutige Kennung des Ereignisses. string
Beispiel: „be318647-3e45-4b05-a382-1364b7950a4f“
timestamp Die Uhrzeit, zu der das Ereignis aufgetreten ist. string
Beispiel: „2019-01-01T00:00:01Z“
relationUpdate Ein Objekt, das Details zur Aktualisierung der Beziehung enthält. object
userId Eine eindeutige, verschleierte Kennung, die den Nutzer repräsentiert. string
Beispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“

Weitere Informationen zu den verschiedenen Ereignistypen und ihrer Funktionsweise finden Sie unter Ereignisse.

Beispiele

Die Ereignisnutzlasten unterscheiden sich für jede Art von Beziehungsereignis:

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 Raum wurde gelöscht

Ressourcenereignisse

Ein Ressourcenereignis stellt eine Aktualisierung einer Ressource dar. Dies kann als Reaktion auf eine Änderung des Werts eines Trait-Felds erfolgen, z. B. die Änderung des Modus eines Thermostats. Es kann sich auch um eine Geräteaktion handeln, die ein Trait-Feld nicht ändert, z. B. das Drücken einer Gerätetaste.

Ein Ereignis, das als Reaktion auf eine Änderung des Werts des Trait-Felds generiert wird, enthält ein traits-Objekt, ähnlich wie bei einem GET-Aufruf des Geräts:

Nutzlast

{
  "eventId" : "c5448841-a7fd-496b-9d28-afbd3b3c7d4d",
  "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 einzelnen Traits findest du Informationen zum Nutzlastformat für jedes Ereignis von Trait-Feldänderungsressourcen.

Ein Ereignis, das als Reaktion auf eine Geräteaktion generiert wird, die ein Trait-Feld nicht ändert, hat auch eine Nutzlast mit einem resourceUpdate-Objekt, aber mit einem events-Objekt anstelle eines traits-Objekts:

Nutzlast

{
  "eventId" : "d955c5f3-ef8c-4785-95d0-8c9e1a235d53",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "Rj8TzS9Prbe9GlRwQmiOzC1Lco...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ] }

Diese Arten von Ressourcenereignissen sind mit bestimmten Merkmalen definiert. Das Ereignis „Bewegung“ ist beispielsweise im Trait CameraMotion definiert. Informationen zum Nutzlastformat für diese Arten von Ressourcenereignissen finden Sie in der Dokumentation der einzelnen Traits.

Felder

Field Beschreibung Datentyp
eventId Die eindeutige Kennung des Ereignisses. string
Beispiel: „d955c5f3-ef8c-4785-95d0-8c9e1a235d53“
timestamp Die Uhrzeit, zu der das Ereignis aufgetreten ist. string
Beispiel: „2019-01-01T00:00:01Z“
resourceUpdate Ein Objekt, das Details zur Ressourcenaktualisierung enthält. object
userId Eine eindeutige, verschleierte Kennung, die den Nutzer repräsentiert. string
Beispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“
eventThreadId Die eindeutige Kennung für den Ereignisthread. string
Beispiel: „d67cd3f7-86a7-425e-8bb3-462f92ec9f59“
eventThreadState Der Status des Ereignisthreads. string
Werte: „STARTED“, „UPDATED“, „ENDED“
resourceGroup Ein Objekt, das Ressourcen angibt, die ähnliche Aktualisierungen für 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 Ereignistypen 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, bei der vorhandene Benachrichtigungen anhand nachfolgender Ereignisse im selben Ereignisthread mit neuen Informationen aktualisiert werden.

Ausgewählte Ereignisse unterstützen aktualisierbare Benachrichtigungen und sind in der Dokumentation mit Updateable  gekennzeichnet. In den Nutzlasten dieser Ereignisse gibt es ein zusätzliches Feld namens eventThreadId. Verwenden Sie dieses Feld, um einzelne Ereignisse miteinander zu verknüpfen, um eine vorhandene Benachrichtigung zu aktualisieren, die einem Nutzer angezeigt wurde.

Ein Ereignisthread ist nicht mit einer Ereignissitzung identisch. Der Ereignisthread identifiziert einen aktualisierten Status für ein vorheriges Ereignis im selben Thread. Die Ereignissitzung identifiziert separate Ereignisse, die miteinander in Beziehung stehen, und es kann mehrere Ereignisthreads für eine bestimmte Ereignissitzung geben.

Zu Benachrichtigungszwecken werden verschiedene Ereignistypen in verschiedenen Threads gruppiert.

Diese Threadgruppierung und die Zeitlogik werden von Google verwaltet und kann 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 Ereignisthreads zu diesem Zeitpunkt angibt. Dieses Feld hat die folgenden Werte:

  • STARTED: Das erste Ereignis in einem Ereignisthread.
  • UPDATED: Ein Ereignis in einem laufenden Terminthread. Es kann null oder mehr Ereignisse mit diesem Status in einem einzelnen Thread geben.
  • 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 sein Ende verfolgt werden.

Ereignisfilterung

In einigen Fällen können von einem Gerät erkannte Ereignisse aus der Veröffentlichung in einem SDM-Pub/Sub-Thema herausgefiltert werden. Dieses Verhalten wird als Ereignisfilterung bezeichnet. Der Zweck der Ereignisfilterung besteht darin, zu vermeiden, dass zu viele ähnliche Ereignisnachrichten innerhalb kurzer Zeit veröffentlicht werden.

Beispielsweise kann eine Nachricht für ein erstes Bewegungsereignis in einem SDM-Thema veröffentlicht werden. Danach werden alle weiteren Motion-Nachrichten bis zu einer festgelegten Zeitspanne aus der Veröffentlichung herausgefiltert. Nach Ablauf dieses Zeitraums kann eine Ereignisnachricht für diesen Ereignistyp wieder veröffentlicht werden.

In der Google Home App (GHA) werden gefilterte Ereignisse weiterhin im Ereignisverlauf von userangezeigt. Solche Ereignisse generieren jedoch keine App-Benachrichtigung (auch nicht, wenn dieser Benachrichtigungstyp aktiviert ist).

Jeder Ereignistyp hat eine eigene Ereignisfilterlogik, die von Google definiert wird und jederzeit geändert werden kann. Diese Ereignisfilterlogik ist unabhängig vom Ereignisthread und der Sitzungslogik.

Dienstkonten

Für die Verwaltung von SDM API-Abos und -Ereignisnachrichten werden Dienstkonten empfohlen. Ein Dienstkonto wird von einer Anwendung oder virtuellen Maschine (nicht von einer Person) verwendet und hat einen eigenen eindeutigen Kontoschlüssel.

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

Gehen Sie bei der 2LO-Autorisierung so vor:

  • developer fordert mithilfe eines Dienstschlüssels ein Zugriffstoken an.
  • developer verwendet das Zugriffstoken mit API-Aufrufen.

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:

  1. Aktivieren Sie die Cloud Pub/Sub API in Google Cloud.
  2. Erstellen Sie ein Dienstkonto und einen Dienstkontoschlüssel, wie unter Dienstkonto erstellen beschrieben. Wir empfehlen, ihr nur die Rolle Pub/Sub Subscriber (Pub/Sub-Abonnent) zuzuweisen. Achten Sie darauf, den Dienstkontoschlüssel auf den Computer herunterzuladen, der die Pub/Sub API verwenden wird.
  3. Geben Sie Ihre Anmeldedaten zur Authentifizierung (Dienstkontoschlüssel) für Ihren Anwendungscode ein, indem Sie der Anleitung auf der Seite im vorherigen Schritt folgen. Alternativ können Sie mit oauth2l manuell ein Zugriffstoken anfordern, um den API-Zugriff schnell zu testen.
  4. Verwenden Sie die Anmeldedaten des Dienstkontos oder das Zugriffstoken mit der Pub/Sub project.subscriptions API, um Nachrichten abzurufen und zu bestätigen.

OAuth2l

Google oauth2l ist ein in Go geschriebenes OAuth-Befehlszeilentool. Sie können es mit Go für Mac oder Linux installieren.

  1. Wenn Go nicht auf Ihrem System installiert ist, laden Sie die App zuerst herunter und installieren Sie sie.
  2. Nachdem Go installiert ist, installieren Sie oauth2l und fügen Sie den Speicherort in die Umgebungsvariable PATH ein:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Verwenden Sie oauth2l, um ein Zugriffstoken für die API mit den entsprechenden OAuth-Bereichen 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, gilt Folgendes:
    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 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 dem Pub/Sub APIverwenden, geben Sie die folgenden Bereichsstrings an:

https://www.googleapis.com/auth/pubsub
https://www.googleapis.com/auth/cloud-platform

Fehler

In Bezug auf diese Anleitung können folgende Fehlercodes zurückgegeben werden:

Fehlermeldung RPC Fehlerbehebung
Kamerabild kann nicht mehr heruntergeladen werden. DEADLINE_EXCEEDED Ereignisbilder laufen 30 Sekunden nach der Veröffentlichung des Ereignisses ab. Laden Sie das Bild unbedingt vor dem Ablaufdatum herunter.
Ereignis-ID gehört nicht zur Kamera. FAILED_PRECONDITION Verwende die korrekte eventID, die vom Kameraereignis zurückgegeben wurde.

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