Update WindowOrDoorOpen.groovy
[smartapps.git] / third-party / AutomaticCarHA.groovy
1 /**
2  *  AutomaticCarHA
3  *
4  *  Copyright 2015 Yves Racine
5  *  LinkedIn profile: ca.linkedin.com/pub/yves-racine-m-sc-a/0/406/4b/
6  *
7  *  Developer retains all right, title, copyright, and interest, including all copyright, patent rights, trade secret 
8  *  in the Background technology. May be subject to consulting fees under the Agreement between the Developer and the Customer. 
9  *  Developer grants a non exclusive perpetual license to use the Background technology in the Software developed for and delivered 
10  *  to Customer under this Agreement. However, the Customer shall make no commercial use of the Background technology without
11  *  Developer's written consent.
12  *
13  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
14  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
15  *
16  *  Software Distribution is restricted and shall be done only with Developer's written approval.
17  *
18  *  N.B. Requires MyAutomatic device available at 
19  *          http://www.ecomatiqhomes.com/#!store/tc3yr 
20  *
21  */
22 definition(
23         name: "AutomaticCarHA",
24         namespace: "yracine",
25         author: "Yves Racine",
26         description: "Near Real-Time Automatic Car automation with SmartThings", 
27         category: "My Apps",
28         iconUrl: "https://www.automatic.com/_assets/images/favicons/favicon-32x32-3df4de42.png",
29         iconX2Url: "https://www.automatic.com/_assets/images/favicons/favicon-96x96-06fd8c85.png",
30         iconX3Url: "https://www.automatic.com/_assets/images/favicons/favicon-96x96-06fd8c85.png"
31 )
32
33 preferences {
34
35         page(name: "HASettingsPage", title: "Home Automation Settings")
36         page(name: "otherSettings", title: "OtherSettings")
37
38 }
39
40 def HASettingsPage() {
41         def phrases = location.helloHome?.getPhrases()*.label
42
43         dynamicPage(name: "HASettingsPage", install: false, uninstall: true, nextPage: "otherSettings") {
44                 section("About") {
45                         paragraph "Near Real-Time Automatic Car automation with SmartThings" 
46                         paragraph "Version 1.0.4" 
47                         paragraph "If you like this smartapp, please support the developer via PayPal and click on the Paypal link below " 
48                                 href url: "https://www.paypal.me/ecomatiqhomes",
49                                         title:"Paypal donation..."
50                         paragraph "Copyright©2016 Yves Racine"
51                                 href url:"http://github.com/yracine/device-type.myautomatic", style:"embedded", required:false, title:"More information..."  
52                                         description: "http://github.com/yracine"
53                 }
54                 section("For the following Automatic Connected Vehicle") {
55                         input "vehicle", "capability.presenceSensor", title: "Which vehicle?"
56                 }
57                 section("And, when these trip events are triggered") {
58                         input "givenEvents", "enum",
59                                 title: "Which Events(s)?",
60                                 multiple: true,
61                                 required: true,
62                                 metadata: [
63                                         values: [
64                                                 'ignition:on',
65                                                 'ignition:off',
66                                                 'trip:finished',
67                                                 'notification:speeding',
68                                                 'notification:hard_brake',
69                                                 'notification:hard_accel',
70                                                 'mil:on',
71                                                 'mil:off',
72                                                 'hmi:interaction',
73                                                 'location:updated',
74                                         ]    
75                                 ]    
76
77                 }
78                 section("Turn on/off or Flash the following switch(es) [optional]") {
79                         input "switches", "capability.switch", required:false, multiple: true, title: "Which switch(es)?"
80                         input "switchMode", "enum", metadata: [values: ["Flash", "Turn On","Turn Off"]], required: false, defaultValue: "Turn On", title: "Action?"
81                 }
82                 section("Select Routine for Execution [optional]") {
83                         input "phrase", "enum", title: "Routine?", required: false, options: phrases
84                 }
85         } /* end of dynamic page */
86 }
87
88
89 def otherSettings() {
90         dynamicPage(name: "otherSettings", title: "Other Settings", install: true, uninstall: false) {
91                 section("Detailed Notifications") {
92                         input "detailedNotif", "bool", title: "Detailed Notifications?", required:
93                                 false
94                 }
95                 section("Notifications") {
96                         input "sendPushMessage", "enum", title: "Send a push notification?", metadata: [values: ["Yes", "No"]], required:
97                                 false
98                         input "phoneNumber", "phone", title: "Send a text message?", required: false
99                 }
100                 section([mobileOnly: true]) {
101                         label title: "Assign a name for this SmartApp", required: false
102                 }
103         }
104 }
105
106
107
108
109 def installed() {
110         initialize()
111 }
112
113 def updated() {
114         try {
115                 unschedule()
116         } catch (e) {
117                 log.debug ("updated>exception $e while trying to call unschedule") 
118         }    
119         unsubscribe()
120         initialize()
121 }
122
123 def initialize() {
124         subscribe(vehicle, "eventTripCreatedAt", eventHandler)
125 }
126
127 def eventHandler(evt) {
128         def msg
129
130         def createdAt =vehicle.currentEventTripCreatedAt   
131         String eventType = vehicle.currentEventType
132         log.debug "eventHandler>evt.value=${evt.value}, eventType=${eventType}"
133     
134         def lat = vehicle.currentEventTripLocationLat    
135         def lon = vehicle.currentEventTripLocationLon
136         msg = "AutomaticCarHA>${vehicle} vehicle has triggered ${eventType} event at ${createdAt}, (lon: ${lon}, lat: ${lat})..."
137         log.debug msg
138         if (detailedNotif) {
139                 send msg    
140         }
141         check_event(eventType)
142 }
143
144
145 private boolean check_event(eventType) {
146         def msg
147         boolean foundEvent=false  
148     
149         log.debug "check_event>eventType=${eventType}, givenEvents list=${givenEvents}"
150         if ((givenEvents.contains(eventType))) {
151                 foundEvent=true    
152                 msg = "AutomaticCarHA>${vehicle} vehicle has triggered ${eventType}, about to ${switchMode} ${switches}"
153                 log.debug msg
154                 if (detailedNotif) {
155                         send msg    
156                 }
157                         
158                 if (switches) {
159                         if (switchMode?.equals("Turn On")) {
160                                 switches.on()
161                         } else if (switchMode?.equals("Turn Off")) {
162                                 switches.off()
163                         } else {
164                                 flashLights()
165                         }       
166                 }
167                 if (phrase) {
168                         msg = "AutomaticCarHA>${vehicle} vehicle has triggered ${eventType}, about to execute ${phrase} routine"
169                         log.debug msg
170                         if (detailedNotif) {
171                                 send msg    
172                         }
173                         location.helloHome?.execute(phrase)        
174                 }        
175         }
176         return foundEvent
177 }
178
179
180 private flashLights() {
181         def doFlash = true
182         def onFor = onFor ?: 1000
183         def offFor = offFor ?: 1000
184         def numFlashes = numFlashes ?: 3
185
186         log.debug "LAST ACTIVATED IS: ${state.lastActivated}"
187         if (state.lastActivated) {
188                 def elapsed = now() - state.lastActivated
189                 def sequenceTime = (numFlashes + 1) * (onFor + offFor)
190                 doFlash = elapsed > sequenceTime
191                 log.debug "DO FLASH: $doFlash, ELAPSED: $elapsed, LAST ACTIVATED: ${state.lastActivated}"
192         }
193
194         if (doFlash) {
195                 log.debug "FLASHING $numFlashes times"
196                 state.lastActivated = now()
197                 log.debug "LAST ACTIVATED SET TO: ${state.lastActivated}"
198                 def initialActionOn = switches.collect {
199                         it.currentSwitch != "on"
200                 }
201                 int delay = 1 
202                 numFlashes.times {
203                         log.trace "Switch on after  $delay msec"
204                         switches.eachWithIndex {
205                                 s, i ->
206                                         if (initialActionOn[i]) {
207                                                 s.on(delay: delay)
208                                         } else {
209                                                 s.off(delay: delay)
210                                         }
211                         }
212                         delay += onFor
213                         log.trace "Switch off after $delay msec"
214                         switches.eachWithIndex {
215                                 s, i ->
216                                         if (initialActionOn[i]) {
217                                                 s.off(delay: delay)
218                                         } else {
219                                                 s.on(delay: delay)
220                                         }
221                         }
222                         delay += offFor
223                 }
224         }
225 }
226
227
228
229
230
231 private def send(msg) {
232         if (sendPushMessage != "No") {
233                 log.debug("sending push message")
234                 sendPush(msg)
235
236         }
237
238         if (phoneNumber) {
239                 log.debug("sending text message")
240                 sendSms(phoneNumber, msg)
241         }
242
243         log.debug msg
244 }