definition( name: "setTimeout", namespace: "cramforce", author: "Malte", description: "Debounce switches based on switches, contact, and motion sensors.", category: "Convenience", iconUrl: "https://png.pngtree.com/svg/20170719/react_1353128.png", iconX2Url: "https://png.pngtree.com/svg/20170719/react_1353128.png" ) preferences { section("Debounce on motion"){ input "motion", "capability.motionSensor", title: "Motion sensors", multiple: true } section("Debounce on door open"){ input "contact", "capability.contactSensor", title: "Contact sensors", multiple: true } section("And off after minutes..."){ input "minutes", "number", title: "Minutes?" } section("Turn on/off light(s)..."){ input "switches", "capability.switch", multiple: true } } def installed() { subscribe(motion, "motion", stateChanged) subscribe(contact, "contact", stateChanged) subscribe(switches, "switch", stateChanged) } def updated() { unsubscribe() installed() } def stateChanged(evt) { log.debug "$evt.name: $evt.value" if (evt.value == "on") { log.info "Switched turned on: ${evt.description}" maybeDebounce(); return; } if (evt.value == "off") { log.info "Switched turned on: ${evt.description}" // Ignore the next event if light was manually turned off. state.ignoreNext = true; return; } if (evt.value == "active") { log.info "Motion active: ${evt.description}" maybeDebounce(); return; } if (evt.value == "open") { log.info "Door open: ${evt.description}" maybeDebounce(); return; } } def maybeDebounce() { log.info "Debounce. Turning on lights. Scheduling timer." state.ignoreNext = false; switches.on(); runIn(minutes * 60, timerHandler) } def timerHandler() { if (state.ignoreNext) { log.info "Ignoring debounce" state.ignoreNext = false; return; } log.info "Timer fired" if (motion.currentValue("motion").any { log.debug it; it == "action" }) { log.info "Motion still active" maybeDebounce(); return } if (contact.currentValue("contact").any { log.debug it; it == "open" }) { log.info "Door still open" maybeDebounce(); return } log.info "No debounce condition met. Turning off lights" switches.off(); }