I wanted to share the modifications I’ve made, as well as a problem I’m having.
I added additional “classes” of switches, so there are now three:
- Switches to dim to a certain level when motion is detected
- Switches to turn on (without dimming) when motion is detected
- Switches to monitor, which will disable the motionOff when turned on but are NOT turned on when motion is detected
I would like the motionOff handler to get disabled anytime anyone presses any of the switches in any of the three groups after the lights have already been turned on with motion. So if someone walks into the room and lights B, C, and D are turned on, I can tap switch B to keep the lights on and disable the auto-off. I want this because the whole room isn’t quite covered by the motion sensor, and even if you’re in sight of the motion sensor but you’re (for example) being a lump on the couch watching TV, it will think no one’s there and trigger motion Off.
The problem with this idea is that it seems my switches (Evolves) don’t send any events if they’re already on and you tap the “on” part of the paddle.
Here’s my code, adapted from @bravenel 's above:
definition(
name: "Conditional Motion OnOff",
namespace: "rogersmj",
author: "Matt Rogers",
description: "Turn on some lights with motion, only if they're ALL currently off.",
category: "My Apps",
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("Select the motion sensor...") {
input "motion1", "capability.motionSensor", title: "Which?", required: true, multiple: false
}
section("Select the switches to set to a certain dimmer level...") {
input "dimmer_switches", "capability.switchLevel", title: "Which?", required: false, multiple: true
}
section("Select the dimmer level...") {
input "level", "number", title: "Level?", required: false
}
section("Select the switches to turn on without setting dimmer level...") {
input "switches", "capability.switch", title: "Which?", required: false, multiple: true
}
section("And disable the motion trigger if any of these switches are on, but don't turn them on with motion...") {
input "watch_switches", "capability.switch", title: "Which?", required: false, multiple: true
}
section("Turn off this many minutes after motion stops...") {
input "minutes", "number", title: "Minutes?", required: true
}
}
def installed() {
// log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
// log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
subscribe(motion1, "motion.active", motionOnHandler)
subscribe(motion1, "motion.inactive", motionOffHandler)
}
def motionOnHandler(evt) {
state.switchOff = true
for(mySwitch in switches) state.switchOff = state.switchOff && (mySwitch.currentValue("switch") == "off")
for(mySwitch in dimmer_switches) state.switchOff = state.switchOff && (mySwitch.currentValue("switch") == "off")
for(mySwitch in watch_switches) state.switchOff = state.switchOff && (mySwitch.currentValue("switch") == "off")
if(state.switchOff) {
if(level) dimmer_switches.setLevel(level)
switches.on()
//Now we're in "auto" mode, so we need to start listening to these switches. If any are pressed,
//we need to disable the auto-off.
subscribe(switches, "switch.on", manualPressCheck)
subscribe(dimmer_switches, "switch.on", manualPressCheck)
subscribe(watch_switches, "switch.on", manualPressCheck)
}
}
def motionOffHandler(evt) {
if(state.switchOff) {
if(minutes>0) {
runIn(minutes*60,switchesOff)
} else {
switchesOff()
}
}
}
def switchesOff() {
switches.off()
dimmer_switches.off()
}
def manualPressCheck(evt) {
//This gets called when one of the listened-to switches gets turned on after the motion sensor already
//turned them on.
//If the event was physical (someone actually touched the switch), this will
//prevent the motionOff event from doing anything
if(evt.isPhysical()) {
state.switchOff = false
//And we can go ahead and stop listening to these switches now.
unsubscribe(switches)
unsubscribe(dimmer_switches)
unsubscribe(watch_switches)
}
}