1 //Infrastructure for SmartThings Application
3 import groovy.transform.Field
6 import ContactSensor.Contacting
7 import ContactSensor.Contacts
10 import Switch.Switching
11 import Switch.Switches
13 import Location.LocationVar
14 import Location.Phrase
15 import appTouch.Touched
18 //GlobalVariables for both Apps
19 //Create a global variable for send event
20 @Field def sendEvent = {eventDataMap ->
21 app1.eventHandler(eventDataMap)
22 app2.eventHandler(eventDataMap)
25 @Field def locationObject = new LocationVar()
27 @Field def appObject = new Touched(sendEvent, 0)
29 //Extracted global objects for both Apps
30 //Global Object for class lock!
31 @Field def lockObject = new Locking(sendEvent, 1)
32 //Global Object for class contactSensor!
33 @Field def contactObject = new Contacting(sendEvent, 1)
34 //Global Object for class Switch!
35 @Field def switchObject = new Switching(sendEvent, 2)
43 //Extracted objects for App1
44 //Object for class lock!
46 //Object for class contactSensor!
48 //Global variable for number!
50 //Global variable for number!
52 //Global variable for recipients!
53 def recipients = ['AJ']
54 //Global variable for phone number!
55 def phoneNumber = 9495379373
56 //Global Object for functions in subscribe method!
57 def installed = this.&installed
58 //Global Object for functions in subscribe method!
59 def updated = this.&updated
60 //Global Object for functions in subscribe method!
61 def initialize = this.&initialize
62 //Global Object for functions in subscribe method!
63 def lockDoor = this.&lockDoor
64 //Global Object for functions in subscribe method!
65 def unlockDoor = this.&unlockDoor
66 //Global Object for functions in subscribe method!
67 def doorHandler = this.&doorHandler
71 location = obj.locationObject
73 lock1 = obj.lockObject
74 contact = obj.contactObject
76 //Global variables for each app
77 //Settings variable defined to settings on purpose
78 def settings = "Settings"
79 //Global variable for state[mode]
80 def state = [home:[],away:[],night:[]]
81 //Create a global logger object for methods
82 def log = new Logger()
83 //Create a global variable for Functions in Subscribe method
85 //Create a global variable for Objects in Subscribe method
87 //Create a global variable for Events in Subscribe method
89 //Create a global list for function schedulers
90 def timersFuncList = []
91 //Create a global list for timer schedulers
93 //Create a global list for events
97 /////////////////////////////////////////////////////////////////////
98 def setLocationMode(String mode) {
102 /////////////////////////////////////////////////////////////////////
103 ////subscribe(obj, func)
104 def subscribe(Object obj, Closure FunctionToCall) {
106 eventList.add("Touched")
107 functionList.add(FunctionToCall)
109 ////subscribe(obj, event, func)
110 def subscribe(Object obj, String event, Closure FunctionToCall) {
113 functionList.add(FunctionToCall)
115 ////subscribe(obj, event, func, data)
116 def subscribe(Object obj, String event, Closure FunctionToCall, LinkedHashMap metaData) {
119 functionList.add(FunctionToCall)
121 /////////////////////////////////////////////////////////////////////
122 ////runIn(time, func)
123 def runIn(int seconds, Closure functionToCall) {
124 timersFuncList.add(functionToCall)
125 timersList.add(new Timer())
126 def task = timersList[-1].runAfter(1000*seconds, functionToCall)
128 /////////////////////////////////////////////////////////////////////
130 def unschedule(Closure functionToUnschedule) {
131 for (int i = 0;i < timersFuncList.size();i++) {
132 if (timersFuncList[i] == functionToUnschedule) {
133 timersList[i].cancel()
137 /////////////////////////////////////////////////////////////////////
138 ////sendNotificationToContacts(text, recipients)
139 def sendNotificationToContacts(String text, List recipients) {
140 for (int i = 0;i < recipients.size();i++) {
141 for (int j = 0;j < location.contacts.size();j++) {
142 if (recipients[i] == location.contacts[j]) {
143 println("Sending \""+text+"\" to "+location.phoneNumbers[j].toString())
148 /////////////////////////////////////////////////////////////////////
149 ////sendSms(phone, text)
150 def sendSms(long phoneNumber, String text) {
151 println("Sending \""+text+"\" to "+phoneNumber.toString())
153 /////////////////////////////////////////////////////////////////////
154 def eventHandler(LinkedHashMap eventDataMap) {
155 def value = eventDataMap["value"]
156 def name = eventDataMap["name"]
157 def deviceId = eventDataMap["deviceId"]
158 def descriptionText = eventDataMap["descriptionText"]
159 def displayed = eventDataMap["displayed"]
160 def linkText = eventDataMap["linkText"]
161 def isStateChange = eventDataMap["isStateChange"]
162 def unit = eventDataMap["unit"]
163 def data = eventDataMap["data"]
165 for (int i = 0;i < eventList.size();i++) {
166 if (eventList[i] == name) {
168 evt[-1].value = value
170 evt[-1].deviceId = deviceId
171 evt[-1].descriptionText = descriptionText
172 evt[-1].displayed = displayed
173 evt[-1].linkText = linkText
174 evt[-1].displayName = linkText
175 evt[-1].isStateChange = isStateChange
178 functionList[i](evt[-1])
194 log.debug "Settings: ${settings}"
195 subscribe(lock1, "lock", doorHandler, [filterEvents: false])
196 subscribe(lock1, "unlock", doorHandler, [filterEvents: false])
197 subscribe(contact, "contact.open", doorHandler)
198 subscribe(contact, "contact.closed", doorHandler)
202 log.debug "Locking the door."
204 if(location.contactBookEnabled) {
206 log.debug ( "Sending Push Notification..." )
207 sendNotificationToContacts( "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!", recipients)
211 log.debug("Sending text message...")
212 sendSms( phoneNumber, "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!")
217 log.debug "Unlocking the door."
219 if(location.contactBookEnabled) {
221 log.debug ( "Sending Push Notification..." )
222 sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!", recipients)
226 log.debug("Sending text message...")
227 sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!")
231 def doorHandler(evt){
232 if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...
233 //def delay = (secondsLater) // runIn uses seconds
234 runIn( secondsLater, unlockDoor ) // ...schedule (in minutes) to unlock... We don't want the door to be closed while the lock is engaged.
236 else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
237 unschedule( unlockDoor ) // ...we don't need to unlock it later.
239 else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
240 unschedule( lockDoor ) // ...we don't need to lock it later.
242 else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
243 //def delay = (minutesLater * 60) // runIn uses seconds
244 runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
246 else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
247 unschedule( lockDoor ) // ...we don't need to lock it later.
249 else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
250 //def delay = (minutesLater * 60) // runIn uses seconds
251 runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
253 else { //Opening or Closing door when locked (in case you have a handle lock)
254 log.debug "Unlocking the door."
256 if(location.contactBookEnabled) {
258 log.debug ( "Sending Push Notification..." )
259 sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
263 log.debug("Sending text message...")
264 sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
277 //Extracted objects for App2
278 //Object for class Switch!
280 //Object for class Switch!
282 //Object for class lock!
284 //Global variable for mode!
286 //Global variable for number!
288 //Global Object for functions in subscribe method!
289 def installed = this.&installed
290 //Global Object for functions in subscribe method!
291 def updated = this.&updated
292 //Global Object for functions in subscribe method!
293 def appTouch = this.&appTouch
297 location = obj.locationObject
299 switchesoff = obj.switchObject
300 switcheson = obj.switchObject
301 lock1 = obj.lockObject
303 //Global variables for each app
304 //Settings variable defined to settings on purpose
305 def settings = "Settings"
306 //Global variable for state[mode]
307 def state = [home:[],away:[],night:[]]
308 //Create a global logger object for methods
309 def log = new Logger()
310 //Create a global variable for Functions in Subscribe method
311 def functionList = []
312 //Create a global variable for Objects in Subscribe method
314 //Create a global variable for Events in Subscribe method
316 //Create a global list for function schedulers
317 def timersFuncList = []
318 //Create a global list for timer schedulers
320 //Create a global list for events
324 /////////////////////////////////////////////////////////////////////
325 def setLocationMode(String mode) {
329 /////////////////////////////////////////////////////////////////////
330 ////subscribe(obj, func)
331 def subscribe(Object obj, Closure FunctionToCall) {
333 eventList.add("Touched")
334 functionList.add(FunctionToCall)
336 ////subscribe(obj, event, func)
337 def subscribe(Object obj, String event, Closure FunctionToCall) {
340 functionList.add(FunctionToCall)
342 ////subscribe(obj, event, func, data)
343 def subscribe(Object obj, String event, Closure FunctionToCall, LinkedHashMap metaData) {
346 functionList.add(FunctionToCall)
348 /////////////////////////////////////////////////////////////////////
349 ////runIn(time, func)
350 def runIn(int seconds, Closure functionToCall) {
351 timersFuncList.add(functionToCall)
352 timersList.add(new Timer())
353 def task = timersList[-1].runAfter(1000*seconds, functionToCall)
355 /////////////////////////////////////////////////////////////////////
357 def unschedule(Closure functionToUnschedule) {
358 for (int i = 0;i < timersFuncList.size();i++) {
359 if (timersFuncList[i] == functionToUnschedule) {
360 timersList[i].cancel()
364 /////////////////////////////////////////////////////////////////////
365 ////sendNotificationToContacts(text, recipients)
366 def sendNotificationToContacts(String text, List recipients) {
367 for (int i = 0;i < recipients.size();i++) {
368 for (int j = 0;j < location.contacts.size();j++) {
369 if (recipients[i] == location.contacts[j]) {
370 println("Sending \""+text+"\" to "+location.phoneNumbers[j].toString())
375 /////////////////////////////////////////////////////////////////////
376 ////sendSms(phone, text)
377 def sendSms(long phoneNumber, String text) {
378 println("Sending \""+text+"\" to "+phoneNumber.toString())
380 /////////////////////////////////////////////////////////////////////
381 def eventHandler(LinkedHashMap eventDataMap) {
382 def value = eventDataMap["value"]
383 def name = eventDataMap["name"]
384 def deviceId = eventDataMap["deviceId"]
385 def descriptionText = eventDataMap["descriptionText"]
386 def displayed = eventDataMap["displayed"]
387 def linkText = eventDataMap["linkText"]
388 def isStateChange = eventDataMap["isStateChange"]
389 def unit = eventDataMap["unit"]
390 def data = eventDataMap["data"]
392 for (int i = 0;i < eventList.size();i++) {
393 if (eventList[i] == name) {
395 evt[-1].value = value
397 evt[-1].deviceId = deviceId
398 evt[-1].descriptionText = descriptionText
399 evt[-1].displayed = displayed
400 evt[-1].linkText = linkText
401 evt[-1].displayName = linkText
402 evt[-1].isStateChange = isStateChange
405 functionList[i](evt[-1])
412 log.debug "Installed with settings: ${settings}"
413 log.debug "Current mode = ${location.mode}"
414 subscribe(app, appTouch)
420 log.debug "Updated with settings: ${settings}"
421 log.debug "Current mode = ${location.mode}"
423 subscribe(app, appTouch)
427 log.debug "changeMode, location.mode = $location.mode, newMode = $newMode, location.modes = $location.modes"
428 if (location.mode != newMode) {
429 setLocationMode(newMode)
430 log.debug "Changed the mode to '${newMode}'"
432 log.debug "New mode is the same as the old mode, leaving it be"
434 log.debug "appTouch: $evt"
437 def delay = (waitfor != null && waitfor != "") ? waitfor * 1000 : 120000
438 switchesoff.off(delay: delay)
442 @Field def app1 = new App1(this)
443 @Field def app2 = new App2(this)