Smart Home Toggles Trait Schema

action.devices.traits.Toggles - This trait belongs to any devices with settings that can only exist in one of two states. In other words, this trait covers all available custom binary settings on a device.

These settings can represent a physical button with an on/off or active/inactive state, a checkbox in HTML, or any other sort of specifically enabled/disabled element. If the setting has more than two states, or has a state in which neither of the binary options is selected, it is better represented as a Modes trait, which equates to multi-state dials, radio buttons (physical or HTML), or binary states that are not explicitly on/off (for example, "AM/FM" or "hot/cold").

This trait covers one or more individual toggles which users can set. In general, these toggles should be used for functionality that is unlinked from other device behavior. Linked behavior, such as turning the device itself on or off, should use more specific traits (for example, the thermostatMode in the trait TemperatureSetting).

Device ATTRIBUTES

Attribute Definition
availableToggles Contains the following:
  • name String. Internal name of the toggle, which will be used in commands and states. This can be non-user-friendly, and will be shared across all languages. Currently, you must use the names in the reference; custom names are not yet supported.
  • name_values Contains names and supported languages:
    • name_synonym Strings. User-friendly names for the toggle, in each language supported; the first name will be used in TTS as needed. Currently, you must use the name synonyms available in the reference; custom name synonyms are not yet supported.
    • lang String. Supported language for the names (see Supported Languages/Language Codes).
commandOnlyToggles Boolean. Optional. Defaults to false. Indicates if the device operates using one-way (true) or two-way (false) communication. For example, if the controller can confirm the new device state after sending the request, this field would be false. If it's not possible to confirm if the request is successfully executed or to get the state of the device, set this field to true.
The following is an example for a refrigerator:
"availableToggles": [{
    "name": "cool",
    "name_values": [ {  "name_synonym": [ "supercool", "super cooling", ... ],
          "lang": "en"  }, … ]
  },
  {
    "name": "quiet",
    "name_values": [ {  "name_synonym": [ "noiseless", "silent", ...  ],
          "lang": "en"  }, … ]
  }
]

Sample SYNC Request and Response

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

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

const app = smarthome();

app.onSync((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      agentUserId: '1836.15267389',
      devices: [{
        id: '123',
        type: 'action.devices.types.DRYER',
        traits: [
          'action.devices.traits.Toggles'
        ],
        name: {
          defaultNames: ['AAA Super Dryer'],
          name: 'Washer',
          nicknames: ['clothes dryer']
        },
        willReportState: false,
        attributes: {
          availableToggles: [{
            name: 'sterilization',
            name_values: [{
              name_synonym: ['bio-clean', 'ultrasound'],
              lang: 'en'
            }]
          }, {
            name: 'energysaving',
            name_values: [{
              name_synonym: ['normal', 'medium', 'high'],
              lang: 'en'
            }]
          }]
        },
        deviceInfo: {
          manufacturer: 'AAA Corporation',
          model: '492134',
          hwVersion: '3.2',
          swVersion: '11.4'
        },
        customData: {
          fooValue: 74,
          barValue: true,
          bazValue: 'lambtwirl'
        }
      }]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
JavaResponse
@NotNull
@Override
public SyncResponse onSync(@NotNull SyncRequest syncRequest, @Nullable Map<?, ?> headers) {
  Payload payload = new Payload();
  payload.setAgentUserId("1836.15267389");
  payload.setAgentUserId("1836.15267389");
  payload.setDevices(new SyncResponse.Payload.Device[] {
      new SyncResponse.Payload.Device.Builder()
          .setId("123")
          .setType("action.devices.types.DRYER")
          .addTrait("action.devices.traits.Toggles")
          .setName(
              Collections.singletonList("AAA Super Dryer"),
              "Dryer",
              Collections.singletonList("clothes dryer")
          )
          .setWillReportState(true)
          .setAttributes(new JSONObject()

              .put("availableToggles", new JSONObject[]{
                  new JSONObject()
                      .put("name", "Sterilization")
                      .put("name_values", new JSONObject[] {
                      new JSONObject()
                          .put("name_synonym", new String[] {"Bio-clean", "Ultrasound"})
                          .put("lang", "en")
                  }),
                  new JSONObject()
                      .put("name", "Energy Saving")
                      .put("name_values", new JSONObject[] {
                      new JSONObject()
                          .put("name_synonym", new String[] {"normal", "medium", "high"})
                          .put("lang", "en")
                  })
              })
          )
          .setDeviceInfo("AAA Corporation", "492134", "3.2", "11.4")
          .setCustomData(new JSONObject()
              .put("fooValue", 74)
              .put("barValue", true)
              .put("bazValue", "lambtwirl")
              .toString()
          )
          .build()
  });
  return new SyncResponse(syncRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "agentUserId": "1836.15267389",
    "devices": [
      {
        "id": "123",
        "type": "action.devices.types.DRYER",
        "traits": [
          "action.devices.traits.Toggles"
        ],
        "name": {
          "defaultNames": [
            "AAA Super Dryer"
          ],
          "name": "Washer",
          "nicknames": [
            "clothes dryer"
          ]
        },
        "willReportState": false,
        "attributes": {
          "availableToggles": [
            {
              "name": "sterilization",
              "name_values": [
                {
                  "name_synonym": [
                    "bio-clean",
                    "ultrasound"
                  ],
                  "lang": "en"
                }
              ]
            },
            {
              "name": "energysaving",
              "name_values": [
                {
                  "name_synonym": [
                    "normal",
                    "medium",
                    "high"
                  ],
                  "lang": "en"
                }
              ]
            }
          ]
        },
        "deviceInfo": {
          "manufacturer": "AAA Corporation",
          "model": "492134",
          "hwVersion": "3.2",
          "swVersion": "11.4"
        },
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "lambtwirl"
        }
      }
    ]
  }
}
Validator

Device STATES

State Definition
currentToggleSettings Array of objects containing one element for each toggle defined on the object, as a boolean. One object per language. For example:
"currentToggleSettings": {
     "sterilization": true,
     "energysaving": false
}

Sample QUERY Request and Response

Is my dryer sterilization on?
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": 'action.devices.QUERY',
    "payload": {
      "devices": [{
        "id": "123",
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "foo"
        }
      }]
    }
  }]
}
Node.jsResponse
'use strict';

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

const app = smarthome();

app.onQuery((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      devices: {
        123: {
          on: true,
          online: true,
          currentToggleSettings: {
            sterilization: true
          }
        },
        456: {
          on: true,
          online: true,
          currentToggleSettings: {
            sterilization: false
          }
        }
      }
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
JavaResponse
@NotNull
@Override
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("on", true);
          put("online", true);
          put("currentToggleSettings", new HashMap<String, Object>() {{              put("sterilization", true);
          }});
      }});
      put("456", new HashMap<String, Object>() {{          put("on", true);
          put("online", true);
          put("currentToggleSettings", new HashMap<String, Object>() {{              put("sterilization", false);
          }});
      }});
  }});

  return new QueryResponse(queryRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "devices": {
      "123": {
        "on": true,
        "online": true,
        "currentToggleSettings": {
          "sterilization": true
        }
      },
      "456": {
        "on": true,
        "online": true,
        "currentToggleSettings": {
          "sterilization": false
        }
      }
    }
  }
}

Device COMMANDS

Command Parameters/Definition
action.devices.commands.SetToggles updateToggleSettings Object containing the new boolean value for each toggle that's being set.

Sample EXECUTE Request and Response

Turn on sterilization for the dryer.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "lambtwirl"
          }
        }],
        "execution": [{
          "command": "action.devices.commands.SetToggles",
          "params": {
            "updateToggleSettings": {
              "sterilization": true
            }
          }
        }]
      }]
    }
  }]
}
Node.jsResponse
'use strict';

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

const app = smarthome();

app.onExecute((body, headers) => {
  return {
    requestId: body.requestId,
    payload: {
      commands: [{
        ids: ['123'],
        status: 'SUCCESS',
        states: {
           currentToggleSettings: {
             sterilization: true,
             energysaving: false
           }
        }
      }]
    }
  };
});

// ...

exports.smarthome = functions.https.onRequest(app);
JavaResponse
@NotNull
@Override
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("currentToggleSettings", new HashMap<String, Object>() {{                  put("sterilization", true);
                  put("energysaving", false);
              }});
          }},
          null
      )
  });
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "currentToggleSettings": {
            "sterilization": true,
            "energysaving": false
          }
        }
      }
    ]
  }
}