Eventi

Gli eventi sono asincroni e gestiti da Google Cloud Pub/Sub, in un unico argomento per Project. Gli eventi forniscono aggiornamenti per tutti i dispositivi e le strutture e la ricezione degli eventi è garantita, a condizione che il token di accesso non venga revocato dall'utente e che i messaggi degli eventi non siano scaduti.

Attiva eventi

Gli eventi sono una funzionalità facoltativa dell'API SDM. Consulta Attiva gli eventi per scoprire come attivarli per il tuo Project.

Google Cloud Pub/Sub

Consulta la documentazione di Google Cloud Pub/Sub per scoprire di più sul funzionamento di Pub/Sub. In particolare:

Sottoscrizione agli eventi

Prima di gennaio 2025, se gli eventi erano attivati per il tuo Project, ti veniva fornito un argomento ospitato da Google specifico per quell' Project ID, nel formato:

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

Ora tutti i progetti devono ospitare autonomamente i propri argomenti Pub/Sub nel proprio progetto Google Cloud (obbligatorio per i nuovi progetti da gennaio 2025 e per tutti i progetti esistenti entro il 30 novembre 2026), sotto forma di:

projects/gcp-project-name/subscriptions/topic-id

Se il tuo project utilizza già un argomento in hosting autonomo nel tuo progetto cloud Google, non è necessaria alcuna azione. La migrazione della configurazione dell'argomento Pub/Sub non invalida i token di accesso utente o le autorizzazioni OAuth esistenti. Gli argomenti e le sottoscrizioni in hosting autonomo sono soggetti ai prezzi standard di Google Cloud Pub/Sub (che includono un livello senza costi di 10 GB al mese). Per ulteriori informazioni, consulta Crea un argomento.

Per ricevere gli eventi, crea una sottoscrizione pull o push per l'argomento, a seconda del tuo caso d'uso. Sono supportate più sottoscrizioni all'argomento SDM. Per saperne di più, consulta Gestione delle sottoscrizioni.

Avvia eventi

Per avviare gli eventi per la prima volta dopo la creazione della sottoscrizione Pub/Sub, effettua una chiamata API devices.list come trigger una tantum. Gli eventi per tutte le strutture e i dispositivi verranno pubblicati dopo questa chiamata.

Per un esempio, consulta la pagina Autorizza nella guida rapida.

Ordine degli eventi

Pub/Sub non garantisce la distribuzione ordinata degli eventi e l'ordine di ricezione degli eventi potrebbe non corrispondere all'ordine in cui si sono effettivamente verificati. Utilizza il campo timestamp per facilitare la riconciliazione dell'ordine degli eventi. Gli eventi possono anche arrivare singolarmente o combinati in un unico messaggio di evento.

Per saperne di più, consulta Ordinamento dei messaggi.

ID utente

Se la tua implementazione è basata sugli utenti (anziché sulla struttura o sul dispositivo), utilizza il campo userID del payload dell'evento per correlare risorse ed eventi. Questo campo è un ID offuscato che rappresenta un utente specifico.

Il userID è disponibile anche nell'intestazione della risposta HTTP di ogni chiamata API.

Eventi di relazione

Gli eventi di relazione rappresentano un aggiornamento relazionale per una risorsa. Ad esempio, quando un dispositivo viene aggiunto o eliminato da una struttura.

Esistono tre tipi di eventi di relazione:

  • CREATED
  • ELIMINATO
  • AGGIORNATA

Il payload di un evento di relazione è il seguente:

Payload

{
  "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 un evento di relazione, object è la risorsa che ha attivato l'evento e subject è la risorsa con cui object ha ora una relazione. Nell'esempio precedente, un user ha concesso l'accesso a questo dispositivo specifico a un developere il dispositivo autorizzato del userè ora correlato alla sua struttura autorizzata, il che attiva l'evento.

Un subject può essere solo una stanza o una struttura. Se a developer non dispone dell'autorizzazione per visualizzare la struttura di user, subject è sempre vuoto.

Campi

Campo Descrizione Tipo di dati
eventId L'identificatore univoco dell'evento. string
Esempio: "a121b435-e3bb-4ba1-9dea-945686b7dabf"
timestamp L'ora in cui si è verificato l'evento. string
Esempio: "2019-01-01T00:00:01Z"
relationUpdate Un oggetto che fornisce informazioni dettagliate sull'aggiornamento della relazione. object
userId Un identificatore univoco e offuscato che rappresenta l'utente. string
Esempio: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"

Per saperne di più sui diversi tipi di eventi e sul loro funzionamento, consulta la pagina Eventi.

Esempi

I payload degli eventi variano per ogni tipo di evento di relazione:

DATA/ORA CREAZIONE

Struttura creata

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

Dispositivo creato

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

Dispositivo creato

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

AGGIORNATA

Dispositivo spostato

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

ELIMINATO

Struttura eliminata

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

Dispositivo eliminato

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

Dispositivo eliminato

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

Gli eventi di relazione non vengono inviati quando:

  • Una stanza viene eliminata

Eventi risorsa

Un evento di risorsa rappresenta un aggiornamento specifico di una risorsa. Può essere in risposta a una modifica del valore di un campo di un tratto, ad esempio la modifica della modalità di un termostato. Può anche rappresentare un'azione del dispositivo che non modifica un campo di un tratto, ad esempio la pressione di un pulsante del dispositivo.

Un evento generato in risposta a una modifica del valore del campo di un tratto contiene un oggetto traits, simile a una chiamata GET del dispositivo:

Payload

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

Utilizza la documentazione relativa ai singoli tratti per comprendere il formato del payload per qualsiasi evento di risorsa di modifica del campo del tratto.

Anche un evento generato in risposta a un'azione del dispositivo che non modifica un campo di un tratto ha un payload con un oggetto resourceUpdate, ma con un oggetto events anziché un oggetto traits:

Payload

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

Questi tipi di eventi delle risorse sono definiti in tratti specifici. Ad esempio, l'evento Motion è definito nel tratto CameraMotion . Consulta la documentazione di ogni tratto per comprendere il formato del payload per questi tipi di eventi delle risorse.

Campi

Campo Descrizione Tipo di dati
eventId L'identificatore univoco dell'evento. string
Esempio: "0111d3f2-5e7d-4ecf-88ed-8f3b0324f75c"
timestamp L'ora in cui si è verificato l'evento. string
Esempio: "2019-01-01T00:00:01Z"
resourceUpdate Un oggetto che fornisce informazioni dettagliate sull'aggiornamento della risorsa. object
userId Un identificatore univoco e offuscato che rappresenta l'utente. string
Esempio: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"
eventThreadId L'identificatore univoco del thread dell'evento. string
Esempio: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59"
eventThreadState Lo stato del thread dell'evento. string
Valori: "STARTED", "UPDATED", "ENDED"
resourceGroup Un oggetto che indica le risorse che potrebbero avere aggiornamenti simili a questo evento. La risorsa dell'evento stesso (dall'oggetto resourceUpdate) sarà sempre presente in questo oggetto. object

Per saperne di più sui diversi tipi di eventi e sul loro funzionamento, consulta la pagina Eventi.

Notifiche aggiornabili

Le notifiche basate sugli eventi delle risorse possono essere implementate in un'app, ad esempio per Android o iOS. Per ridurre il numero di notifiche inviate, è possibile implementare una funzionalità chiamata notifiche aggiornabili, in cui le notifiche esistenti vengono aggiornate con nuove informazioni in base agli eventi successivi nello stesso thread di eventi.

Alcuni eventi supportano le notifiche aggiornabili e sono contrassegnati come Aggiornabile  nella documentazione. Questi eventi hanno un campo aggiuntivo chiamato eventThreadId nei payload. Utilizza questo campo per collegare singoli eventi allo scopo di aggiornare una notifica esistente che è stata mostrata a un utente.

Un thread di eventi non è la stessa cosa di una sessione di eventi. Il thread di eventi identifica uno stato aggiornato per un evento precedente nello stesso thread. La sessione di eventi identifica eventi separati correlati tra loro e possono esistere più thread di eventi per una determinata sessione di eventi.

Ai fini delle notifiche, i diversi tipi di eventi sono raggruppati in thread diversi.

Questo raggruppamento dei thread e la logica di tempistica sono gestiti da Google e sono soggetti a modifiche in qualsiasi momento. Un developer dovrebbe aggiornare le notifiche in base ai thread e alle sessioni degli eventi forniti dall'API SDM.

Stato del thread

Gli eventi che supportano le notifiche aggiornabili hanno anche un campo eventThreadState che indica lo stato del thread dell'evento in quel momento. Questo campo ha i seguenti valori:

  • STARTED: il primo evento di un thread di eventi.
  • UPDATED: un evento in un thread di eventi in corso. In un singolo thread possono essere presenti zero o più eventi con questo stato.
  • ENDED: l'ultimo evento di un thread di eventi, che potrebbe essere un duplicato dell'ultimo evento UPDATED, a seconda del tipo di thread.

Questo campo può essere utilizzato per monitorare l'avanzamento di un thread di eventi e quando è terminato.

Filtro degli eventi

In alcuni casi, gli eventi rilevati da un dispositivo potrebbero essere esclusi dalla pubblicazione in un argomento Pub/Sub SDM. Questo comportamento è chiamato filtro degli eventi. Lo scopo del filtro degli eventi è evitare di pubblicare troppi messaggi di eventi simili in un breve periodo di tempo.

Ad esempio, un messaggio potrebbe essere pubblicato in un argomento SDM per un evento di movimento iniziale. Gli altri messaggi per Motion successivi verranno esclusi dalla pubblicazione fino al termine di un periodo di tempo prestabilito. Trascorso questo periodo di tempo, è possibile pubblicare nuovamente un messaggio di evento per quel tipo di evento.

Nell'app Google Home (GHA), gli eventi filtrati verranno comunque visualizzati nella cronologia eventi di user. Tuttavia, questi eventi non generano una notifica dell'app (anche se questo tipo di notifica è attivo).

Ogni tipo di evento ha la propria logica di filtro degli eventi, definita da Google e soggetta a modifiche in qualsiasi momento. Questa logica di filtro degli eventi è indipendente dalla logica del thread e della sessione degli eventi.

Service account

Per gestire le sottoscrizioni all'API SDM e i messaggi di evento, è consigliabile utilizzare i service account. Un service account viene utilizzato da un'applicazione o da una macchina virtuale, non da una persona, e ha una propria chiave account univoca.

L'autorizzazione del service account per l'API Pub/Sub utilizza OAuth a due vie (2LO).

Nel flusso di autorizzazione 2LO:

  • developer richiede un token di accesso utilizzando una chiave di servizio.
  • developer utilizza il token di accesso con le chiamate all'API.

Per scoprire di più su Google 2LO e su come configurarlo, consulta Utilizzo di OAuth 2.0 per applicazioni server-to-server.

Autorizzazione

Il service account deve essere autorizzato per l'utilizzo con l'API Pub/Sub:

  1. Abilita l'API Cloud Pub/Sub in Google Cloud.
  2. Crea un service account e una chiave del service account come descritto in Creazione di un service account. Ti consigliamo di assegnargli solo il ruolo Sottoscrittore Pub/Sub. Assicurati di scaricare la chiave del service account sulla macchina che utilizzerà l'API Pub/Sub.
  3. Fornisci le tue credenziali di autenticazione (chiave del service account) al codice dell'applicazione seguendo le istruzioni riportate nella pagina del passaggio precedente oppure ottieni un token di accesso manualmente utilizzando oauth2l, se vuoi testare rapidamente l'accesso all'API.
  4. Utilizza le credenziali del service account o il token di accesso con l'API Pub/Sub project.subscriptions per eseguire il pull e confermare i messaggi.

oauth2l

Google oauth2l è uno strumento a riga di comando per OAuth scritto in Go. Installalo per Mac o Linux utilizzando Go.

  1. Se non hai Go sul tuo sistema, scaricalo e installalo.
  2. Una volta installato Go, installa oauth2l e aggiungi la sua posizione alla variabile di ambiente PATH:
    go install github.com/google/oauth2l@latest
    export PATH=$PATH:~/go/bin
  3. Utilizza oauth2l per ottenere un token di accesso per l'API, utilizzando gli ambiti OAuth appropriati:
    oauth2l fetch --credentials path-to-service-key.json --scope https://www.googleapis.com/auth/pubsub
    https://www.googleapis.com/auth/cloud-platform
    Ad esempio, se la chiave di servizio si trova in ~/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...

Per ulteriori informazioni sull'utilizzo, consulta il file README di oauth2l.

Librerie client delle API di Google

Sono disponibili diverse librerie client per le API di Google che utilizzano OAuth 2.0. Per saperne di più sul linguaggio che preferisci, consulta Librerie client delle API di Google.

Quando utilizzi queste librerie con Pub/Sub API, utilizza le seguenti stringhe di ambito:

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

Errori

Per questa guida potrebbero essere restituiti i seguenti codici di errore:

Messaggio di errore RPC Risoluzione dei problemi
L'immagine della videocamera non è più disponibile per il download. DEADLINE_EXCEEDED Le immagini degli eventi scadono 30 secondi dopo la pubblicazione dell'evento. Assicurati di scaricare l'immagine prima della scadenza.
L'ID evento non appartiene alla videocamera. FAILED_PRECONDITION Utilizza l'eventID corretto restituito dall'evento della videocamera.

Per l'elenco completo dei codici di errore dell'API, consulta il riferimento ai codici di errore dell'API.