Can someone help me write a code for a contact sensor

This is true. I’m wondering how you would account in a smart app for a “fake” non-motion event though.

(i’m not trying to prove my code or anything, i know it works in my home… nor am i trying disprove yours… i have a genuine interest in how you would account for this.) :smile:

My code would definitely work for the general someone is taking a pee or doing their hair scenario though… lol

If someone is motionless for large periods of time in the bathroom i can’t help you lol :stuck_out_tongue:

I am just doing this as a challenge. I gave up on trying to figure it out once before, but this post has sparked my interest in it. I think I have a solution that might work, but I won’t know until I get some actual code.

I think that the only way to stop a “fake” non-motion would be to make it dependent on the door sensor being at the very least open a 2nd time in a specific time space.

Let’s say a person went into the bathroom closed the door and is taking a bath, if the motion sensor doesn’t see motion but the door was never open again after being closed then it should not make an action

This would work in most cases… But then someone opens the door to grab a toothbrush and it would throw the whole sequence off.

1 Like

Hence, the challenge aspect of this. The bathroom is probably the hardest room in the house.

Agreed :smile:

Here’s my philosophy when i write an app. I try not to assume for any variable. If i don’t have emperical data about a situation i tend to not write it into an app. This is what I would do.

  1. You could custom make a trip sensor for the bath that would override all the different inputs for the smart app. SO when someone enters the shower the light stays on permanently.

2.You could use a moisture sensor in the bathtub that would also do the same thing when water is detected. Same thing here. It would over ride the other sensor inputs until no water is detected.

Agreed, but that’s why I have an absolute restart sequence timer for however long I think would be the minimum.

Most importantly as long as my wife doesn’t have the lights turn off on her which I think they won’t, if the lights stay on because something out of normal occurred than no problem.

P.S. who takes baths anymore? lol!

This bathroom occupancy thing was one thing I wanted to use ST for in the beginning but it’s too complicated for our household. In the end, this simple motion switch did it for us and it still works when the internet goes bonkers. I just have to make sure to move the shower door a bit to reset the motion counter.

http://amzn.com/B005WM3ALC

The problem isn’t the bath lol. It’s that fact that the motion sensor doesn’t sense a person behind the shower door.

1 Like

Much discussion of trying to determine occupancy in the following topic. It often comes down to whether you want to account for visitors (inlaws? little kids? new girlfriend?) who may not know your light protocols:

Many people will close a bathroom door almost all the way, but not quite, for any of many reasons. Little kids are an obvious example, but there are also people with arthritis who find door knobs difficult, parents listening for little kids in the other room, people in wheelchairs, new girlfriend taking a shower who wants to subtly let you know it’s OK to come in, etc.

In your own household, it’s up to you whether you want to take all of those into account or not.

1 Like

Seriously guys! Just “dump” the idea!

1 Like

Ok. I got something working. The door scenario described earlier works. The motion detector will turn off the light after a set period of time only if the door is open. Also, if it detects motion when the door is closed, it assumes that somebody is present and won’t turn off the light until after the door opens and closes again (or is opened and the timer expires). Let me know if this works for you, or if there is some special case I didn’t consider. Cheers!

/**
 *  Bathroom Lights Automater
 *
 *  Copyright 2015 Eric Roberts
 *
 *  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: "Bathroom Lights Automater",
    namespace: "baldeagle072",
    author: "Eric Roberts",
    description: "Automate your bathroom lights",
    category: "Convenience",
    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")


preferences {
	section("Bathroom Setup") {
		input "doorContact", "capability.contactSensor", title: "Door Contact Sensor", required: false, multiple: true
        input "motionSensor", "capability.motionSensor", title: "Motion Detector", required: false, multiple: true
        input "mainLights", "capability.switch", title: "Light", required: true, multiple: true
        input "timeout", number, title: "Timeout in minutes if door left open", required: false
	}
}

def installed() {
	log.debug "Installed with settings: ${settings}"

	initialize()
}

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

	unsubscribe()
	initialize()
}

def initialize() {
	subscribe(doorContact, "contact.open", openHandler)
    subscribe(doorContact, "contact.closed", closedHandler)
    state.out = true
}

def openHandler(evt) {
	log.debug("Open - state.out: ${state.out}")
    unsubscribe(motionSensor)
	subscribe(motionSensor, "motion", openMotionHandler)
    mainLights.on()
    if (state.out) {
    	state.out = false
    } else {
    	state.out = true
    }
}

def closedHandler(evt) {
	log.debug("Closed - state.out: ${state.out}")
	unsubscribe(motionSensor)
    unschedule()
    subscribe(motionSensor, "motion.active", closedMotionHandler)
	if (state.out) {
    	mainLights.off()
    }
}

def closedMotionHandler(evt) {
	log.debug("closed motion")
	state.out = false
    mainLights.on()
}

def openMotionHandler(evt) {
	log.debug("Motion - evt.value: ${evt.value}")
	if (evt.value == "active") {
    	mainLights.on()
        unschedule()
    } else {
    	runIn(timeout.toInteger() * 60, timedout)
    }
}

def timedout() {
	log.debug("timedout")
	mainLights.off()
}
2 Likes

@baldeagle072 I think its great, only thing I would want to do is be able to assign the time of day when the app should run. Im sure there will be a situation under which something will need to be changed, but currently I cant imagine what it could possibly be.

You can set which mode it runs in at the bottom of the preferences page

The enerwave ceiling mount motion sensor does a fabulous job of dealing with that.

I think @baldeagle072 has solved it. I am working on some tweaks to the code that might prevent some false positives/negatives.

1 Like

@baldeagle072 I had a chance to run the system, and while by no means am I close to it being as perfect as I thought it would be, I think the main thing Im missing is that the lights don’t turn off if the door is left open. For some reason the feature is not working. Thank You again for the help.

Are you using a motion sensor?

@borya - I think I might have fixed what the problem might have been. If there was no motion registered, but the door was left open, the light would stay on. Replace the openHandler(evt) function with the code below. It should fix it. It sets the timer if there is no motion to begin with. Let me know if that works for you.

def openHandler(evt) {
	log.debug("Open - state.out: ${state.out}")
    unsubscribe(motionSensor)
	subscribe(motionSensor, "motion", openMotionHandler)
    mainLights.on()
    motionSensor.each {
        if (it.currentValue("motion") != "active"){
            runIn(timeout.toInteger() * 60, timedout)
        }
    }
    if (state.out) {
    	state.out = false
    } else {
    	state.out = true
    }
}