Best way to loop through a set of color changes in absence of a CASE statement?

Continuing the discussion from If Case Statements:

I appreciate the constructive conversation on use of IF THEN/ELSE/ENDIF being repeated but I'd like to renew the thought for CASE or IF x THEN - ELSEIF x THEN - ELSE - ENDIF or ideally, get suggestions on the best way to implement.

I'm using a simple numeric variable on a Button 5.1 rule and a set of IFs to rotate through a list of colors or "modes" for a set of LED lights.

Basically, I want to increment through BLUE GREEN RED EFFECT1 EFFECT2 every time I push a scene control button.

I'm incrementing a variable to keep track of which one's active (and looping at end of list) or reset to 1 on power-on.

It leaves me with a very lengthy set of IF statements - originally built with ELSE for processing efficency. However, as they're exclusive, the referenced threads makes a good point that IF THEN ENDIF is sufficient and cleaner to read.

Better ways to do this? Otherwise, I yearn for a Case 1: Case2 simplicity and will put this use case out there again!

Thanks

Write an app. You can, relatively easily, spin up an app that would do this and allow for a case statement.

2 Likes

@bertabcd1234 - I'm thinking your dimmer button controller app may handle this already, in the way it mimicked the hue rotation of scenes? If the colours were setup as scenes? Or at least an example of the logic for rotating through a preset list of commands.

webcore has a switch statement...fyi

1 Like

More or less, though depending on what the OP means with "effects," it may or may not support setting those (it's really meant to work with standard switch, level/dimmer, and color/CT commands, though can activate Hubitat or CoCoHue scenes as well). It does support cycling through different settings, like the Hue Dimmer does on a Hue Bridge with scenes, that being one of the main reasons I wrote it -- to replicate that function on Hubitat with a Pico (as I originally had in mind) or really any button device.

Sounds like some good options here... haven't written an app yet, so this sounds like a fun learning moment anyhow @FriedCheese2006

Getting deeper since we're talking implementation specifics:
ZEN32 scene controller, with a specific button pressed that I'd like to rotate through choices. Right now, button controller 5.1 "script" with said IF statements and a simple counter. It's controlling TWO ZEN31 RGBW light strips (one above kitchen cabinets, one below cabinets).

@bertabcd1234 regarding colors/effects, standard color/dimmer choices (blue, yellow etc) but also the ZEN31's "Deep Fade" and "Light Fade" functionality -- so I do believe standard won't help me out here @sburke781 but it was a good idea.

The intent is to also later apply this to a screen porch strip, same controller sequence, but in that instance one strip/zen31.

Haven't checked out webcore yet -- I hear good things @nh.schottfam (I was in Nashua until about 4 yrs ago...) and will add that to the queue behind trying out @bertabcd1234's zen32 driver.

ChatGPT is actually pretty handy for getting a start on stuff like this. I know for me, it's easiest to see the code, then go figure out what it's doing to learn. I didn't even really look at the code, but it does look like the general gist of what you want. If nothing else, it's a good nudge in the right direction.

definition(
    name: "Color Cycle",
    namespace: "your namespace here",
    author: "your name here"
)

preferences {
    page(name: "settings")
}

def settings() {
    dynamicPage(name: "settings", title: "Settings", install: true, uninstall: true) {
        section("Select Bulbs") {
            input "bulbs", "capability.colorControl", title: "Bulbs", multiple: true
        }
        section("Button Device") {
            input "button", "capability.button", title: "Button Device", required: true
        }
    }
}

def installed() {
    subscribe(button, "button.pushed", buttonPushedHandler)
}

def updated() {
    unsubscribe()
    subscribe(button, "button.pushed", buttonPushedHandler)
}

def buttonPushedHandler(evt) {
    def currentColor = "red" // set the initial color to red
    def colors = ["red", "green", "blue", "purple", "yellow", "orange"] // add more colors as desired
    
    bulbs.each { bulb ->
        bulb.setColor(currentColor) // set the initial color for each bulb
    }
    
    runEvery5Seconds(30, cycleColors) // cycle colors every 30 seconds
    
    log.info("Button pushed: cycle colors")
}

def cycleColors() {
    def currentColorIndex = colors.indexOf(currentColor)
    def nextColorIndex = (currentColorIndex + 1) % colors.size()
    def nextColor = colors[nextColorIndex]
    
    bulbs.each { bulb ->
        bulb.setColor(nextColor) // set the next color for each bulb
    }
    
    currentColor = nextColor
}
Conversation


This wasn't quite there, so I probed it a few more times and got to something that should at least cycle through colors.

definition(
    name: "Color Cycle",
    namespace: "your namespace here",
    author: "your name here"
)

preferences {
    page(name: "settings")
}

def settings() {
    dynamicPage(name: "settings", title: "Settings", install: true, uninstall: true) {
        section("Select Bulbs") {
            input "bulbs", "capability.colorControl", title: "Bulbs", multiple: true
        }
        section("Button Device") {
            input "button", "capability.button", title: "Button Device", required: true
        }
    }
}

def installed() {
    subscribe(button, "button.pushed", buttonPushedHandler)
}

def updated() {
    unsubscribe()
    subscribe(button, "button.pushed", buttonPushedHandler)
}

def buttonPushedHandler(evt) {
    def currentColor = bulbs[0].getCurrentColor() // get the current color of the first bulb
    def colors = ["red", "green", "blue", "purple", "yellow", "orange"] // add more colors as desired
    def currentIndex = colors.indexOf(currentColor) // get the index of the current color
    def nextIndex = (currentIndex + 1) % colors.size() // get the index of the next color
    def nextColor = colors[nextIndex] // get the next color

    bulbs.each { bulb ->
        bulb.setColor(nextColor) // set the next color for each bulb
    }

    log.info("Button pushed: cycle colors")

}

Conversation



@FriedCheese2006 That looks like a great idea. Easy enough to throw in the "Fade" into the array and an IF around the code to do color or effect. This may be a way to go with press/release OR just turn it into a stateful button press routine. I'll absolutely play with it a bit!

Thanks!

1 Like