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
19 /////////////////////////////////////////////////////////////////////
20 def eventHandler(LinkedHashMap eventDataMap) {
21 def value = eventDataMap["value"]
22 def name = eventDataMap["name"]
23 def deviceId = eventDataMap["deviceId"]
24 def descriptionText = eventDataMap["descriptionText"]
25 def displayed = eventDataMap["displayed"]
26 def linkText = eventDataMap["linkText"]
27 def isStateChange = eventDataMap["isStateChange"]
28 def unit = eventDataMap["unit"]
29 def data = eventDataMap["data"]
33 //make search efficient
34 if (app1.eventList.size() == app2.eventList.size()) {
35 minSize = app1.eventList.size()
37 } else if (app1.eventList.size() < app2.eventList.size()) {
38 minSize = app1.eventList.size()
41 minSize = app2.eventList.size()
45 for (int i = 0;i < minSize;i++) {
46 if (app1.eventList[i] == name) {
50 evt[-1].deviceId = deviceId
51 evt[-1].descriptionText = descriptionText
52 evt[-1].displayed = displayed
53 evt[-1].linkText = linkText
54 evt[-1].displayName = linkText
55 evt[-1].isStateChange = isStateChange
58 app1.functionList[i](evt[-1])
60 if (app2.eventList[i] == name) {
64 evt[-1].deviceId = deviceId
65 evt[-1].descriptionText = descriptionText
66 evt[-1].displayed = displayed
67 evt[-1].linkText = linkText
68 evt[-1].displayName = linkText
69 evt[-1].isStateChange = isStateChange
72 app2.functionList[i](evt[-1])
76 if (smallest == "app1") {
77 for (int i = minSize;i < app2.eventList.size();i++) {
78 if (app2.eventList[i] == name) {
82 evt[-1].deviceId = deviceId
83 evt[-1].descriptionText = descriptionText
84 evt[-1].displayed = displayed
85 evt[-1].linkText = linkText
86 evt[-1].displayName = linkText
87 evt[-1].isStateChange = isStateChange
90 app2.functionList[i](evt[-1])
93 } else if (smallest == "app2") {
94 for (int i = minSize;i < app1.eventList.size();i++) {
95 if (app1.eventList[i] == name) {
99 evt[-1].deviceId = deviceId
100 evt[-1].descriptionText = descriptionText
101 evt[-1].displayed = displayed
102 evt[-1].linkText = linkText
103 evt[-1].displayName = linkText
104 evt[-1].isStateChange = isStateChange
107 app1.functionList[i](evt[-1])
113 //GlobalVariables for both Apps
114 //Create a global variable for send event
115 @Field def sendEvent = {eventDataMap ->
116 eventHandler(eventDataMap)
118 //Object for location
119 @Field def locationObject = new LocationVar()
121 @Field def appObject = new Touched(sendEvent, 0)
122 //Create a global list for events
125 //Extracted global objects for both Apps
126 //Global Object for class lock!
127 @Field def lockObject = new Locking(sendEvent, 1)
128 //Global Object for class contactSensor!
129 @Field def contactObject = new Contacting(sendEvent, 1)
130 //Global Object for class Switch!
131 @Field def switchObject = new Switching(sendEvent, 1)
139 //Extracted objects for App1
140 //Object for class lock!
142 //Object for class contactSensor!
144 //Global variable for number!
146 //Global variable for number!
148 //Global variable for recipients!
149 def recipients = ['AJ']
150 //Global variable for phone number!
151 def phoneNumber = 9495379373
152 //Global Object for functions in subscribe method!
153 def installed = this.&installed
154 //Global Object for functions in subscribe method!
155 def updated = this.&updated
156 //Global Object for functions in subscribe method!
157 def initialize = this.&initialize
158 //Global Object for functions in subscribe method!
159 def lockDoor = this.&lockDoor
160 //Global Object for functions in subscribe method!
161 def unlockDoor = this.&unlockDoor
162 //Global Object for functions in subscribe method!
163 def doorHandler = this.&doorHandler
167 location = obj.locationObject
169 lock1 = obj.lockObject
170 contact = obj.contactObject
172 //Global variables for each app
173 //Settings variable defined to settings on purpose
174 def settings = "Settings"
175 //Global variable for state[mode]
176 def state = [home:[],away:[],night:[]]
177 //Create a global logger object for methods
178 def log = new Logger()
179 //Create a global variable for Functions in Subscribe method
180 def functionList = []
181 //Create a global variable for Objects in Subscribe method
183 //Create a global variable for Events in Subscribe method
185 //Create a global list for function schedulers
186 def timersFuncList = []
187 //Create a global list for timer schedulers
191 /////////////////////////////////////////////////////////////////////
192 def setLocationMode(String mode) {
196 /////////////////////////////////////////////////////////////////////
197 ////subscribe(obj, func)
198 def subscribe(Object obj, Closure FunctionToCall) {
200 eventList.add("Touched")
201 functionList.add(FunctionToCall)
203 ////subscribe(obj, event, func)
204 def subscribe(Object obj, String event, Closure FunctionToCall) {
207 functionList.add(FunctionToCall)
209 ////subscribe(obj, event, func, data)
210 def subscribe(Object obj, String event, Closure FunctionToCall, LinkedHashMap metaData) {
213 functionList.add(FunctionToCall)
215 /////////////////////////////////////////////////////////////////////
216 ////runIn(time, func)
217 def runIn(int seconds, Closure functionToCall) {
218 timersFuncList.add(functionToCall)
219 timersList.add(new Timer())
220 def task = timersList[-1].runAfter(1000*seconds, functionToCall)
222 /////////////////////////////////////////////////////////////////////
224 def unschedule(Closure functionToUnschedule) {
225 for (int i = 0;i < timersFuncList.size();i++) {
226 if (timersFuncList[i] == functionToUnschedule) {
227 timersList[i].cancel()
231 /////////////////////////////////////////////////////////////////////
232 ////sendNotificationToContacts(text, recipients)
233 def sendNotificationToContacts(String text, List recipients) {
234 for (int i = 0;i < recipients.size();i++) {
235 for (int j = 0;j < location.contacts.size();j++) {
236 if (recipients[i] == location.contacts[j]) {
237 println("Sending \""+text+"\" to "+location.phoneNumbers[j].toString())
242 /////////////////////////////////////////////////////////////////////
243 ////sendSms(phone, text)
244 def sendSms(long phoneNumber, String text) {
245 println("Sending \""+text+"\" to "+phoneNumber.toString())
259 log.debug "Settings: ${settings}"
260 subscribe(lock1, "lock", doorHandler, [filterEvents: false])
261 subscribe(lock1, "unlock", doorHandler, [filterEvents: false])
262 subscribe(contact, "contact.open", doorHandler)
263 subscribe(contact, "contact.closed", doorHandler)
267 log.debug "Locking the door."
269 if(location.contactBookEnabled) {
271 log.debug ( "Sending Push Notification..." )
272 sendNotificationToContacts( "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!", recipients)
276 log.debug("Sending text message...")
277 sendSms( phoneNumber, "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!")
282 log.debug "Unlocking the door."
284 if(location.contactBookEnabled) {
286 log.debug ( "Sending Push Notification..." )
287 sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!", recipients)
291 log.debug("Sending text message...")
292 sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!")
296 def doorHandler(evt){
297 if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...
298 //def delay = (secondsLater) // runIn uses seconds
299 runIn( secondsLater, unlockDoor ) // ...schedule (in minutes) to unlock... We don't want the door to be closed while the lock is engaged.
301 else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
302 unschedule( unlockDoor ) // ...we don't need to unlock it later.
304 else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
305 unschedule( lockDoor ) // ...we don't need to lock it later.
307 else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
308 //def delay = (minutesLater * 60) // runIn uses seconds
309 runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
311 else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
312 unschedule( lockDoor ) // ...we don't need to lock it later.
314 else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
315 //def delay = (minutesLater * 60) // runIn uses seconds
316 runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
318 else { //Opening or Closing door when locked (in case you have a handle lock)
319 log.debug "Unlocking the door."
321 if(location.contactBookEnabled) {
323 log.debug ( "Sending Push Notification..." )
324 sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
328 log.debug("Sending text message...")
329 sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
342 //Extracted objects for App2
343 //Object for class Switch!
345 //Object for class Switch!
347 //Object for class lock!
349 //Global variable for mode!
351 //Global variable for number!
353 //Global Object for functions in subscribe method!
354 def installed = this.&installed
355 //Global Object for functions in subscribe method!
356 def updated = this.&updated
357 //Global Object for functions in subscribe method!
358 def appTouch = this.&appTouch
362 location = obj.locationObject
364 switchesoff = obj.switchObject
365 switcheson = obj.switchObject
366 lock1 = obj.lockObject
368 //Global variables for each app
369 //Settings variable defined to settings on purpose
370 def settings = "Settings"
371 //Global variable for state[mode]
372 def state = [home:[],away:[],night:[]]
373 //Create a global logger object for methods
374 def log = new Logger()
375 //Create a global variable for Functions in Subscribe method
376 def functionList = []
377 //Create a global variable for Objects in Subscribe method
379 //Create a global variable for Events in Subscribe method
381 //Create a global list for function schedulers
382 def timersFuncList = []
383 //Create a global list for timer schedulers
387 /////////////////////////////////////////////////////////////////////
388 def setLocationMode(String mode) {
392 /////////////////////////////////////////////////////////////////////
393 ////subscribe(obj, func)
394 def subscribe(Object obj, Closure FunctionToCall) {
396 eventList.add("Touched")
397 functionList.add(FunctionToCall)
399 ////subscribe(obj, event, func)
400 def subscribe(Object obj, String event, Closure FunctionToCall) {
403 functionList.add(FunctionToCall)
405 ////subscribe(obj, event, func, data)
406 def subscribe(Object obj, String event, Closure FunctionToCall, LinkedHashMap metaData) {
409 functionList.add(FunctionToCall)
411 /////////////////////////////////////////////////////////////////////
412 ////runIn(time, func)
413 def runIn(int seconds, Closure functionToCall) {
414 timersFuncList.add(functionToCall)
415 timersList.add(new Timer())
416 def task = timersList[-1].runAfter(1000*seconds, functionToCall)
418 /////////////////////////////////////////////////////////////////////
420 def unschedule(Closure functionToUnschedule) {
421 for (int i = 0;i < timersFuncList.size();i++) {
422 if (timersFuncList[i] == functionToUnschedule) {
423 timersList[i].cancel()
427 /////////////////////////////////////////////////////////////////////
428 ////sendNotificationToContacts(text, recipients)
429 def sendNotificationToContacts(String text, List recipients) {
430 for (int i = 0;i < recipients.size();i++) {
431 for (int j = 0;j < location.contacts.size();j++) {
432 if (recipients[i] == location.contacts[j]) {
433 println("Sending \""+text+"\" to "+location.phoneNumbers[j].toString())
438 /////////////////////////////////////////////////////////////////////
439 ////sendSms(phone, text)
440 def sendSms(long phoneNumber, String text) {
441 println("Sending \""+text+"\" to "+phoneNumber.toString())
446 log.debug "Installed with settings: ${settings}"
447 log.debug "Current mode = ${location.mode}"
448 subscribe(app, appTouch)
454 log.debug "Updated with settings: ${settings}"
455 log.debug "Current mode = ${location.mode}"
457 subscribe(app, appTouch)
461 log.debug "changeMode, location.mode = $location.mode, newMode = $newMode, location.modes = $location.modes"
462 if (location.mode != newMode) {
463 setLocationMode(newMode)
464 log.debug "Changed the mode to '${newMode}'"
466 log.debug "New mode is the same as the old mode, leaving it be"
468 log.debug "appTouch: $evt"
471 def delay = (waitfor != null && waitfor != "") ? waitfor * 1000 : 120000
472 switchesoff.off(delay: delay)
476 @Field def app1 = new App1(this)
477 @Field def app2 = new App2(this)
480 appObject.setValue([name: "Touched", value: "Touched", deviceId: 0, descriptionText: "",
481 displayed: true, linkText: "", isStateChange: false, unit: "", data: []])