Custom Capability and CLI Developer Preview

@cdikland and @DjAnu,

I changed my DTH for a light sensor to show lux instead of battery. Here’s how I got started. Just have a little (ok, a lot) of patience…

Thanks for the example but I cant even get past the first CLI command of
presentation:device-config:generate MYUID --dth --output=config.json

Which returns

[2020-09-27T11:23:12.441] [ERROR] login-authenticator - received “server_error” error when trying to authenticate
[2020-09-27T11:23:12.441] [ERROR] login-authenticator - Unexpected server error.

See the config notes in the first post.

1 Like

This is probably a stupid question, but if you have a custom capability with a command that doesn’t take any arguments and isn’t tied to an attribute, how do you add it to the Automation section of the capability presentation?

There isn’t a displayType that just takes the command name and I haven’t been able to find an example…

Update: It turns out the pushButton displayType on the device details screen isn’t displaying for that command either, but a different attribute in that custom capability is showing so I know the custom capability is being displayed and it’s not a caching issue.

Refresh and Momentary have presentations of the form:

"automation": {
    "conditions": [],
    "actions": [
        {
            "label": "___PO_CODE_SMARTTHINGS_DREAM_SAC_BUTTON_REFRESH_8",
            "displayType": "list",
            "list": {
                "alternatives": [
                    {
                        "key": "refresh",
                        "value": "___PO_CODE_SMARTTHINGS_DREAM_SAC_BUTTON_REFRESH_8",
                        "type": "active"
                    }
                ]
            }
        }
    ]
},

Of course, what the app actually does with the capability may be another story …

I’ve not been keeping up with events. Are automations now being implemented for custom capabilities?

I just want to use the standard button capability and create a capability with 4 buttons but I can’t understand the syntax. Does anyone have an example I can look at? This is the problem with this new CLI. By the time someone creates a DTH, all the ‘how to’ is hidden so there is no way for me to re-use/modify.

If you say so.
All I get is

Configuration

The CLI can be configured by creating a YAML file called config.yaml in the following location:

  • $HOME/.config/@smartthings/cli on OS/X or Linux
  • %LOCALAPPDATA%\@smartthings\cli on Windows

Authentication

The CLI supports an automatic login flow that pops up a browser window asking you to log in and give the CLI permission to access your account. The CLI will automatically request login as needed.

More details about configuration of the CLI can be found on the configuration documentation page.
I

The first screen I get is Allow “smartthings-cli” to access all your locations, devices and scenes Allow/Deny.

I click Allow and get the error I mentioned above. Never saw any login popup.

1 Like

I never had the “automatic login flow” work either. Just go to $HOME/.config/@smartthings/cli and create a config.yaml file. All it needs to contain is:

default:
token: “insert your personal access token here”

Good luck. I have spent hours working on this and managed to finally make a few things work. However, it has been incredibly frustrating. I agree and have personally experienced almost everything @carcuss said.

I was on vacation and came back and installed the latest CLI. Now I notice a new error. When I rung the presentation:device-config:generate, the resulting file has these two lines:

"presentationId": "blah",
"manufacturerName": "SmartThingsCommunity",

I cannot successfully run the device-config:create until I delete these lines. Not sure why they are there or why the next step won’t accept them but it is annoying.

Where do you this token from???

This is really crazy. I just want my custom temperature (Acurite Tower) gauges to work… Nothing fancy just simple numbers supplied by an external app.

You can generate a token from this link https://account.smartthings.com/tokens

1 Like

Did you create the original dth?

Thank you for posting that, but how did you generate it? The first version of the cli had some commands related to the built-in capabilities, but it looks like those were removed…

No, but I’d rather not have to go back and change all my presentations again once it’s implemented.

Well that got me a bit further but still no luck. The error I get now is: “Error: null profile specified. Check config.yaml for errors.”

I just used the CLI, which I have installed as st

st capabilities:presentation momentary -j

(I think - I often get my singulars and plurals wrong as the API is a little inconsistent).

I tried it with “SmartThingsCommunity.” and “smartthings.”, but never without the namespace, which explains why I couldn’t get it to work.

Have you found a way to view the device config of a built-in vid?

Did you include the "default: " line? That’s the name of the profile.
See https://github.com/SmartThingsCommunity/smartthings-cli/blob/master/packages/cli/doc/configuration.md for details.

Yes, I used your example of

default:
token: “the-token-by-st”

This raised the error I described above.

Following an example provided on the page you linked I also tried

default:
  indent: 4
  compactTableOutput: false
token: “the-token-by-st”

This raised the authentication error…

As you can get the presentation with …

st presentation generic-switch SmartThings -j

… you ideally ought to be able to do …

st presentation:device-config generic-switch SmartThings -j

… but that isn’t baked into the CLI yet (indeed it doesn’t look like it is in the SDK). In curl terms it is …

curl --header "Authorization: Bearer AUTHTOKEN" https://api.smartthings.com/v1/presentation/deviceconfig?"presentationId=generic-switch&mnmn=SmartThings"

That’s a bit of a hybrid as presentationId is the new vid, and manufacturerName is the new mnmn. I’d imagine any combination of old and new should work. The double quotes around the query string are just escaping the ampersand from the command line.

Oh, and in case anyone is wondering what the config looks like for generic-switch

{
  "type": "profile",
  "iconUrl": null,
  "dashboard": {
    "states": [
      {
        "component": "main",
        "capability": "switch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "sensor",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "actuator",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "relaySwitch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "healthCheck",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      }
    ],
    "actions": [
      {
        "component": "main",
        "capability": "switch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "sensor",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "actuator",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "relaySwitch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "healthCheck",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      }
    ]
  },
  "detailView": [
    {
      "component": "main",
      "capability": "switch",
      "version": 1,
      "values": [],
      "patch": [],
      "visibleCondition": null
    },
    {
      "component": "main",
      "capability": "sensor",
      "version": 1,
      "values": [],
      "patch": [],
      "visibleCondition": null
    },
    {
      "component": "main",
      "capability": "actuator",
      "version": 1,
      "values": [],
      "patch": [],
      "visibleCondition": null
    },
    {
      "component": "main",
      "capability": "relaySwitch",
      "version": 1,
      "values": [],
      "patch": [],
      "visibleCondition": null
    },
    {
      "component": "main",
      "capability": "healthCheck",
      "version": 1,
      "values": [],
      "patch": [],
      "visibleCondition": null
    }
  ],
  "automation": {
    "conditions": [
      {
        "component": "main",
        "capability": "switch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "sensor",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "actuator",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "relaySwitch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "healthCheck",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      }
    ],
    "actions": [
      {
        "component": "main",
        "capability": "switch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "sensor",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "actuator",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "relaySwitch",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      },
      {
        "component": "main",
        "capability": "healthCheck",
        "version": 1,
        "values": [],
        "patch": [],
        "visibleCondition": null
      }
    ]
  },
  "presentationId": "generic-switch",
  "manufacturerName": "SmartThings",
  "vid": "generic-switch",
  "mnmn": "SmartThings"
}
1 Like

Interesting to see, thanks. So that gives 5 buttons, what are the commands/actions triggered by them? Is it taken from the name of the capability in the action section?