Report State is an important feature which lets the smart home Action proactively
report the latest status of the user’s device back to Google’s Home Graph rather
than waiting for a QUERY
intent.
Report State reports to Google the states of user devices with the
specified agentUserId
associated
with them (sent in the original SYNC
request). When Google
Assistant wants to take an action that requires understanding the current
state of a device, it can simply look up the state information in the Home Graph instead
of issuing a QUERY
intent to various third-party clouds prior to issuing the
EXECUTE
intent.
Without Report State, given lights from multiple providers in a living room,
the command Ok Google, brighten my living room requires resolving
multiple QUERY
intents sent to multiple clouds, as opposed to simply looking
up the current brightness values based on what has been previously reported. For
the best user experience, Google Assistant needs to have the current state
of a device, without requiring a round-trip to the device.
Following the initial SYNC
for a device, the platform sends a QUERY
intent
that gathers the state of the device to populate Home Graph. After that point,
Home Graph only stores the state that is sent with Report State.
When calling Report State, make sure to provide complete state data for a given
trait. Home Graph updates states on a per-trait basis and overwrites all data
for that trait when a Report State call is made. For example, if you are reporting
state for the StartStop trait,
the payload needs to include values for both isRunning
and isPaused
.
Get started
To implement Report State, follow these steps:
- Enable the Google HomeGraph API
- Create a Service Account Key
- Call the API
- Handle the Disconnect intent
Enable the Google HomeGraph API
-
In the Google Cloud Platform Console, go to the HomeGraph API page.
Go to the HomeGraph API page - Select the project that matches your smart home project ID.
- Click ENABLE.
Create a Service Account Key
Follow these instructions to generate a service account key from the GCP Console:
-
In the GCP Console, go to the Create service account key page.
Go to the Create Service Account Key page - From the Service account list, select New service account.
- In the Service account name field, enter a name.
- In the Service account ID field, enter a ID.
From the Role list, select Service Accounts > Service Account Token Creator.
For the Key type, select the JSON option.
- Click Create. A JSON file that contains your key downloads to your computer.
Call the API
Select an option from the tabs below:
Node.js
The Actions on Google library for Node.js supports Report State over HTTP.
- Place the downloaded service account JSON in your project directory.
- Pass the file location into your
smarthome
constructor - Call the
reportState
method with your payload. It returns a Promise.
const {smarthome} = require('actions-on-google'); const app = smarthome({ jwt: mySecretKeyJson }); // ... // Device state changed app.reportState({ requestId: '123ABC', agentUserId: 'user-123', payload: { devices: { states: { "light-123": { on: true } } } } }) .then((res) => { // Report state was successful }) .catch((res) => { // Report state failed });
Java
The Actions on Google library for Java supports Report State over gRPC.
- Place the downloaded service account JSON in your project directory.
- Read the file location to generate a
GoogleCredentials
object. - Call the
reportState
method with your payload. It returns a server response.
private void onDeviceStateUpdated() throws IOException { // Get service account key from file FileInputStream stream = new FileInputStream("service-account-key.json"); GoogleCredentials credentials = GoogleCredentials.fromStream(stream); mySmartHomeApp.setCredentials(credentials); Value deviceStates = Value.newBuilder() .setStructValue( Struct.newBuilder() .putFields("on", Value.newBuilder().setBoolValue(true).build()) .build()) .build(); Struct requestStates = Struct.newBuilder().putFields("light-123", deviceStates).build(); ReportStateAndNotificationResponse response = mySmartHomeApp.reportState( ReportStateAndNotificationRequest.newBuilder() .setRequestId("123ABC") .setAgentUserId("user-123") .setPayload( StateAndNotificationPayload.newBuilder() .setDevices( ReportStateAndNotificationDevice.newBuilder() .setStates(requestStates) .build()) .build()) .build()); }
HTTP POST
- Use the downloaded service account JSON file to create a JSON Web Token (JWT). For more information, see Authenticating Using a Service Account.
- Obtain an OAuth 2.0 access token with the
https://www.googleapis.com/auth/homegraph
scope using oauth2l: - Create the JSON request with the
agentUserId
. Here's a sample JSON request for Report State: - Combine the Report State JSON and the token in your HTTP POST
request to the Google Home Graph endpoint. Here's an example of how
to make the request in the command line using
curl
, as a test:
oauth2l fetch --credentials service-account.json \ --scope https://www.googleapis.com/auth/homegraph
{ "requestId": "123ABC", "agentUserId": "user-123", "payload": { "devices": { "states": { "light-123": { "on": true } } } } }
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d @request-body.json \ "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
Test Report State
In order to get your action ready for certification, it is important to test report state.
Prerequisites
Before being able to test your action, you need your Service Account
Key and your agentUserId
. If you already have your Service Account Key and
agentUserId
, see Deploy the Report State Dashboard.
Deploy the Report State dashboard
Once you have the Service Account Key and agentUserId for your project, download
and deploy the latest version from Report State Dashboard.
Once you have downloaded the latest version, follow the instructions from the included README.MD
file.
After you have deployed the Report State dashboard, access the dashboard from the following URL (replace your_project_id with your project ID):
http://<your-project-id>.appspot.com
On the dashboard, do the following:
- Choose your Account Key File
- Add your agentUserId
Then, click List.
All of your devices are listed. Once the list is populated, you can use the Refresh button to update device states. If there is a device state change, the row is highlighted in green.
Error Responses
You may receive one of the following error responses when calling Report State. These responses come in the form of HTTP status codes.
400
- Failure: The server was unable to process the request sent by the client due to invalid syntax. Common causes include malformed JSON or usingnull
instead of "" for a string value.404
- Failure: The requested resource could not be found but may be available in the future. Typically, this means that we cannot find the requested device. It may also mean that the user account is not linked with Google or we received an invalidagentUserId
. Ensure that theagentUserId
matches the value provided in your SYNC response, and you are properly handling DISCONNECT intents.