How to append variable on device name?

Here’s a super simple version of what I am trying to achieve:

Let’s say I have two switches named switch1 and switch2. I am trying to code up something like this:

for(int n = 1; n <= 2; n++) {
     switch${n}*.on()
}

This is inside of a big IF statement, so, depending on the current state, either one bulb should be turned on or the other. Only that doesn’t work.

Note that this is greatly simplified for demonstration. My reasons for needing something like that are fairly complicated, but I’ll have a pretty cool app if I can figure it out. Any thoughts?

You could try:
switch"${n}".on() //notice the addition of the double quotes

HTH

1 Like

Thanks for the reply, Twak! unfortunately, that doesn’t seem to be working. I’m getting an error saying there’s no signature for the method I am invoking. Any other ideas?

I’ve had success with double quotes around the entire object name:

"switch_${i}".on()

But I might be able to offer more help if you could share the entire code for more context and debugging.

Hi, tgauchat. Thanks for the reply. That doesn’t seem to be working either, but here’s the chunk of code in question, so maybe you can tell me where I’m going awry:

for(int n = 1; n <= sceneNumber; n++) {

	mathCurrentTop = mathPercent * n
    
    if(n == 1){
        mathCurrentBottom = mathCurrentTop - mathPercent
	} else {
    	mathCurrentBottom = mathCurrentTop - mathPercent + 1
    }

	log.debug "Math Top = $mathCurrentTop"
    log.debug "Math Bottom = $mathCurrentBottom"
        
	if (level >= mathCurrentBottom && level < mathCurrentTop) {

        switch("color${n}") {
            case "White":
                hueColor = 52
                saturation = 19
                break;
            case "Daylight":
                hueColor = 53
                saturation = 91
                break;
            case "Soft White":
                hueColor = 23
                saturation = 56
                break;
            case "Warm White":
                hueColor = 20
                saturation = 80 //83
                break;
            case "Blue":
                hueColor = 70
                break;
            case "Green":
                hueColor = 39
                break;
            case "Yellow":
                hueColor = 25
                break;
            case "Orange":
                hueColor = 10
                break;
            case "Purple":
                hueColor = 75
                break;
            case "Pink":
                hueColor = 83
                break;
            case "Red":
                hueColor = 100
                break;
            case "Movie Red":
                hueColor = 12
                break;
        }

        def newValue = [hue: hueColor, saturation: saturation, level: lightLevel as Integer ?: 100]
        def bulbNewValue = [level: bulbLevel as Integer ?: 100]

        log.debug "new hue value = $newValue"
        log.debug "new bulb value = $bulbNewValue.level"

        hues*.setColor(newValue)
        "bulbs${n}"*.setLevel(bulbNewValue.level)
        "bulbsOn${n}"*.on()
        "bulbsOff${n}"*.off()
    }
}

Thanks so much for your help!

1 Like

I think I may need your preferences section too, please … i.e., where bulbs... is defined.

And I think you gave the error message… well… full code and error is best, that way I can plug it right into my own IDE and try a tweak or two super quickly.

You are a hero for your helpfulness! Here’s the full code:

    /**
 *  Hue Scene Slider
 *
 *  Author: Josiah Spence
 *  
 *  Version: 1.0.0
 *  
 *  Date: 2015-02-21
 */
definition(
    name: "Hue Scene Slider",
    namespace: "hueslider",
    author: "Josiah Spence",
    description: "Cycle through Hue Scenes based on a dimmer slider.",
    category: "SmartThings Labs",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/hue.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/hue@2x.png"
)

preferences {

    page(name: "basicSetup", title: "Basic Setup", nextPage: "sceneSetup", uninstall: true) {
        section("Info") {
            paragraph "Author: \tJosiah Spence"
            paragraph "Version: \t1.0.0"
            paragraph "Date: \t2/21/2015"
        }


        section("Dimmer") {
            input "dimmer", "capability.switchLevel", title: "Which dimmer switch?", description: "Tap to select a switch", multiple: false
            input name: "sceneNumber", type: "number", title: "How many Scenes Do You Need?", defaultValue: 2
            input name: "defaultOption", type: "bool", title: "Default to First Scene When Switched On?", defaultValue: false
        }


        // Bulb Selection //
        section("Bulb Selection") {
            input "hues", "capability.colorControl", title: "Which Hue Bulbs?", required:false, multiple:true
        }
    }

    page(name: "sceneSetup", title: "Basic Setup", install: true, uninstall: true)

}


def sceneSetup() {
   dynamicPage(name: "sceneSetup"){

        for(int i = 1; i <= sceneNumber; i++) {
            // Scene 1 //
            section("Scene $i settings") {
                input "color$i", "enum", title: "Hue Color?", required: false, multiple:false, options: [
                    "Soft White":"Soft White - Default",
                    "White":"White - Concentrate",
                    "Daylight":"Daylight - Energize",
                    "Warm White":"Warm White - Relax",
                    "Red":"Red",
                    "Movie Red":"Movie Red",
                    "Green":"Green",
                    "Blue":"Blue",
                    "Yellow":"Yellow",
                    "Orange":"Orange",
                    "Purple":"Purple",
                    "Pink":"Pink"]
                input "lightLevel$i", "enum", title: "Light Level?", required: false, options: [10:"10%",20:"20%",30:"30%",40:"40%",50:"50%",60:"60%",70:"70%",80:"80%",90:"90%",100:"100%"]



                // Smart Bulbs //
                input "bulbs$i", "capability.switchLevel", title: "Which Smart Bulbs to Dim?", required:false, multiple:true
                input "bulbLevel$i", "enum", title: "Light Level?", required: false, options: [10:"10%",20:"20%",30:"30%",40:"40%",50:"50%",60:"60%",70:"70%",80:"80%",90:"90%",100:"100%"]

                // Turn Off //
                input "bulbsOff$i", "capability.switch", title: "Turn Off Which Bulbs?", required:false, multiple:true

                // Turn On //
                input "bulbsOn$i", "capability.switch", title: "Turn On Which Bulbs?", required:false, multiple:true
            }
        }
    }
}


def installed() {
    log.debug "Installing 'Hue Scene Slider'"

    commonInit()
}

def updated() {
    log.debug "Updating 'Hue Scene Slider'"
    unsubscribe()

    commonInit()
}

private commonInit() {
    subscribe(dimmer,"level",updateLevel)
    subscribe(dimmer,"switch.on",onHandler)
    subscribe(dimmer,"switch.off",offHandler)
}

def onHandler(evt) {
     log.debug "Multi Dimmer: ON"

     if (defaultOption){

        dimmer.setLevel(1)

     } else {

        hues*.on()
        bulbsAllOff*.on()

     }
}


def offHandler(evt) {
    log.debug "Multi Dimmer: OFF"
    hues*.off()
    bulbsAllOff*.off()
}

def updateLevel(evt) {

    log.debug "UpdateLevel: $evt"
    int level = dimmer.currentValue("level")
    log.debug "level: $level"

    def i = 1
    def hueColor = 0
    def saturation = 100

    def mathPercent = 100/sceneNumber
    def mathCurrentTop = 0
    def mathCurrentBottom = 0

    log.debug "Math Percent = $mathPercent"

    for(int n = 1; n <= sceneNumber; n++) {

        mathCurrentTop = mathPercent * n

        if(n == 1){
            mathCurrentBottom = mathCurrentTop - mathPercent
        } else {
            mathCurrentBottom = mathCurrentTop - mathPercent + 1
        }

        log.debug "Math Top = $mathCurrentTop"
        log.debug "Math Bottom = $mathCurrentBottom"

        if (level >= mathCurrentBottom && level < mathCurrentTop) {

            switch("color${n}") {
                case "White":
                    hueColor = 52
                    saturation = 19
                    break;
                case "Daylight":
                    hueColor = 53
                    saturation = 91
                    break;
                case "Soft White":
                    hueColor = 23
                    saturation = 56
                    break;
                case "Warm White":
                    hueColor = 20
                    saturation = 80 //83
                    break;
                case "Blue":
                    hueColor = 70
                    break;
                case "Green":
                    hueColor = 39
                    break;
                case "Yellow":
                    hueColor = 25
                    break;
                case "Orange":
                    hueColor = 10
                    break;
                case "Purple":
                    hueColor = 75
                    break;
                case "Pink":
                    hueColor = 83
                    break;
                case "Red":
                    hueColor = 100
                    break;
                case "Movie Red":
                    hueColor = 12
                    break;
            }

            def newValue = [hue: hueColor, saturation: saturation, level: lightLevel as Integer ?: 100]
            def bulbNewValue = [level: bulbLevel as Integer ?: 100]

            log.debug "new hue value = $newValue"
            log.debug "new bulb value = $bulbNewValue.level"

            hues*.setColor(newValue)
            "bulbs${n}"*.setLevel(bulbNewValue.level)
            "bulbsOn${n}"*.on()
            "bulbsOff${n}"*.off()
        }
    }

}

And the error I am getting is:

groovy.lang.MissingMethodException: No signature of method: java.lang.String.setLevel() is applicable for argument types: (java.lang.Integer) values: [100] @ line 208

Thanks again!

1 Like

OK… I think I’ve got it…***, but I’m not sure “exactly” what your SmartApp is doing, so you’ll have to test…

Your original lines…
@spencejs:

"bulbs${n}"*.setLevel(bulbNewValue.level)
"bulbsOn${n}"*.on()
"bulbsOff${n}"*.off()

Change this to:

settings."bulbs${n}"*.setLevel(bulbNewValue.level)
settings."bulbsOn${n}"*.on()
settings."bulbsOff${n}"*.off()

Quite a small change, right? Since the Preferences are actually stored in a Map called settings, you “need” or “can” refer to the full Map name when referencing the Devices.

By using the “settings” Map name, the string expansion appears to work correctly. I notice that I did this in one of my SmartApps before, and didn’t recall why … but I figured I had a reason.

Please let me know if this works. :pray:

1 Like

It works!!! You are my hero! Thanks and thanks again!

1 Like

My pleasure! :+1: … Groovy string expansion into variables or objects or Maps or whatever they’re called, still gets me a bit confused; so debugging stuff like this is a fun and educational challenge.

Clever SmartApp idea, by the way! I haven’t quite figured out if there’s any / too many redundant requests for Devices? … But tying the scene selection to a slider is a creative idea.

Feel free to “delete” the post that includes the full source code, if you wish to keep your code private.


If you wish to give me a small thanks mention within your Credits comment area, please just mention my GitHub “@cosmicpuppy” and/or my name “Terry Gauchat”.

Reach out to me here Private Message or postings anytime. Cheers!

1 Like

Yeah, there may be some redundancy - I want to be sure there is maximum possible control over each scene, but I’ll probably keep looking for ways to simplify as well.

I’m publishing this to the community, so no need to delete the post. I’ll definitely credit you!

1 Like

When I think of it, I use a Groovy web console (whichever comes up in a Google search) to figure out variable expansion (and other “how does this work?” stuff) by trial and error.

1 Like