Turning on my lights when it is raining?


(Justin) #1

This should be an easy one, but I am getting stuck and I am getting stuck on the UTC offset.

This is my goal: When it gets cloudy and/or rainy outside, I would like certain lights my house to come on. If I use an illuminance handler to trigger this it should be easy, but for the fact that the sunsets (and it gets dark before the sunset).

For example, I do not want the lights going on each day an hour before sunset because the illuminance drops, but I do want the lights to go on at 11:30am if it is pouring rain. In essence, I have to use the time of day as a buffer between when (and when not) to turn on the lights.

I used light up the night as my starting point and then added sections for start time, end time and offset time for UTC.

In a perfect world I would prefer that the app run based on sunrise and sunset meaning I can turn it on to activate 2 hours after sunrise and 2 hours after sunset and would love help on that

I must be doing something wrong because I receive the following error…

java.lang.NullPointerException: Cannot invoke method contains() on null object @ line 88

This is where I am on the app:

/**

  • Light Up The Night
  • Author: SmartThings
    */

// Automatically generated. Make future change here.
definition(
name: “Cloudy and Rainy Day”,
namespace: “smartthings”,
author: “SmartThings”,
description: “Turn your lights on when it gets dark and off when it becomes light again.”,
category: “Convenience”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet-luminance.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet-luminance@2x.png”,
iconX3Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)

preferences {
section(“Monitor the luminosity…”) {
input “lightSensor”, “capability.illuminanceMeasurement”

}
section("Time Settings"){
	input "What time does this Start?", "timeOfDay_begin", title: "Begins"
  	input "What time does this End?", "timeOfDay_end", title: "Ends"
    input "What is the UTC offset?", "timeOffset", title: "Offset"

}
section(“Turn On Switch…”) {
input “switches”, “capability.switch”, multiple: true
}
section(“Turn on Dimmers…”) {
input “dimmers”, “capability.switchLevel”, multiple: true

}
section("How bright?") {
	input "level","number", title: "How bright 0-99?", required:true
}

}

def installed() {
subscribe(lightSensor, “illuminance”, illuminanceHandler)
}

def updated() {
unsubscribe()

def currTime = now()
def currTime5 = currTime + 56060*1000
def timeOfDay_begin = timeToday(timeBegin)
def timeOfDay_end = timeToday(timeEnd)

def timeOfDay_end_plus24hours = timeOfDay_end.time+ 24*60*60*1000

def timeOfDay_begin5 = timeOfDay_begin.time - 5*60*60*1000  
def timeOfDay_end5 = timeOfDay_end.time - 5*60*60*1000

log.debug "currTime     $currTime   $currTime5"
log.debug "timeOfDay_begin.time   $timeOfDay_begin.time    $timeOfDay_begin5"
log.debug "timeOfDay_end.time    $timeOfDay_end.time    $timeOfDay_end5"


log.debug "timeOfDay_begin   $timeOfDay_begin"
log.debug "timeOfDay_end   $timeOfDay_end"

if(currTime >= timeOfDay_begin.time) log.debug "currTime >= timeOfDay_begin.time"
if(currTime <= timeOfDay_end.time) log.debug "currTime <= timeOfDay_end.time"

if(currTime >= timeOfDay_begin.time || currTime <= timeOfDay_end.time){
log.debug "should work"
}

if(currTime >= timeOfDay_begin5 || currTime <= timeOfDay_end5){
log.debug "555 should work  $timeOffset"
}

subscribe(lightSensor, “illuminance”, illuminanceHandler)

}
// New aeon implementation
def illuminanceHandler(evt) {
def lastStatus = state.lastStatus

def currTime = now()
def currTime5 = currTime + 5*60*60*1000
def timeOfDay_begin = timeToday(timeBegin)
def timeOfDay_end = timeToday(timeEnd)
def timeOfDay_end_plus24hours = timeOfDay_end.time+ 24*60*60*1000

log.debug currTime
log.debug timeOfDay_begin.time
log.debug timeOfDay_end_plus24hours

def timeOfDay_begin_UTCoffset = timeOfDay_begin.time - timeOffset*60*60*1000
def timeOfDay_end_plus24_UTCoffset = timeOfDay_end_plus24hours - timeOffset*60*60*1000


//http://build.smartthings.com/forums/topic/comparing-current-time-with-input-time/
//if current time is equal to or after user's time
if(currTime >= timeOfDay_begin.time || currTime <= timeOfDay_end.time){ //timeOfDay_end_plus24hours){
//  if(currTime5 >= timeOfDay_begin5 || currTime <= timeOfDay_end5){
 if (evt.integerValue < 201) {
    switches.on()
	dimmers.setLevel(level)
	state.lastStatus = "on"
}
else if (evt.integerValue > 201) {
    switches.off()
	state.lastStatus = "off"
}

}
}


(Justin) #2

I like replying to my own thread:

Alternatively the Smart Nightlight App accomplishes almost everything I need except one thing. The app is setup to key either off of the illuminance measurement or sunrise and sunset. I want to take an illuminance measurement, but at the same time only want to trigger the activity about 3 hours after sunrise or 2 hours before sunset as to avoid early morning and late evening light ups.


(Ray) #3

You are looking for something like this but without the Dimming option. Dusk-to-Dawn Dimming Motion Light - RC1


(Justin) #4

Not really… I saw this and this is sort of the opposite of what I am looking for. I have a few parts of my house that will get very dark when it rains outside (or gets very cloud). So when the Lux level drops below a certain point, I would like these lights to come on. That is the easy part. The tricky part involves dusk, dawn and night because during these periods of time the lux level will drop beneath the threshold and will turn on these lights (not good).

The workaround would be to enable the app to trigger only between certain times of the day. I think of two ways to do this:

  1. Only fire the trigger between x time and y time (ie. 11:00 am and 4:00pm); or
  2. Only fire the trigger between 3 hours after sunrise or 3 hours before sunset.

I actually made headway with alternative one, but the UTC offset thing really messed me up because no matter what time I placed into the app, the lights came on at 7 am in the morning.


(Mike Maxwell) #5

If you guys are still looking:


(Justin) #6

awsome! Wanna help with a bathroom lighting app I am working on?


(Mike Maxwell) #7

sure, first need to finish my ultimate scene capture replay app (95% done, waiting for a patch on the ST platform side), which is one app, unlimited device groups, each with unlimited scenes, then my bathroom motion/lux/humidity app…
Which I hope solves the issue of having the freaking lights turn off when you’re in the tub or shower…
What bathroom app are you working on?


(Justin) #8

Take a look at this, along with the comments. I am struggling on the last part. You see when you go into and out of a shower you open and close the door so you will run into a situation when you get out of the shower and close the door and ST will behave as if you got into the shower. What I need help with is coding the following if then statement: if bathroom door opens and then closes within 30 seconds --> turn off light1 and turn on light2 and re-enable motion detection I have no idea how to do this. Take a look at the code below:

    /**
* Lights Off, When Closed
*
* Author: SmartThings
*/
definition(
name: "Take A Shower",
namespace: "JDogg016",
author: "Justin Bennett",
description: "When you walk into the bathroom the bathroom light will come on. When you close the shower door, the bathroom light will go off after 5 seconds and the shower light will come on and the motion detection will be disabled for 20 minutes (during the shower). When you open the door, motion detection will re-enable and the light will come on.",
category: "Convenience",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_contact-outlet.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_contact-outlet@2x.png"
)

preferences {
section ("When the door closes...") {
input "contact1", "capability.contactSensor", title: "Where?"
}
section ("Turn on the shower light...") {
input "switch1", "capability.switch", title: "Shower Light"
}
section ("And turn off the bathroom light..."){
input "switch2", "capability.switch", title: "Bathroom Dimmer"
}
section ("Disable the bathroom motion sensor..."){
input "motion1", "capability.motionSensor", title: "Which Motion Sensor"

}
} 
def initialize() {
subscribe(switch1, "switch", showerSwitch)
subscribe(switch2, "switch", bathroomSwitch)
subscribe(contact1, "contact", showerEvent)
subscribe(motion1, "motion", motionHandler)
state.enabled = true
state.runOff = true

}
def installed()
{
log.debug "Intalled with settings ${settings}"
initialize ()

}
def updated(){
log.debug "Updated with settings ${settings}"
unsubscribe()
subscribe(switch1, "switch", showerSwitch)
subscribe(contact1, "contact", showerEvent)
subscribe(motion1, "motion", motionHandler)
subscribe(switch2, "switch", bathroomSwitch)

}
def enable() {
log.trace "Motion enabled"
state.enabled = true

}
def disable() {
log.trace "Motion disabled"
state.enabled = false

}

def turnOff() {
log.trace "Turning Bathroom Switch and re-enabling motion detection."
switch2.off()
state.enabled = true

}

def showerSwitch(evt) {
log.debug "$evt.value: $evt, $settings"
if (evt.value == "on") {
state.showerStatus = "on"
state.showerTimeOn = now()
log.debug "I have turned ${state.showerStatus} the shower light for you at ${state.showerTimeOn}"

} else {

if (evt.value == "off") {
state.showerStatus = "off"
state.showerTimeOff = now()
log.debug "I have turned ${state.showerStatus} the shower light for you at ${state.showerTimeOn}"
}
}
}

def bathroomSwitch(evt) {
log.debug "$evt.value: $evt, $settings"
if (evt.value == "on") {
state.lastStatus = "on"
state.onTime = now()
log.debug "I have turned on the bathroom switch for the next 7 minutes at ${state.onTime}" //I do not need to run the schedule at this point in time because it gets scheduled with the motion

} else if (evt.value == "off"){
state.lastStatus = "off"
state.offTime = now()
log.debug "I have turned off the bathroom switch at ${state.offTime}"
}
}
def motionHandler(evt) {
log.trace "Motion Handler - Evt value ${evt.value}"
if (evt.value == "active") {
if (state.enabled) {
log.trace ("I am turning on the lights because there was motion, I will turn them off automatically in 7 minutes")
switch2.on()
def sevenMinuteDelay = 60 * 7
runIn(sevenMinuteDelay, turnOff)
} else {
log.trace ("Motion is disabled - not turning on lights")
}
}	
}

def showerEvent(evt) {
log.trace "Currently the Shower Door is ${evt.value}"
if (evt.value == "open") {
state.enabled = true
state.ContactSensor = "open"
log.trace "The Shower Door is now ${state.ContactSensor} and Motion Detection is ${state.enabled} because you are about to get into the shower"
switch2.on() //instead of turning on the lights How do I call the event motionHandler(evt) and just activate motion to turn on the light? I want to do this in order to trigger the 7 minutes delay in turning off the light.
switch1.off([delay: 60 * 1000]);

} else {
   state.enabled = false
   switch1.on([delay:  3 * 1000])
   switch2.off([delay: 3 * 1000])
   state.ContactSensor = "closed"
   log.debug "The Shower Door is now ${state.ContactSensor} and Motion Detection is ${state.enabled} because you are now in the shower"
}
// }
// def outOfShower() {
//log.debug "$evt.value: $evt, $settings"
// def exitShower = 1 * 30
// if (state.OnTime < exitShower && state.ContactSensor != "closed") {
// switch2.on()
// state.enabled
// log.debug "The Batrhoom Switch is off and the Shower Door is ${state.ContactSensor} and Motion Detection is ${state.enabled} because you are exiting the shower"
// }
}

// def outOfShower is really giving me problems. What I want to do is ask the following statement: if switch2 time on < 30 seconds AND shower door is closed, then turn on (leave on) switch2 and turn off switch1

#9

Unfortunately, mesh networks like zwave and zigbee just don’t have any way of forcing sequencing. The whole reason these networks are inexpensive to run in terms of money and energy draw is that messages can bounce around the network for awhile, and even arrive out of order.

So it’s pretty much guaranteed that any logic based on “Happens within 30 seconds” is bound to fail sooner or later.

Is there anything other than a time interval or strict sequencing that could give you the result you want?


(Mike Maxwell) #10

The bath app I’m currently dinky doinking with uses moisture sensors to bump/extend the motion off timing.
You pick a humidity sensor as your baseline, then the one(s) in the bath, set a fixed interval above base line.
The auto off timing gets extended by an adjustable interval when the sensor(s) have detected humidity.
It’s a thought anyway…
The moisture sensors seem to take about 5 minutes to respond, while it’s working in beta.
I need to add auto fan control to the mix before releasing it…

Oh yea, and the motion lighting is controlled by selectable lux as well, so the entire activation is controlled by lux readings.


(Justin) #11

I have a humidity sensor and it takes too long to respond so it seems the best way would be to use the open/close sensor for a shower door.


(Mike Maxwell) #12

Yea, were it not for the timing issues, and the inevitable resulting out of sync problem.
I have two humidity sensors, one in the shower, the other on the tub. The key to getting this to work with humidity is setting the default motion off time to be longer than the humidity sensor rise time.
In my case, 10 minutes does the trick.

A water sensor would be better in the shower, but the freaking ST one illuminates the built in LED when it detects water, which was a stupid idea IMHO…


(Justin) #13

Didn’t even know that about the water sensor, I was told on this board not to get the water sensor because it may become unreliable if submerged (i.e. showered on daily).

I will keep plugging away and maybe I can come up with the trick.