Custom Capabilities

Custom capabilities are defined by the developer. A custom capability consists of a namespace and a capability name to uniquely identify it.

Namespace

A namespace is an identifier used to group a developer's capabilities together. A namespace is created for the developer when the first capability is created for the account. The namespace is generated based on the developer's account information and there is one namespace per account. The generated namespaces are unique and presented in a way that is easy to remember. A namespace might look something like perfectlife6617.

Capability

A capability is created under the developer's namespace. When accessing the capablility, it is referenced in the format namespace.capabilityName. This combination is referred to as the capabilityId. An example could be perfectlife6617.colorTemperature. Capabilities consist of attributes and commands.

Attributes

Attributes are used to describe the state of a capability and stores its status. In the following example, a light can be a range of color temperatures ranging from warm to cool. The schema that defines the color temperature attribute is JSON schema version 4.

"attributes": {
    "colorTemperature": {
        "schema": {
            "type": "object",
            "properties": {
                "value": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 30000
                },
                "unit": {
                    "type": "string",
                    "enum": [
                        "K"
                    ],
                    "default": "K"
                }
            },
            "additionalProperties": false
        },
        "required": [
            "value"
        ]
    }
}

Commands

Commands describe the functionality of a capability and what a device can do. In the color temperature example, the light can be set to a value representing how warm or cool it is.

"commands": {
    "setColorTemperature": {
        "arguments": [
            {
                "name": "temperature",
                "optional": false,
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 30000
                }
            }
        ]
    }
}

Creating a Custom Capability

When creating a custom capability, consider what statuses the capability can have (attributes) and what it can do (commands). When the first custom capability is created for an account, a unique namespace will be generated. In the following example, a capability for color temperature is created.

{
  "name": "Color Temperature",
  "attributes": {
    "colorTemperature": {
      "schema": {
        "type": "object",
        "properties": {
          "value": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30000
          },
          "unit": {
            "type": "string",
            "enum": [
              "K"
            ],
            "default": "K"
          }
        },
        "additionalProperties": false
      },
      "required": [
        "value"
      ]
    }
  },
  "commands": {
    "setColorTemperature": {
      "arguments": [
        {
          "name": "temperature",
          "optional": false,
          "schema": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30000
          }
        }
      ]
    }
  }
}

On successful creation, a message will be returned with the full capabilityId <namespace>.colorTemperature. Note that the version has defaulted to 1 and the status to proposed.

{
    "id": "<namespace>.colorTemperature",
    "version": 1,
    "status": "proposed",
    "name": "Color Temperature",
    "attributes": {
        "colorTemperature": {...}
    },
    "commands": {
        "setColorTemperature": {...}
    }
}

Using a custom capability

Custom capabilities are assigned to devices via device profiles. Anyone who knows the capabilityId and version has access to view details about the capability. However, there are no special permissions needed to use a custom capability on a device profile. Only the namespace owner is able to create capabilities under that namespace.

Capability Presentations

Overview

A capability presentation defines how a capability is rendered in the SmartThings app.

This guide describes the different areas of the app's UI and how they are expressed in the JSON schema.

The documentation for the API can be found here.

Creating a Capability Presentation

Capability presentations are created by using an existing capability ID and version. The presentation describes how the capability will look in the app, what actions and states are shown, as well as how conditions and actions are expressed in an automation.

Dashboard

The dashboard is the main view in the SmartThings app that shows a list of devices and their statuses.

State

You can use the State attribute to show the current status of the capability on a device. This can be a formatted string with an attribute value. For example the following: {{<attributeName>.value}}{{<attributeName>.unit}} could be used to describe a temperature result of 73F.

State Alternatives

"Alternatives" in the state model mean that we can replace an attribute value with a specific string when the value is equal to a test value. In the example below, instead of listing the play and pause values, the alternative provides something that makes more sense with the label in the state.

Actions

Dashboard actions have a display type and allow the user to initiate an action on a device from the dashboard. Allowed display types are the following: "pushButton", "toggleSwitch", "switch", "standbyPowerSwitch", "playPause", and "playStop". Display types are explained in more detail at: TODO - insert link to the display types in displayTypes.md

Dashboard Example

Here is an example of a dashboard that could describe a music player.

"dashboard": {
    "states": [
        {
            "label": "Player is {{playbackStatus.value}}",
            "alternatives": [
                {
                    "key": "playing",
                    "value": "playing"
                },
                {
                    "key": "paused",
                    "value": "paused"
                }
            ]
        }
    ],
    "actions": [
        {
            "playPause": {
                "command": {
                    "name": "setPlaybackStatus",
                    "play": "playing",
                    "pause": "paused"
                },
                "state": {
                    "value": "playbackStatus.value",
                    "play": "playing",
                    "pause": "paused"
                }
            }
        }
    ]
}

Detail View

The detail view is displayed when the user clicks on a device. The detail view requires a label and a displayType. Available display types for detail view include "toggleSwitch" "standbyPowerSwitch" "switch" "slider" "pushButton" "playPause" "playStop" "list" "textField" "numberField" "stepper" and "state". More details on available options for display types can be found in the SmartThings API.

Here is an abbreviated example of a music player that allows the user to start, pause, and control volume from the detail view.

"detailView": [
    {
        "label": "Pause",
        "displayType": "playPause",
        "playPause": {...}
    },
    {
        "label": "Stop",
        "displayType": "playStop",
        "playStop": {...}
    },
    {
        "label": "Volume",
        "displayType": "slider",
        "slider": {...}
    }
]

Automation

The automation section describes how the process for setting up an automation for a device will look.

Conditions

An automation condition is the if portion of an automation. This section determines how the user is able to choose a value for the automation to be triggered by. The condition under which an automation for this capability is triggered can be rendered with the following display types: "slider" "list" "numberField" "textField".

Actions

An automation action is the then portion of an automation. This section determines how the user is able to configure the effect of the automation once the condition is triggered. The action that an automation will take when triggered can be rendered with the following display types: "slider" "list" "numberField" "textField"

Automation Example

The following is an example for the music player that allows automations based on volume condition and play status. Here you can set up an automation based on volume while the actions allow the device to play or pause music in an automation.

"automation": {
    "conditions": [
        {
            "label": "Volume",
            "displayType": "slider",
            "slider": {
                "range": [
                    0,
                    11
                ],
                "step": 1,
                "value": "volume.value"
            }
        }
    ],
    "actions": [
        {
            "label": "Player actions",
            "displayType": "list",
            "list": {
                "command": "setPlaybackStatus",
                "alternatives": [
                    {
                        "key": "playing",
                        "value": "Playing"
                    },
                    {
                        "key": "paused",
                        "value": "Paused"
                    }
                ]
            }
        }
    ]
}

Language Support

Language support can be indicated with an array of strings. This indicates to the app which languages are available.

Display Types

Display types are used in capability presentations. They identify different visual representations that can be used to display a capability in the SmartThings app. Each view(dashboard, detail view, and automations) has a different set of display types available. This guide describes each of the display types by view.

The payload examples shown are valid; however, they are abbreviated to show the most common use-cases. Additional fields, such as alternative texts and groupings, can be found in the complete API documention found HERE.

Dashboard

pushButton

The pushButton display type will render a capability as a button on the dashboard. A command for the capability is required on a pushButton. It may have argument to be sent.

"pushButton": {
    "command": "setButton",
    "argument": "push"
}

Switches

There are multiple display options for switches. The display types available are switch, toggleSwitch, and standbyPowerSwitch. All switches follow a similar structure, but render differently in the app. A switch will be rendered with an on/off icon while a standbyPowerSwitch will have an on/standby icon. A toggleSwitch will show a sliding toggle. Below is an example for a switch that will display in the app as a toggle.

"toggleSwitch": {
    "command": {
        "name": "setSwitch",
        "on": "on",
        "off": "off"
    },
    "state": {
        "value": "switch.value",
        "on": "on",
        "off": "off",
        "label": "My Switch",
    }
}

Play Status

The options for rendering play status are playStop and playPause. Both have a similar payload structure for describing the state of a player. It is similar to a switch type, but will display as a play, pause, or stop symbol in the dashboard.

"playPause": {
    "command": {
        "name": "setPlaybackStatus",
        "play": "playing",
        "pause": "paused"
}   ,
    "state": {
        "value": "playbackStatus.value",
        "play": "playing",
        "pause": "paused",
        "label": "Music player: {{playbackStatus.value}}",
        "alternatives": [
            {
                "key": "playing",
                "value": "playing",
                "type": "active"
            },
            {
                "key": "paused",
                "value": "paused",
                "type": "inactive"
            }
        ]
    }
}

Detail View

Display types in the detail view will be rendered when a user clicks on the device card from the main dashboard. There are several additional display types available for the detailed views.

pushButton

See Dashboard pushButton.

Switches

See Dashboard Switches.

Play Status

See Dashboard Play Status.

Slider

A slider can be used to select a range of integer values. It can be useful for describing a temperature or volume.

"slider": {
    "value": "volume.value",
    "unit": "volume.unit",
    "command": "setVolume",
    "range": [
        0,
        100
    ],
    "step": 1
}

List

A list can be used to display and select a number of options available for a capability. The list elements are described in the alternatives section of the payload. The following is an abbreviated example of a list display type for a thermostat.

"list": {
    "command": {
        "name": "setThermostatMode",
        "alternatives": [
            {
                "key": "heat",
                "value": "Heat mode"
            },
            {
                "key": "cool",
                "value": "Cool mode"
            },
            {
                "key": "fan",
                "value": "Fan mode"
            }
        ],
        "supportedValues": "supportedThermostatModes.value"
    },
    "state": {
        "value": "thermostatMode.value",
        "alternatives": [
            {
                "key": "heat",
                "value": "Heat mode"
            },
            {
                "key": "cool",
                "value": "Cool mode"
            },
            {
                "key": "fan",
                "value": "Fan mode"
            }
        ]
    }
}

textField

A textField is used for text input and display. The view will have an Edit button for the user to input text which will popup an input screen with a field for text, Cancel, and OK buttons.

"textField": {
    "command": "setLightColor",
    "value": "lightColor.value"
}

numberField

If an integer value is used for input, consider using the numberField instead of textField. A min and max value can be specified.

"numberField": {
    "command": "setVolume",
    "value": "volume.value",
    "unit": "volume.unit",
    "range": [0, 100]
}

stepper

A stepper display type is useful for incremental input changes. Instead of having the user input a temperature, the user can increase/decrease the value with a +/- icon.

"stepper": {
    "command": "setVolume",
    "value": "volume.value",
    "step": 1,
    "range": [0, 100]
}

state

A capability with a state display type does not have an option to control the device with a command. This is information only communicated to the user of the SmartThings app about the capability's state.

"state": {
    "label": "PM2.5: {{fineDustLevel.value}}",
    "unit": "fineDustLevel.unit"
}

Automation

Automations have a more limited set of display types available as compared to the other views.

slider

See Detail View Slider.

list

See Detail View List.

numberField

See Detail View Number Field.

textField

See Detail View Text Field.