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 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:

Ereignisabo

Wenn Ereignisse für Ihre Projectaktiviert sind, erhalten Sie ein Thema, das speziell für diese Project -ID gilt. Es hat folgende Form:

projects/sdm-prod/topics/enterprise-project-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 nach dem Erstellen des Pub/Sub-Abos zum ersten Mal Ereignisse initiieren möchten, 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 in der Kurzanleitung auf der Seite Autorisieren.

Ereignisreihenfolge

Pub/Sub garantiert nicht die geordnete Zustellung von Ereignissen. Die Reihenfolge des Empfangs von Ereignissen entspricht möglicherweise nicht der Reihenfolge, in der die Ereignisse tatsächlich stattgefunden haben. Verwenden Sie das Feld timestamp, um die Ereignisreihenfolge abzugleichen. Ereignisse können auch einzeln oder in einer einzelnen Ereignisnachricht eintreffen.

Weitere Informationen finden Sie unter Nachrichten sortieren.

Nutzer-IDs

Wenn Ihre Implementierung auf Nutzern (und nicht auf Gebäuden oder Geräten) basiert, verwenden Sie 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 relationale Aktualisierung für eine Ressource dar. Beispielsweise, wenn ein Gerät einem Gebäude hinzugefügt oder aus einem Gebäude gelöscht wird.

Es gibt drei Arten von Beziehungsereignissen:

  • CREATED
  • GELÖSCHT
  • AKTUALISIERT

Die Nutzlast für ein Beziehungsereignis sieht so aus:

Nutzlast

{
  "eventId" : "d5c0f0bd-de65-44fd-ac60-686c302e56eb",
  "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, zu der die object jetzt eine Beziehung hat. Im Beispiel oben hat ein user einem developerZugriff auf dieses Gerät gewährt. Das autorisierte Gerät des userist jetzt mit dem autorisierten Gebäude verknüpft, wodurch das Ereignis ausgelöst wird.

Eine subject kann nur ein Raum oder ein Gebäude sein. Wenn a developer nicht berechtigt ist, die Struktur von useraufzurufen, ist subject immer leer.

Felder

Feld Beschreibung Datentyp
eventId Die eindeutige Kennung für das Ereignis. string
Beispiel: „64b87b46-1aec-42a4-8c01-997a407814df“
timestamp Die Zeit, zu der das Ereignis aufgetreten ist. string
Beispiel: „2019-01-01T00:00:01Z“
relationUpdate Ein Objekt mit Informationen zur Beziehungsaktualisierung. object
userId Eine eindeutige, verschleierte Kennung, die den Nutzer darstellt. string
Beispiel: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi“

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

Beispiele

Die Ereignisnutzlasten unterscheiden sich je nach Beziehungsereignistyp:

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 Gruppenbereich wird gelöscht

Ressourcenereignisse

Ein Ressourcenereignis stellt eine Aktualisierung dar, die sich auf eine Ressource bezieht. Dies kann auf eine Änderung des Werts eines Merkmalfelds zurückzuführen sein, z. B. auf eine Änderung des Modus eines Thermostats. Es kann auch eine Geräteaktion darstellen, die kein Merkmalsfeld ändert, z. B. das Drücken einer Gerätetaste.

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

Nutzlast

{
  "eventId" : "a88bc884-d2b8-42d6-adba-b7be92c232a3",
  "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 Merkmalen finden Sie Informationen zum Nutzlastformat für jedes Ereignis vom Typ „Ressourcenänderung für Merkmalfeld“.

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" : "4f80de08-1b77-42a4-b33e-40876a2a1865",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "MWJ253hZMPAsJZJWbrGM4ThsKM...", } } } "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 Attribut CameraMotion definiert. Informationen zum Nutzlastformat für diese Arten von Ressourcenereignissen finden Sie in der Dokumentation der einzelnen Merkmale.

Felder

Feld Beschreibung Datentyp
eventId Die eindeutige Kennung für das Ereignis. string
Beispiel: „4f80de08-1b77-42a4-b33e-40876a2a1865“
timestamp Die Zeit, zu der das Ereignis aufgetreten ist. string
Beispiel: „2019-01-01T00:00:01Z“
resourceUpdate Ein Objekt mit Informationen 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 ähnliche Aktualisierungen wie dieses Ereignis haben könnten. Die Ressource des Ereignisses selbst (aus dem resourceUpdate-Objekt) ist in diesem Objekt immer vorhanden. object

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

Aktualisierbare Benachrichtigungen

Benachrichtigungen auf Grundlage von Ressourcenereignissen können in einer App implementiert werden, z. B. für Android oder iOS. Um die Anzahl der gesendeten Benachrichtigungen zu reduzieren, kann die Funktion aktualisierbare Benachrichtigungen implementiert werden. Dabei werden vorhandene Benachrichtigungen anhand nachfolgender Ereignisse im selben Ereignis-Thread mit neuen Informationen aktualisiert.

Für ausgewählte Ereignisse werden aktualisierbare Benachrichtigungen unterstützt und sie sind in der Dokumentation mit dem Tag Updateable  gekennzeichnet. 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 für einen Nutzer angezeigt wurde.

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

Für Benachrichtigungen werden verschiedene Ereignistypen in verschiedene Threads gruppiert.

Diese Gruppierungs- und Zeitlogik für Threads wird von Google verwaltet und kann jederzeit geändert werden. A 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 außerdem ein Feld eventThreadState, das den Status des Ereignisthreads zu diesem Zeitpunkt angibt. Dieses Feld hat folgende Werte:

  • STARTED: Das erste Ereignis in einem Ereignis-Thread.
  • AKTUALISIERT – Ein Ereignis in einem laufenden Ereignis-Thread. In einem einzelnen Thread kann es null oder mehrere Ereignisse mit diesem Status geben.
  • ENDED: Das letzte Ereignis in einem Ereignis-Thread, das je nach Threadtyp ein Duplikat des letzten AKTUALISIERTEN Ereignisses sein kann.

Mit diesem Feld können Sie den Fortschritt eines Ereignis-Threads und das Ende des Threads verfolgen.

Ereignisfilter

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 dem Ereignisfilter wird verhindert, 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 zu einem bestimmten Zeitraum herausgefiltert. Nach Ablauf dieses Zeitraums kann eine Ereignismeldung für diesen Ereignistyp wieder veröffentlicht werden.

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

Für jeden Ereignistyp gibt es eine eigene Ereignisfilterlogik, die von Google definiert wird und sich jederzeit ändern kann. Diese Ereignisfilterlogik ist unabhängig von der Ereignis- und Sitzungslogik.

Dienstkonten

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

Für die Dienstkontoautorisierung für die Pub/Sub API wird OAuth mit zwei Schritten (2LO) verwendet.

Im 2LO-Autorisierungsablauf:

  • Der 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:

  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, 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. Geben Sie Ihre Anmeldedaten (Dienstkontoschlüssel) in den Anwendungscode ein. 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 oauth2l abrufen.
  4. Verwenden Sie Anmeldedaten für das Dienstkonto oder das Zugriffstoken mit der Pub/Sub project.subscriptions API, um Nachrichten abzurufen und zu bestätigen.

oauth2l

Google oauth2l ist ein Befehlszeilentool für OAuth, das in Go geschrieben wurde. Installieren Sie es mit Go für Mac oder Linux.

  1. Wenn Go nicht auf Ihrem System installiert ist, laden Sie es zuerst herunter und installieren Sie es.
  2. Nachdem Go installiert ist, installieren Sie oauth2l und fügen Sie den Speicherort der Umgebungsvariablen PATH hinzu:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Verwende 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 dein 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

Es gibt mehrere Clientbibliotheken für Google APIs, die OAuth 2.0 verwenden. Weitere Informationen zur Sprache Ihrer Wahl finden Sie unter Google API-Clientbibliotheken.

Wenn Sie diese Bibliotheken mit der Pub/Sub APIverwenden, verwenden Sie den folgenden Bereichsstring:

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

Fehler

In Bezug auf diesen Leitfaden können die folgenden Fehlercodes 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 wird.

Eine vollständige Liste der API-Fehlercodes findest du in der API-Fehlercode-Referenz.