Wydarzenia

Zdarzenia są asynchroniczne i zarządzane przez Google Cloud Pub/Sub w jednym temacie na Project. Wydarzenia zapewniają aktualizacje wszystkich urządzeń i struktur, a ich odbiór jest gwarantowany, o ile użytkownik nie cofnie tokena dostępu i wiadomości o wydarzeniach nie wygasną.

Włącz wydarzenia

Zdarzenia są opcjonalną funkcją interfejsu SDM API. Zobacz Włączanie zdarzeń , aby dowiedzieć się, jak włączyć je w przypadku Project.

Google Cloud Pub/Sub

Więcej informacji o działaniu Pub/Sub znajdziesz w dokumentacji Google Cloud Pub/Sub. W szczególności:

Subskrypcja zdarzeń

Przed styczniem 2025 r., jeśli zdarzenia były włączone w przypadku Twojego Project, otrzymywałeś temat powiązany z tym Project ID w formie:

projects/gcp-project-name/subscriptions/topic-id
Projekty utworzone po styczniu 2025 r. muszą samodzielnie hostować swoje tematy Pub/Sub, a Ty musisz podać własny identyfikator tematu. Więcej informacji znajdziesz w artykule Tworzenie tematu.

Aby otrzymywać zdarzenia, utwórz subskrypcję pull lub push do tego tematu w zależności od przypadku użycia. Obsługiwanych jest wiele subskrypcji tematu SDM. Więcej informacji znajdziesz w artykule Zarządzanie subskrypcjami.

Wydarzenia inicjujące

Aby po raz pierwszy zainicjować zdarzenia po utworzeniu subskrypcji Pub/Sub, wykonaj wywołanie interfejsu API devices.list jako jednorazowy wyzwalacz. Po tym wywołaniu będą publikowane zdarzenia dotyczące wszystkich struktur i urządzeń.

Przykład znajdziesz na stronie Autoryzacja w przewodniku dla początkujących.

Kolejność wydarzeń

Pub/Sub nie gwarantuje dostarczania zdarzeń w określonej kolejności, a kolejność otrzymywania zdarzeń może nie odpowiadać kolejności, w jakiej faktycznie wystąpiły. Użyj pola timestamp, aby ułatwić uzgadnianie kolejności zdarzeń. Zdarzenia mogą też docierać pojedynczo lub w połączeniu w jednej wiadomości o zdarzeniu.

Więcej informacji znajdziesz w sekcji Porządkowanie wiadomości.

Identyfikatory użytkowników

Jeśli Twoja implementacja jest oparta na użytkownikach (a nie na strukturze lub urządzeniu), użyj pola userID z ładunku zdarzenia, aby powiązać zasoby i zdarzenia. To pole zawiera zniekształcony identyfikator reprezentujący konkretnego użytkownika.

Wartość userID jest też dostępna w nagłówku odpowiedzi HTTP każdego wywołania interfejsu API.

Zdarzenia relacji

Zdarzenia relacji reprezentują aktualizację relacji dla zasobu. Na przykład gdy urządzenie zostanie dodane do struktury lub z niej usunięte.

Istnieją 3 rodzaje zdarzeń związanych z relacjami:

  • CREATED
  • USUNIĘTY
  • ZAKTUALIZOWANO

Ładunek zdarzenia dotyczącego relacji wygląda tak:

Ładunek

{
  "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"
}

W przypadku zdarzenia relacji object to zasób, który wywołał zdarzenie, a subject to zasób, z którym object ma teraz relację. W przykładzie powyżej użytkownik a user przyznał dostęp do tego konkretnego urządzenia użytkownikowi a developer, a autoryzowane urządzenie użytkownika userjest teraz powiązane z jego autoryzowaną strukturą, co wywołuje zdarzenie.

subject może być tylko pokojem lub konstrukcją. Jeśli a developer nie ma uprawnień do wyświetlania struktury user, pole subject jest zawsze puste.

Pola

Pole Opis Typ danych
eventId Unikalny identyfikator zdarzenia. string
Przykład: „4ec221c5-4cbc-4fd5-ae2e-6eebd1311876”
timestamp Czas wystąpienia zdarzenia. string
Przykład: „2019-01-01T00:00:01Z”
relationUpdate Obiekt zawierający szczegółowe informacje o aktualizacji relacji. object
userId Unikalny, zniekształcony identyfikator reprezentujący użytkownika. string
Przykład: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi”

Więcej informacji o różnych typach zdarzeń i sposobach ich działania znajdziesz w sekcji Zdarzenia.

Przykłady

Ładunki zdarzeń różnią się w zależności od typu zdarzenia dotyczącego relacji:

UTWORZONO

Utworzono strukturę

"relationUpdate" : {
  "type" : "CREATED",
  "subject" : "",
  "object" : "enterprises/project-id/structures/structure-id"
}

Urządzenie utworzone

"relationUpdate" : {
  "type" : "CREATED",
  "subject" : "enterprises/project-id/structures/structure-id",
  "object" : "enterprises/project-id/devices/device-id"
}

Urządzenie utworzone

"relationUpdate" : {
  "type" : "CREATED",
  "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
  "object" : "enterprises/project-id/devices/device-id"
}

ZAKTUALIZOWANO

Przeniesiono urządzenie

"relationUpdate" : {
  "type" : "UPDATED",
  "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
  "object" : "enterprises/project-id/devices/device-id"
}

USUNIĘTY

Obiekt został usunięty

"relationUpdate" : {
  "type" : "DELETED",
  "subject" : "",
  "object" : "enterprises/project-id/structures/structure-id"
}

Urządzenie zostało usunięte

"relationUpdate" : {
  "type" : "DELETED",
  "subject" : "enterprises/project-id/structures/structure-id",
  "object" : "enterprises/project-id/devices/device-id"
}

Urządzenie zostało usunięte

"relationUpdate" : {
  "type" : "DELETED",
  "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id",
  "object" : "enterprises/project-id/devices/device-id"
}

Zdarzenia relacji nie są wysyłane, gdy:

  • Pokój zostanie usunięty

Zdarzenia związane z zasobami

Zdarzenie zasobu reprezentuje aktualizację dotyczącą konkretnego zasobu. Może to być reakcja na zmianę wartości pola cechy, np. zmianę trybu termostatu. Może też reprezentować działanie urządzenia, które nie zmienia pola cechy, np. naciśnięcie przycisku urządzenia.

Zdarzenie wygenerowane w odpowiedzi na zmianę wartości pola cechy zawiera obiekt traits podobny do wywołania GET urządzenia:

Ładunek

{
  "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"
  ]
}

dokumentacji dotyczącej poszczególnych cech znajdziesz informacje o formacie ładunku w przypadku zdarzenia zmiany zasobu pola cechy.

Zdarzenie wygenerowane w odpowiedzi na działanie urządzenia, które nie zmienia pola cechy, również ma ładunek z obiektem resourceUpdate, ale z obiektem events zamiast obiektu traits:

Ładunek

{
  "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" ] }

Te typy zdarzeń dotyczących zasobów są zdefiniowane w określonych cechach. Na przykład zdarzenie Motion jest zdefiniowane w  CameraMotion . Aby poznać format ładunku w przypadku tych typów zdarzeń dotyczących zasobów, zapoznaj się z dokumentacją poszczególnych cech.

Pola

Pole Opis Typ danych
eventId Unikalny identyfikator zdarzenia. string
Przykład: „803821e5-2626-41d5-8ea2-04b6fdb88f8c”
timestamp Czas wystąpienia zdarzenia. string
Przykład: „2019-01-01T00:00:01Z”
resourceUpdate Obiekt zawierający szczegółowe informacje o aktualizacji zasobu. object
userId Unikalny, zniekształcony identyfikator reprezentujący użytkownika. string
Przykład: „AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi”
eventThreadId Unikalny identyfikator wątku zdarzenia. string
Przykład: „d67cd3f7-86a7-425e-8bb3-462f92ec9f59”
eventThreadState Stan wątku zdarzenia. string
Wartości: „STARTED”, „UPDATED”, „ENDED”
resourceGroup Obiekt wskazujący zasoby, które mogą mieć podobne aktualizacje do tego zdarzenia. Zasób samego zdarzenia (z obiektu resourceUpdate) będzie zawsze obecny w tym obiekcie. object

Więcej informacji o różnych typach zdarzeń i sposobach ich działania znajdziesz w sekcji Zdarzenia.

Powiadomienia, które można aktualizować

Powiadomienia oparte na zdarzeniach dotyczących zasobów można wdrożyć w aplikacji, np. na Androida lub iOS. Aby zmniejszyć liczbę wysyłanych powiadomień, można wdrożyć funkcję aktualizowanych powiadomień, w której istniejące powiadomienia są aktualizowane o nowe informacje na podstawie kolejnych zdarzeń w tym samym wątku zdarzeń.

Wydarzenia obsługują aktualizowane powiadomienia i są oznaczone w dokumentacji jako Aktualizowane . Te zdarzenia mają w swoich ładunkach dodatkowe pole o nazwie eventThreadId. Użyj tego pola, aby połączyć ze sobą poszczególne zdarzenia w celu zaktualizowania istniejącego powiadomienia, które zostało wyświetlone użytkownikowi.

Wątek zdarzenia nie jest tym samym co sesja zdarzenia. Wątek zdarzenia określa zaktualizowany stan poprzedniego zdarzenia w tym samym wątku. Sesja zdarzenia identyfikuje oddzielne zdarzenia, które są ze sobą powiązane. W przypadku danej sesji zdarzenia może występować wiele wątków zdarzeń.

Na potrzeby powiadomień różne typy zdarzeń są grupowane w różne wątki.

Grupowanie wątków i logika czasowa są obsługiwane przez Google i mogą ulec zmianie w dowolnym momencie. A developer powinny aktualizować powiadomienia na podstawie wątków zdarzeń i sesji udostępnianych przez interfejs SDM API.

Stan wątku

Wydarzenia, które obsługują powiadomienia z możliwością aktualizacji, mają też pole eventThreadState, które wskazuje stan wątku wydarzenia w danym momencie. To pole ma te wartości:

  • STARTED – pierwsze zdarzenie w wątku zdarzeń.
  • ZAKTUALIZOWANO – wydarzenie w wątku trwającego wydarzenia. W jednym wątku może wystąpić zero lub więcej zdarzeń w tym stanie.
  • ENDED – ostatnie zdarzenie w wątku zdarzeń, które w zależności od typu wątku może być duplikatem ostatniego zdarzenia UPDATED.

Tego pola można używać do śledzenia postępów wątku zdarzeń i momentu jego zakończenia.

Filtrowanie zdarzeń

W niektórych przypadkach zdarzenia wykryte przez urządzenie mogą być odfiltrowywane z publikowania w temacie SDM Pub/Sub. Takie działanie nazywamy filtrowaniem zdarzeń. Filtrowanie zdarzeń ma na celu uniknięcie publikowania zbyt wielu podobnych komunikatów o zdarzeniach w krótkim czasie.

Na przykład wiadomość może zostać opublikowana w temacie SDM w przypadku początkowego zdarzenia ruchu. Inne wiadomości dotyczące Motion będą po tym czasie odfiltrowywane z publikacji do momentu upłynięcia określonego czasu. Po upływie tego czasu komunikat o zdarzeniu tego typu może zostać ponownie opublikowany.

W aplikacji Google Home odfiltrowane zdarzenia będą nadal widoczne w historii zdarzeń user. Takie zdarzenia nie generują jednak powiadomienia w aplikacji (nawet jeśli ten typ powiadomień jest włączony).

Każdy typ zdarzenia ma własną logikę filtrowania zdarzeń, która jest zdefiniowana przez Google i może ulec zmianie w dowolnym momencie. Ta logika filtrowania zdarzeń jest niezależna od wątku zdarzeń i logiki sesji.

Konta usługi

Konta usługi są zalecane do zarządzania subskrypcjami interfejsu SDM API i wiadomościami o zdarzeniach. Konto usługi jest używane przez aplikację lub maszynę wirtualną, a nie przez osobę, i ma własny, unikalny klucz konta.

Autoryzacja konta usługi w interfejsie Pub/Sub API korzysta z dwuetapowej autoryzacji OAuth (2LO).

W przepływie autoryzacji 2LO:

  • developer wysyła żądanie tokena dostępu za pomocą klucza usługi.
  • developer używa tokena dostępu w wywołaniach interfejsu API.

Więcej informacji o 2LO Google i sposobie konfiguracji znajdziesz w artykule Używanie OAuth 2.0 w aplikacjach typu serwer-serwer.

Autoryzacja

Konto usługi powinno być autoryzowane do korzystania z interfejsu Pub/Sub API:

  1. Włącz interfejs Cloud Pub/Sub API w Google Cloud.
  2. Utwórz konto usługi i klucz konta usługi zgodnie z instrukcjami w artykule Tworzenie konta usługi. Zalecamy przypisanie mu tylko roli Subskrybent Pub/Sub. Pamiętaj, aby pobrać klucz konta usługi na komputer, który będzie korzystać z interfejsu Pub/Sub API.
  3. Podaj w kodzie aplikacji dane logowania (klucz konta usługi), postępując zgodnie z instrukcjami na stronie z poprzedniego kroku, lub ręcznie uzyskaj token dostępu za pomocą oauth2l, jeśli chcesz szybko przetestować dostęp do interfejsu API.
  4. Użyj danych logowania konta usługi lub tokena dostępu z interfejsem API project.subscriptions Pub/Sub do pobierania i potwierdzania wiadomości.

oauth2l

Google oauth2l to narzędzie wiersza poleceń do OAuth napisane w języku Go. Zainstaluj je na komputerze Mac lub Linux za pomocą Go.

  1. Jeśli nie masz Go w systemie, najpierw pobierz i zainstaluj ten język.
  2. Po zainstalowaniu Go zainstaluj oauth2l i dodaj jego lokalizację do zmiennej środowiskowej PATH:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Użyj oauth2l, aby uzyskać token dostępu do interfejsu API, korzystając z odpowiednich zakresów OAuth:
    oauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub
    https://www.googleapis.com/auth/cloud-platform
    Jeśli na przykład klucz usługi znajduje się w lokalizacji ~/myServiceKey-eb0a5f900ee3.json:
    oauth2l fetch --credentials ~/myServiceKey-eb0a5f900ee3.json --scope https://www.googleapis.com/auth/pubsub
    https://www.googleapis.com/auth/cloud-platform
    ya29.c.Elo4BmHXK5...

Więcej informacji o używaniu znajdziesz w oauth2l pliku README.

Biblioteki klienta Google API

Dostępnych jest kilka bibliotek klienta interfejsów API Google, które korzystają z OAuth 2.0. Więcej informacji o wybranym języku znajdziesz w sekcji Biblioteki klienta interfejsów API Google.

Jeśli używasz tych bibliotek z  Pub/Sub API, użyj tych ciągów zakresu:

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

Błędy

W związku z tym przewodnikiem mogą zostać zwrócone te kody błędów:

Komunikat o błędzie RPC Rozwiązywanie problemów
Obraz z kamery nie jest już dostępny do pobrania. DEADLINE_EXCEEDED Obrazy wydarzeń wygasają 30 sekund po opublikowaniu wydarzenia. Pamiętaj, aby pobrać obraz przed wygaśnięciem.
Identyfikator zdarzenia nie należy do kamery. FAILED_PRECONDITION Użyj prawidłowego parametru eventID zwróconego przez zdarzenie kamery.

Pełną listę kodów błędów interfejsu API znajdziesz w dokumentacji kodów błędów interfejsu API.