Smart Home ArmDisarm Trait Schema

action.devices.traits.ArmDisarm - This trait supports arming and disarming as used in, for example, security systems. For devices with multiple levels of security levels, these levels should be reported with the availableArmLevels attribute.

Device ATTRIBUTES

Attribute Definition
availableArmLevels

Object. Optional. Describes different levels of arming the device. If this attribute is not reported, the device only supports one level.

  • levels Array of objects, each denoting a different level of security.

    • level_name String. The internal name of the security level that is used in commands and states. This name can be non-user-friendly and is shared across all languages.
    • level_values contains level_synonym and lang.
      • level_synonym List of Strings. User-friendly name for the level in each supported language.
      • lang String. Supported language for the level synonym. See Supported languages.
  • ordered Boolean. If set to true, additional grammar for increase/decrease logic applies, in the order of the levels array. For example, Hey Google, increase my security level by 1, results in the Assistant determining the current security level and then increasing that security level by one. If this value is set to false, additional grammar for increase/decrease logic is not supported.

Example:

{
  "availableArmLevels": {
    "levels": [{
      "level_name": "L1",
      "level_values": [{
        "level_synonym": ["low security", "home and guarding", "level 1", "SL1"],
        "lang": "en"
      }]
    },
    {
      "level_name": "L2",
      "level_values": [{
        "level_synonym": ["high security", "away and guarding", "level 2", "away", "SL2"],
        "lang": "en"
      }]
    }],
    "ordered": true
  }
}

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.SECURITYSYSTEM',
        traits: [
          'action.devices.traits.ArmDisarm'
        ],
        name: {
          defaultNames: ['Maldives Security System'],
          name: 'security system',
          nicknames: []
        },
        willReportState: true,
        attributes: {
          availableArmLevels: {
            levels: [{
              level_name: 'L1',
              level_values: [{
                level_synonym: ['home and guarding', 'SL1'],
                lang: 'en'
              }, {
                level_synonym: ['zuhause und bewachen', 'SL1'],
                lang: 'de'
              }]
            }, {
              level_name: 'L2',
              level_values: [{
                level_synonym: ['away and guarding', 'SL2'],
                lang: 'en'
              }, {
                level_synonym: ['weg und bewachen', 'SL2'],
                lang: 'de'
              }]
            }],
            ordered: true
          }
        },
        deviceInfo: {
          manufacturer: 'sirius',
          model: '422',
          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.SECURITYSYSTEM")
          .addTrait("action.devices.traits.ArmDisarm")
          .setName(
              Collections.singletonList("Maldives Security System"),
              "security system",
              Collections.emptyList()
          )
          .setWillReportState(true)
          .setAttributes(new JSONObject()
              .put("availableArmLevels", new JSONObject()
                  .put("levels", new JSONObject[] {
                      new JSONObject()
                          .put("level_name", "L1")
                          .put("level_values", new JSONObject[] {
                              new JSONObject()
                                  .put("level_synonym", new String[] {"home and guarding", "SL1"})
                                  .put("lang", "en"),
                              new JSONObject()
                                  .put("level_synonym", new String[] {
                                      "zuhause und bewachen",
                                      "SL1"
                                  })
                                  .put("lang", "de")
                          }),
                      new JSONObject()
                          .put("level_name", "L2")
                          .put("level_values", new JSONObject[] {
                              new JSONObject()
                                  .put("level_synonym", new String[] {"away and guarding", "SL2"})
                                  .put("lang", "en"),
                              new JSONObject()
                                  .put("level_synonym", new String[] {"weg und bewachen", "SL2"})
                                  .put("lang", "de")
                          })
                  })
                  .put("ordered", true)
              )
          )
          .setDeviceInfo("sirius", "442", "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.SECURITYSYSTEM",
        "traits": [
          "action.devices.traits.ArmDisarm"
        ],
        "name": {
          "defaultNames": [
            "Maldives Security System"
          ],
          "name": "security system",
          "nicknames": []
        },
        "willReportState": true,
        "attributes": {
          "availableArmLevels": {
            "levels": [
              {
                "level_name": "L1",
                "level_values": [
                  {
                    "level_synonym": [
                      "home and guarding",
                      "SL1"
                    ],
                    "lang": "en"
                  },
                  {
                    "level_synonym": [
                      "zuhause und bewachen",
                      "SL1"
                    ],
                    "lang": "de"
                  }
                ]
              },
              {
                "level_name": "L2",
                "level_values": [
                  {
                    "level_synonym": [
                      "away and guarding",
                      "SL2"
                    ],
                    "lang": "en"
                  },
                  {
                    "level_synonym": [
                      "weg und bewachen",
                      "SL2"
                    ],
                    "lang": "de"
                  }
                ]
              }
            ],
            "ordered": true
          }
        },
        "deviceInfo": {
          "manufacturer": "sirius",
          "model": "422",
          "hwVersion": "3.2",
          "swVersion": "11.4"
        },
        "customData": {
          "fooValue": 74,
          "barValue": true,
          "bazValue": "lambtwirl"
        }
      }
    ]
  }
}
Validator

Device STATES

State Definition
isArmed Boolean. Indicates if the device is currently armed.
currentArmLevel String. Required if the availableArmLevels attribute is specified. If multiple security levels exist, indicates the name of the current security level.
exitAllowance Integer. Optional. Indicates the time, in seconds, the user has to leave the house when arming to a certain security level.

Sample QUERY Request and Response

User Is my security system armed?
Google Assistant The security system is armed to low security.
Request
{
    "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
    "inputs": [{
      "intent": "action.devices.QUERY",
      "payload": {
        "devices": [{
          "id": "123",
          "customData": {
            "fooValue": 74,
            "barValue": true,
            "bazValue": "foo"
          }
        }, {
          "id": "456",
          "customData": {
            "fooValue": 12,
            "barValue": false,
            "bazValue": "bar"
          }
        }]
      }
    }]
}
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,
          isArmed: true,
          currentArmLevel: 'L1'
        }
      }
    }
  };
});

// ...

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("isArmed", true);
          put("currentArmLevel", "L1");
      }});
  }});

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

Device COMMANDS

Command Parameters/Definition
action.devices.commands.ArmDisarm
  • arm Boolean. True when command is to arm. False to disarm.
  • cancel Boolean. True when command is to cancel the arm value.
  • armLevel String. The level_name to arm to.

Note the following:

  • If there are multiple security levels, and no armLevel is provided in the user query (for example, Hey Google, arm the security system), the Google Assistant responds Sorry, I'm not sure what level you want to arm to. Can you be more specific? to force the user to specify a level to arm.
  • The cancel value is related to the arm value. For example, if the user wants to cancel arming, arm needs to be true and cancel needs to be true. If the user wants to cancel disarming, arm needs to be false and cancel needs to be true.

Sample EXECUTE Request and Response

This example shows the case where there are no named security level attributes, just armed and not armed. In this case, it is optional to report back the currentArmLevel.

User Arm the security system.
Google Assistant Ok, arming the security system. You have 2 minutes to leave.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123"
        }],
        "execution": [{
          "command": "action.devices.commands.ArmDisarm",
          "params": {
            "arm": 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: {
          isArmed: true,
          exitAllowance: 120
        }
      }]
    }
  };
});

// ...

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

This example shows the case where there are named levels attributes.

User Set the security system to away and guarding.
Google Assistant Ok, arming the security system to away and guarding. You have 2 mins to leave.
Request
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123"
        }],
        "execution": [{
          "command": "action.devices.commands.ArmDisarm",
          "params": {
            "arm": true,
            "armLevel": "L1"
          }
        }]
      }]
    }
  }]
}
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: {
          isArmed: true,
          currentArmLevel: 'L1',
          exitAllowance: 120
        }
      }]
    }
  };
});

// ...

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

This example shows a user arming the security system and then issuing a command to cancel arming the system.

User Arm the security system.
Google Assistant Ok, arming the security system.
User Cancel arming.
Google Assistant Ok, canceling security.
Request 1
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123"
        }],
        "execution": [{
          "command": "action.devices.commands.ArmDisarm",
          "params": {
            "arm": true,
            "cancel": 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: {
          isArmed: 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("isArmed", false);
        }},
        null
    )
});
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "SUCCESS",
        "states": {
          "isArmed": false
        }
      }
    ]
  }
}
Request 2
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123"
        }],
        "execution": [{
          "command": "action.devices.commands.ArmDisarm",
          "params": {
            "arm": 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: {
          isArmed: true,
          exitAllowance: 120
        }
      }]
    }
  };
});

// ...

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

This example shows a user attempting to arm the security system with a pinNeeded two-factor authentication challenge. For more information, see Two-factor authentication.

User Arm the security system.
Google Assistant Can I have your security code?
User 333444
Google Assistant Ok, arming the security system.
Request 1
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123"
        }],
        "execution": [{
          "command": "action.devices.commands.ArmDisarm",
          "params": {
            "arm": 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: 'ERROR',
        errorCode: 'challengeNeeded',
        challengeNeeded: {
          type: 'pinNeeded'
        }
      }]
    }
  };
});

// ...

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"},
        "ERROR",
        null,
        "challengeNeeded"
    )
});
  return new ExecuteResponse(executeRequest.getRequestId(), payload);
}
JSONResponse
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "123"
        ],
        "status": "ERROR",
        "errorCode": "challengeNeeded",
        "challengeNeeded": {
          "type": "pinNeeded"
        }
      }
    ]
  }
}
Request 2
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123"
        }],
        "execution": [{
          "command": "action.devices.commands.ArmDisarm",
          "params": {
            "arm": true
          },
          "challenge": {
            "pin": "333444"
          }
        }]
      }]
    }
  }]
}
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: {
          isArmed: true,
          exitAllowance: 120
        }
      }]
    }
  };
});

// ...

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

Device ERRORS

  • alreadyInState The device is already armed or disarmed.
  • deviceTampered The device has been tampered with.
  • passphraseIncorrect The input passphrase is incorrect. Dialog will end.
  • pinIncorrect The input pin is incorrect. Dialog will end.
  • securityRestriction The system can’t give the user status information because it's armed to a high security level.
  • tooManyFailedAttempts There are too many failed attempts. Dialog will end.
  • userCancelled User said no when ackNeeded is required. Dialog will end.

See the full list of errors and exceptions.