"First commit!"
[smartthings-infrastructure.git] / main.groovy
1 //Infrastructure for SmartThings Application
2 //Importing Libraries
3 import groovy.transform.Field
4
5 //Importing Classes
6 import ContactSensor.contacting
7 import ContactSensor.contacts
8 import Lock.locking
9 import Lock.locks
10 import Switch.switching
11 import Switch.switches
12 import Event.Event
13 import Logger.Logger
14 import Location.locationVar
15 import Location.Phrase
16 import appTouch.Touch
17
18 //GlobalVariables
19 //create a location object to change the variable inside the class
20 @Field def location = new locationVar()
21 //Settings variable defined to settings on purpose
22 @Field def settings = "Settings"
23 //Global variable for state[mode]
24 @Field def state = [home:[],away:[],night:[]]
25 //Create a global logger object for methods
26 @Field def log = new Logger()
27 //Create a global object for app
28 @Field def app = new Touch(1)
29 //Create a global list for objects for events on subscribe methods
30 @Field def ObjectList = []
31 //Create a global list for events
32 @Field def EventList = []
33 //Create a global list for function calls based on corresponding events
34 @Field def FunctionList = []
35 //Create a global list for function schedulers
36 @Field def ListofTimersFunc = []
37 //Create a global list for timer schedulers
38 @Field def ListofTimers = []
39
40
41
42 //ExtractedObjects
43 //Global Object for class lock!
44 @Field def lock1 = new locking(1)
45 //Global Object for class contactSensor!
46 @Field def contact = new contacting(1)
47 //Global variable for number!
48 @Field def minutesLater = 1
49 //Global variable for number!
50 @Field def secondsLater = 10
51 //Global variable for recipients!
52 @Field def recipients = ['AJ']
53 //Global variable for phone number!
54 @Field def phoneNumber = 9495379373
55 //Global Object for functions in subscribe method!
56 @Field def installed = this.&installed
57 //Global Object for functions in subscribe method!
58 @Field def updated = this.&updated
59 //Global Object for functions in subscribe method!
60 @Field def initialize = this.&initialize
61 //Global Object for functions in subscribe method!
62 @Field def lockDoor = this.&lockDoor
63 //Global Object for functions in subscribe method!
64 @Field def unlockDoor = this.&unlockDoor
65 //Global Object for functions in subscribe method!
66 @Field def doorHandler = this.&doorHandler
67
68 //Methods
69 /////////////////////////////////////////////////////////////////////
70 def definition(LinkedHashMap LHM) {
71         println("IGNORE -- JUST SOME DEFINITION")
72 }
73
74 /////////////////////////////////////////////////////////////////////
75 def preferences(Closure Input) {
76         println("IGNORE -- JUST SOME DEFINITION")
77 }
78 /////////////////////////////////////////////////////////////////////
79 def setLocationMode(String mode) {
80         location.mode = mode
81 }
82
83 /////////////////////////////////////////////////////////////////////
84 ////subscribe(app, func)
85 def subscribe(Object Obj, Closure Input) {
86         EventList.add("Touched")
87         FunctionList.add(Input)
88 }
89 ////subscribe(obj, string, func)
90 def subscribe(Object Obj, String S, Closure Input) {
91         ObjectList.add(Obj)
92         EventList.add(S)
93         FunctionList.add(Input)
94 }
95 ////subscribe(obj, string, func, hashmap)
96 def subscribe(Object Obj, String S, Closure Input, LinkedHashMap LHM) {
97         ObjectList.add(Obj)     
98         EventList.add(S)
99         FunctionList.add(Input)
100 }
101 /////////////////////////////////////////////////////////////////////
102 def EventHandler() {
103         while(true) {
104                 List evt = []
105                 print "Waiting for an event...\n"
106                 def EVENT = System.in.newReader().readLine()
107                 SepLine = EVENT.split()
108                 for (int i = 0; i < EventList.size(); i++) {
109                         if (EventList[i] == SepLine[0]) {
110                                 println("The following effect: \n")
111                                 evt.add(new Event())
112                                 switch(SepLine[0]) { 
113                                         case "Touched":
114                                                 ObjectList[i].touched = 1
115                                                 evt[-1].value = "Touched"
116                                                 evt[-1].linkText = "touched by user"
117                                                 evt[-1].name = "TouchSensor"
118                                                 evt[-1].descriptionText = "Touching"
119                                                 break
120                                         case "lock":
121                                                 if (SepLine[1] == "0") {
122                                                         ObjectList[i][0].lock()
123                                                         evt[-1].deviceId = 0
124                                                         evt[-1].value = "locked"
125                                                         evt[-1].linkText = "lock0"
126                                                         evt[-1].displayName = "lock0"
127                                                         evt[-1].name = "lock"
128                                                         evt[-1].descriptionText = "locking"
129                                                 } else if (SepLine[1] == "1") {
130                                                         ObjectList[i][1].lock()
131                                                         evt[-1].deviceId = 1
132                                                         evt[-1].value = "locked"
133                                                         evt[-1].linkText = "lock1"
134                                                         evt[-1].displayName = "lock1"
135                                                         evt[-1].name = "lock"
136                                                         evt[-1].descriptionText = "locking"
137                                                 } else if (SepLine[1] == "2") {
138                                                         ObjectList[i][2].lock()
139                                                         evt[-1].deviceId = 2
140                                                         evt[-1].value = "locked"
141                                                         evt[-1].linkText = "lock2"
142                                                         evt[-1].displayName = "lock2"
143                                                         evt[-1].name = "lock"
144                                                         evt[-1].descriptionText = "locking"
145                                                 }
146                                                 break
147                                         case "unlock":
148                                                 if (SepLine[1] == "0") {
149                                                         ObjectList[i][0].unlock()
150                                                         evt[-1].deviceId = 0
151                                                         evt[-1].value = "unlocked"
152                                                         evt[-1].linkText = "lock0"
153                                                         evt[-1].displayName = "lock0"
154                                                         evt[-1].name = "lock"
155                                                         evt[-1].descriptionText = "unlocking"   
156                                                 } else if (SepLine[1] == "1") {
157                                                         ObjectList[i][1].unlock()
158                                                         evt[-1].deviceId = 0
159                                                         evt[-1].value = "unlocked"
160                                                         evt[-1].linkText = "lock1"
161                                                         evt[-1].displayName = "lock1"
162                                                         evt[-1].name = "lock"
163                                                         evt[-1].descriptionText = "unlocking"
164                                                 } else if (SepLine[1] == "2") {
165                                                         ObjectList[i][2].unlock()
166                                                         evt[-1].deviceId = 2
167                                                         evt[-1].value = "unlocked"
168                                                         evt[-1].linkText = "lock2"
169                                                         evt[-1].displayName = "lock2"
170                                                         evt[-1].name = "lock"
171                                                         evt[-1].descriptionText = "unlocking"
172                                                 }
173                                                 break
174                                         case "contact.open":
175                                                 if (SepLine[1] == "0") {
176                                                         ObjectList[i][0].contactLatestValue = ObjectList[i].currentContact
177                                                         ObjectList[i][0].currentContact = "open"
178                                                         evt[-1].deviceId = 0
179                                                         evt[-1].value = "contact.open"
180                                                         evt[-1].linkText = "contact0"
181                                                         evt[-1].displayName = "contact0"
182                                                         evt[-1].name = "ContactSensor"
183                                                         evt[-1].descriptionText = "opening"     
184                                                 } else if (SepLine[1] == "1") {
185                                                         ObjectList[i][1].contactLatestValue = ObjectList[i].currentContact
186                                                         ObjectList[i][1].currentContact = "open"
187                                                         evt[-1].deviceId = 1
188                                                         evt[-1].value = "contact.open"
189                                                         evt[-1].linkText = "contact1"
190                                                         evt[-1].displayName = "contact1"
191                                                         evt[-1].name = "ContactSensor"
192                                                         evt[-1].descriptionText = "opening"
193                                                 } else if (SepLine[1] == "2") {
194                                                         ObjectList[i][2].contactLatestValue = ObjectList[i].currentContact
195                                                         ObjectList[i][2].currentContact = "open"
196                                                         evt[-1].deviceId = 2
197                                                         evt[-1].value = "contact.open"
198                                                         evt[-1].linkText = "contact2"
199                                                         evt[-1].displayName = "contact2"
200                                                         evt[-1].name = "ContactSensor"
201                                                         evt[-1].descriptionText = "opening"
202                                                 }
203                                                 break
204                                         case "contact.closed":
205                                                 if (SepLine[1] == "0") {
206                                                         ObjectList[i][0].contactLatestValue = ObjectList[i].currentContact
207                                                         ObjectList[i][0].currentContact = "closed"
208                                                         evt[-1].deviceId = 0
209                                                         evt[-1].value = "contact.closed"
210                                                         evt[-1].linkText = "contact0"
211                                                         evt[-1].displayName = "contact0"
212                                                         evt[-1].name = "ContactSensor"
213                                                         evt[-1].descriptionText = "closing"
214                                                 } else if (SepLine[1] == "1") {
215                                                         ObjectList[i][1].contactLatestValue = ObjectList[i].currentContact
216                                                         ObjectList[i][1].currentContact = "closed"
217                                                         evt[-1].deviceId = 1
218                                                         evt[-1].value = "contact.closed"
219                                                         evt[-1].linkText = "contact1"
220                                                         evt[-1].displayName = "contact1"
221                                                         evt[-1].name = "ContactSensor"
222                                                         evt[-1].descriptionText = "closing"
223                                                 } else if (SepLine[1] == "2") {
224                                                         ObjectList[i][2].contactLatestValue = ObjectList[i].currentContact
225                                                         ObjectList[i][2].currentContact = "closed"
226                                                         evt[-1].deviceId = 2
227                                                         evt[-1].value = "contact.closed"
228                                                         evt[-1].linkText = "contact2"
229                                                         evt[-1].displayName = "contact2"
230                                                         evt[-1].name = "ContactSensor"
231                                                         evt[-1].descriptionText = "closing"
232                                                 }
233                                                 break
234                                         default:
235                                                 break
236                                 }
237                                 FunctionList[i](evt[-1])
238                         }
239                 }
240         }
241 }
242 /////////////////////////////////////////////////////////////////////
243 ////runIn(time, func)
244 def runIn(int seconds, Closure Input) {
245         ListofTimersFunc.add(Input)
246         ListofTimers.add(new Timer())
247         def task = ListofTimers[-1].runAfter(1000*seconds, Input)
248 }
249 /////////////////////////////////////////////////////////////////////
250 ////unschedule(func)
251 def unschedule(Closure Input) {
252         for (int i = 0;i < ListofTimersFunc.size();i++) {
253                 if (ListofTimersFunc[i] == Input) {
254                         ListofTimers[i].cancel()
255                 }
256         }
257 }
258 /////////////////////////////////////////////////////////////////////
259 ////sendNotificationToContacts(text, recipients)
260 def sendNotificationToContacts(String S, List recipients) {
261         for (int i = 0;i < recipients.size();i++) {
262                 for (int j = 0;j < location.CONTACTS.size();j++) {
263                         if (recipients[i] == location.CONTACTS[j]) {
264                                 println("Sending \""+S+"\" to "+location.PhoneNums[j].toString())
265                         }
266                 }
267         }
268 }
269 /////////////////////////////////////////////////////////////////////
270 ////sendNotificationToContacts(text, recipients)
271 def sendSms(long Phone, String S) {
272         println("Sending \""+S+"\" to "+Phone.toString())
273 }
274
275 ///////////////////////////////////////////
276 definition(
277     name: "Enhanced Auto Lock Door",
278     namespace: "Lock Auto Super Enhanced",
279     author: "Arnaud",
280     description: "Automatically locks a specific door after X minutes when closed  and unlocks it when open after X seconds.",
281     category: "Safety & Security",
282     iconUrl: "http://www.gharexpert.com/mid/4142010105208.jpg",
283     iconX2Url: "http://www.gharexpert.com/mid/4142010105208.jpg"
284 )
285
286 preferences{
287     section("Select the door lock:") {
288         input "lock1", "capability.lock", required: true, multiple: true
289     }
290     section("Select the door contact sensor:") {
291         input "contact", "capability.contactSensor", required: true
292     }   
293     section("Automatically lock the door when closed...") {
294         input "minutesLater", "number", title: "Delay (in minutes):", required: true
295     }
296     section("Automatically unlock the door when open...") {
297         input "secondsLater", "number", title: "Delay (in seconds):", required: true
298     }
299     section( "Notifications" ) {
300         input("recipients", "contact", title: "Send notifications to", required: false) {
301             input "phoneNumber", "phone", title: "Warn with text message (optional)", description: "Phone Number", required: false
302         }
303     }
304 }
305
306 def installed(){
307     initialize()
308 }
309
310 def updated(){
311     unsubscribe()
312     unschedule()
313     initialize()
314 }
315
316 def initialize(){
317     log.debug "Settings: ${settings}"
318     subscribe(lock1, "lock", doorHandler, [filterEvents: false])
319     subscribe(lock1, "unlock", doorHandler, [filterEvents: false])  
320     subscribe(contact, "contact.open", doorHandler)
321     subscribe(contact, "contact.closed", doorHandler)
322 }
323
324 def lockDoor(){
325     log.debug "Locking the door."
326     lock1.lock()
327     if(location.contactBookEnabled) {
328         if ( recipients ) {
329             log.debug ( "Sending Push Notification..." ) 
330             sendNotificationToContacts( "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!", recipients)
331         }
332     }
333     if (phoneNumber) {
334         log.debug("Sending text message...")
335         sendSms( phoneNumber, "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!")
336     }
337 }
338
339 def unlockDoor(){
340     log.debug "Unlocking the door."
341     lock1.unlock()
342     if(location.contactBookEnabled) {
343         if ( recipients ) {
344             log.debug ( "Sending Push Notification..." ) 
345             sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!", recipients)
346         }
347     }
348     if ( phoneNumber ) {
349         log.debug("Sending text message...")
350         sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!")
351     }
352 }
353
354 def doorHandler(evt){
355     log.debug evt.value
356     log.debug contact.latestValue("contact")
357     if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...  
358         //def delay = (secondsLater) // runIn uses seconds
359         log.debug "1"
360         runIn( secondsLater, unlockDoor )   // ...schedule (in minutes) to unlock...  We don't want the door to be closed while the lock is engaged. 
361     }
362     else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
363         log.debug "2"        
364         unschedule( unlockDoor ) // ...we don't need to unlock it later.
365     }
366     else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
367         log.debug "3"
368         unschedule( lockDoor ) // ...we don't need to lock it later.
369     }   
370     else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
371         log.debug "4"
372        //def delay = (minutesLater * 60) // runIn uses seconds
373         runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
374     }
375     else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
376         log.debug "5"
377         unschedule( lockDoor ) // ...we don't need to lock it later.
378     }
379     else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
380         //def delay = (minutesLater * 60) // runIn uses seconds
381         log.debug "6"
382         runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
383     }
384     else { //Opening or Closing door when locked (in case you have a handle lock)
385         log.debug "Unlocking the door."
386         lock1.unlock()
387         if(location.contactBookEnabled) {
388             if ( recipients ) {
389                 log.debug ( "Sending Push Notification..." ) 
390                 sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
391             }
392         }
393         if ( phoneNumber ) {
394             log.debug("Sending text message...")
395             sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
396         }
397     }
398 }
399
400 installed()
401 EventHandler()