Simple Piston to Native HE

Hi All,

With the recent webcore issues and chatter around performance, I'm starting to try and move some of my simpler pistons to native HE.

One simple one I'm struggling with is this. I can't set such a short timer (10 seconds) and I dont seem to be able to set the color tempreature using simple lighting/rule machine.

Can anyone suggest what my options are?

D

I think this should work. In most cases you shouldnt need the "Turn on". Set Level should automatically turn the light on to the level specified. Ignore the FADE part...I must have clicked that by miistake.

1 Like

This is true for all the built in drivers.

Thank you so much for this! All working!

what type of light is this?, and what driver is it using?

a hubitat group?, or a hue group...

is this paired to hubitat?, or hue...

Mike - Thanks for the quick reply.

It was a hue light in a hue group.

I've deleted my original post, because, although I can't explain why, I I ended up moving this out of the hue group being controlled by the by the switch. What I cant explain is why the switch would operate after a power cycle correctly... and why it only started occurring when I moved this from webcore to rule engine. But I dont think it has anything to do with Hubitat - perhaps a coincidence on timing.

Thanks again for replying so quickly though

And if you really want to go fully native. This was mostly for fun since it can't be edited easily, but man is it fast:

definition(
	name: "Sleep Bedroom Light",
    namespace: "jp0550",
    description: "Sleep Bedroom Light",
    author: "jp0550",
    iconUrl: "about:blank",
    iconX2Url: "about:blank"    
)

preferences {    
    section(){
        input "motionSensor", "capability.motionSensor", title: "Bedroom Motion Sensor", required: true
        input "sleepSwitch", "capability.switch", title: "Sleep Switch", required: true
        input "doorLight", "capability.switchLevel", title: "Bedroom Door", required: true
        input "colorTemperature", "number", title: "Color Temperature", required: true, defaultValue: 2101
        input "lightLevel", "number", title: "Light Level", required: true, defaultValue: 1
        input "turnOffAfter", "number", title: "Turn off after x seconds of activity", required: true, defaultValue: 10
    }    
}

def installed(){
    initialize()
}

def updated(){
    initialize()
}

def initialize(){
    unsubscribe()
    unschedule()
    
    subscribe(motionSensor, "motion", "motionHandler")
}
              

def motionHandler(evt){
    unschedule()
    
    if(sleepSwitch.currentValue("switch") == "on"){
        if(evt.value == "active"){
                doorLight.on()    
                if(doorLight.hasCommand("setColorTemperature")){
                	doorLight.setColorTemperature(colorTemperature)    
                }                
                doorLight.setLevel(lightLevel)
        }
        else {
            runIn(turnOffAfter, "noMotion")
        }
    }
}

def noMotion(){
    if(sleepSwitch.currentValue("switch") == "on"){
        doorLight.off()
    }	
}

*Removed double if check for switch on

1 Like

whats with the unschedule?

Just a quick and dirty way to have the turn off cancelled if motion is detected

you're better off setting a state var some place instead of unschedule, then checking that in the noMotion method...

Like I said, it was just for fun, wasn't going for full optimization.

Can I ask why? In ST, I recall the unschedule function was reported to be expensive/slow--is it the same on Hubitat? Or are you just suggesting that the flow would be cleaner if that's how the code worked? (Asking because, like the original poster, I'm about to port some lighting pistons to native apps. I already have the logic worked out if I can use unschedule but want to avoid anything slow or otherwise not recommended on the platform. :slight_smile: )

I ran a quick test from above and it looks like it takes 4-8ms to unschedule in the example above on my hub:

def motionHandler(evt){
    runIn(turnOffAfter, "noMotion")
    def start = now()
    unschedule()
    log.debug "Unschedule called in ${now() - start}ms"
}

[app:2025](http://192.168.2.124/logs#app2025)2018-08-31 20:59:36.294:debugUnschedule called in 5ms

[app:2025](http://192.168.2.124/logs#app2025)2018-08-31 20:59:34.701:debugUnschedule called in 4ms

[app:2025](http://192.168.2.124/logs#app2025)2018-08-31 20:59:23.985:debugUnschedule called in 6ms

[app:2025](http://192.168.2.124/logs#app2025)2018-08-31 20:59:22.945:debugUnschedule called in 8ms

I'm not sure what the typical response time was in ST. I know unschedule was expensive, though, and was typically only used in the installed and updated methods for performance reasons from what I've read.

@mike.maxwell I'm creating my own occupancy app that is coded similarly to @jp0550. If we set a state variable to hold the the status of the motion sensor, it would only tell the noMotion method the state at the time that method is run (after the delay). Wouldnt we want the motion active event to cancel the scheduled noMtion method altogether? Otherwise it would run if the motion happens to go inactive just before the end of the timeout.

An earful I know...hard to put in words but I hope you get the jist.

Maybe something like this:

def motionHandler(evt){
    if(evt.value == "active") state.lastMotionEvent = now() //keep track of last active event time
    if(sleepSwitch.currentValue("switch") == "on"){
        if(evt.value == "active"){
                doorLight.on()    
                if(doorLight.hasCommand("setColorTemperature")){
                	doorLight.setColorTemperature(colorTemperature)    
                }                
                doorLight.setLevel(lightLevel)
        }
        else {            
            runIn(turnOffAfter, "noMotion") //will overwrite last timer if it exists
        }
    }    
}

def noMotion(){
    def delta = (now() - (state.lastMotionEvent ?: 0)) / 1000    
    if( delta < turnOffAfter ) return //if the last event is less than 10 seconds we got an "active" event and should cancel
    
    if(sleepSwitch.currentValue("switch") == "on"){
        doorLight.off()
    }	
}

I'm not sure if Hubitat's schedule ever fires early like in ST so I only track the last motion evt if it was active.

1 Like

I forgot about this important part of the equation. I was thinking a bunch of events would be scheduled even if they didn't fire because of an evaluation.

I'll give your code a shot sometime today. Thanks for posting.

1 Like

I too would eventually like to migrate from webcore which I'm setting up now lol.

I find either it's featureset or wording a bit lacking though... No offense...