[OBSOLETE] Bathroom Light Control

Bathroom Light Control
Initial Release: 1.0.1

Controls bathroom lights:

  • Turn on light when motion is detected.
  • Turn off light after x minutes of no motion detection
  • Extend light off timer to x minutes if humidity sensor is above the average for the room and trending upward (shower in use?)

Developed / Tested with Aeon Multisensor which by default sends humidity every 8 minutes. We need to detect that humidity is rising with 1 reading as most people will want this to kick in by the 8 minute period and not 2 polls which would be 16 minutes. To do so we calculate the average temp over a period of readings (4 by default), then if the humidity is higher than the average and higher than the last reading, it is determined that humidity level is trending upward, so we adjust the off timer to extend light run time.

I am using 5 minute off time based on motion and 10 minute off time if Humidity level is high and trending upward.

Someday I may redo configuration as a dynamic page so that I can show in the app the current humidity trend and timer being used.

Latest sourcecode can be found at:


I have found some issues with the released 1.0.1 app that I am working out. Specifically some debug stuff made it into the final posting for Version 1.0.1 which actually breaks the expected humidity trending.

I am testing and working on Version 1.0.2 which should be out soon.

looking forward to the update.

If you anyone would like to test, I have the version 1.0.2-Beta2 test code up in the testing tree on GitHub here:

If you test it, please let me know if you find any bugs, if you see something that can be adjusted/improved or if it is working for you as desired. Keep in mind that with the Aeon multisensor, we have to determine the trend off of a limited 1 reading to determine if the shower is in use to keep trending time down to 8 minutes rather than 16+ minutes; it may be best to set the motion timer to a minimum of 9 minutes to prevent the light from turning off before it can detect that humidity is rising).

Beta release 1.0.2-Beta2.
Change Log

  • 1.0.2-Beta1
  • Modified pages to dynamic pages
  • Added default app launch into Status page showing humidity, light, and fan status. Status page contains Configure button.
  • Added auto-exhaust fan option (toggles on when humidity > avg. or off when humidity <= avg and humidity or light switch event occurs)
  • Removed debug code that prevented analyzing “currentHumidity” and averaging/trending as intended
  • Added in app notification event (not push notifications, but notices within the SmartThings mobile app) for testing/debugging purposes
  • Modified logged data to better detect where we are in code based on Trace/Debug log.
  • Added logging level option in code. 0 = off, 1 = on, 2 = debug. Configured by changing variable in initialize()
  • General code cleanup (tabs/spacing, commenting, etc)
  • 1.0.2-Beta2
  • Adjusted trending determination threshold from +/- 1% to +/- 0.5%

Found a bug related to manually turning the light on, fixed and pushed 1.0.2-Beta3 to the testing branch.

  • 1.0.2-Beta3
  • Corrected issue with comparing current light change event with last known status.

Also failed to mention in the last post that I rearranged a few points where I called out to turn the light on, to make that process faster. Previously, I called some unschedule events before calling to turn the lights on. This seemed to cause a noticeable delay in turning the light on. Calling lightsOn() before unschedule() resolved the issue.

Sometimes (most of the time), I update too soon. I have tested and added quite a few changes to the testing branch since my last update. 1.0.2-Beta5 should be more stable.

  • Added timestamp to: last Humidity reading, last light switch event, and last fan event
  • Show timestamp on status page (will not show until after an event actually occurs)
  • Will show “null” until an event occurs if you do not go into configure and hit Done.
  • Adjusted humidity trend sensitivity back to 1% instead of the previous adjustment to 0.5% as this was way to sensitive. Note the actual humidity trend will still show “stay” even if it decreases/increases naturally by more than 1.0% consecutively up/down per reading. I think when the shower is in use this will be more than 1.0% per reading. This may continue to be adjusted during testing. Even though actual environment humidity may be trending up/down, I don’t think we want to adjust our light timer unless the trend is significant as our target is to detect the shower being in use, not natural occurance.
  • Just a note that it seems that the Aeon multisensor does not send any humidity data if the humidity hasn’t changed, which is another reason to change the sensitivity back to 1% from 0.5% so that we re-enter “stay” mode and return our lightsOut timer back to motion from humidity quicker.

just installed and it looks good. Are you plaining on adding control over multiple lights?

I have 1 light in my bathroom, so I designed it really for that. The app is setup to be installed once per bathroom so I have my app installed twice and labeled for “Front Bathroom” and “Back Bathroom”.
I don’t have a z-wave controlled fan though, but did add support for one.
If it’s a need, I’ll check into adding additional light/fan support per bathroom/install.

My vanity fixture has four bulbs in. The light on the ceiling I don’t use as the room is small. Multiple lights would make it a more elegant solution for me. :slight_smile: great work!

This is so close to something I have been looking for, I just happen to stink at writing groovy.

I have two lights in my bathroom, a bathroom light and a shower light each controlled by their z-wave switch.

What I would like to do is

  1. Turn on the bathroom light when I enter the bathroom.
  2. When the humidity trends up then turn off the bathroom light and turn on the shower light BUT
  3. Don’t turn on the bathroom light until the humidity trends down.

Anyway this can be accomplished @rayzurbock

In my half bath on the main floor I just have a Lutron dimmer/motion sensor (non zwave/zigbee). I have it set to turn off the light three minutes after no motion is detected but the feature I really like and might benefit your app (and others maybe) is when there is 30 seconds of the 3 minutes left it dims the lights to 50% as a warning. I can see different reasons why someone is still in the bathroom but does not trigger the motion sensor so this is a nice warning feature. I wonder how easy/hard that would be to incorporate.

1 Like

3 minutes? I can definitely say “your use case is not my use case.” :wink:

Bathroom habits are one of those things that vary a lot.

Just a couple of use case thoughts. Doesn’t mean any changes are needed, just means people considering approach should make sure the settings they choose fit their particular use case, including visitors. (Lights going off in the bathroom while new girlfriend is taking a bath = not good.)

  1. if the bathroom has a tub as well as a shower, lights will probably turn off too soon if the time off extension is based on humidity trending up. Baths and showers both increase humidity substantially, but have very different trend graphs.

  2. if somebody passes out, the room will be dark when they come to.

  3. people do a lot of different things in bathrooms, some of which involve very little motion for extended periods of time. Those with IBS, women with menstrual cramps, people dyeing their hair or exfoliating, even meditation. And baths.

  4. dimming lights to 50 % would be a safety hazard for many people. (Realizing you have to get out of the bath quickly, for example.)

Obviously set up anything you want if you’re the only one who ever uses the bathroom. Just a few things to consider if you do have guests. :smiley::blush:

1 Like

Well, that would be your use case and opinions. My wife uses that bathroom as well and the motion sensor is quite sensitive and the lights have never gone out while the room was being used. Dimming the lights 50% is not a safety hazard, at least for my (as stated in my post) half bath which obviously has no shower or tub. This particular dimmer/motion sensor has a light on/off feature override if the bathroom had a shower and/or bathtub that would take the motion sensor and auto-off feature out of the picture. Having the 50% dim feature is quite nice and, if added to this or other smartapps, should be something that is configurable (if you don’t like it, don’t use it).

Personally I don’t think I’d tie my lights to temperature or humidity going up or down, don’t see how that would make any sense but that’s just me. After re-reading some of the posts I see the reasons for showers/baths and how it is implemented to keep the lights on, good idea. Just because you don’t think it is useful doesn’t mean others wouldn’t, my wife thinks the 50% dim 30 seconds before it is supposed to shutoff is a great feature. Yes, we do have guests and haven’t had any issues to date.

Yeah, like I said, different people, different use cases. If it’s working for you that’s great. :blush:

I’m quadriparetic, wheelchair dependent. Fall planning is a part of life, and a higher priority than ultra efficient energy saving. But every household’s different.

Another option for some households would be a guest switch where you can turn off some of the automatic shut offs by flipping a virtual switch.

I spend most of my time at home in one of the the bathrooms which missus has graciously declared and signed an agreement to be my zone… I code there too… And all gadgets gets tested there before it makes it to its designated place. It’s the lab and office for me.,:wink:

1 Like

Thanks for the conversation. I’ve picked up on some additional ideas for future releases. I’ve severely neglected the Bathroom Light Control SmartApp lately. It works for my situation (most of the time). I have some feature requests, mainly ability to control multiple lights such as a vanity with 4 or 5 smart light bulbs each with their own on/off “switch”. I’ve been focusing much of my development time on the Big Talker SmartApp where I have learned a lot. I’ll soon go back and revisit the feature requests and play with some of the ideas I have picked up from the recent conversation here for Bathroom Light Control.


Does this work with normal wall in-wall switches or does it need wifi switch and smart bulbs?

It needs either smart switches (typically Z wave or ZIgbee) or smart bulbs, but it doesn’t need both.

I got it and it works (almost) perfectly. Like mentioned on this post bathroom habits are very difficult. The goal was simple, when you get into the shower turn on the shower light and turn off the bathroom light and then reverse the process when you get out. The key was creating a virtual switch to blend with a series of if/then statements.

When you are not in the shower the virtual switch would be on, when you opened the door nothing happened, but when you closed the door the VS would turn off thus triggering the shower light and turning off the other lights. This is a super subjective smart app so it may not be for everyone but at least you can take from it what you want… and big thanks to all in the community that helped.

* Lights Off, When Closed
* Author: SmartThings
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 ("Virtual Switch goes here...") {
input "switch3", "capability.switch", title: "Virtual Switch"

section ("Turn on the shower light...") {
input "switch1", "capability.colorControl", 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(switch1, "setColor",colorHandler)
subscribe(switch2, "switch", bathroomSwitch)
subscribe(contact1, "contact.open", showerOpen)
subscribe(contact1, "contact.closed", showerClosed)
subscribe(motion1, "motion", motionHandler)
subscribe(switch3, "switch", virtualSwitch)
state.enabled = true

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

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

state.enabled = true

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

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

def motionHandler(evt) {
	log.debug "Motion Handler - Evt value: ${evt.value}"
    if (evt.value == "active") {
    	if (state.enabled) {
        	log.debug("Turning on lights")
            //switch2.off([delay: 600 * 1000])
        } else {
        	log.debug("Motion is disabled - not turning on lights")

def showerSwitch(evt) {
def bathroomState = switch2.currentValue("switch")
def showerState = switch1.currentValue("switch")
	if (evt.value == "on") {
        log.debug "The Shower Light is ${showerState} and the bathroom light is ${bathroomState}"
	} else {
		log.debug "The Shower Light is ${showerState} and the bathroom light is ${bathroomState}"
def bathroomSwitch(evt) {
def bathroomState = switch2.currentValue("switch")
def showerState = switch1.currentValue("switch")
	if (evt.value == "on"  && evt.isPhysical()){
    	log.debug "The Bathroom Light is ${bathroomState} and the Shower Light is ${showerState}"
  	} else {
    	log.debug "Switch Handler - Evt value: ${evt.value}, isPhysical: ${evt.isPhysical()}"
    if (evt.value == "off" && evt.isPhysical()) {
    	log.debug "Motion disabled"
    	state.enabled = true  
        log.debug "The Bathroom Light is ${bathroomState} and the Shower Light is ${showerState} and the Virtual Switch is now back on"  

def showerOpen(evt){
def bathroomState = switch2.currentValue("switch")
def showerState = switch1.currentValue("switch")
def vsOn = switch3.currentValue("switch")
def twentyMinutes = 12000
if (evt.value == "open" && bathroomState == "on" && showerState == "off"  && vsOn == "on") {
log.debug "The Shower Door is open and the bathroom light is on and the shower light is off so I am not really doing anything"
    log.debug "switch 3 is ${vsOn}"
    } else {
		if (evt.value == "open" && bathroomState == "off" && showerState == "on"  && vsOn == "off") {
        log.debug "The Shower Door is open and the bathroom light is off and the shower light is on so I am turning motion ${state.enable} because you are getting out of the shower"
         log.debug "switch 3 is ${vsOn}"

def showerClosed(evt){
def vsOn = switch3.currentValue("switch")
def bathroomState = switch2.currentValue("switch")
def showerState = switch1.currentValue("switch")
def motionState = motion1.currentState("motion")
def colorMap = [hue:new Random().nextInt(99) + 1,saturation:new Random().nextInt(99) + 1]
//def newestColor = colorMap + Math.abs(new Random().nextInt() % 500)
if (evt.value == "closed" && bathroomState == "on"  && showerState == "off"  && vsOn == "on"){
def showerOn = switch1.setLevel(99)
def twoSeconds = ([delay:2000])
//switch1.setColor(colorMap,[delay: 4 * 100])

// runIn(1,colorMap)

 log.debug "switch 3 is ${vsOn}"
log.debug "Door is Closed because you ARE taking a shower"

	} else {
if (evt.value == "closed" && showerState == "off"  && vsOn == "off"){
 log.debug "switch 3 is ${vsOn}"
1 Like

Can you please share? How to uninstall and reinstall this app? I am going to have to reconfigure as something went wrong when I changed my security to WPA2 with Aeon Multisensor.