Question - How do I find a device in a smart app based on a device preference value

Hopefully someone can help me. I have a list of devices in a smart app. The app acts as a web service endpoint. When I receive a call in the app, I want to send a command to a specific device. The device is identified by a preference - defined in the device handler.

I am relatively new to SmartThings and feel like I am missing something obvious.

Thanks

What’s the use case here? I can’t help with the app but depending on what you are trying to do you may be able to set up a CoRE piston to accomplish the same thing.

If by “I have a list of devices in a smart app” you mean that you have used an “input” preference and allowed the user to choose a list of devices, then you will have to search that list to match the device with some data from the endpoint call. For example, if the endpoint uses the device display name, you would do something similar to:

targetDevice = deviceList.find { it.displayName == endpointData.deviceName }

But, I agree, knowing more about your use case and what you are trying to accomplish may help the community answer better.

1 Like

Thanks all - let me explain the use case a bit more.

I wanted to explore a local integration with lightwaverf. I have created a virtual switch device handler. Each switch has a number preference that describes the room and device is.

On my local service I have a java process that listens to UDP broadcasts from the lightwaverf wifi link. This in turn calls a smartapp web end point. The smartapp has a user specified list of all the virtual switches.

This all works - however I need to select the switch (by the device preference room and device id) that corresponds to the web service call.

I can’t for the life of me find out how to access the device preference from the smartapp web service call.

OK, well within a device handler you would reference a preference value as follows:

settings.inputName

If settings were accesible from outside the context of the device (i.e. from a smartapp), you might be able to do something like the following:

targetDevice = deviceList.find { it.settings.inputName == "value we are looking for" }

However, I doubt this will work (I haven’t tried it though, so it’s worth a shot).

If not, then you would need to define a new command in your device handler to expose the value of the preference you are interested in. E.g.

In your device handler:

command "getPrefValue" // remember to declare it in the metadata

...

def getPrefValue() {
    return settings.inputName
}

Then in your smartapp:

targetDevice = deviceList.find( { it.getPrefValue() == "value we are looking for" } ) // find first one.
targetDevices = deviceList.findAll( { it.getPrefValue() == "value we are looking for" } )// find all.

HTH

1 Like

Many thanks - of course a getter is the obvious solution! Let me test out this and let you know. Once I have made some significant progress I will share the solution.

Thinking about it, there are also several other solutions you could try.
E.g. use the updated() method to:

  • Update the device’s displayName, label, or deviceNetworkId attributes. Though I think there could some issues with one or more of these being read-only after the device is created (?).

  • Publish a data value, e.g.

    updateDataValue("inputName",settings.inputName)

Not really sure which would be the best…