Custom Capability and CLI Developer Preview

@nayelyz I sent you updated screenshots and a VID. The dashboard state presentation active/inactive icons does not work in iOS but it works in Android.

That is one of the first questions I ever asked about this process, months back. I never did get an answer. It just seems to differ from reality.

Let’s consider replacing attribute "todayFlow", "string" with a custom capability called waterMeter.

When you do …

smartthings capabilities:create

… that creates your capability for you. You will see if you call it “Water Meter” it will give it an ID munged into camel case and you will be assigned a unique namespace. So your custom capability has the capabilityId that looks something like strangehorse12345.waterMeter.

In your DTH you should replace attribute "todayFlow", "string"with capability "strangehorse12345.waterMeter". That is job done. You continue to create events for the todayFlow attribute. It doesn’t need the namespace anywhere else.

What that paragraph in the docs seems to be suggesting is that you need to refer to the attributes as e.g. strangehorse12345.waterMeter.todayFlow. There is a stock capability that even makes a point of adding that format as well as todayFlow. I’ve queried that on more than one occasion without getting an explanation. It just seems to be unnecessary yet the ST developers seemed to think otherwise. Simply using todayFlow just seems to work fine.

You define a capability presentation to go with your capability, using either JSON or YAML. I haven’t worked with YAML so find JSON easier to read. The capability presentation defines how you want your capability to be presented in five places: the status text on the dashboard tile; as the action icon on the dashboard tile; as a tile on the device details page; as a condition in an Automation; as an action in an Automation. If you only have an attribute in your capability you wouldn’t need to define either of the actions. If you only have a command in your capability you wouldn’t need the dashboard status or the condition. You only have to define it for the places you might want to use it. A simple example for you might be:

{
    "dashboard": {
        "states": [
            {
                "label": "{{todayFlow.value}}",
                "alternatives": []
            }
        ],
        "actions": [],
        "basicPlus": []
    },
    "detailView": [
        {
            "label": "Today Flow or other text of your choosing",
            "displayType": "state",
            "state": {
                "label": "{{todayFlow.value}}",
                "alternatives": []
            }
        }
    ],
    "automation": {
        "conditions": [
            {
                "label": "Today Flow",
                "displayType": "list",
                "list": {
                    "alternatives": [],
                    "value": "todayFlow.value"
                }
            }
        ],
        "actions": []
    },
    "id": "strangehorse12345.waterMeter",
    "version": 1
}

Let’s say you have created that as presentation.json. You create the capability presentation by doing:

smartthings capabilities:presentation:create --input=presentation.json

That will prompt you for the capability you are creating the presentation for. You can skip that by using command line arguments.

That’s the capability side of things done. Now you need to address the device side of things. What you are ultimately creating is a device presentation which tells the app how it should display a device. You start with a device config, which is the user configurable parts of the presentation. This is another JSON file that defines which capabilities should be used in various places: which ones can be used for the dashboard status (the app only uses the first one); which one for the actions (ditto); which ones should be displayed on the details page; which ones are offered as Automation conditions; which ones are shown as Automation actions.

You can generate a default config file based on your DTH (hence why it needs to have been updated for the custom capability already). You use the ID of the DTH (shown in the URL in the IDE). Let’s put it in config.json.

smartthings capabilities:device-config:generate <DTH ID> --dth --output=config.json

You can edit that file as required, but at the moment you just need to make sure that if it has the lines presentationId and manufacturerName they are removed (they are new keys that will ultimately replace vid and mnmn that the API generates but can’t currently consume).

smartthings presentation:device-config:create --input=config.json

That will save your device config into the system, expand it out into a presentation (using the capability presentations), and assign a unique vid (another UUID) that identifies the config and presentation.

You then need to edit your DTH again, adding mnmn: "SmartThingsCommunity", vid: "<vid>" into the definition() parameters.

That is pretty much it, but you will need to bust the cache on your mobile app for any existing devices. You can just clear the cache, but I prefer to edit each device using the IDE, change the device name slightly, then update. That should suffice but sometimes you need to reload the app, and sometimes it is easier to create a new device from scratch.

If you are curious to see what the actual presentation file looks like, you can ask the CLI to show you it using smartthings presentation <vid> -j. Expect rather a long file as it will include all the i8n stuff for the stock capabilities and there are a lot of languages supported.

4 Likes

Hello @mvevitsis,

The Health Check capability has no presentation configured. Although you include it in the device presentation configuration, it won’t be added into the final presentation, you can verify this with the command:

smartthings presentation presentation-id -j

Only “Refresh” has a presentation, but this capability is not mandatory.

Hello @hongtat,

Thank you for your feedback. I was able to replicate the behavior of the device history you mentioned so I will proceed to report this to our engineering department.

1 Like

Hello @bangali,

You can go to the custom capabilities documentation, there are examples of the automation view configuration at the bottom of the page.
In the same document, you will find the State Display Type, this is used to display the capability’s attribute value. Here is an example of how to use it in the Detail View:

"detailView": [
        {
            "label": "Attr value",
            "displayType": "state",
            "state": {
                "label": "{{stringAttr.value}}"
            }
        }
    ]

About the device presentation creation, here is the document and in the API reference documentation you will find more details about its properties.

1 Like

thank you @nayelyz. figured it out earlier today by trial and error and got my custom capability working in both the new and old app here:

going to release the updated version to the community in the next couple of days :crossed_fingers:t3:

i have spent a bunch of time browsing the API reference doc. some additional info on how each section works like examples of how to use the visibleConditions would be great :slight_smile:

on the topic of visibleCondition from the API reference doc:

visibleCondition

This resource is shown in the UI when the condition is met. If visibleCondition is omitted, it is always visible. visibleCondition object might reference a different component, capability and version.

from here:

  1. what does component mean in that context?
  2. is it possible to compare a device attribute in that condition?

thank you.

how do i set the text size on displayType "state”? e.g. here on the Last Updated card:

@erickv or @nayelyz , Any idea when the stepper will start working again? This is frustrating.

Also, are you working on the new app loading time? It is ridiculously slow to get status on every device each time I open the app. Sometimes it doesn’t load at all and I have to kill it and restart. It’s painful to open it. I avoid it as much as possible.

Appreciate any feedback you can provide.

3 Likes

Not sure if it was asked here before, but do I have to create a new vid every time I change something?

I’m using the presentation:device-config:create -j -i=xyz.json command.

If you have changed the config file, then yes. If nothing has actually changed the vid will be the same.

Rather annoyingly, if you just change the order of the entries in the config you will not get a new vid, even though it can affect critical things like what is on the dashboard tile.

Equally frustrating is that the presentation is only dependent on changes to the config, not to the capability presentations it includes. So if you change how you want a capability to look you have to contrive a change to your config. The trick here is to avoid removing unnecessary entries in your config that don’t do anything. All those Actuator, Sensor and Health Check entries give you something to remove when you need to force an update.

2 Likes

Thank you for helping me again :smiley:
PS: Generating a config file from a existing DTH seems too work mostly :sweat_smile: I think it’s better then nothing :grinning:

i was getting this same error with a list type because i didn’t have the setter command defined as a function in my dth. once i added that function all went well.

Slider seems to have stopped calling set command as well, same as @guxdude reports. Slider worked last week, now set command is not called and gives a network error. Tried stepper and get the same result. Any ideas @nayelyz @erickv

3 Likes

Do the Android and iOS app updates rolling out the past couple of days contain any fixes for custom capabilities?

1 Like

52.23 onto UK S10 from Galaxy store delivery has a broken STHM , that needs fixing to begin with

1 Like

Hello @natec007,

We have replicated and reported this behavior to our engineering department, they are currently working to have it fixed as soon as possible. Thanks for your input.

1 Like

Hi @bangali,

The options to limit the number of characters displayed and configure the font size of the text in the device presentation are not available yet.
About your question of the VisibleCondition:

  1. The “component” property is used to specify in which component of the device is located the capability.
  2. VisibleCondition is used to hide/display a capability based on the comparison’s result.
    In the sample below, the doorControl capability should be displayed only if the attribute “vacationMode” of the capability “vacation“ equals to “disabled”
{
    "component": "main",
    "capability": "doorControl",
    "version": 1,
    "values": [],
    "patch": [],
    "visibleCondition": {
        "capability": "xxxxx.vacation",
        "version": 1,
        "component": "main",
        "value": "vacationMode.value",
        "operator": "EQUALS",
        "operand": "disabled"
    }
}
1 Like

OK. is there any docs on what properties will be available to set number of characters and font configuration? if there is would like to include them now so the presentation just works once they are available on the server side.

thanks for the clarification on component … i had forgotten about use of that.

on visibleCondition example assuming capability xxxxx.vacation has an attribute named vacationMode which is what is being compared here. question on this: can a capability have multiple attributes and if yes how would that be configured in the capability presentation and/or device config?

thank you.

So I decided to stop working on my custom DTH for a while with the hope that when I come back there may be some improvements/fixes. Not surprisingly, all the same issues seem to exist and possibly some new ones. Well any way, now when I try to run my batch file to build the capability/presentation/etc. I am getting the below error. Nothing has changed on my side and this use to work 2 weeks ago. Any ideas?

caught error Error: Request failed with status code 404: {
"requestId":"7892A94F-CDF3-4B66-BC78-701DC7574A97",
"error":{"code":"4030000"
,"message":"Only certain users are allowed to modify standard Capabilities","details":[]}}

Thanks,
Joe