Update double-tap.groovy
[smartapps.git] / official / the-flasher.groovy
1 /**
2  *  Copyright 2015 SmartThings
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  *  in compliance with the License. You may obtain a copy of the License at:
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
10  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
11  *  for the specific language governing permissions and limitations under the License.
12  *
13  *  The Flasher
14  *
15  *  Author: bob
16  *  Date: 2013-02-06
17  */
18 definition(
19     name: "The Flasher",
20     namespace: "smartthings",
21     author: "SmartThings",
22     description: "Flashes a set of lights in response to motion, an open/close event, or a switch.",
23     category: "Convenience",
24     iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_motion-outlet-contact.png",
25     iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_motion-outlet-contact@2x.png"
26 )
27
28 preferences {
29         section("When any of the following devices trigger..."){
30                 input "motion", "capability.motionSensor", title: "Motion Sensor?", required: false
31                 input "contact", "capability.contactSensor", title: "Contact Sensor?", required: false
32                 input "acceleration", "capability.accelerationSensor", title: "Acceleration Sensor?", required: false
33                 input "mySwitch", "capability.switch", title: "Switch?", required: false
34                 input "myPresence", "capability.presenceSensor", title: "Presence Sensor?", required: false
35         }
36         section("Then flash..."){
37                 input "switches", "capability.switch", title: "These lights", multiple: true
38                 input "numFlashes", "number", title: "This number of times (default 3)", required: false
39         }
40         section("Time settings in milliseconds (optional)..."){
41                 input "onFor", "number", title: "On for (default 1000)", required: false
42                 input "offFor", "number", title: "Off for (default 1000)", required: false
43         }
44 }
45
46 def installed() {
47         log.debug "Installed with settings: ${settings}"
48
49         subscribe()
50 }
51
52 def updated() {
53         log.debug "Updated with settings: ${settings}"
54
55         unsubscribe()
56         subscribe()
57 }
58
59 def subscribe() {
60         if (contact) {
61                 subscribe(contact, "contact.open", contactOpenHandler)
62         }
63         if (acceleration) {
64                 subscribe(acceleration, "acceleration.active", accelerationActiveHandler)
65         }
66         if (motion) {
67                 subscribe(motion, "motion.active", motionActiveHandler)
68         }
69         if (mySwitch) {
70                 subscribe(mySwitch, "switch.on", switchOnHandler)
71         }
72         if (myPresence) {
73                 subscribe(myPresence, "presence", presenceHandler)
74         }
75 }
76
77 def motionActiveHandler(evt) {
78         log.debug "motion $evt.value"
79         flashLights()
80 }
81
82 def contactOpenHandler(evt) {
83         log.debug "contact $evt.value"
84         flashLights()
85 }
86
87 def accelerationActiveHandler(evt) {
88         log.debug "acceleration $evt.value"
89         flashLights()
90 }
91
92 def switchOnHandler(evt) {
93         log.debug "switch $evt.value"
94         flashLights()
95 }
96
97 def presenceHandler(evt) {
98         log.debug "presence $evt.value"
99         if (evt.value == "present") {
100                 flashLights()
101         } else if (evt.value == "not present") {
102                 flashLights()
103         }
104 }
105
106 private flashLights() {
107         def doFlash = true
108         def onFor = onFor ?: 1000
109         def offFor = offFor ?: 1000
110         def numFlashes = numFlashes ?: 3
111
112         log.debug "LAST ACTIVATED IS: ${state.lastActivated}"
113         if (state.lastActivated) {
114                 def elapsed = now() - state.lastActivated
115                 def sequenceTime = (numFlashes + 1) * (onFor + offFor)
116                 doFlash = elapsed > sequenceTime
117                 log.debug "DO FLASH: $doFlash, ELAPSED: $elapsed, LAST ACTIVATED: ${state.lastActivated}"
118         }
119
120         if (doFlash) {
121                 log.debug "FLASHING $numFlashes times"
122                 state.lastActivated = now()
123                 log.debug "LAST ACTIVATED SET TO: ${state.lastActivated}"
124                 def initialActionOn = switches.collect{it.currentSwitch != "on"}
125                 def delay = 0L
126                 numFlashes.times {
127                         log.trace "Switch on after  $delay msec"
128                         switches.eachWithIndex {s, i ->
129                                 if (initialActionOn[i]) {
130                                         s.on(delay: delay)
131                                 }
132                                 else {
133                                         s.off(delay:delay)
134                                 }
135                         }
136                         delay += onFor
137                         log.trace "Switch off after $delay msec"
138                         switches.eachWithIndex {s, i ->
139                                 if (initialActionOn[i]) {
140                                         s.off(delay: delay)
141                                 }
142                                 else {
143                                         s.on(delay:delay)
144                                 }
145                         }
146                         delay += offFor
147                 }
148         }
149 }
150