Determine if a Device supports a Command

I figure someone has asked this before but couldn’t seem to quite find the answer. Maybe it’s just a mental block of mine and the answer is obvious, dunno.

Anyhow, what I am trying to do is interrogate devices to make sure that they support a command before my app calls the command. I’m dealing with some thermostats but I figure that there are probably lots of potential devices that are similar but don’t support the same command set or the DTH wasn’t written to a suggested spec. The reason is that if you try and execute a command on say a group of devices then you get an error saying that device X doesn’t support the command and then app execution stops.

I couldn’t figure out any way to do something similar to the Elvis operator “?”. Given that its a group of devices, I wanted to find a way to do this on all the devices without going through each one but I didn’t find anything helpful there either. However, I did find in the docs that you could of course list the commands supported:
https://docs.smartthings.com/en/latest/ref-docs/command-ref.html

I then created some simple code to look at each device:

thermostats.each {
    cmds = it.supportedCommands
    log.debug "\nCommands: ${it.supportedCommands}\nResult: ${cmds.contains("resumeProgram")}\nFind: ${cmds.find {element -> element == "resumeProgram"}}"
}

But this seems to fail always, for instance the logs for the above on one of the devices that does support the desired functionality:

Commands: [refresh, setHeatingSetpoint, setCoolingSetpoint, off, heat, emergencyHeat, cool, setThermostatMode, fanOn, fanAuto, fanCirculate, setThermostatFanMode, auto, setSchedule, ping, generateEvent, resumeProgram, switchMode, switchFanMode, lowerHeatingSetpoint, raiseHeatingSetpoint, lowerCoolSetpoint, raiseCoolSetpoint, poll]
Result: false
Find: null

My questions are basically:

  1. Any ideas to do this in a more elegant fashion?
  2. If not, what groovy oddity am I forgetting about that makes the search always fail above?

Thanks!

Try this:

log.debug "Find: ${cmds.find {element -> element.name == "resumeProgram"}}"

Yep, that did it. Still not sure why contains() seems to not work but anyhow using this in an if statement to check not null works. Thanks!

I think contains isn’t working because supportedCommands returns an array of Command objects. You have to then call getName to use the name of each Command as a string. I’m glad it’s working!

I just stumbled upon the hasCommand() function near the bottom of the device reference page. It looks like it would be the more elegant approach to this. Something like this should return a boolean:

it.hasCommand("resumeProgram")
1 Like

Good grief. I can’t believe all the ways I searched for variants of “check if device supports command” that never returned that. I also can’t believe I read portions of that page too without noticing that. Seems like exactly what I was hoping for. Thanks!!

1 Like