Smart Home StartStop Trait Schema

action.devices.traits.StartStop - This trait covers starting and stopping the device.

Starting and stopping a device serves a similar function to turning it on and off. Devices that inherit this trait function differently when turned on and when started. Certain washing machines, for instance, are able to be turned on and have their settings modified before actually starting operation.

Unlike devices that simply have an on and off state, some devices that can start and stop are also able to pause while performing an operation. Devices that can pause will cease operation, but upon resume will continue in the same state as when they were paused. Unpausing differs from starting/restarting as regardless of the current state of the device, this will begin operation from the beginning.

Some devices may support running in certain zones. For example, a sprinkler may have various watering zones and support the ability to water particular zones separately, while a vacuum may support cleaning specific rooms.

Device ATTRIBUTES

Attribute Definition
pausable Boolean indicating whether the device can be paused during operation.
availableZones Required if the devices supports zones. Array of strings indicating supported zone names. Strings should be localized as set by the user. This list is not fixed, users can report whatever names they want.

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.WASHER',
        traits: [
          'action.devices.traits.StartStop'
        ],
        name: {
          defaultNames: ['Sirius Cybernetics Corporation Washer 3421'],
          name: 'Washer',
          nicknames: ['clothes washer']
        },
        willReportState: false,
        attributes: {
          pausable: true,
          availableZones: ['kitchen', 'living room', 'master bedroom']
        },
        deviceInfo: {
          manufacturer: 'AAA Cybernetics Corporation',
          model: '233451',
          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.setDevices(new Device[] {
      new Device.Builder()
          .setId("123")
          .setType("action.devices.types.WASHER")
          .addTrait("action.devices.traits.StartStop")
          .setName(
              Collections.singletonList("Sirius Cybernetics Corporation Washer 3421"),
              "Washer",
              Collections.singletonList("clothes washer")
          )
          .setWillReportState(true)
          .setAttributes(new JSONObject()
              .put("pausable", true)
              .put("availableZones", new String[] {"kitchen", "living room", "master bedroom"})
          )
          .setDeviceInfo("AAA Cybernetics Corporation", "233451", "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.WASHER",
        "traits": [
          "action.devices.traits.StartStop"
        ],
        "name": {
          "defaultNames": [
            "Sirius Cybernetics Corporation Washer 3421"
          ],
          "name": "Washer",
          "nicknames": [
            "clothes washer"
          ]
        },
        "willReportState": false,
        "attributes": {
          "pausable": true,
          "availableZones": [
            "kitchen",
            "living room",
            "master bedroom"
          ]
        },
        "deviceInfo": {
          "manufacturer": "AAA Cybernetics Corporation",
          "model": "233451",
          "hwVersion": "3.2",
          "swVersion": "11.4"
        },
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "lambtwirl"
        }
      }
    ]
  }
}
Validator

Device STATES

State Definition
isRunning Boolean. Indicates if the device is currently in operation.
isPaused Boolean. Indicates if the device is explicitly paused. Note that paused implies isRunning is false but can be resumed.
activeZones Optional. Array of strings indicating zones in which the device is currently running, from list of availableZones.

Sample QUERY Request and Response

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: {
          online: true,
          isPaused: true,
          isRunning: false,
          activeZones: ['kitchen']
        }
      }
    }
  };
});

// ...

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("online", true);
          put("isPaused", true);
          put("isRunning", false);
          put("activeZones", new String[] {"kitchen"});
      }});
  }});

  return new QueryResponse(queryRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "devices": {
      "123": {
        "online": true,
        "isPaused": true,
        "isRunning": false,
        "activeZones": [
          "kitchen"
        ]
      }
    }
  }
}

Device COMMANDS

Command Parameters/Definition
action.devices.commands.StartStop

start Boolean. True when command is to start, false to stop.

zone Optional. String indicating zone in which to start running (stop in zone not supported).

action.devices.commands.PauseUnpause

pause Boolean. True when command is to pause, false to unpause.

Sample EXECUTE Request and Response

Start the washing machine.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "sheepdip"
          }
        }],
        "execution": [{
          "command": "action.devices.commands.StartStop",
          "params": {
            "start": 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: {
          isRunning: true,
          isPaused: 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("isRunning", true);
            put("isPaused", false);
        }},
        null
    )
});
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "isRunning": true,
          "isPaused": false
        }
      }
    ]
  }
}
Vacuum the kitchen.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "sheepdip"
          }
        }],
        "execution": [{
          "command": "action.devices.commands.StartStop",
          "params": {
            "start": true,
            "zone": "kitchen"
          }
        }]
      }]
    }
  }]
}
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: {
          isRunning: true,
          isPaused: false,
          activeZones: ['kitchen']
        }
      }]
    }
  };
});

// ...

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("isRunning", true);
            put("isPaused", false);
            put("activeZones", new String[] {"kitchen"});
        }},
        null
    )
});
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "isRunning": true,
          "isPaused": false,
          "activeZones": [
            "kitchen"
          ]
        }
      }
    ]
  }
}
Pause the vacuum.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "sheepdip"
          }
        }],
        "execution": [{
          "command": "action.devices.commands.PauseUnpause",
          "params": {
            "pause": 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: {
          isRunning: true,
          isPaused: true
        }
      }]
    }
  };
});

// ...

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("isRunning", true);
          put("isPaused", true);
        }},
        null
    )
});
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "isRunning": true,
          "isPaused": true
        }
      }
    ]
  }
}

Device ERRORS

See the full list of errors and exceptions.

unpausableState - The user tried to pause a device with the pausable trait, but the device is in some state that it cannot be paused.