Custom Capability and CLI Developer Preview

So I thought I got it to work. Realized in one of my custom capabilities I made a typo. Changed that one item and did a capabilities presentation update via the CLI. Lost the custom items in detail view.

So did the steps I outlined above, still didn’t work…but something interesting happened. When I view the device handler details in the IDE it shows my custom capabilities. However, when I make an instance of that device and look at it’s details in the IDE it shows non CLI attributes that are no longer in my DTH code…WTF, I have deleted and renamed my DTH multiple times and it has not had these attributes for some time, where are they coming from? And why is there a mismatch between the device handler and the actual device that is created?

Also. now when I recreate the device config I get a VID that I have seen before…from some time ago. I believe that is related…how can I force a VID change?

There are severe caching issues making it near impossible for developers in the new space right now.

6 Likes

Hello @crazylukedog,

For the capability presentation of the display type List you need to make sure that it accomplishes these points:

  • Use the attribute name of the capability to show the current value.
  • Use the same alternatives in the “state” and “command” properties

You can check the sample below:

{
    "dashboard": {
        "states": [
            {
                "label": "Source: {{sourceNum.value}}"
            }
        ]
    },
    "detailView": [
    {
        "label": "Source",
        "displayType": "list",
        "list": {
            "command": {
                "name": "setSourceNum",
                "alternatives": [
                    {
                        "key": "1",
                        "value": "Input 1"
                    },
                    {
                        "key": "2",
                        "value": "Input 2"
                    },
                    {
                        "key": "3",
                        "value": "Input 3"
                    },
                    {
                        "key": "4",
                        "value": "Input 4"
                    },
                    {
                        "key": "5",
                        "value": "Input 5"
                    },
                    {
                        "key": "6",
                        "value": "Input 6"
                    }
                ]
            },
            "state": {
                "value": "sourceNum.value",
                "alternatives": [
                    {
                        "key": "1",
                        "value": "Input 1"
                    },
                    {
                        "key": "2",
                        "value": "Input 2"
                    },
                    {
                        "key": "3",
                        "value": "Input 3"
                    },
                    {
                        "key": "4",
                        "value": "Input 4"
                    },
                    {
                        "key": "5",
                        "value": "Input 5"
                    },
                    {
                        "key": "6",
                        "value": "Input 6"
                    }
                ]
            }
        }
    }
    ],
    "id": "xxxxxx.sourcelist",
    "version": 1
    }

To visualize the presentation configuration, use the following command:
smartthings presentation VID -j

Is there going to be a fix for this bug anytime soon?

Thank you. I saw that some people were having troubles with that as well as some bugs (not sure if those are resolved). So to avoid the trouble I did this:

{
"dashboard": {
	"states": [
		{
			"label": "Source: {{sourcelist.value}}",
		}
	],
    "actions": [],
    "basicPlus": []
},
"detailView": [
	{
		"label": "Source",
		"displayType": "list",
		"list": {
			"state": {
				"label": "Source",
				"value": "sourcelist.value",
				"alternatives": [
					{
						"key": "1",
						"value": "1" 
					},
					{
						"key": "2",
						"value": "2" 
					},
					{
						"key": "3",
						"value": "3" 
					},
					{
						"key": "4",
						"value": "4" 
					},
					{
						"key": "5",
						"value": "5" 
					},
					{
						"key": "6",
						"value": "6" 
					},
				]
			},
			"command":	{
				"name": "setSourceNum",
				"alternatives": [
					{
						"key": "1",
						"value": "1" 
					},
					{
						"key": "2",
						"value": "2" 
					},
					{
						"key": "3",
						"value": "3" 
					},
					{
						"key": "4",
						"value": "4" 
					},
					{
						"key": "5",
						"value": "5" 
					},
					{
						"key": "6",
						"value": "6" 
					},
				]
			},
		}
	}
],

However, whenever I try to access the values of these capabilities in my app it does not work (states it is a null object). Interestingly enough though, when I move the custom capability with a slider it will call the command but not update any values. However, it seems that the devices created with the handler have different presentations. Why are they different and how can I resolve? Also, it messes up the code because I am referencing items that don’t exist. Or I can interestingly access items that aren’t declared anywhere in the code. Uh. Example:

Device Handler Page:

A device created with that Handler:

Hi @crazylukedog,

You can edit your DTH and send an event to initialize the capability when the device is installed, use the Capability’s attribute name for the event name. For example:

sendEvent(name: "sourceNum", value: "1")

Thank you. I believe I have figured out how to do some of this. I have gotten the custom capability squaresmoke31960.volume to work by initializing it via a sendEvent(). Thank you.

However, for squaresmoke31960.sourcelist (using the definition of my list you’ve helped me with) and initializing it via a sendEvent I only get a cloud with a line through it in the app. Not sure what to do with that, I feel like my presentation file for the list is still incorrect. (I did realize I was using “states” instead of “state” and since I made that update it hasn’t really worked.

Thank you for all the help, I am picking up groovy and this new CLI stuff at the same time, it has been one heck of a learning curve (especially with the CLI stuff, hard to differentiate stuff). I appreciate it.

Thank @nayelyz for all of your help. I finally got what you mean by the attribute in the sendEvent as I have figured that out for a custom capability with a slider. After creating the device I send the following sendEvent command per your recommendation:

sendEvent(name: “sourceNum”, value: “1”)

However, I still can’t seem to get it with the list. Here is some info:
The Capability:

{
    "id": "XXXXXXXXXXX.sourcelist",
    "version": 1,
    "status": "proposed",
    "name": "sourcelist",
    "attributes": {
        "sourceNum": {
            "schema": {
                "type": "object",
                "properties": {
                    "value": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 6
                    }
                },
                "additionalProperties": false,
                "required": [
                    "value"
                ]
            },
            "setter": "setSourceNum",
            "enumCommands": []
        }
    },
    "commands": {
        "setSourceNum": {
            "name": "setSourceNum",
            "arguments": [
                {
                    "name": "sourceNum",
                    "optional": false,
                    "schema": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 6
                    }
                }
            ]
        }
    }
}

The capability presentation:

{
    "dashboard": {
        "states": [
            {
                "label": "Source: {{sourcelist.sourceNum}}"
            }
        ],
        "actions": [],
        "basicPlus": []
    },
    "detailView": [
        {
            "label": "Source",
            "displayType": "list",
            "list": {
                "command": {
                    "name": "setSourceNum",
                    "alternatives": [
                        {
                            "key": "1",
                            "value": "1",
                            "type": "active"
                        },
                        {
                            "key": "2",
                            "value": "2",
                            "type": "active"
                        },
                        {
                            "key": "3",
                            "value": "3",
                            "type": "active"
                        },
                        {
                            "key": "4",
                            "value": "4",
                            "type": "active"
                        },
                        {
                            "key": "5",
                            "value": "5",
                            "type": "active"
                        },
                        {
                            "key": "6",
                            "value": "6",
                            "type": "active"
                        }
                    ]
                },
                "state": {
                    "value": "sourcelist.sourceNum",
                    "alternatives": [
                        {
                            "key": "1",
                            "value": "1",
                            "type": "active"
                        },
                        {
                            "key": "2",
                            "value": "2",
                            "type": "active"
                        },
                        {
                            "key": "3",
                            "value": "3",
                            "type": "active"
                        },
                        {
                            "key": "4",
                            "value": "4",
                            "type": "active"
                        },
                        {
                            "key": "5",
                            "value": "5",
                            "type": "active"
                        },
                        {
                            "key": "6",
                            "value": "6",
                            "type": "active"
                        }
                    ]
                }
            }
        }
    ],
    "id": "XXXXXXXXXXXXX.sourcelist",
    "version": 1
}

I feel I am getting so close to getting a list to work but also feel like I am missing some fundamental concept. Any ideas what I am doing wrong here?

Hi @crazylukedog,
Have you checked the payload of this device when you make a request to get the devices list?
There you can see its presentation ID, capabilities and also, verify the configuration. For example:

{
    "deviceId": "xxxx-xxxx-xxxx-xxxx",
    "name": "device_name",
    "label": "device_label",
    "manufacturerName": "SmartThingsCommunity",
    "presentationId": "xxxx-xxxx-xxxx-xxxx",
    "locationId": "xxxx-xxxx-xxxx-xxxx",
    ...
}

Yes I did. So I realized that my attribute names were messed up and a bunch were confusing for me.

It seems difficult to know when and how to reference a capabilities attribute and commands.

Ex 1: sendEvent(name: “attributename”, value: “ABC”)
Ex 2: capability.attributename
Ex 3: capabilityname.attributename.value
Ex 4: attributename.value
Ex 5: namespace.capability

This caused a lot of problems in my code as I was mixing them up in all kinds of weird ways. If I had started with the classic tool some of this may have come more naturally, not sure. This was compounded by wacky issues with caching (as you are aware is a problem).

It does seem odd that in my HTD I can reference a capabilities attribute with strictly the attribute name (which feels out of scope, like a global variable almost, I can also see potential naming problems). But then inside a capabilities presentation or device config I have to explicitly spell out the full capability or attribute even though it is within it’s own presentation json.

So, all in all, I finally got it working. I added and removed a refresh capability in different views to generate unique vid’s so that my testing could be more efficient. A lit of trial and error and a lot of reading this forum for clues that were difficult to find elsewhere or in documentation. It may also be a good idea to pin known bugs and “in process of improvement” items up front in the tutorial post.

Regardless, everyone here has been super helpful and I am sure all the details will get pinned down. I know that I am super excited to get my HTD MCA66 audio amplifier connected with the help of Smartthings via a server on a raspberry pi connected to the amplifier via a serial cable. That seems insane to me! With that, this is a new home and everything for audio/video (including a 4x8 HDBaseT Matrix and 2 Surround sound receivers) is connected to Smartthings, my harmony remotes, and action tiles on tablets. Super stoked and keep on keeping on…you all have your work cut out for you. Community has been awesome so far too, thank you.

Yes, I suspect that is an unfortunate design ‘feature’ of the legacy environment.

In the stock Smart Weather Station Tile Thingy Or Whatever It Is Called, the custom events are duplicated, using both name: 'attributeId' and name: 'namespace.capabilityId.attributeId'. I have queried a few times what we are to make of a stock DTH doing this, as on the face of it either the ST engineers know something we don’t, or they don’t know something we do. Answer came there none.

Not in a capability presentation you don’t. Your scope, as it were, is the namespace.capabilityId so you just use the attributeId.

In a device config, yes you need to use the namespace.capabilityId for custom capabilities.

@nayelyz I tried using the developer workspace tool to create a custom device profile, unfortunately that’s also partly broken. I included 12 capabilities using that tool:

  1. “Temperature Measurement” doesn’t render in the UI. I’ve checked that the attribute temperature is initialized in the DTH correctly but it doesn’t show up in the Detail view.
  2. The UI Display part is broken, I selected Smoke Detector for State and no action, and nothing is rendering on the Dashboard, infact it’s stuck showing Checking status in the app

However it does seem to work through the custom CLI.

Hi @RBoy,

I was able to replicate the case you described. However, If you create the device presentation configuration using the DTH ID and use that generated VID, the device UI is correct.

I will check if a presentation created with a device profile can be implemented this way.

1 Like

Hi @RBoy,

The device presentations generated must be used for the same origin, this means, profile presentations are used only in device profiles, and DTH presentations are used only in DTH.
You can see that even if both (device profile and DTH) are using the same capabilities, the generated presentation ID is different.

Is there a noddy guide to all the namings and explanations of stuff? I find it incredibly difficult to follow with so many minute differences between things!

What is a profile presentation compared to a capability presentation compared to a DTH presentation? I know there is this FAQ/guide page, but then there are tons of topics covered here that aren’t mentioned there, such as mnmn and mnmm

2 Likes

Incidentally, if somebody has already created a presentation for say a text box or a button, can you paste the code here, or can it be reused in other device handlers without any changes? If I took the presentation for one text box of somebody else’s DTH, could I just change one line in my DTH to use the existing presentation?

1 Like

Even if you have a reusable capability with a presentation you’ll need to create a custom configuration file to display it on the UI for your DTH. The platform doesn’t render custom capabilities (proposed) automatically the way it does with stock (active) capabilities. Feel free to PM me for more details.

1 Like

Oh boy… I’m not even sure where to start.

I’ve been on the platform for about three years and have written a bunch of custom DTHs to integrate my (non-smart) alarm system and various automations to automate just about everything I care about. I’ve been extremely happy with the platform… until now!

Migrating my custom work to the new app is just about the most frustrating experience I’ve had – and I’ve been in the tech industry for 20+ years and have architected/oversaw/executed on several large scale technology migrations so I’ve seen a lot of frustrating things before.

First off, the development process is horrendous. If someone has a better process, please enlighten me. This is what I’ve been able to cobble together for myself through trial and error but the development-feedback loop is painful. There’s just too much “run this command, edit this file, run this other command, copy this value into a browser and click some buttons” type actions for this to be efficient. This is what I’ve found as a reasonably reliable workaround to the seemingly arbitrary app refresh issues:

  1. Update the capability’s presentation.
  2. Update DTH with different combinations of capabilities to force generation of a new vid & publish.
  3. Generate a device presentation config from DTH and move/delete elements as needed.
  4. Create a new presentation config to get a new vid.
  5. Update the DTH with the new vid & publish.
  6. Update the device name and/or device type.
  7. Open the app and my device is (usually) updated to reflect my presentation changes.

This was somewhat reliable and I was able to make some progress. But over the last day or so, this process stopped working for me. No matter how I changed up the combinations of capabilities or updated the device name and type, I can’t seem to force a refresh. Using the CLI to pull up the device definition shows a few things:

  • When I update the device name and device type, the name and dth sections in the response does indeed update correctly as expected.
  • The presentationId is stuck with some old vid and doesn’t reflect the one used in the DTH. This results in the app not showing the latest capabilities.
  • The components section does not always (but does change sometimes but I’ve yet to discern a pattern to this) update to reflect the capabilities defined in the DTH. This results in a mismatch between the device presentation that the vid is pulling up and the underlying components so the capabilities without the corresponding component present will show up with the disabled cloud icon in the card.

Second, even when I get things to show up properly everything is functionally broken even if they may appear visually correct:

  • The schema for detailView indicates that an array of objects is accepted but only the first component ever shows up. I’ve resorted to breaking my capability into multiple capabilities just to get multiple cards to render. Not sure why the JSON payload takes an array if only one component is ever intended to be displayed in the app per capability.
  • Likewise, the actions array in the dashboard only shows the first item. I was expecting multiple items to show up (eg. two switches if I had two actions defined) since the schema for the payload specifies that an array of objects is valid.
  • The pushButton component doesn’t work. It shows up but clicking on it results in the circular spinner but the command is never executed.
  • The toggleSwitch also doesn’t work. It renders fine and displays the alternative text as expected but pressing on the button to toggle results in a network error popup.
  • The numberField does not work. I can bring it up and enter in some numbers but when I try and accept the values entered, the corresponding command does not get triggered.
  • The list component does work and triggers the correct command with the expected parameter. But it also doesn’t quite work in the way that I expected it to. I’d assumed that the commands mapped to the popup list of actions that the user can select and the states mapped to the label displayed in the card. In my particular case, I have more states that can be displayed than I have actions that can be executed so my command list is only a subset of my state list. The popup does indeed work as I’d assumed but the label seemed to use the alternatives defined with the commands and not the state. So for values that do not have a matching alternative in the command list, they show the raw value even though the state alternatives do have matching values. How do we decouple the label from the commands?
  • Child devices – what is the equivalent of childDeviceTiles to have child devices show up as part of the parent device’s UI? Child devices show up as separate standalone devices as well as being listed as child devices.

With a few weeks left before the classic app is sunset, I have no idea how I’ll be able to get all my custom devices migrated over to the new app. As I said before, I’d been pleased with smartthings up to now and it’s been running reliably for a long time but with the classic app going away, I’m going to be left with integrations and automations that won’t work anymore. It doesn’t sound like I’m alone in this boat since this thread seems rife with documented issues.

How on earth is the classic app supposed to sunset successfully within this timeline when it appears that many of us are struggling with even getting basic functionality working? Is the sunset date going to be pushed back? It feels like I’m working with a pre-beta product at this point and not anything ready for primetime.

17 Likes

I am not an IT guy but I had been able to integrate all the devices I have to ST that includes several custom DTH, Echo Speaks, Rule Machine etc. Now this CLI preview is getting over my head. I cant find a step by step guide to do it either. All I need is to to show the Value I want on device icon in the new ST APP.

For example on Aeon energy meter I want to see current instead of watts when I open the app. I was able to do all this easily on Classic App. New is very messy and I can’t find anyway to do it. Can someone please help me with this ??

1 Like

Basically want the same thing. My custom DH’s are simply showing a data value it gets from either the device or external apps. Worked like a charm in the Classic app. Seems like a whole lot of headaches to convert…