Report State

Report State is an important feature which lets the Home Action proactively report the latest status of the user's device back to Google 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, 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

  1. In the Google Cloud Console, go to the HomeGraph API page.

    Go to the HomeGraph API page
  2. Select the project that matches your smart home project ID.
  3. Click ENABLE.

Create a Service Account Key

Follow these instructions to generate a service account key from the Google Cloud Console:

Note: Ensure that you are using the correct GCP project when performing these steps. This is the project that matches your smart home project ID.
  1. In the Google Cloud Console, go to the Create service account key page.

    Go to the Create Service Account Key page
  2. From the Service account list, select New service account.
  3. In the Service account name field, enter a name.
  4. In the Service account ID field, enter a ID.
  5. From the Role list, select Service Accounts > Service Account Token Creator.

  6. For the Key type, select the JSON option.

  7. Click Create. A JSON file that contains your key downloads to your computer.

Call the API

Select an option from the tabs below:

HTTP

The Home Graph provides an HTTP endpoint

  1. Use the downloaded service account JSON file to create a JSON Web Token (JWT). For more information, see Authenticating Using a Service Account.
  2. Obtain an OAuth 2.0 access token with the https://www.googleapis.com/auth/homegraph scope using oauth2l:
  3. oauth2l fetch --credentials service-account.json \
      --scope https://www.googleapis.com/auth/homegraph
    
  4. Create the JSON request with the agentUserId. Here's a sample JSON request for Report State and Notification:
  5. {
      "requestId": "123ABC",
      "agentUserId": "user-123",
      "payload": {
        "devices": {
          "states": {
            "light-123": {
              "on": true
            }
          }
        }
      }
    }
    
  6. Combine the Report State and Notification 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:
  7. curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d @request-body.json \
      "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
    

gRPC

The Home Graph provides a gRPC endpoint

  1. Get the protocol buffers service definition for the Home Graph API.
  2. Follow the gRPC developer documentation to generate client stubs for one of the supported languages.
  3. Call the ReportStateAndNotification method.

Node.js

The Google APIs Node.js Client provides bindings for the Home Graph API.

  1. Initialize the google.homegraph service using Application Default Credentials.
  2. Call the reportStateAndNotification method with the ReportStateAndNotificationRequest. It returns a Promise with the ReportStateAndNotificationResponse.
const homegraphClient = homegraph({
  version: 'v1',
  auth: new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/homegraph'
  })
});

const res = await homegraphClient.devices.reportStateAndNotification({
  requestBody: {
    agentUserId: 'PLACEHOLDER-USER-ID',
    requestId: 'PLACEHOLDER-REQUEST-ID',
    payload: {
      devices: {
        states: {
          "PLACEHOLDER-DEVICE-ID": {
            on: true
          }
        }
      }
    }
  }
});
    

Java

The HomeGraph API Client Library for Java provides bindings for the Home Graph API.

  1. Initialize the HomeGraphApiService using Application Default Credentials.
  2. Call the reportStateAndNotification method with the ReportStateAndNotificationRequest. It returns a ReportStateAndNotificationResponse.
  // Get Application Default credentials.
  GoogleCredentials credentials =
      GoogleCredentials.getApplicationDefault()
          .createScoped(List.of("https://www.googleapis.com/auth/homegraph"));

  // Create Home Graph service client.
  HomeGraphService homegraphService =
      new HomeGraphService.Builder(
              GoogleNetHttpTransport.newTrustedTransport(),
              GsonFactory.getDefaultInstance(),
              new HttpCredentialsAdapter(credentials))
          .setApplicationName("HomeGraphExample/1.0")
          .build();

  // Build device state payload.
  Map<?, ?> states = Map.of("on", true);

  // Report device state.
  ReportStateAndNotificationRequest request =
      new ReportStateAndNotificationRequest()
          .setRequestId("PLACEHOLDER-REQUEST-ID")
          .setAgentUserId("PLACEHOLDER-USER-ID")
          .setPayload(
              new StateAndNotificationPayload()
                  .setDevices(
                      new ReportStateAndNotificationDevice()
                          .setStates(Map.of("PLACEHOLDER-DEVICE-ID", states))));
  homegraphService.devices().reportStateAndNotification(request);
}
    

Test Report State

Recommended tools for this task

In order to get your action ready for certification, it is important to test Report State.

To do this, we recommend using the Home Graph Viewer tool, which is a standalone web app that doesn't require downloading or deployment.

The Report State Dashboard is still available, but is deprecated and no longer supported.

Report State Dashboard

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 Agent User ID 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 Bad Request - The server was unable to process the request sent by the client due to invalid syntax. Common causes include malformed JSON or using null instead of "" for a string value.
  • 404 Not Found - 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 invalid agentUserId. Ensure that the agentUserId matches the value provided in your SYNC response, and you are properly handling DISCONNECT intents.