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.