How to migrate your DTH to a custom capability

Introduction

As Device Type Handlers (DTHs) are phased out, you'll need to migrate from your existing DTHs to custom capabilities. This guide will take you through the migration process of migrating a DTH to a custom capability. After the migration is complete, your device will now use custom capabilities in place of a DTH to be controlled and displayed in the SmartThings app.

Here's a look at the migration process we will follow:

  1. Convert custom commands and attributes in our DTH to custom capabilities.
  2. Create custom capabilities through the SmartThings CLI
  3. Create a capability presentation through the SmartThings CLI for each new capability.
  4. Update your DTH to use your new custom capabilities
  5. Generate and create a Device Configuration based on the structure of your DTH
  6. Publish your DTH with updated keys to link your devices with the new presentations.

The last step of publishing your DTH will automatically update the devices installed with this DTH. This step can be repeated if you decide you would like to change the presentation of your device.

For more information on custom capabilities including additional migration tutorials, visit our SmartThings Community page here

Prerequisites:

It is also recommended that you familiarize yourself with the following concepts:

  • Custom Capabilities
  • Capability Presentations
  • Device Configurations

Designing your Custom Capabilities

When looking at your DTH, you should design your custom capabilities around encapsulating functionality and related data into logical units. In many cases, this will flow from the way your DTH makes use of custom commands and attributes.

Example: Gentle Wake Up Controller

Taking a look at the example DTH file, we can see that this DTH has one custom command and one custom attribute.

For our example, we will create a single custom capability called "Completion Percentage".

This capability will have one number type attribute called percentageComplete with a minimum of 0 and a max of 100, and a setter command, which is offered by the CLI during attribute creation.

Creating Custom Capabilities

Using the CLI, we can create our new capabilities.

$ smartthings capabilities:create

The CLI will ask you a series of questions about your new capability. In this example, we will set our capability name as Completion Percentage. When this is specified as the name, the ID will become <your namespace>.completionPercentage. Your namespace is automatically generated based on your user credentials. After the command succeeds, copy your capability ID for later use.

Creating Capabilities Presentations

Once we have our capability created, we will create the capability presentation.

Here is the payload for the capability presentation we are going to build for our new capability:

dashboard:
  states:
  - label: percent complete {{percentageComplete.value}}
detailView:
- label: Completion Status
  displayType: status
  status:
    state:
      label: "{{percentageComplete.value}}"
      alternatives:
      - key: '0'
        value: Not Started
      - key: '100'
        value: Complete
- label: Completion Percentage
  displayType: slider
  slider:
    range:
    - 0
    - 100
    step: 0.5
    command: setPercentageComplete
    attribute: percentageComplete
automation:
  conditions:
  - label: Completion Percentage
    displayType: slider
    slider:
      range:
      - 0
      - 100
      step: 0.5
      attribute: percentageComplete
  actions:
  - label: Completion Percentage
    displayType: slider
    slider:
      range:
      - 0
      - 100
      step: 0.5
      command: setPercentageComplete
id: connectvirtual42931.completionPercentage
version: 1

In the next sections, we will cover important design decisions that were made.

Example Capability Presentation: Dashboard View

In the dashboard view, we are going to place a formatted string that gives the status of the capability. We are not going to offer control for this particular capability from the dashboard, because the slider widget does not fit nicely on the dashboard card.

Example Capability Presentation: Detail View

In our detail view, we have 2 widgets. One will display the status of the capability, and one will be a slider control for the capability. Note that the slider has a min of 0 and a max of 100 to be consistent with the semantic "percentage" nature of the percentageComplete attribute.

Example Capability Presentation: Automation View

In our automation section, we are going to present a slider display type for both conditions and actions. The main difference between conditions and actions here is that our condition does not include the command field. Think of a condition as a state that will trigger the action, which corresponds to a command on the platform.

Once we have completed the creation of our capability presentation YAML file, we will use the CLI to post this presentation to the appropriate API.

TODO: LINK TO API

Updating DTH to use Custom Capabilities

Now that we have created our capability presentation, we are ready to make the first modification to our DTH. Begin by logging in to the graph IDE.

  • Log in to graph IDE.

  • Browse to My Device Handlers on the top navigation bar.

  • Edit the appropriate device type handler's code.

  • Remove custom commands and attributes which were encapsulated in your custom capability. Update direct references to your custom attributes and instead reference them through \{capabilityId\}.\{attributeName\}.

  • Save and publish your DTH

Make sure to grab the ID of your DTH, as it will be necessary for the next step. While you are viewing your DTH, the UUID in the URL bar will be your DTH ID.

Generate and Post Device Configuration

The next step is to create the configuration that will define how the device is displayed.

We have provided an endpoint that can generate a basic device configuration for you that will ensure that all of your capabilities show up in each of 3 main views (dashboard, automation, detail view). Most of the device configuration's purpose other than an abillity to show or hide capabilities from particular views is to override display defaults from the capability presentations it composes.

The CLI will make this call for generation of the device config, and here is what the API returned:

TODO: LINK API

mnmn: SmartThings
vid: 5e1d0bb6-be97-34a8-952b-e3fe18dac4cc
type: dth
dpInfo:
iconUrl:
dashboard:
  states:
  - component: main
    capability: switch
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: timedSession
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: connectvirtual42931.completionPercentage
    version: 1
    values: []
    visibleCondition:
  actions:
  - component: main
    capability: switch
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: timedSession
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: connectvirtual42931.completionPercentage
    version: 1
    values: []
    visibleCondition:
detailView:
- component: main
  capability: switch
  version: 1
  values: []
  visibleCondition:
- component: main
  capability: timedSession
  version: 1
  values: []
  visibleCondition:
- component: main
  capability: connectvirtual42931.completionPercentage
  version: 1
  values: []
  visibleCondition:
automation:
  conditions:
  - component: main
    capability: switch
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: timedSession
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: connectvirtual42931.completionPercentage
    version: 1
    values: []
    visibleCondition:
  actions:
  - component: main
    capability: switch
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: timedSession
    version: 1
    values: []
    visibleCondition:
  - component: main
    capability: connectvirtual42931.completionPercentage
    version: 1
    values: []
    visibleCondition:

You can choose what states to display for each view. For example, if you did no want to display the state configured for the dashboard view for the new capability connectvirtual42931.completionPercentage, we could omit its entry from the dashboard section of the device config file.

Once you are happy with your device configuration, use the CLI to post the YAML file to the API.

Note make sure that you keep the MNMN and the VID fields from your device config handy, because we will need to update your DTH to use these fields.

"mnmn": "SmartThings",
"vid": "5e1d0bb6-be97-34a8-952b-e3fe18dac4cc"

TODO: LINK API

Publish DTH with updated display keys

Now take the mnmn and vid from the returned device configuration and add them to your DTH and publish.

To update the vid and mnmn:

  • Log in to the IDE and edit your DTH.
  • In the definition near the top of the DTH file, either modify existing fields vid and mnmn, or add them.

Example

definition (name: "Gentle Wake Up Controller", namespace: "smartthings", author: "SmartThings", vid: "af1a244e-1816-493f-83f1-246d6491cecf", mnmn: "SmartThingsCommunity") {

The VID is a hashed value based on the contents of your device type and device configuration, so as you modify your device config, the value of this key may change. This is the key that the mobile app will use to find your device configuration.

Once your DTH is published with the final mnmn and vid from the returned device config, the devices using this DTH should already have been updated with the new keys. The device presentation will now be available for the SmartThings application to display.

The device presentation is the entity that the phone uses to display your device. The device configuration is a slimmed down input that the presentation service uses to construct the final presentation, which is a full description for how the devices of this type are to be displayed, including all of the capability presentation information and any values you've overridden in your device configuration.