+//Infrastructure for SmartThings Application
+//Importing Libraries
+import groovy.transform.Field
+
+//Importing Classes
+import ContactSensor.contacting
+import ContactSensor.contacts
+import Lock.locking
+import Lock.locks
+import Switch.switching
+import Switch.switches
+import Event.Event
+import Logger.Logger
+import Location.locationVar
+import Location.Phrase
+import appTouch.Touch
+
+//GlobalVariables
+//create a location object to change the variable inside the class
+@Field def location = new locationVar()
+//Settings variable defined to settings on purpose
+@Field def settings = "Settings"
+//Global variable for state[mode]
+@Field def state = [home:[],away:[],night:[]]
+//Create a global logger object for methods
+@Field def log = new Logger()
+//Create a global object for app
+@Field def app = new Touch(1)
+//Create a global list for objects for events on subscribe methods
+@Field def ObjectList = []
+//Create a global list for events
+@Field def EventList = []
+//Create a global list for function calls based on corresponding events
+@Field def FunctionList = []
+//Create a global list for function schedulers
+@Field def ListofTimersFunc = []
+//Create a global list for timer schedulers
+@Field def ListofTimers = []
+
+
+
+//ExtractedObjects
+//Global Object for class lock!
+@Field def lock1 = new locking(1)
+//Global Object for class contactSensor!
+@Field def contact = new contacting(1)
+//Global variable for number!
+@Field def minutesLater = 1
+//Global variable for number!
+@Field def secondsLater = 10
+//Global variable for recipients!
+@Field def recipients = ['AJ']
+//Global variable for phone number!
+@Field def phoneNumber = 9495379373
+//Global Object for functions in subscribe method!
+@Field def installed = this.&installed
+//Global Object for functions in subscribe method!
+@Field def updated = this.&updated
+//Global Object for functions in subscribe method!
+@Field def initialize = this.&initialize
+//Global Object for functions in subscribe method!
+@Field def lockDoor = this.&lockDoor
+//Global Object for functions in subscribe method!
+@Field def unlockDoor = this.&unlockDoor
+//Global Object for functions in subscribe method!
+@Field def doorHandler = this.&doorHandler
+
+//Methods
+/////////////////////////////////////////////////////////////////////
+def definition(LinkedHashMap LHM) {
+ println("IGNORE -- JUST SOME DEFINITION")
+}
+
+/////////////////////////////////////////////////////////////////////
+def preferences(Closure Input) {
+ println("IGNORE -- JUST SOME DEFINITION")
+}
+/////////////////////////////////////////////////////////////////////
+def setLocationMode(String mode) {
+ location.mode = mode
+}
+
+/////////////////////////////////////////////////////////////////////
+////subscribe(app, func)
+def subscribe(Object Obj, Closure Input) {
+ EventList.add("Touched")
+ FunctionList.add(Input)
+}
+////subscribe(obj, string, func)
+def subscribe(Object Obj, String S, Closure Input) {
+ ObjectList.add(Obj)
+ EventList.add(S)
+ FunctionList.add(Input)
+}
+////subscribe(obj, string, func, hashmap)
+def subscribe(Object Obj, String S, Closure Input, LinkedHashMap LHM) {
+ ObjectList.add(Obj)
+ EventList.add(S)
+ FunctionList.add(Input)
+}
+/////////////////////////////////////////////////////////////////////
+def EventHandler() {
+ while(true) {
+ List evt = []
+ print "Waiting for an event...\n"
+ def EVENT = System.in.newReader().readLine()
+ SepLine = EVENT.split()
+ for (int i = 0; i < EventList.size(); i++) {
+ if (EventList[i] == SepLine[0]) {
+ println("The following effect: \n")
+ evt.add(new Event())
+ switch(SepLine[0]) {
+ case "Touched":
+ ObjectList[i].touched = 1
+ evt[-1].value = "Touched"
+ evt[-1].linkText = "touched by user"
+ evt[-1].name = "TouchSensor"
+ evt[-1].descriptionText = "Touching"
+ break
+ case "lock":
+ if (SepLine[1] == "0") {
+ ObjectList[i][0].lock()
+ evt[-1].deviceId = 0
+ evt[-1].value = "locked"
+ evt[-1].linkText = "lock0"
+ evt[-1].displayName = "lock0"
+ evt[-1].name = "lock"
+ evt[-1].descriptionText = "locking"
+ } else if (SepLine[1] == "1") {
+ ObjectList[i][1].lock()
+ evt[-1].deviceId = 1
+ evt[-1].value = "locked"
+ evt[-1].linkText = "lock1"
+ evt[-1].displayName = "lock1"
+ evt[-1].name = "lock"
+ evt[-1].descriptionText = "locking"
+ } else if (SepLine[1] == "2") {
+ ObjectList[i][2].lock()
+ evt[-1].deviceId = 2
+ evt[-1].value = "locked"
+ evt[-1].linkText = "lock2"
+ evt[-1].displayName = "lock2"
+ evt[-1].name = "lock"
+ evt[-1].descriptionText = "locking"
+ }
+ break
+ case "unlock":
+ if (SepLine[1] == "0") {
+ ObjectList[i][0].unlock()
+ evt[-1].deviceId = 0
+ evt[-1].value = "unlocked"
+ evt[-1].linkText = "lock0"
+ evt[-1].displayName = "lock0"
+ evt[-1].name = "lock"
+ evt[-1].descriptionText = "unlocking"
+ } else if (SepLine[1] == "1") {
+ ObjectList[i][1].unlock()
+ evt[-1].deviceId = 0
+ evt[-1].value = "unlocked"
+ evt[-1].linkText = "lock1"
+ evt[-1].displayName = "lock1"
+ evt[-1].name = "lock"
+ evt[-1].descriptionText = "unlocking"
+ } else if (SepLine[1] == "2") {
+ ObjectList[i][2].unlock()
+ evt[-1].deviceId = 2
+ evt[-1].value = "unlocked"
+ evt[-1].linkText = "lock2"
+ evt[-1].displayName = "lock2"
+ evt[-1].name = "lock"
+ evt[-1].descriptionText = "unlocking"
+ }
+ break
+ case "contact.open":
+ if (SepLine[1] == "0") {
+ ObjectList[i][0].contactLatestValue = ObjectList[i].currentContact
+ ObjectList[i][0].currentContact = "open"
+ evt[-1].deviceId = 0
+ evt[-1].value = "contact.open"
+ evt[-1].linkText = "contact0"
+ evt[-1].displayName = "contact0"
+ evt[-1].name = "ContactSensor"
+ evt[-1].descriptionText = "opening"
+ } else if (SepLine[1] == "1") {
+ ObjectList[i][1].contactLatestValue = ObjectList[i].currentContact
+ ObjectList[i][1].currentContact = "open"
+ evt[-1].deviceId = 1
+ evt[-1].value = "contact.open"
+ evt[-1].linkText = "contact1"
+ evt[-1].displayName = "contact1"
+ evt[-1].name = "ContactSensor"
+ evt[-1].descriptionText = "opening"
+ } else if (SepLine[1] == "2") {
+ ObjectList[i][2].contactLatestValue = ObjectList[i].currentContact
+ ObjectList[i][2].currentContact = "open"
+ evt[-1].deviceId = 2
+ evt[-1].value = "contact.open"
+ evt[-1].linkText = "contact2"
+ evt[-1].displayName = "contact2"
+ evt[-1].name = "ContactSensor"
+ evt[-1].descriptionText = "opening"
+ }
+ break
+ case "contact.closed":
+ if (SepLine[1] == "0") {
+ ObjectList[i][0].contactLatestValue = ObjectList[i].currentContact
+ ObjectList[i][0].currentContact = "closed"
+ evt[-1].deviceId = 0
+ evt[-1].value = "contact.closed"
+ evt[-1].linkText = "contact0"
+ evt[-1].displayName = "contact0"
+ evt[-1].name = "ContactSensor"
+ evt[-1].descriptionText = "closing"
+ } else if (SepLine[1] == "1") {
+ ObjectList[i][1].contactLatestValue = ObjectList[i].currentContact
+ ObjectList[i][1].currentContact = "closed"
+ evt[-1].deviceId = 1
+ evt[-1].value = "contact.closed"
+ evt[-1].linkText = "contact1"
+ evt[-1].displayName = "contact1"
+ evt[-1].name = "ContactSensor"
+ evt[-1].descriptionText = "closing"
+ } else if (SepLine[1] == "2") {
+ ObjectList[i][2].contactLatestValue = ObjectList[i].currentContact
+ ObjectList[i][2].currentContact = "closed"
+ evt[-1].deviceId = 2
+ evt[-1].value = "contact.closed"
+ evt[-1].linkText = "contact2"
+ evt[-1].displayName = "contact2"
+ evt[-1].name = "ContactSensor"
+ evt[-1].descriptionText = "closing"
+ }
+ break
+ default:
+ break
+ }
+ FunctionList[i](evt[-1])
+ }
+ }
+ }
+}
+/////////////////////////////////////////////////////////////////////
+////runIn(time, func)
+def runIn(int seconds, Closure Input) {
+ ListofTimersFunc.add(Input)
+ ListofTimers.add(new Timer())
+ def task = ListofTimers[-1].runAfter(1000*seconds, Input)
+}
+/////////////////////////////////////////////////////////////////////
+////unschedule(func)
+def unschedule(Closure Input) {
+ for (int i = 0;i < ListofTimersFunc.size();i++) {
+ if (ListofTimersFunc[i] == Input) {
+ ListofTimers[i].cancel()
+ }
+ }
+}
+/////////////////////////////////////////////////////////////////////
+////sendNotificationToContacts(text, recipients)
+def sendNotificationToContacts(String S, List recipients) {
+ for (int i = 0;i < recipients.size();i++) {
+ for (int j = 0;j < location.CONTACTS.size();j++) {
+ if (recipients[i] == location.CONTACTS[j]) {
+ println("Sending \""+S+"\" to "+location.PhoneNums[j].toString())
+ }
+ }
+ }
+}
+/////////////////////////////////////////////////////////////////////
+////sendNotificationToContacts(text, recipients)
+def sendSms(long Phone, String S) {
+ println("Sending \""+S+"\" to "+Phone.toString())
+}
+
+///////////////////////////////////////////
+definition(
+ name: "Enhanced Auto Lock Door",
+ namespace: "Lock Auto Super Enhanced",
+ author: "Arnaud",
+ description: "Automatically locks a specific door after X minutes when closed and unlocks it when open after X seconds.",
+ category: "Safety & Security",
+ iconUrl: "http://www.gharexpert.com/mid/4142010105208.jpg",
+ iconX2Url: "http://www.gharexpert.com/mid/4142010105208.jpg"
+)
+
+preferences{
+ section("Select the door lock:") {
+ input "lock1", "capability.lock", required: true, multiple: true
+ }
+ section("Select the door contact sensor:") {
+ input "contact", "capability.contactSensor", required: true
+ }
+ section("Automatically lock the door when closed...") {
+ input "minutesLater", "number", title: "Delay (in minutes):", required: true
+ }
+ section("Automatically unlock the door when open...") {
+ input "secondsLater", "number", title: "Delay (in seconds):", required: true
+ }
+ section( "Notifications" ) {
+ input("recipients", "contact", title: "Send notifications to", required: false) {
+ input "phoneNumber", "phone", title: "Warn with text message (optional)", description: "Phone Number", required: false
+ }
+ }
+}
+
+def installed(){
+ initialize()
+}
+
+def updated(){
+ unsubscribe()
+ unschedule()
+ initialize()
+}
+
+def initialize(){
+ log.debug "Settings: ${settings}"
+ subscribe(lock1, "lock", doorHandler, [filterEvents: false])
+ subscribe(lock1, "unlock", doorHandler, [filterEvents: false])
+ subscribe(contact, "contact.open", doorHandler)
+ subscribe(contact, "contact.closed", doorHandler)
+}
+
+def lockDoor(){
+ log.debug "Locking the door."
+ lock1.lock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!", recipients)
+ }
+ }
+ if (phoneNumber) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} locked after ${contact} was closed for ${minutesLater} minutes!")
+ }
+}
+
+def unlockDoor(){
+ log.debug "Unlocking the door."
+ lock1.unlock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!", recipients)
+ }
+ }
+ if ( phoneNumber ) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened for ${secondsLater} seconds!")
+ }
+}
+
+def doorHandler(evt){
+ log.debug evt.value
+ log.debug contact.latestValue("contact")
+ if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...
+ //def delay = (secondsLater) // runIn uses seconds
+ log.debug "1"
+ runIn( secondsLater, unlockDoor ) // ...schedule (in minutes) to unlock... We don't want the door to be closed while the lock is engaged.
+ }
+ else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
+ log.debug "2"
+ unschedule( unlockDoor ) // ...we don't need to unlock it later.
+ }
+ else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
+ log.debug "3"
+ unschedule( lockDoor ) // ...we don't need to lock it later.
+ }
+ else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
+ log.debug "4"
+ //def delay = (minutesLater * 60) // runIn uses seconds
+ runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
+ }
+ else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
+ log.debug "5"
+ unschedule( lockDoor ) // ...we don't need to lock it later.
+ }
+ else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
+ //def delay = (minutesLater * 60) // runIn uses seconds
+ log.debug "6"
+ runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
+ }
+ else { //Opening or Closing door when locked (in case you have a handle lock)
+ log.debug "Unlocking the door."
+ lock1.unlock()
+ if(location.contactBookEnabled) {
+ if ( recipients ) {
+ log.debug ( "Sending Push Notification..." )
+ sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
+ }
+ }
+ if ( phoneNumber ) {
+ log.debug("Sending text message...")
+ sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
+ }
+ }
+}
+
+installed()
+EventHandler()