/** * Copyright 2015 SmartThings * * 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. * * Double Tap * * Author: SmartThings */ definition( name: "Double Tap", namespace: "smartthings", author: "SmartThings", description: "Turn on or off any number of switches when an existing switch is tapped twice in a row.", category: "Convenience", iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet.png", iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_outlet@2x.png" ) preferences { section("When this switch is double-tapped...") { input "master", "capability.switch", title: "Where?" } section("Turn on or off all of these switches as well") { input "switches", "capability.switch", multiple: true, required: false } section("And turn off but not on all of these switches") { input "offSwitches", "capability.switch", multiple: true, required: false } section("And turn on but not off all of these switches") { input "onSwitches", "capability.switch", multiple: true, required: false } } def installed() { subscribe(master, "switch", switchHandler, [filterEvents: false]) } def updated() { unsubscribe() subscribe(master, "switch", switchHandler, [filterEvents: false]) } def switchHandler(evt) { log.info evt.value // use Event rather than DeviceState because we may be changing DeviceState to only store changed values def recentStates = master.eventsSince(new Date(now() - 4000), [all:true, max: 10]).findAll{it.name == "switch"} log.debug "${recentStates?.size()} STATES FOUND, LAST AT ${recentStates ? recentStates[0].dateCreated : ''}" if (evt.physical) { if (evt.value == "on" && lastTwoStatesWere("on", recentStates, evt)) { log.debug "detected two taps, turn on other light(s)" onSwitches1()*.on() } else if (evt.value == "off" && lastTwoStatesWere("off", recentStates, evt)) { log.debug "detected two taps, turn off other light(s)" offSwitches1()*.off() } } else { log.trace "Skipping digital on/off event" } } private onSwitches1() { def t1 = (switches).findAll{it} def t2 = (onSwitches).findAll{it} def t3 = t1+t2 t3 } private offSwitches1() { def t1 = (switches).findAll{it} def t2 = (offSwitches).findAll{it} def t3 = t1+t2 t3 } private lastTwoStatesWere(value, states, evt) { def result = true /*if (states) { log.trace "unfiltered: [${states.collect{it.dateCreated + ':' + it.value}.join(', ')}]" def onOff = states.findAll { it.physical || !it.type } log.trace "filtered: [${onOff.collect{it.dateCreated + ':' + it.value}.join(', ')}]" // This test was needed before the change to use Event rather than DeviceState. It should never pass now. if (onOff[0].date.before(evt.date)) { log.warn "Last state does not reflect current event, evt.date: ${evt.dateCreated}, state.date: ${onOff[0].dateCreated}" result = evt.value == value && onOff[0].value == value } else { result = onOff.size() > 1 && onOff[0].value == value && onOff[1].value == value } }*/ result }