How to issue commands to devices from your SmartApp

In this article, we go over how to issue commands to devices from a SmartApp, using the SmartThings API. commands are associated with a device’s capabilities, and represent ways to control or actuate a device.

NOTE

For more on developing SmartApps, see SmartApp basics.

The steps are as follows:

  1. Set command permissions
  2. Get OAuth token
  3. Obtain device ID of the device
  4. Construct POST request URL
  5. Construct POST request body

Set command permissions

When a user installs your SmartApp, they will select a device to control. You must first add the permissions to control the device in your SmartApp (AWS Lambda function or WebHook).

The OAuth scope for the SmartApp is specified in the INITIALIZE phase of the CONFIGURATION lifecycle event:

{
  "ConfigurationData": {

    "initialize": {
      "name": "On When Open/Off When Shut WebHook App",
      "description": "On When Open/Off When Shut App",
      "id": "app",
      "permissions": [
        "l:devices:*",
        "l:schedules",
        "r:devices:*",
        "x:devices:*"
       ],
      "firstPageId": "1"
    }
  }
}

Our example SmartApp asks the user to select a switch device. Permissions on selecting the switch device are set in the PAGE phase. Note that we also specify the device’s “switch” capability.

{
  "configurationData": {
    "page": {
      "pageId": "1",
      "nextPageId": null,
      "complete": true,
      "sections": [
        {
          "name": "Turn on/off this light...",
          "settings": [
            {
              "id": "lightSwitch",
              "name": "Which switch?",
              "description": "Tap to set",
              "type": "DEVICE",
              "required": true,
              "multiple": false,
              "capabilities": ["switch"],
              "permissions": [ "r" ,"x"]
            }
          ]
        }
      ]
    }
  }
}

Get OAuth token

After the SmartApp is installed, it will receive the INSTALL lifecycle from SmartThings. The JSON data returns the OAuth token as authToken. This string is required in your request header when you send a command request.

{
  "lifecycle": "INSTALL",
  "executionId": "b328f242-c602-4204-8d73",
  "executionId": "b328f242-c602-4204-8d73-33c48ae180af",
  "locale": "en",
  "version": "1.0.0",
  "installData": {
    "authToken": "string",
    "refreshToken": "string",
    "installedApp": {
      "installedAppId": "d692699d-e7a6-400d-a0b7-d5be96e7a564",
      "locationId": "e675a3d9-2499-406c-86dc-8a492a886494",
      "config": {

        "lightSwitch": [
          {
            "valueType": "DEVICE",
            "deviceConfig": {
              "deviceId": "74aac3bb-91f2-4a88-8c49-ae5e0a234d76",
              "componentId": "main"
            }
          }
       ...
       ]
     }
   }
 }
}

Obtain the device ID of the device

In the above JSON body, you can find the device ID of the device to control. Using the deviceId value, we can construct the URL request for a device command.

Construct POST request URL

Now we can construct our POST request to the SmartThings API. The request uses the below format:

https://api.smartthings.com/v1/devices/{deviceId}/commands

We replace {deviceId} with the value of deviceId in the JSON data.

https://api.smartthings.com/v1/devices/74aac3bb-91f2-4a88-8c49-ae5e0a234d76/commands

Construct POST request body

We are now ready to construct a command request to the device. Using the information in the capabilities reference, we construct the POST request body according to the API to execute commands on a device.

From the capabilities reference, we can see that the Switch capability has two commands without arguments: ‘off’ and ‘on’.

The POST request body looks like this:

{
  "commands": [
    {
      "component": "main",
      "capability": "switch",
      "command": "off",
      "arguments": [
      ]
    }
  ]
}

Note that the arguments field is empty. This represents a simple device command without an argument. When sending a command that does use arguments, the POST request body will depend on the argument’s data type. The below table summarizes the possible data types for command arguments.

Data Type Example Description
STRING “this is a string” Represents character strings
NUMBER 5, 10.6 The Number data type is a guideline indicating that a number should be expected, and not a specific type. Device Handlers contain the implementation of what kind of number object is actually returned.
VECTOR3 (x, y, z) This data type is a representation of x,y,z coordinates in space. Device Handlers contain the implementation of the actual data structure, but it is usually as a Map: [x: 0, y: 0, z: 0].
ENUM “one”, “two”, “three” The Enum data type is a static set of predefined String values that an Attribute can have, or that a command can accept as an argument.
DYNAMIC_ENUM “any”, “value” Much like the Enum data type, Dynamic Enum is a set of String values. However, the set is not static or predefined.
COLOR_MAP [hue: 50, saturation: 60] The Color Map is a Map specifically for the use of color control. As such, the Map should contain a Hue and a Saturation value.
JSON_OBJECT A standard JSON object. Device Handlers contain the implementation and thus should be consulted when looking for the JSON object structure.
DATE A Date, usually represented as a java.util.Date object.

For example, below is a POST request body using the Color Control capability. To send both the setHue and setSaturation commands, we have to specify value and unit in the arguments field. From the reference, we see that both commands have the NUMBER type.

{
  "commands": [
    {
      "component": "main",
      "capability": "colorControl",
      "command": "setHue",
      "arguments": [
        {
          "value": 25,
          "unit": "percent"
        }
      ]
    },
    {
      "component": "main",
      "capability": "colorControl",
      "command": "setSaturation",
      "arguments": [
        {
          "value": 50,
          "unit": "percent"
        }
      ]
    }
  ]
}

Here is a code example for executing the Switch command in Node.js:

function executecommandDevice(authToken, deviceid, command) {
    var baseUrl ="api.smartthings.com";
    var path = "/v1/devices/"+deviceid+"/commands";
    var token = "Bearer " + authToken;

    var body ='';

    var postData =
    {
       "commands": [
          {
           "component": "main",
           "capability": "switch",
           "command": command,
           "arguments": [
            ]
         }
        ]
     }
     var options = {
            host: baseUrl,
            path: path,
            method: 'POST',
headers :{"Authorization" : token, "content-type" : "application/json","accept" : "application/json"}
            };

     console.log("=========== start request command Device =================");
     var reqPost = https.request(options, function(res) {
        res.on('data', function(chunk) {
           body += chunk;
        });
        res.on('end', function() {
        console.log(body);
        console.log("statusCode: ", res.statusCode);
        console.log("=========== end request command Device =================");

      });
    });
    reqPost.write(JSON.stringify(postData));
    reqPost.end();
}