Events

Events are asynchronous and managed by Google Cloud Pub/Sub, in a single topic per Project. Events provide updates for all devices and structures and receipt of events is assured as long as the access token is not revoked by the user and the event messages have not expired.

Enable events

Events are an optional feature of the Smart Device Management (SDM) API. See Enable events to learn how to enable them for your Project.

Google Cloud Pub/Sub

See the Google Cloud Pub/Sub documentation to learn more about how Pub/Sub works. In particular:

Event subscription

When events are enabled for your Project, you will be provided a topic specific to that Project ID, in the form of:

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

To receive events, create a pull or push subscription to that topic, depending on your use case. Multiple subscriptions to the SDM topic are supported. See Managing subscriptions for more information.

Initiate events

To initiate events for the first time once the Pub/Sub subscription has been created, make a devices.list API call as a one-time trigger. Events for all structures and devices will publish after this call.

For an example, see the Authorize page in the Quick Start Guide.

Event order

Pub/Sub does not guarantee ordered delivery of events, and the receipt order of events may not correspond to the order in which the events actually occurred. Use the timestamp field to aid in reconciliation of event order. Events may also arrive individually or combined into a single event message.

For more information, see Ordering messages.

User IDs

If your implementation is based around users (rather than structure or device), use the userID field from the event payload to correlate resources and events. This field is an obfuscated ID representing a specific user.

The userID is also available in the HTTP response header of each API call.

Relation events

Relation events represent a relational update for a resource. For example, when a device is added to a structure, or when a device is deleted from a structure.

There are three types of relation events:

  • CREATED
  • DELETED
  • UPDATED

The payload for a relation event contains a unique eventId, a timestamp of when the event occurred, a relationUpdate object detailing information about the relational update, and a userId that represents the user. For example:

{
  "eventId" : "0120ecc7-3b57-4eb4-9941-91609f189fb4",
  "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 a relation event, the object is the resource that triggered the event and the subject is the resource that the object now has a relation with. In the example above, a user has granted access to this specific device to a developer, and the user's authorized device is now related to their authorized structure, which triggers the event.

A subject can only be a room or a structure. If a developer does not have permission to view the user's structure, the subject is always empty.

Examples

Event payloads differ for each type of relation event:

CREATED

Structure created

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

Device created

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

Device created

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

UPDATED

Device moved

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

DELETED

Structure deleted

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

Device deleted

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

Device deleted

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

Resource events

A resource event represents an update specific to a resource. It can be in response to a change in the value of a trait field, such as changing the mode of a thermostat. It can also represent a device action that doesn't change a trait field such as pressing a device button.

The payload for a resource event contains a unique eventId, a timestamp of when the event occurred, a resourceUpdate object detailing information about the resource update, and a userId that represents the user.

An event generated in response to a change in the value of trait field contains a traits object, similar to a device GET call:

Payload

{
  "eventId" : "0120ecc7-3b57-4eb4-9941-91609f189fb4",
  "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"
}

Use the individual trait documentation to understand the payload format for any trait field change resource event.

An event generated in response to a device action that doesn't change a trait field also has a payload with a resourceUpdate object, but with an events object instead of a traits object:

Payload

{
  "eventId" : "0120ecc7-3b57-4eb4-9941-91609f189fb4",
  "timestamp" : "2019-01-01T00:00:01Z",
  "resourceUpdate" : {
    "name" : "enterprises/project-id/devices/device-id",
    "events" : {
      "sdm.devices.events.CameraMotion.Motion" : {
        "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...",
        "eventId" : "FWWVQVUdGNUlTU2V4MGV2aTNXV..."
      }
    }
  },
  "userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"
}

These types of resource events are defined in specific traits. For example, the Motion event is defined in the CameraMotion trait. See each trait's documentation to understand the payload format for these types of resource events.

Service accounts

Service accounts are recommended for managing SDM API subscriptions and event messages. A service account is used by an application or virtual machine, not a person, and has its own unique account key.

Service account authorization for the Google Cloud Pub/Sub API uses Two-legged OAuth (2LO).

In the 2LO authorization flow:

  • The developer requests an access token using a service key.
  • The developer uses the access token with calls to the API.

To learn more about Google 2LO and how to get set up, see Using OAuth 2.0 for Server to Server Applications.

Authorization

The service account should be authorized for use with the Pub/Sub API:

  1. Enable the Cloud Pub/Sub API in Google Cloud Platform (GCP).
  2. Create a service account and service account key as described in Creating a service account. We recommend giving it only the Pub/Sub Subscriber role. Make sure to download the service account key to the machine that will be using the Pub/Sub API.
  3. Provide your authentication credentials (service account key) to your application code by following the instructions at the page in the previous step, or get an access token manually using oauth2l, if you want to quickly test API access.
  4. Use service account credentials or the access token with the Pub/Sub project.subscriptions API to pull and acknowledge messages.

oauth2l

Google oauth2l is a command line tool for OAuth written in Go. Install it for Mac or Linux using Go.

  1. If you do not have Go on your system, download and install it first.
  2. Once Go is installed, install oauth2l and add its location to your PATH environment variable:
    go get github.com/google/oauth2l
    go install github.com/google/oauth2l
    export PATH=$PATH:~/go/bin
  3. Use oauth2l to get an access token for the API, using the appropriate OAuth scope(s):
    oauth2l fetch --credentials path-to-service-key.json --scope pubsub,cloud-platform
    For example, if your service key is located at ~/myServiceKey-eb0a5f900ee3.json:
    oauth2l fetch --credentials ~/myServiceKey-eb0a5f900ee3.json --scope pubsub,cloud-platform
    ya29.c.Elo4BmHXK5...

See the oauth2l README for more usage information.

Google API Client Libraries

There are several client libraries available for Google APIs that utilize OAuth 2.0. See Google API Client Libraries for more information on the language of your choice.

When using these libraries with the Pub/Sub API, use the following scope string(s):

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

Errors

The following error code(s) may be returned in relation to this guide:

Error Message RPC Troubleshooting
Camera image is no longer available for download. DEADLINE_EXCEEDED Event images expire 30 seconds after the event is published. Make sure to download the image prior to expiration.
Event id does not belong to the camera. FAILED_PRECONDITION Use the correct eventID returned by the camera event.

See the API Error Code Reference for the full list of Device Access error codes.