Input to array / collection?

I just started with groovy for the first time in my life. Have been a php developer about 8 years ago. So please be gentle :innocent:
Is it possible to put the value of an input in an array / collection? Like this:
Input(name: "Level[]", type: number

So I can do:
Level.each {

I know I can do "Level${id}" but that makes all different variables which are impossible to loop through.

Input only passes one data element.

input "zipCode", "text", title:"Zip code or city name or latitude,longitude?", required:true

passes one data element, a String named "zipCode".

input "pollEvery", "enum", title:"Poll ApiXU how frequently?\nrecommended setting 30 minutes.\nilluminance updating defaults to every 5 minutes.", required:false, defaultValue: 30, options:[5:"5 minutes",10:"10 minutes",15:"15 minutes",30:"30 minutes",60:"1 hour",180:"3 hours"]

passes one data element.. the selection made by the user, a string named "pollEvery"

And so on through the data types.

You can parse a string of JSON data into a map/collection:

def sunRiseSet = parseJson(getDataValue("sunRiseSet"))

OR

def sunRiseSet = resp.getJson().results

(The first uses a string previously stored in DeviceData, while the second is the result of an asyncHttp... neither are important to your answer. Where the string is, isn't important.)

I think I'm missing something in the original question... :frowning:

log.debug "${settings}" is a Map of all the inputs.

Yes, you add multiple: true to the input statement. Then the user can select multiple devices. The object created is a list (array). Even if only a single device is selected, it will be in a list. The default is multiple: false. That returns a single object, not a list of objects.

So yes, after you have input the list of devices, you could do devices.each {

Example:

input "myDimmers", "capability.switchLevel", title: "Select dimmers", multiple: true

The resulting list can be accessed several different ways, including myDimmers.each, myDimmers[0], myDimmers.last(), etc.

In Groovy, a single dimensional array is called a list.

1 Like

oh yea, I really DID miss something!!! :frowning:

@csteele sorry, I forgot to mention something.

What I want to do is ask for level for each device chosen and per mode, so:

Devices.each { a ->
Input (name: "Modes[$a]", type: mode, multiple: true)
Modes.each { b ->
Input (name: "Level[$a][$b]", type: number)
}
}

1 Like

You don't want those square brackets.

Devices.each {a ->
   def myModes = "Modes$a"
   input (name: myModes, type: "mode", multiple: true, title: "Modes for device $a")
   settings[myModes].each {b ->
      input (name: "Level$a$b", type: "number", title: "Level for mode $b")
   }
}

What you are constructing is similar to Dimmer Per Mode in RM, except you are allowing different levels for each device for each mode.

BTW, not to discourage you, but you can do the outcome of this with Scenes Per Mode. In fact, I'd really encourage you to keep going. Groovy is not hard to learn, and it can open up many cool things for you.

Also, notice the shorthand that Groovy allows:

input "Level$a$b, "number", title: "Level for mode $b"

4 Likes

Thank you. I am going on with Groovy. Because I've got a lot of stuff up my sleeves. And a lot I can do with other apps, but some things are either to much work to make (especially with RM) or demands such a combination of apps that I lose oversight of all rules. And there are some things I just can't do at all (get items from Google calendar is also on my to-do list)

BTW I like RM, but it can be a monster to work with.

Before RM, the only option for doing automations was to write your own in Groovy. So it's intent is to allow most automations to be constructed. It has a lot of power, and with that power can come complexity. And complexity is the bane of understanding and hence of things working as expected.

I always encourage KISS.

3 Likes

With great Power comes.. great Confusion.

:slight_smile:

4 Likes

I like KISS.
And yes RM is very powerful. But the learning curve is pretty steep (no problem there) and the UI can be a bitch if you mess up your rule.

Haha, yes. And I just spent months reworking the UI... The app ui model in general needs a rework...

3 Likes

btw no disrespect for all the great work of course! I mean really, you (and the whole team) are really working hard to help everybody and to improve your product!

It's like you've read my mind (or the few posts I've made wishing for this exact thing). :slight_smile: I'm really impressed with what you've managed to do with RM (and other apps) given the limitations of an app UI structure you more or less weren't responsible for creating, but I've always wondered what would be possible if Hubitat created its own.

Sounds a lot like you're trying to modify my app. :wink: I hope my code is readable to normal humans! If it's what you mentioned in the other thread, I'm almost thinking that what you want might be possible with just RM (it has a "capture" and "restore" feature for dimmers/switches, which you could use before and after changing lights for motion activity/inactivity). Not that there's anything wrong with learning Groovy--as Bruce said, it opens up a lot of possibilities.

Yes, I am rebuilding your app to overcome my difficult desires :crazy_face:. But to be honest I have not looked at your code yet. I decided to start from scratch. Though I have looked at some code of Cobra and some others I came across while searching for answers. And I really don't mind learning Groovy actually. It sort of a trip down memory lane. :joy:

We have some tricks up our sleeve. But I have to say that addressing the RM UI is down on our list a bit. Our focus will be on new-to-HA users, and giving them a smoother path into this fun.

6 Likes

Ok, it's been a while since I got around to go on with Groovy. Though I'm still struggling with the whole array part (List, Collection, Map or whatever they wanna call it).
The solution Bruce gave was fine for making it work on the "input" of things. But on the "output" side it's a hell. So I end up with all kinds of variables called "LevelBulb_1In_the_evening": 90
How would one go through all the different variables names and use the values? It does not make any sense. Well from a Basic point of view maybe... Should we use GOTO line number X also? I thought this was 2019? Where we can use multi-dimensional array's? What make sense to me is having something like: settings["Bulb_1"]["In_the_evening"]["Level"][90]

How do I get that? Or something like that.

Yeah, what you want to create is a data structure to store all of this in one place, a Map would be a good one to use, Maps are great, but you're going to have to study up to make good use of them.
Something like this maybe

["bulb1":["mode":"in the evening","level":"90"]]

Ok, thanks for helping me out here. I've come a little further now!
Running in the next chalange:

actions = ["$a.name":settings[modes].each {}]
log.debug actions["$a.name"].each {}
log.debug actions

This gives:
NULL
[bulb:[evening,day]]

I don't understand why the first log is NULL...

That should probably be

actions["$a.name"].each {log.debug it}

That would also make sense... But that gives nothing... So log.debug isn't even executed.

Which means the first part is wrong: actions["$a.name"].each