Join us online for the "Hey Google" Smart Home Summit on July 8th! Register here to learn what's new, and what's coming up for Google Smart Home.

Smart Home Energy Storage Trait Schema

action.devices.traits.EnergyStorage - This trait belongs to devices that can store energy in a battery and potentially recharge, or devices that can charge another device. The trait supports starting and stopping charging, and checking the current charge level, capacity remaining, and capacity until full values.

Device ATTRIBUTES

Devices with the EnergyStorage trait may report the following attribute as part of SYNC:
Attribute Definition
queryOnlyEnergyStorage Boolean. True if this device only supports queries about the stored energy levels and, optionally, active charging state (dependent on the isRechargeable attribute), but does not support starting and stopping charging.
energyStorageDistanceUnitForUX String. Must be either "MILES" or "KILOMETERS". Will be used in responses to the user. Defaults to "KILOMETERS".
isRechargeable Boolean. Set to true if this device is rechargeable. This indicates the device may report capacityUntilFull, isCharging, and optionally, isPluggedIn state, and can accept the Charge command. Defaults to false.

Sample SYNC Request and Response

Request
{
    "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    "inputs": [{
      "intent": "action.devices.SYNC"
    }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onSync((body, headers) => {
  return {
    requestId: "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    payload: {
      agentUserId: "1836.15267389",
      devices: [{
        id: "123",
        type: "action.devices.types.CHARGER",
        traits: [
          "action.devices.traits.EnergyStorage"
        ],
        name: {
          name: "Rechargable Device",
        },
        willReportState: true,
        attributes: {
          isRechargeable: true,
          queryOnlyEnergyStorage: false
        },
        deviceInfo: {
          manufacturer: "ACME Inc.",
          model: "GIZMO-R",
          hwVersion: "PVT-2",
          swVersion: "1.0.1"
        }
      }]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
@SmartHomeSnippetJson("smart-home-traits-energystorage_sync_1.json")
public SyncResponse onSync(@NotNull SyncRequest syncRequest, @Nullable Map<?, ?> headers) {
  Payload payload = new Payload();
  payload.setAgentUserId("1836.15267389");
  payload.setDevices(
      new Device[] {
        new Device.Builder()
            .setId("123")
            .setType("action.devices.types.CHARGER")
            .addTrait("action.devices.traits.EnergyStorage")
            .setName(Collections.emptyList(), "Rechargable Device", Collections.emptyList())
            .setWillReportState(true)
            .setAttributes(
                new JSONObject().put("isRechargeable", true).put("queryOnlyEnergyStorage", false))
            .setDeviceInfo("ACME Inc.", "GIZMO-R", "PVT-2", "1.0.1")
            .build()
      });
  return new SyncResponse(syncRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "123",
        "type": "action.devices.types.CHARGER",
        "traits": [
          "action.devices.traits.EnergyStorage"
        ],
        "name": {
          "name": "Rechargable Device"
        },
        "willReportState": true,
        "attributes": {
          "isRechargeable": true,
          "queryOnlyEnergyStorage": false
        },
        "deviceInfo": {
          "manufacturer": "ACME Inc.",
          "model": "GIZMO-R",
          "hwVersion": "PVT-2",
          "swVersion": "1.0.1"
        }
      }
    ]
  }
}
Validator

Device STATES

States Definition
descriptiveCapacityRemaining String. A qualitative description of the energy capacity level.

Valid states:

  • "CRITICALLY_LOW"
  • "LOW"
  • "MEDIUM"
  • "HIGH"
  • "FULL"
capacityRemaining

Array of { unit: string, rawValue: float } pairs that represent the current energy capacity of the device. For example, "How many miles does my <device> currently have?" and "What percentage charge does my <device> have?"

Supported units include:

  • "SECONDS"
  • "MILES"
  • "KILOMETERS"
  • "PERCENTAGE"

The following states may be present if isRechargeable is set to true:

States Definition
isPluggedIn Boolean. Whether the device is currently plugged in. The device can be plugged in, but not actively charging.
isCharging Boolean. Whether the device is currently charging.
capacityUntilFull

Array of { unit: string, rawValue: float } pairs that represent the capacity until the device is fully charged. For example, "How much time until my <device> is fully charged?"

Supported units include:

  • "SECONDS"
  • "MILES"
  • "KILOMETERS"
  • "PERCENTAGE"

Sample QUERY Request and Response

Example 1: Vacuum that reports percentage and time.

User How much time is left on the vacuum?
Google Assistant The vacuum has 10 hours of charge.
User What is the vacuum’s battery level?
Google Assistant The vacuum has 90 percent battery.
User How much time until my vacuum is done charging?
Google Assistant The vacuum needs 2 more minutes to be fully charged.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": 'action.devices.QUERY',
    "payload": {
      "devices": [{
        "id": "123",
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "foo"
        }
      }]
    }
  }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onQuery((body, headers) => {
  return {
    requestId: "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    payload: {
      devices: {
        123: {
          online: true,
          isPluggedIn: true,
          isCharging: true,
          capacityRemaining: [
            {
              unit: "SECONDS",
              rawValue: 36000
            },
            {
              unit: "PERCENTAGE",
              rawValue: 90
            }
          ],
          capacityUntilFull: [
            {
              unit: "SECONDS",
              rawValue: 120
            }
          ],
          status: "SUCCESS"
        }
      }
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
@SmartHomeSnippetJson("smart-home-traits-energystorage_query_1.json")
public QueryResponse onQuery(@NotNull QueryRequest queryRequest, @Nullable Map<?, ?> map) {
  QueryResponse.Payload payload = new QueryResponse.Payload();
  payload.setDevices(
      new HashMap<String, Map<String, Object>>() {
        {
          put(
              "123",
              new HashMap<String, Object>() {
                {
                  put("online", true);
                  put("isPluggedIn", true);
                  put("isCharging", true);
                  put(
                      "capacityRemaining",
                      new ArrayList<Object>() {
                        {
                          add(
                              new HashMap<String, Object>() {
                                {
                                  put("unit", "SECONDS");
                                  put("rawValue", 36000);
                                }
                              });
                          add(
                              new HashMap<String, Object>() {
                                {
                                  put("unit", "PERCENTAGE");
                                  put("rawValue", 90);
                                }
                              });
                        }
                      });
                  put(
                      "capacityUntilFull",
                      new ArrayList<Object>() {
                        {
                          add(
                              new HashMap<String, Object>() {
                                {
                                  put("unit", "SECONDS");
                                  put("rawValue", 120);
                                }
                              });
                        }
                      });
                  put("status", "SUCCESS");
                }
              });
        }
      });

  return new QueryResponse(queryRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "devices": {
      "123": {
        "online": true,
        "isPluggedIn": true,
        "isCharging": true,
        "capacityRemaining": [
          {
            "unit": "SECONDS",
            "rawValue": 36000
          },
          {
            "unit": "PERCENTAGE",
            "rawValue": 90
          }
        ],
        "capacityUntilFull": [
          {
            "unit": "SECONDS",
            "rawValue": 120
          }
        ],
        "status": "SUCCESS"
      }
    }
  }
}

Example 2: Electric vehicle that reports miles and time.

User How many miles added to my electric vehicle?
Google Assistant The electric vehicle has 12 miles of charge.
User How much time until my electric vehicle is done charging?
Google Assistant The electric vehicle needs 100 more minutes to be fully charged.
User Is my electric vehicle plugged in?
Google Assistant The electric vehicle is plugged in and charging.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": 'action.devices.QUERY',
    "payload": {
      "devices": [{
        "id": "123",
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "foo"
        }
      }]
    }
  }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onQuery((body, headers) => {
  return {
    requestId: "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    payload: {
      devices: {
        123: {
          online: true,
          isPluggedIn: true,
          isCharging: true,
          capacityRemaining: [
            {
              unit: "MILES",
              rawValue: 12
            }
          ],
          capacityUntilFull: [
            {
              unit: "SECONDS",
              rawValue: 6000
            }
          ],
          status: "SUCCESS"
        }
      }
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
@SmartHomeSnippetJson("smart-home-traits-energystorage_query_2.json")
public QueryResponse onQuery(@NotNull QueryRequest queryRequest, @Nullable Map<?, ?> map) {
  QueryResponse.Payload payload = new QueryResponse.Payload();
  payload.setDevices(
      new HashMap<String, Map<String, Object>>() {
        {
          put(
              "123",
              new HashMap<String, Object>() {
                {
                  put("online", true);
                  put("isPluggedIn", true);
                  put("isCharging", true);
                  put(
                      "capacityRemaining",
                      new ArrayList<Object>() {
                        {
                          add(
                              new HashMap<String, Object>() {
                                {
                                  put("unit", "MILES");
                                  put("rawValue", 12);
                                }
                              });
                        }
                      });
                  put(
                      "capacityUntilFull",
                      new ArrayList<Object>() {
                        {
                          add(
                              new HashMap<String, Object>() {
                                {
                                  put("unit", "SECONDS");
                                  put("rawValue", 6000);
                                }
                              });
                        }
                      });
                  put("status", "SUCCESS");
                }
              });
        }
      });

  return new QueryResponse(queryRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "devices": {
      "123": {
        "online": true,
        "isPluggedIn": true,
        "isCharging": true,
        "capacityRemaining": [
          {
            "unit": "MILES",
            "rawValue": 12
          }
        ],
        "capacityUntilFull": [
          {
            "unit": "SECONDS",
            "rawValue": 6000
          }
        ],
        "status": "SUCCESS"
      }
    }
  }
}

Example 3: Lock that only reports a qualitative battery level.

User What’s my lock’s battery level?
Google Assistant The lock has low battery.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": 'action.devices.QUERY',
    "payload": {
      "devices": [{
        "id": "123",
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "foo"
        }
      }]
    }
  }]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onQuery((body, headers) => {
  return {
  requestId: "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    payload: {
      devices: {
        123: {
          online: true,
          descriptiveCapacityRemaining: "LOW",
          status: "SUCCESS"
        }
      }
    }
  };
});
// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
@SmartHomeSnippetJson("smart-home-traits-energystorage_query_3.json")
public QueryResponse onQuery(@NotNull QueryRequest queryRequest, @Nullable Map<?, ?> map) {
  QueryResponse.Payload payload = new QueryResponse.Payload();
  payload.setDevices(
      new HashMap<String, Map<String, Object>>() {
        {
          put(
              "123",
              new HashMap<String, Object>() {
                {
                  put("online", true);
                  put("descriptiveCapacityRemaining", "LOW");
                  put("status", "SUCCESS");
                }
              });
        }
      });
  return new QueryResponse(queryRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "devices": {
      "123": {
        "online": true,
        "descriptiveCapacityRemaining": "LOW",
        "status": "SUCCESS"
      }
    }
  }
}

Device COMMANDS

Command Parameters/Definition
action.devices.commands.Charge charge: Boolean. True to start charging, false to stop charging.

Sample EXECUTE Request and Response

Example 1

User Start charging my car.
Google Assistant Ok, I'll start charging <device>.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [
    {
      "intent": "action.devices.EXECUTE",
      "payload": {
        "commands": [
          {
            "devices": [
              {
                "id": "123"
              }
            ],
            "execution": [
              {
                "command": "action.devices.commands.Charge",
                "params": {
                  "charge": true
                }
              }
            ]
          }
        ]
      }
    }
  ]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onExecute((body, headers) => {
  return {
    requestId: "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    payload: {
      commands: [
        {
          ids: [
            "123"
          ],
          status: "SUCCESS",
          states: {
            online: true,
            isPluggedIn: true,
            isCharging: true
          }
        }
      ]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
@SmartHomeSnippetJson("smart-home-traits-energystorage_execute_1.json")
public ExecuteResponse onExecute(
    @NotNull ExecuteRequest executeRequest, @Nullable Map<?, ?> map) {
  ExecuteResponse.Payload payload = new ExecuteResponse.Payload();
  payload.setCommands(
      new Commands[] {
        new Commands(
            new String[] {"123"},
            "SUCCESS",
            new HashMap<String, Object>() {
              {
                put("online", true);
                put("isPluggedIn", true);
                put("isCharging", true);
              }
            },
            null,
            null)
      });
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "online": true,
          "isPluggedIn": true,
          "isCharging": true
        }
      }
    ]
  }
}

Example 2

User Stop charging my car.
Google Assistant Ok, I'll stop charging <device>.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [
    {
      "intent": "action.devices.EXECUTE",
      "payload": {
        "commands": [
          {
            "devices": [
              {
                "id": "123"
              }
            ],
            "execution": [
              {
                "command": "action.devices.commands.Charge",
                "params": {
                  "charge": false
                }
              }
            ]
          }
        ]
      }
    }
  ]
}
Node.js
'use strict';

const {smarthome} = require('actions-on-google');
const functions = require('firebase-functions');

const app = smarthome();

app.onExecute((body, headers) => {
  return {
    requestId: "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    payload: {
      commands: [
        {
          ids: [
            "123"
          ],
          status: "SUCCESS",
          states: {
            online: true,
            isPluggedIn: true,
            isCharging: false
          }
        }
      ]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
Java
@NotNull
@Override
@SmartHomeSnippetJson("smart-home-traits-energystorage_execute_2.json")
public ExecuteResponse onExecute(
    @NotNull ExecuteRequest executeRequest, @Nullable Map<?, ?> map) {
  ExecuteResponse.Payload payload = new ExecuteResponse.Payload();
  payload.setCommands(
      new Commands[] {
        new Commands(
            new String[] {"123"},
            "SUCCESS",
            new HashMap<String, Object>() {
              {
                put("online", true);
                put("isPluggedIn", true);
                put("isCharging", false);
              }
            },
            null,
            null)
      });
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSON
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "online": true,
          "isPluggedIn": true,
          "isCharging": false
        }
      }
    ]
  }
}

Device ERRORS

See the full list of errors and exceptions.

deviceUnplugged: The user tried to charge a device that is not plugged in.