Candle Flicker App


(Doug Hogan) #1

Hey Everyone!

It’s my first time posting here and I’m new to this coding language, so please excuse any newbie coding mistakes I’ve made while playing around with this Candle Flicker smartapp idea I had. But I wanted to ask for some help on getting this to work. I have a bunch of new Hue bulbs, and I know there are a bunch of ios apps that do this exact things better, but I wanted to take a stab at making it a Smartapp so I can trigger it automatically. My goal is to make them dim up and down at a random value and then offset that action by a random constrained value as well.

This is what I have so far today, but I obviously haven’t gotten it to work yet. Could one of the experts on these forums let me know what I don’t?

Thanks in advance, it’s a fun new language to hack around with!

/**

  • Candle Flicker
  • Copyright 2015
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/
definition(
name: “Candle Flicker”,
namespace: “”,
author: “Doug Hogan”,
description: “Flicker your lights like Candles using a constrained random dimming value.”,
category: “My Apps”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)

preferences {

section("Select Lights...") {
    input "dimmers", "capability.switchLevel", title: "Dimmers", required: false, multiple: true
}   

}

def installed() {
log.debug “Installed with settings: ${settings}”

initialize()

}

def updated() {
log.debug “Updated with settings: ${settings}”

unsubscribe()
initialize()

}

def initialize() {
subscribe(app, appTouchHandler)
}

def eventHandler(evt) {
log.debug “eventHandler $evt hit”

//Get Random Number
def ranNum = getRandom(30,80)
log.debug "Flame Intensity is $ranNum"
//Dim lights to a random value
def delay = 1L
for (int i=1; i < getRandom(30,80); i++)
{
    lights?.on(delay: delay)
    delay += ranNum * 1000
    lights?.off(delay: delay)
    delay += ranNum * 1000
}

}
def appTouchHandler(evt) {
//takeAction(evt)
}

def getRandom(int min, int max) {
return Math.abs(new Random().nextInt() % max + min)
}


(Tony - SmartThings Unpublished Contributor ) #2

Instead of using the app itself as the switch for the flicker scene, use a virtual on/off switch that you create in the IDE.

Then 1) in your app preferences ask user to pick the switch that will turn on/off your flicker scene; 2) In initilize(), subscribe to that switch, and send to eventHandler() 3) In eventHandler(), use flicker logic you already have inside of a “dimmers.each {” loop; 4) Delete subscription to app in initalize() and delete appTouchHandler.

Hope this helps. Have fun!


(Justin) #3

I have to chime in because I took the advice of @infofiend, because a virtual switch is a switch and not a dimmer, you cannot install it when running (at least) the simulator because it is not a dimmer and I do not see a virtual dimmer.


(Tony - SmartThings Unpublished Contributor ) #4

Not sure whether you agree or not with what I suggested. But the virtual switch is just for turning the Candle Flicker scene on / off. It doesn’t need to be a dimmer. But if you wanted to created a virtual dimmer, then just add “capability.switch Level” to the virtual device.


(Doug Hogan) #5

Thanks for all the help infofiend! You’ve gotten me much closer to getting this to work, but I did run into a little road block that I’d really appreciate your expertise on.

I’m getting the following error in the logs that’s preventing the app from working…

groovy.lang.MissingMethodException: No signature of method: script1427213020541672256434.sendValue() is applicable for argument types: (physicalgraph.app.EventWrapper, script1427213020541672256434$_handleSwitchEvent_closure2) values: [physicalgraph.app.EventWrapper@394d3b39, …]

Obviously this has to do with how I’m sending information to the eventhandler, but I’m not sure what I’m doing wrong. Would you mind looking at my code below and let me know what I’m missing. I’d really appreciate it and thanks in advance!!

/**

  • Candle Flicker
  • Copyright 2015
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  • http://www.apache.org/licenses/LICENSE-2.0
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/
definition(
name: “Candle Flicker”,
namespace: “”,
author: “Doug Hogan”,
description: “Flicker your lights like Candles using a constrained random dimming value.”,
category: “My Apps”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)

preferences {

section(“Select Dimmable Lights…”) {
input “dimmers”, “capability.switchLevel”, title: “Lights”, required: true, multiple: true
}

section(“Trigger with Switch…”){
input “mySwitch”, “capability.switch”, title: “Switch”, required: true, multiple: false
}
}

def installed() {
initialize()
}

def updated() {
unsubscribe()
initialize()
}

def initialize() {
subscribe(mySwitch, “switch”, handleSwitchEvent)
}

def handleSwitchEvent(evt) {
sendValue(evt) { it == “on” ? “true” : “false” }
}

def eventHandler(evt) {
log.debug “eventHandler $evt hit”

dimmers.each{
//Get Random Number
def ranNum = getRandom(30,80)
log.debug “Flame Intensity is $ranNum”

//Dim lights to a random value
def delay = 1L
for (int i=1; i < getRandom(30,80); i++)
{
lights?.on(delay: delay)
delay += ranNum * 1000
lights?.off(delay: delay)
delay += ranNum * 2000
}
}
}
def lights(evt) {
//takeAction(evt)
}

def getRandom(int min, int max) {
return Math.abs(new Random().nextInt() % max + min)
}


(Jim Anderson) #6

That error is telling you that no method with signature sendValue() that matches your invocation.

I don’t see a method named sendValue in your code - did you mean to call eventHandler(evt)?


(Tony - SmartThings Unpublished Contributor ) #7

Hey Doug-

I’m unable to test your code at the moment. But Jim’s comment is right on point. Feel free to let me know if you have any further questions.

-Tony


(Kristopher Kubicki) #8

Hey Doug,

I spent some time on this and came to some interesting results. I have some low quality LEDs that actually work better for this project than nice ones. Unfortunately, I think the real downside to doing this “correctly” is that the z-wave dimmers all have gradual delays when adjusting the light levels. I think some of the newer ones allow you to specify the delay time, but its still “seconds” to adjust a light level instead of “microseconds”, which is what you need.

In any case, maybe you can build something off what I hacked together:


(Doug Hogan) #9

This is great Kristopher, good work! I’m going to give it a try tonight.


(Doug Hogan) #10

I tested it out last night and it’s working…but with a catch! It only seems to flicker for maybe a minute and then it just stays static. Any ideas about this? Have you experienced this glitch as well? I am using Hue bulbs, so maybe that’s part of the problem.


(Kristopher Kubicki) #11

The big thing is ST will kill recursive jobs and fast scheduled events. I don’t know exactly what criteria they look for.

One thing that might be useful would be to add motion sensor capability so that the program keeps running as motion is detected. I do that for other things and it works well. Alternatively, adding a schedule to the app might work as well