//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 Logger.Logger import Location.LocationVar import Location.Phrase import appTouch.Touched import Event.Event //Global eventHandler ///////////////////////////////////////////////////////////////////// def eventHandler(LinkedHashMap eventDataMap) { def value = eventDataMap["value"] def name = eventDataMap["name"] def deviceId = eventDataMap["deviceId"] def descriptionText = eventDataMap["descriptionText"] def displayed = eventDataMap["displayed"] def linkText = eventDataMap["linkText"] def isStateChange = eventDataMap["isStateChange"] def unit = eventDataMap["unit"] def data = eventDataMap["data"] def minSize def smallest //make search efficient if (app1.eventList.size() == app2.eventList.size()) { minSize = app1.eventList.size() smallest = "equal" } else if (app1.eventList.size() < app2.eventList.size()) { minSize = app1.eventList.size() smallest = "app1" } else { minSize = app2.eventList.size() smallest = "app2" } for (int i = 0;i < minSize;i++) { if (app1.eventList[i] == name) { evt.add(new Event()) evt[-1].value = value evt[-1].name = name evt[-1].deviceId = deviceId evt[-1].descriptionText = descriptionText evt[-1].displayed = displayed evt[-1].linkText = linkText evt[-1].displayName = linkText evt[-1].isStateChange = isStateChange evt[-1].unit = unit evt[-1].data = data app1.functionList[i](evt[-1]) } if (app2.eventList[i] == name) { evt.add(new Event()) evt[-1].value = value evt[-1].name = name evt[-1].deviceId = deviceId evt[-1].descriptionText = descriptionText evt[-1].displayed = displayed evt[-1].linkText = linkText evt[-1].displayName = linkText evt[-1].isStateChange = isStateChange evt[-1].unit = unit evt[-1].data = data app2.functionList[i](evt[-1]) } } if (smallest == "app1") { for (int i = minSize;i < app2.eventList.size();i++) { if (app2.eventList[i] == name) { evt.add(new Event()) evt[-1].value = value evt[-1].name = name evt[-1].deviceId = deviceId evt[-1].descriptionText = descriptionText evt[-1].displayed = displayed evt[-1].linkText = linkText evt[-1].displayName = linkText evt[-1].isStateChange = isStateChange evt[-1].unit = unit evt[-1].data = data app2.functionList[i](evt[-1]) } } } else if (smallest == "app2") { for (int i = minSize;i < app1.eventList.size();i++) { if (app1.eventList[i] == name) { evt.add(new Event()) evt[-1].value = value evt[-1].name = name evt[-1].deviceId = deviceId evt[-1].descriptionText = descriptionText evt[-1].displayed = displayed evt[-1].linkText = linkText evt[-1].displayName = linkText evt[-1].isStateChange = isStateChange evt[-1].unit = unit evt[-1].data = data app1.functionList[i](evt[-1]) } } } } //GlobalVariables for both Apps //Create a global variable for send event @Field def sendEvent = {eventDataMap -> eventHandler(eventDataMap) } //Object for location @Field def locationObject = new LocationVar() //Object for touch @Field def appObject = new Touched(sendEvent, 0) //Create a global list for events @Field def evt = [] //Extracted global objects for both Apps //Global Object for class lock! @Field def lockObject = new Locking(sendEvent, 1) //Global Object for class contactSensor! @Field def contactObject = new Contacting(sendEvent, 1) //Global Object for class Switch! @Field def switchObject = new Switching(sendEvent, 1) //Application #1 class App1 { def reference def location def app //Extracted objects for App1 //Object for class lock! def lock1 //Object for class contactSensor! def contact //Global variable for number! def minutesLater = 1 //Global variable for number! def secondsLater = 1 //Global variable for recipients! def recipients = ['AJ'] //Global variable for phone number! def phoneNumber = 9495379373 //Global Object for functions in subscribe method! def installed = this.&installed //Global Object for functions in subscribe method! def updated = this.&updated //Global Object for functions in subscribe method! def initialize = this.&initialize //Global Object for functions in subscribe method! def lockDoor = this.&lockDoor //Global Object for functions in subscribe method! def unlockDoor = this.&unlockDoor //Global Object for functions in subscribe method! def doorHandler = this.&doorHandler App1(Object obj) { reference = obj location = obj.locationObject app = obj.appObject lock1 = obj.lockObject contact = obj.contactObject } //Global variables for each app //Settings variable defined to settings on purpose def settings = "Settings" //Global variable for state[mode] def state = [home:[],away:[],night:[]] //Create a global logger object for methods def log = new Logger() //Create a global variable for Functions in Subscribe method def functionList = [] //Create a global variable for Objects in Subscribe method def objectList = [] //Create a global variable for Events in Subscribe method def eventList = [] //Create a global list for function schedulers def timersFuncList = [] //Create a global list for timer schedulers def timersList = [] //Methods ///////////////////////////////////////////////////////////////////// def setLocationMode(String mode) { location.mode = mode } ///////////////////////////////////////////////////////////////////// ////subscribe(obj, func) def subscribe(Object obj, Closure FunctionToCall) { objectList.add(obj) eventList.add("Touched") functionList.add(FunctionToCall) } ////subscribe(obj, event, func) def subscribe(Object obj, String event, Closure FunctionToCall) { objectList.add(obj) eventList.add(event) functionList.add(FunctionToCall) } ////subscribe(obj, event, func, data) def subscribe(Object obj, String event, Closure FunctionToCall, LinkedHashMap metaData) { objectList.add(obj) eventList.add(event) functionList.add(FunctionToCall) } ///////////////////////////////////////////////////////////////////// ////runIn(time, func) def runIn(int seconds, Closure functionToCall) { timersFuncList.add(functionToCall) timersList.add(new Timer()) def task = timersList[-1].runAfter(1000*seconds, functionToCall) } ///////////////////////////////////////////////////////////////////// ////unschedule(func) def unschedule(Closure functionToUnschedule) { for (int i = 0;i < timersFuncList.size();i++) { if (timersFuncList[i] == functionToUnschedule) { timersList[i].cancel() } } } ///////////////////////////////////////////////////////////////////// ////sendNotificationToContacts(text, recipients) def sendNotificationToContacts(String text, 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 \""+text+"\" to "+location.phoneNumbers[j].toString()) } } } } ///////////////////////////////////////////////////////////////////// ////sendSms(phone, text) def sendSms(long phoneNumber, String text) { println("Sending \""+text+"\" to "+phoneNumber.toString()) } 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){ 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 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... 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... 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... //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... 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 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!") } } } } //Application #2 class App2 { def reference def location def app //Extracted objects for App2 //Object for class Switch! def switchesoff //Object for class Switch! def switcheson //Object for class lock! def lock1 //Global variable for mode! def newMode = "away" //Global variable for number! def waitfor = 1 //Global Object for functions in subscribe method! def installed = this.&installed //Global Object for functions in subscribe method! def updated = this.&updated //Global Object for functions in subscribe method! def appTouch = this.&appTouch App2(Object obj) { reference = obj location = obj.locationObject app = obj.appObject switchesoff = obj.switchObject switcheson = obj.switchObject lock1 = obj.lockObject } //Global variables for each app //Settings variable defined to settings on purpose def settings = "Settings" //Global variable for state[mode] def state = [home:[],away:[],night:[]] //Create a global logger object for methods def log = new Logger() //Create a global variable for Functions in Subscribe method def functionList = [] //Create a global variable for Objects in Subscribe method def objectList = [] //Create a global variable for Events in Subscribe method def eventList = [] //Create a global list for function schedulers def timersFuncList = [] //Create a global list for timer schedulers def timersList = [] //Methods ///////////////////////////////////////////////////////////////////// def setLocationMode(String mode) { location.mode = mode } ///////////////////////////////////////////////////////////////////// ////subscribe(obj, func) def subscribe(Object obj, Closure FunctionToCall) { objectList.add(obj) eventList.add("Touched") functionList.add(FunctionToCall) } ////subscribe(obj, event, func) def subscribe(Object obj, String event, Closure FunctionToCall) { objectList.add(obj) eventList.add(event) functionList.add(FunctionToCall) } ////subscribe(obj, event, func, data) def subscribe(Object obj, String event, Closure FunctionToCall, LinkedHashMap metaData) { objectList.add(obj) eventList.add(event) functionList.add(FunctionToCall) } ///////////////////////////////////////////////////////////////////// ////runIn(time, func) def runIn(int seconds, Closure functionToCall) { timersFuncList.add(functionToCall) timersList.add(new Timer()) def task = timersList[-1].runAfter(1000*seconds, functionToCall) } ///////////////////////////////////////////////////////////////////// ////unschedule(func) def unschedule(Closure functionToUnschedule) { for (int i = 0;i < timersFuncList.size();i++) { if (timersFuncList[i] == functionToUnschedule) { timersList[i].cancel() } } } ///////////////////////////////////////////////////////////////////// ////sendNotificationToContacts(text, recipients) def sendNotificationToContacts(String text, 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 \""+text+"\" to "+location.phoneNumbers[j].toString()) } } } } ///////////////////////////////////////////////////////////////////// ////sendSms(phone, text) def sendSms(long phoneNumber, String text) { println("Sending \""+text+"\" to "+phoneNumber.toString()) } def installed() { log.debug "Installed with settings: ${settings}" log.debug "Current mode = ${location.mode}" subscribe(app, appTouch) } def updated() { log.debug "Updated with settings: ${settings}" log.debug "Current mode = ${location.mode}" unsubscribe() subscribe(app, appTouch) } def appTouch(evt) { log.debug "changeMode, location.mode = $location.mode, newMode = $newMode, location.modes = $location.modes" if (location.mode != newMode) { setLocationMode(newMode) log.debug "Changed the mode to '${newMode}'" } else { log.debug "New mode is the same as the old mode, leaving it be" } log.debug "appTouch: $evt" lock1.lock() switcheson.on() def delay = (waitfor != null && waitfor != "") ? waitfor * 1000 : 120000 switchesoff.off(delay: delay) } } @Field def app1 = new App1(this) @Field def app2 = new App2(this) app1.installed() app2.installed() appObject.setValue([name: "Touched", value: "Touched", deviceId: 0, descriptionText: "", displayed: true, linkText: "", isStateChange: false, unit: "", data: []])