Bathroom Open/Close Sensor for Shower Door


(Justin) #1

So I was sort of disappointed in the smartthings humidity sensor as I had a significant amount of help crafting an app that would run a series of events based upon my shower turning on (and the humidity rising). So I sort of started over with the idea of triggering sequences based upon the open/closed state of the shower.

Based on what I have written (thus far), the lights trigger when I open/close the shower door. What I am looking for is the following:

  1. To disable my bathroom motion sensor for a period of 30 minutes when the door is closed.
  2. If the shower door is left open for more than 10 seconds, restore the ability to use the motion sensor and turn off the shower light (light one when the door closes again). This covers any scenario whereby the user opens the door not intending to take a shower to NOT trigger the light sequence upon closing the door.

Anyway, this is what I have thus far.

/**
 *  Lights Off, When Closed
 *
 *  Author: SmartThings
 */
definition(
    name: "Take A Shower",
    namespace: "JDogg016",
    author: "Justin Bennett",
    description: "Turn the shower light (for 30 minutes) on when you close the shower door and turn off the bathroom light, then reverse the process when the door opens.",
    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 installed()
{
	log.debug "Intalled with settings ${settings}"
    subscribe(contact1, "contact.closed", contactClosedHandler)
    subscribe(contact1, "contact.open", contactOpenHandler)
    subscribe(motion1, "motion", motionHandler)
    state.enabled = true
    state.runoff = true
}

def updated()
{
	log.debug "Updated with settings ${settings}"
    unsubscribe()
	subscribe(contact1, "contact.closed", contactClosedHandler)
    subscribe(contact1, "contact.open", contactOpenHandler)
}

def motionHandler(evt) {
	log.debug "Motion Handler - Evt value: ${evt.value}"
    if (evt.value == "active") {
    if (state.enabled) {
    	log.debug("Turning on lights")
        switch2?.on()
              } else {
        	log.debug ("Motion disabled - not turning on lights")

}
}
}

def contactClosedHandler(evt) {
	log.debug "Closed Handler - Evt Value: ${evt.value}"
    if (evt.value == "closed") {
     log.trace "I have turned on the shower light and turned off the bathroom light for the next 30 minutes"
     state.enabled = false
    switch1.on()
    switch2.off()
    def thirtyMinuteDelay = 1800
    runIn(thirtyMinuteDelay, getOutShower)
   
}
}

def getOutShower() {
	switch1.off()
    switch2.on()

}

def contactOpenHandler(evt) {
	switch1.off()
    switch2.on()
    def thirtyOneMinuteDelay = 1860
    runIn(thirtyOneMinuteDelay, turnOffSwitch)
   	log.trace "Your Shower is done, I have turned off the shower light and turned on the bathroom light for the next 31 minutes"
}

def turnOnSwitch() {
	switch1.off
    switch2.off
}

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

(Justin) #2

I think the way I would envision the flow is as follows (I am just terrible with writing time into apps)

  1. Shower door closes and light 1 goes on and light 2 goes off (entering the shower), motion detector in the bathroom disables to not inadvertently turn on light 2.
  2. Shower door then opens and light 1 goes OFF and light 2 goes ON (leaving the shower), motion detector then re-anables to detect motion.
  3. Shower door then closes (again)… and NOTHING Happens because you are simply closing a door behind you.

Sorry… this is a bit of a mind puzzler…


(Bruce) #3

Why not add a motion sensor in the shower? I’ve done that in 3 showers – they turn on lights and/or fans, that turn off with no motion later.


(Justin) #4

Tried that too. I can’t place the motion sensor in a place where it won’t get inadvertently triggered due to notion in the bathroom.


(Justin) #5

So this is how far I have gotten with help from @baldeagle072 who helped tremendously with his app that disables the motion sensor. I can now successfully (i) activate the bathroom light for 7 minutes based upon motion; (ii) open the shower door turning on the bathroom light (if needed); (iii) close the shower door and turn off the bathroom light while turning on the shower light and disabling the motion sensor as to not turn on the light due to motion.

Now in the code (below), I am missing one thing and that is the process to get out of the shower. The way I envisioned it, when I re-open the shower door it presents a unique scenario whereby the bathroom switch (switch2) would come on and then I would close the door within 30 seconds. I have no idea how to write this logic as I am just learning about ‘states’. Please see the code below and let me know where I am going wrong.

/**

  • 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