Turn on light based on luminance sensor + motion (day time)

Wondering if anyone has attempted an app that would turn lights on / off based on motion + lux sensor.

The case would be a room that gets lots of outdoor light during the day, hence you don’t want lights to turn on when lux is above say 1000. However, when lux falls to 200, turn on lights with motion. The issue being that the lux will jump when the lights turn on, so do NOT turn lights off after lux jump. Once motion stops, lights can turn off after a set period. So…

  1. Lights on when motion + lux setting below 200;
  2. Lights off after X minutes and no motion, but stay ON even if lux is above threshhold.
  3. Lights off after X minutes, turn lux sensor back on.
1 Like

I would love this same app and it seems like it could be one of the “killer” apps out there. I would even push it a step or two further.

  • instead of just on / off, allow for dimming. This will allow for the increase of lighting as it gets darker.
  • since the above would immediately negate a local lux sensor, offer the ability to use another one “with a deviation option.” For example, either an external one or the weather tile. But you can set each area you want to control with a +/- deviation on the lux level reported. So, a room that has fewer windows or is on the east side of the house might get an option to turn on sooner.

I’m thinking that if this were set lux levels rather than a preset one in the app, you wouldn’t need the deviation. Just a little trial and error as to what levels to use as the basis to start to turn the lights on.

But, I have always wanted to link lux, motion, and mode together.

Have a look at this app.
You run you motion lights via the normal motion triggers, this app just modifies the dim level(s) based on lux settings.
What you want to do, I am already doing with the stock smart apps and auto dimmer.

You know, @Mike_Maxwell, we discussed this one and I guess I misunderstood it. So, I’m going to try it again.

Quick question - what are suggestions on the lux levels on the first screen? Did you make it so the middle selections are “standard?”

Depends on the lux sensor you’re using, but the mid level would be a good place to start.
The Aeon’s tap out at 1000 (low overcast) , making the bright setting not very usable with the option values I have coded. I use a Fibaro pointed outside, winch has a range up to 35K or so.
The lux options are very easy to change in the code if they don’t suite your setup, and you don’t have to uninstall smartapps to republish any changers you made to the preference options, don’t know if you were aware of that or not.

Think of this app as a contrast manager, it doesn’t turn lights on or off, it just manages the contrast ration of interior lighting and exterior conditions.

This was one of the first smartapps I played with last June. So this is a little messy.

I use a modified version of chrisb’s “Improved Smart Nightlight” You can find it in smartapps Convenience category list in IDE. You can hard code or add your own input for on if luminescence < value. I just have the < value hard coded.

It uses any light sensor and optionally a different motion sensor. So I have it setup for most of my downstairs lights. Multiple motion sensors but only two light sensors. Basically if it is sunny and bright outside, most of my lights stay off, otherwise they come on with motion. You can set time or sunrise/sunset values as well.

In my case the light sensors are not in direct path of the room lights so I don’t need any rules to keep the lights brightness causing a light reading high enough to trigger lights off.

I think parts I added set between times were:

section("Between this time:") {
	input "timeOfDay1", "time", title: "Time?"
	}
    section("And end at this time:") {
	input "timeOfDay2", "time", title: "Time?"
	}

And

def motionHandler(evt) {
	log.debug "$evt.name: $evt.value"
        def startTime = timeToday(timeOfDay1)
	def endTime = timeToday(timeOfDay2)
	if (evt.value == "active" && lastStatus != "on" && now() > startTime.time && now() < endTime.time && lightSensor.currentIlluminance < 250) {
		lights.on()
		state.lastStatus = "on"
        }

And IIRC, edit the lux value here so it turns off no matter what when a certain level of brightness is reached. I think the default was too low.

if (lastStatus != "off" && evt.integerValue > 650) {
	lights.off()
	state.lastStatus = "off"
}

Edit–
And this part too

else if (lastStatus != "on" && evt.value < 250 && now() < startTime.time && now() > endTime.time){
	lights.on()
	state.lastStatus = "on"
}
}
1 Like

@Mike_Maxwell - Now I think I remember my confusion. Look at this from a “simple user.”

Controlling lights is a combination of motion control triggers in one sections of SmartThings and this app in another. So, to manage my lights I need to go to two places.

What I would love to see is @tuffcalc’s original request…and here is why. If it was designed to control one set of lights with one set of motion sensors and a lux sensor, you would completely self-contain all the controls for a set of lights. Now, you can then load up multiple versions of this SmartApp in your system to control other sets of lights…perhaps by room.

In my case, I was envisioning a few copies of this app to control several rooms individually, such as kitchen, family room, living room, hallway, foyer, etc.

Actually, what I think might take that app to the next level would be using local (to the room or area) lux sensors (x value) in combination with the brightness of the lights (y value) to come up with a “sum total” lux value (x+y). For example, as it gets darker outside, the X lux value would decrease. As it decreases, the app would then increase the dimmer value on the lights to balance it out. You could then specify an overall lux value for the room you would like to have for that particular mode - adding mode to the equation here in case you wanted a “movie” or “party” mode to adjust the lighting to a lower level.

To me, that would be a truly smart house. You are specifying “this is how bright I want it, now go figure it out if I’m in the room”…all in one app per room.

Did any of that make sense? I realized I was rambling a bit… :smile:

I’m still going to play with your app and I think I can use it in several scenarios.

1 Like

Maybe I’ll break out that “super smart lights” idea into a separate thread for discussion to see if it is even possible,

@brianlees, I get what you’re saying.
The reason I wrote it this way is that it was designed as a set and forget setup.
You select the devices that you want to have managed, set the other junk, then walk away.
There’s nothing to do after the settings are in place, other than to add/remove dimmers that you want managed.
All the existing triggers/modes/hello home actions, whatever stuff you currently use to turn these lights on/off remain as is.
Now, having said that, the basic premise for this app being that there exists a comfortable contrast level between exterior and interior luminosity. This application attempts to manage that relationship.
Certainly not every dimmer in a given setup would be controlled by this app, if the room receives no exterior lighting for example…
I wanted an app that provided this level of function, but not have to replace any of the existing triggers/motion on, timed on/off, hello do something whatever stuff… There’s plenty of perfect apps for that already.
Hope this made some sense…

So… @AaronZON came through in a big way. His code is below and seems to work well in a 1 sensor / 1 dimmer environment:

/**
 *  Turn light on with motion for x minutes if it is dark based on light sensor
 *
 *   Written by Aaron Herzon
 *
 *  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: "Turn light on with motion for x minutes if it is dark based on light sensor",
    namespace: "AaronZON",
    author: "Aaron Herzon",
    description: "Turn on lights temporarily when there is motion but only if it is dark according to light sensor",
    category: "Safety & Security",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",  
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
    //todo:  replace icon with something appropriate.  


preferences {
	section("Select Motion Sensor(s) you want to Use") {
        input "motions", "capability.motionSensor", title: "Motion Detector", required: true, multiple: false
	}
    section("Select Dimmers you want to Use") {
        input "switches", "capability.switchLevel", title: "Dimmer Switches", required: false, multiple: true
	}
    section ("Set Brightness for motion-triggered light and on time after motion stops") {

        input "BrightLevelStr", "enum", title: "Motion-Sensed Level %", required: true, 
        	options: ["100","75","50"], defaultValue: "100"

        input "DelayMinStr", "enum", title: "Bright Delay After Motion Stops, minutes", required: true, 
        	options: ["1","3","5","10","15","30","60"], defaultValue: "5"
        	}
    section ("Ignore motion if light level is above this value") {
    	input "LightMeter", "capability.illuminanceMeasurement", title: "Light Meters", required: true, multiple: false
		input "LuxSetPointStr", "enum", title: "Lux level", required: true, 
        	options: ["50","100","200","400"], defaultValue: "50"
           	}
}
def installed() {
	log.debug "Installed with settings: ${settings}"

	initialize()
}

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

	unsubscribe()
	initialize()
}

def initialize() {
	log.debug "initialize()"

    state.BrightLevel = BrightLevelStr as Integer
   	if (state.BrightLevel == 100) {
    	state.BrightLevel = 99
    }
    state.DelayMin = DelayMinStr as Integer
    state.LuxSetPoint = LuxSetPointStr as Integer


    subscribe(motions, "motion.active", handleMotionEvent)
    subscribe(motions, "motion.inactive", handleEndMotionEvent)

}


def handleMotionEvent(evt) {
	log.debug "handleMotionEvent() Motion detected . . . ."

    unschedule(turnLightsOff)

    if (state.lightIsOn) {
        log.debug ". . . but light is already on so do nothing"
        }
    else {
    	def currentLux=LightMeter.currentIlluminance
       	 if(currentLux < state.LuxSetPoint) {
        	switches?.setLevel(state.BrightLevel)
        	state.lightIsOn=true
        	log.debug ". . . . and it is dark so turn the lights on"
        }
        else {
        	log.debug ". . . .but it is light, so do nothing"
        }
	}
}

def handleEndMotionEvent(evt) {
	log.debug "handleEndMotionEvent() Motion stopped . . . ."

    if (state.lightIsOn) {
    	runIn((state.DelayMin*60), turnLightsOff)
        }

}

def turnLightsOff() {   

	log.debug "turnLightsOff()" 

    switches?.setLevel(0)
    state.lightIsOn=false
}

… here are the issues I am having though:

  1. I would like to use multiple motion sensors. When changing “false” to “true” to pickup multiple motion sensors, the app isn’t able to fire on the lights…

     input "motions", "capability.motionSensor", title: "Motion Detector", required: true, multiple: false
    
  2. Same thing happens when changing the “enum” to “number” for more granular control of the various inputs - the app no long fires on the lights.

Anyone willing to take a stab at these? I’m stumped. This could be a killer app.

Thanks again to @AaronZON for starting this one!

1 Like

@AaronZON - I think I figured out why I thought it wasn’t firing. If the app shuts off the light after a time delay, it resets the state to “state.lightIsOn=false” (lights are off). However, if the lights are manually turned off at the switch, the app still thinks the lights are on, and it keeps thinking that because it never actually turned them off itself. For example, when motion happens after the lights have been turned off mnaually, this is returned:

7:43:59 AM EDT: debug . . . but light is already on so do nothing
7:43:55 AM EDT: trace Deleting scheduled job ‘turnLightsOff’ for InstalledSmartApp: 30fe735e-b5c8
7:43:55 AM EDT: debug Motion detected . . . .

I was turning the lights off manually to test motion “on” before the timer delay.

Does anyone know if this a smartthings bug? I’m using Linear Z-wave wall switches.

Ha! No bug. This app has no awareness of the actual state of the switch. It sends the instruction for for off and on and assumes no one is jacking with the switch in the mean time ;-).

There are ways to add awareness of manual switching to the app but I just haven’t experimented with this. It does seem like there is a lot of chatter in the forums about problems getting switches to report their states in an accurate and timely manner. . . so, it may be one of those things that is not as easy as it would appear.

@AaronZON - ok, makes sense, and on more thought this is probably the better way to do it. For example, if I put a motion sensor right above my sofa, I can then dim the lights and since it will be detecting motion the entire time I’m watching TV, the lights should neither go off or change from their manually controlled dimmed state. After motion stops, the countdown timer will begin and they will go off as per the user selected time.

Works for me… and thanks again for creating this!

1 Like

hi Dlee,
can you share the full code for the app so more of us can use it, the modifications you did are exactly what I am looking for.

Hi Faraz, I actually deleted my custom app when I started using @tslagle13 very helpful Lighting Director smartapp. It has some other time saving advantages like configuring up to 4 lights at once. It covers the use case I mentioned earlier with additional features and multiple code contributors. Take a look,

2 Likes

Hi Mike, I am new to this. I really like your auto dimmer app, the only thing I wish to have is to auto dim based on motion. When motion is detected, the dimmer set a higher level, when no motion detected, set the dimmer to a lower level (night lights), on/off is controlled by other sensor just like you current app does.

I have no programming skill. Is it possible for you or someone else to modify your app and create another “Auto Dim” app based on motion?

James

It would be pretty much a complete re-write of autoDimmer to work this way.
While I don’t know of an app that does this right out of the box, one must exist…
I’m sure folks will jump in with some canned ways of doing this.

I think this can be done with routines. Routines can be triggered when things settle down or when things start happening. So you could theoretically have one routine that says when things start to happen set dimmer to 80% and another one that says when things settle down set dimmer to 20%.

You should be able to select which motion sensor you want to use for when things settle down and things start to happen.

I created Smart Lights On, that solves some of this, but does not have motion detection (yet). It will only turn off the lights if they were off when they were triggered in the first place, and IF you manually turn them off and on while the timer is running, they will stay on.

Unfortunately none of the built-in apps detects this, which makes most of the lights on/off apps rather uselessly annoying in my opinion. I use “Smarts Lights On” all over my house, so if I turn on a light, it stays on if that what I meant to do.