Is devices.findAll() implemented?

I am trying to implement something like this.

def c4dev = devices.findAll { it.name.contains("C4") }
c4dev.each {
	log.debug "Found device: ID: ${it.id}, Label: ${it.label}, Name: ${it.name}"
}

But it doesn't return anything (I do have at least one device with C4 name) neither an error.

If you change that to be

def c4dev = devices.findAll {true}

Do you get any results?

Unfortunately not.

Here what I executed:

log.debug "Executing refresh"
def c4dev = devices.findAll {true}
//def c4dev = devices.findAll { it.name.contains("C4") }
c4dev.each {
	log.debug "Found device: ID: ${it.id}, Label: ${it.label}, Name: ${it.name}"
}
log.debug "Refresh executed"

And here what I got in the log:

dev:7422019-05-05 11:28:49.007 pm debugRefresh executed

dev:7422019-05-05 11:28:48.998 pm debugExecuting refresh

I was trying to do something similar in one of my apps and thought I was doing something wrong, so I'm glad-ish to see someone else with the same problem. I can't find findAll in any Hubitat docs, but I figured it was a standard Groovy method and I'm not sure if it would even be in there (confession: I haven't used Groovy outside of ST or HE, so this may not be a correct assumption). In any case, I'm sure you're aware of workarounds, but I had to do something like this:

 def c4dev = []
 devices.each {
 	if (it.name.contains("C4")) c4dev.add(it)
 }

This should to the same thing, just with a little less syntactic sugar. Note that the above is a totally untested modification of something similar to what I ended up doing in my code, so I hope I didn't make any glaring typos or logic errors, and excuse me if I did. :slight_smile:

I hope I'm not confusing things but I use the findAll() function in my ABC app. Have you defined the "devices" map somewhere and if so you might want to check its contents in the logs.

As far as I know "devices" isn't a built in reference so if you are trying to search your input devices, you would need to look in "settings". Below is a sample of how I use it in ABC. Apologies if anything I have typed above is inaccurate or confusing.

def preferenceNames = settings.findAll{it.key.contains("search string")}

It's difficult to give precise assistance without more of the code but you can try below

def devices = settings.INPUTNAMEHERE
def c4dev = devices.findAll { it.name.contains("C4") }

Silly question, but are you sure that the name property is being set for the device? There are 2 properties (name & label). Without seeing your code it is hard to say but you may want to perform your search against both and see what happens.

Also, what is setting the value of devices? It is a a preference?

My objective is to find a list of device IDs based on some filter, the same way we can easily get an ID from a device by using device.id

I was expecting devices (a collection of all defined device objects) to exist and therefore use findAll method to filter only the ones I need.

I have both device name and label set/defined on all my devices but unfortunately neither works as a filter with devices.findAll (in my case using contains).

@ stephack What puzzles me is no error, such as undefined class, is shown when I run the code. This lead me to think the class (and its methods) is defined but still not implemented.

@ bertabcd1234 I tried your code approach but got an empty c4dev

You cannot query ALL devices on your hub...only devices that are explicitly selected by the user through an input/preference. This is for security reasons....otherwise malicious apps/drivers could pull info that the user did not explicitly allow access to.

I suspected that devices was not being set... You are going to need to create one or more preference inputs to allow a user to select which devices they want to allow to interact with your app. From there, if you still need to filter that list, your calls to findAll will work.

Humm... ok. I buy that but if I can use Maker API to expose all selected devices, why can't I have the same from inside a driver?

Because Maker Api is an app and you still have to explicitly chose which devices you want to allow Maker Api to manipulate. Once you select the devices, they can then be queried for attributes, commands, labels, etc.

Okidoki.

So... back to the drawing board...

Let me see if I can find another way to get the info I need from inside a driver without the using an app.

By the way, all this work is to create a bridge between Control4 and Hubitat. I have it partially working but not yet real-time from Control4 side.