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 ContactSensor.ContactSensor
+import ContactSensor.ContactSensors
+import DoorControl.DoorControl
+import DoorControl.DoorControls
+import Lock.Lock
+import Lock.Locks
+import Thermostat.Thermostat
+import Thermostat.Thermostats
+import Switch.Switch
+import Switch.Switches
+import PresenceSensor.PresenceSensor
+import PresenceSensor.PresenceSensors
import Logger.Logger
-import Location.locationVar
+import Location.LocationVar
import Location.Phrase
-import appTouch.Touch
+import appTouch.Touched
+import NfcTouch.NfcTouch
+import AeonKeyFob.AeonKeyFob
+import AeonKeyFob.AeonKeyFobs
+import MusicPlayer.MusicPlayer
+import MusicPlayer.MusicPlayers
+import MotionSensor.MotionSensor
+import MotionSensor.MotionSensors
+import ImageCapture.ImageCapture
+import ImageCapture.ImageCaptures
+import SmokeDetector.SmokeDetector
+import SmokeDetector.SmokeDetectors
+import Alarm.Alarm
+import Alarm.Alarms
+import SpeechSynthesis.SpeechSynthesis
+import SpeechSynthesis.SpeechSynthesises
+import Event.Event
+import Timer.SimulatedTimer
-//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 = []
+//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"]
+ for (int i = 0;i < app2.eventList.size();i++) {
+ if (app2.eventList[i] == name) {
+ def event = new Event(value, name, deviceId, descriptionText, displayed, linkText, linkText, isStateChange, unit, data)
+ evt.add(event)
+ app2.functionList[i](event)
+ }
+ }
+ for (int i = 0;i < app1.eventList.size();i++) {
+ if (app1.eventList[i] == name) {
+ def event = new Event(value, name, deviceId, descriptionText, displayed, linkText, linkText, isStateChange, unit, data)
+ evt.add(event)
+ app1.functionList[i](event)
+ }
+ }
+}
-//ExtractedObjects
+//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(sendEvent)
+//Object for touch to call function
+@Field def appObject = new Touched(sendEvent, 0)
+//Create a global list for events
+@Field def evt = []
+//Global Object for class Touch Sensor!
+@Field def touchSensorObject = new NfcTouch(sendEvent, 1)
+//Global Object for class switch!
+@Field def switchObject = new Switches(sendEvent, 1)
//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
+@Field def lockObject = new Locks(sendEvent, 1)
+//Global Object for class door control!
+@Field def doorControlObject = new DoorControls(sendEvent, 1)
+//Global Object for class contact sensor!
+@Field def contactObject = new ContactSensors(sendEvent, 1)
+//Global Object for class presence sensor!
+@Field def presenceSensorObject = new PresenceSensors(sendEvent, 1)
+//Global Object for class thermostat!
+@Field def thermostatObject = new Thermostats(sendEvent, 1)
+//Global Object for class aeon key fob!
+@Field def aeonKeyFobObject = new AeonKeyFobs(sendEvent, 1)
+//Global Object for class music player!
+@Field def musicPlayerObject = new MusicPlayers(sendEvent, 1)
+//Global Object for class motion sensor!
+@Field def motionSensorObject = new MotionSensors(sendEvent, 1)
+//Global Object for class image capture!
+@Field def imageCaptureObject = new ImageCaptures(sendEvent, 1)
+//Global Object for class smoke detector!
+@Field def smokeDetectorObject = new SmokeDetectors(sendEvent, 1)
+//Global Object for class alarm!
+@Field def alarmObject = new Alarms(sendEvent, 1)
+//Global Object for class speech synthesis!
+@Field def speechSynthesisObject = new SpeechSynthesises(sendEvent, 1)
-//Methods
-/////////////////////////////////////////////////////////////////////
-def definition(LinkedHashMap LHM) {
- println("IGNORE -- JUST SOME DEFINITION")
-}
+//Application #1
+class App1 {
+ def reference
+ def location
+ def app
-/////////////////////////////////////////////////////////////////////
-def preferences(Closure Input) {
- println("IGNORE -- JUST SOME DEFINITION")
-}
-/////////////////////////////////////////////////////////////////////
-def setLocationMode(String mode) {
- location.mode = mode
-}
+ //Extracted objects for App1
+ //Global variable for time!
+ def time = "15:00"
+ //Object for class lock!
+ def lock
+ //Object for class contactSensor!
+ def contact
+ //Global variable for enum!
+ def sendPushMessage = "Yes"
+ //Global variable for phone!
+ def phone = 9495379373
-/////////////////////////////////////////////////////////////////////
-////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])
+ //Extracted objects for functions for App1
+ //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 setTimeCallback = this.&setTimeCallback
+ //Global Object for functions in subscribe method!
+ def doorOpenCheck = this.&doorOpenCheck
+ //Global Object for functions in subscribe method!
+ def lockMessage = this.&lockMessage
+
+ App1(Object obj) {
+ reference = obj
+ location = obj.locationObject
+ app = obj.appObject
+ lock = obj.lockObject
+ contact = obj.contactObject
+ //Global variable for settings!
+ settings = [app:app, time:time, lock:lock, contact:contact, sendPushMessage:sendPushMessage, phone:phone]
+ }
+ //Global variables for each app
+ //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 = []
+ //Create a global variable for settings
+ def settings
+ //Zip code
+ def zipCode = 92617
+
+ //Methods
+ /////////////////////////////////////////////////////////////////////
+ def setLocationMode(String mode) {
+ location.mode = mode
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ ////subscribe(obj, func)
+ def subscribe(Object obj, Closure FunctionToCall) {
+ if (obj == app) {
+ objectList.add(obj)
+ eventList.add("Touched")
+ functionList.add(FunctionToCall)
+ } else if (obj == location) {
+ objectList.add(obj)
+ eventList.add("Location")
+ 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) {
+ if (timersFuncList.contains(functionToCall)) {
+ timersList[timersFuncList.indexOf(functionToCall)].cancel()
+ def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds*0, functionToCall)
+ } else {
+ timersFuncList.add(functionToCall)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds*0, functionToCall)
+ }
+ }
+
+ def runIn(int seconds, Closure functionToCall, LinkedHashMap metaData) {
+ runIn(seconds, functionToCall)
+ }
+
+ def runIn(int seconds, String nameOfFunction, LinkedHashMap metaData) {
+ runIn(seconds, nameOfFunction)
+ }
+
+ def runIn(int seconds, String nameOfFunction) {
+ timersFuncList.add(nameOfFunction)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(seconds*1000*0) {
+ "$nameOfFunction"()
+ }
+ }
+ /////////////////////////////////////////////////////////////////////
+ ////unschedule(func)
+ def unschedule(Closure functionToUnschedule) {
+ for (int i = 0;i < timersFuncList.size();i++) {
+ if (timersFuncList[i] == functionToUnschedule) {
+ if (timersList != null)
+ timersList[i].cancel()
}
}
}
-}
-/////////////////////////////////////////////////////////////////////
-////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()
+
+
+ def unschedule() {
+ for (int i = 0;i < timersFuncList.size();i++) {
+ if (timersList != null)
+ timersList[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 sendNotificationToContacts(String text, String 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())
+ }
}
}
}
-}
-/////////////////////////////////////////////////////////////////////
-////sendNotificationToContacts(text, recipients)
-def sendSms(long Phone, String S) {
- println("Sending \""+S+"\" to "+Phone.toString())
+ /////////////////////////////////////////////////////////////////////
+ ////sendSms(phone, text)
+ def sendSms(long phoneNumber, String text) {
+ println("Sending \""+text+"\" to "+phoneNumber.toString())
+ }
+
+ def sendSMS(long phoneNumber, String text) {
+ println("Sending \""+text+"\" to "+phoneNumber.toString())
+ }
+ /////////////////////////////////////////////////////////////////////
+ ////sendPush(text)
+ def sendPush(String text) {
+ println(text)
+ }
+ /////////////////////////////////////////////////////////////////////
+ ////schedule(time, nameOfFunction as String)
+ def schedule(String time, String nameOfFunction) {
+ def _inputTime = time.split(':')
+ Date date = new Date()
+ def _currentTime = date.format("HH:mm:ss").split(':')
+
+ //Convert input time and current time to minutes
+ def inputTime = Integer.parseInt(_inputTime[0])*3600+Integer.parseInt(_inputTime[1])*60
+ def currentTime = Integer.parseInt(_currentTime[0])*3600+Integer.parseInt(_currentTime[1])*60+Integer.parseInt(_currentTime[2])
+ def delay
+
+ if (inputTime < currentTime) {
+ delay = 24*60*60-inputTime+currentTime
+ } else {
+ delay = inputTime-currentTime
+ }
+
+ timersFuncList.add(nameOfFunction)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*1000*0) {
+ "$nameOfFunction"()
+ }
+ }
+ ////schedule(time, nameOfFunction as Closure)
+ def schedule(String time, Closure nameOfFunction) {
+ def _inputTime = time.split(':')
+ Date date = new Date()
+ def _currentTime = date.format("HH:mm:ss").split(':')
+
+ //Convert input time and current time to minutes
+ def inputTime = Integer.parseInt(_inputTime[0])*3600+Integer.parseInt(_inputTime[1])*60
+ def currentTime = Integer.parseInt(_currentTime[0])*3600+Integer.parseInt(_currentTime[1])*60+Integer.parseInt(_currentTime[2])
+ def delay
+
+ if (inputTime < currentTime) {
+ delay = 24*60*60-inputTime+currentTime
+ } else {
+ delay = inputTime-currentTime
+ }
+
+ if (timersFuncList.contains(nameOfFunction)) {
+ timersList[timersFuncList.indexOf(nameOfFunction)].cancel()
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds*0, nameOfFunction)
+ } else {
+ timersFuncList.add(nameOfFunction)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds*0, nameOfFunction)
+ }
+ }
+ /////////////////////////////////////////////////////////////////////
+ def now() {
+ return System.currentTimeMillis()
+ }
+ /////////////////////////////////////////////////////////////////////
+ def getTemperatureScale() {
+ return 'C' //Celsius for now
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ def getSunriseAndSunset(LinkedHashMap metaData) {
+ def sunRiseSetInfo = [sunrise:[time:1563800160000],sunset:[time:1563850740000]]
+ return sunRiseSetInfo
+ }
+
+ def installed() {
+ schedule(time, "setTimeCallback")
+
+ }
+
+ def updated(settings) {
+ unschedule()
+ schedule(time, "setTimeCallback")
+ }
+
+ def setTimeCallback() {
+ if (contact) {
+ doorOpenCheck()
+ } else {
+ lockMessage()
+ lock.lock()
+ }
+ }
+ def doorOpenCheck() {
+ def currentState = contact.contactState
+ if (currentState?.value == "open") {
+ def msg = "${contact.displayName} is open. Scheduled lock failed."
+ log.info msg
+ if (sendPushMessage) {
+ sendPush msg
+ }
+ if (phone) {
+ sendSms phone, msg
+ }
+ } else {
+ lockMessage()
+ lock.lock()
+ }
+ }
+
+ def lockMessage() {
+ def msg = "Locking ${lock.displayName} due to scheduled lock."
+ log.info msg
+ if (sendPushMessage) {
+ sendPush msg
+ }
+ if (phone) {
+ sendSms phone, msg
+ }
+ }
}
-///////////////////////////////////////////
-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
- }
- }
-}
+//Application #2
+class App2 {
+ def reference
+ def location
+ def app
-def installed(){
- initialize()
-}
+ //Extracted objects for App2
+ //Object for class Touch Sensor!
+ def tag
+ //Object for class switch!
+ def switch1
+ //Object for class lock!
+ def lock
+ //Object for class door control!
+ def garageDoor
+ //Global variable for enum!
+ def masterSwitch = "Yes"
+ //Global variable for enum!
+ def masterLock = "Yes"
+ //Global variable for enum!
+ def masterDoor = "Yes"
-def updated(){
- unsubscribe()
- unschedule()
- initialize()
-}
+ //Extracted objects for functions for App2
+ //Global Object for functions in subscribe method!
+ def pageTwo = this.&pageTwo
+ //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 touchHandler = this.&touchHandler
-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)
-}
+ App2(Object obj) {
+ reference = obj
+ location = obj.locationObject
+ app = obj.appObject
+ tag = obj.touchSensorObject
+ switch1 = obj.switchObject
+ lock = obj.lockObject
+ garageDoor = obj.doorControlObject
+ //Global variable for settings!
+ settings = [app:app, tag:tag, switch1:switch1, lock:lock, garageDoor:garageDoor, masterSwitch:masterSwitch, masterLock:masterLock, masterDoor:masterDoor]
+ }
+ //Global variables for each app
+ //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 = []
+ //Create a global variable for settings
+ def settings
+ //Zip code
+ def zipCode = 92617
-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!")
- }
-}
+ //Methods
+ /////////////////////////////////////////////////////////////////////
+ def setLocationMode(String mode) {
+ location.mode = mode
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ ////subscribe(obj, func)
+ def subscribe(Object obj, Closure FunctionToCall) {
+ if (obj == app) {
+ objectList.add(obj)
+ eventList.add("Touched")
+ functionList.add(FunctionToCall)
+ } else if (obj == location) {
+ objectList.add(obj)
+ eventList.add("Location")
+ 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) {
+ if (timersFuncList.contains(functionToCall)) {
+ timersList[timersFuncList.indexOf(functionToCall)].cancel()
+ def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds*0, functionToCall)
+ } else {
+ timersFuncList.add(functionToCall)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds*0, functionToCall)
+ }
+ }
+
+ def runIn(int seconds, Closure functionToCall, LinkedHashMap metaData) {
+ runIn(seconds, functionToCall)
+ }
+
+ def runIn(int seconds, String nameOfFunction, LinkedHashMap metaData) {
+ runIn(seconds, nameOfFunction)
+ }
+
+ def runIn(int seconds, String nameOfFunction) {
+ timersFuncList.add(nameOfFunction)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(seconds*1000*0) {
+ "$nameOfFunction"()
+ }
+ }
+ /////////////////////////////////////////////////////////////////////
+ ////unschedule(func)
+ def unschedule(Closure functionToUnschedule) {
+ for (int i = 0;i < timersFuncList.size();i++) {
+ if (timersFuncList[i] == functionToUnschedule) {
+ if (timersList != null)
+ timersList[i].cancel()
+ }
+ }
+ }
+
+
+ def unschedule() {
+ for (int i = 0;i < timersFuncList.size();i++) {
+ if (timersList != null)
+ timersList[i].cancel()
+ }
+ }
+ /////////////////////////////////////////////////////////////////////
+ ////sendNotificationToContacts(text, recipients)
+ def sendNotificationToContacts(String text, String 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 sendSMS(long phoneNumber, String text) {
+ println("Sending \""+text+"\" to "+phoneNumber.toString())
+ }
+ /////////////////////////////////////////////////////////////////////
+ ////schedule(time, nameOfFunction as String)
+ def schedule(String time, String nameOfFunction) {
+ def _inputTime = time.split(':')
+ Date date = new Date()
+ def _currentTime = date.format("HH:mm:ss").split(':')
+
+ //Convert input time and current time to minutes
+ def inputTime = Integer.parseInt(_inputTime[0])*3600+Integer.parseInt(_inputTime[1])*60
+ def currentTime = Integer.parseInt(_currentTime[0])*3600+Integer.parseInt(_currentTime[1])*60+Integer.parseInt(_currentTime[2])
+ def delay
+
+ if (inputTime < currentTime) {
+ delay = 24*60*60-inputTime+currentTime
+ } else {
+ delay = inputTime-currentTime
+ }
+
+ timersFuncList.add(nameOfFunction)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*1000*0) {
+ "$nameOfFunction"()
+ }
+ }
+ ////schedule(time, nameOfFunction as Closure)
+ def schedule(String time, Closure nameOfFunction) {
+ def _inputTime = time.split(':')
+ Date date = new Date()
+ def _currentTime = date.format("HH:mm:ss").split(':')
+
+ //Convert input time and current time to minutes
+ def inputTime = Integer.parseInt(_inputTime[0])*3600+Integer.parseInt(_inputTime[1])*60
+ def currentTime = Integer.parseInt(_currentTime[0])*3600+Integer.parseInt(_currentTime[1])*60+Integer.parseInt(_currentTime[2])
+ def delay
+
+ if (inputTime < currentTime) {
+ delay = 24*60*60-inputTime+currentTime
+ } else {
+ delay = inputTime-currentTime
+ }
+
+ if (timersFuncList.contains(nameOfFunction)) {
+ timersList[timersFuncList.indexOf(nameOfFunction)].cancel()
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds*0, nameOfFunction)
+ } else {
+ timersFuncList.add(nameOfFunction)
+ timersList.add(new SimulatedTimer())
+ def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds*0, nameOfFunction)
+ }
+ }
+ /////////////////////////////////////////////////////////////////////
+ def now() {
+ return System.currentTimeMillis()
+ }
+ /////////////////////////////////////////////////////////////////////
+ def getTemperatureScale() {
+ return 'C' //Celsius for now
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ def getSunriseAndSunset(LinkedHashMap metaData) {
+ def sunRiseSetInfo = [sunrise:[time:1563800160000],sunset:[time:1563850740000]]
+ return sunRiseSetInfo
+ }
-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 pageTwo() {
+ dynamicPage(name: "pageTwo") {
+ section("If set, the state of these devices will be toggled each time the tag is touched, " +
+ "e.g. a light that's on will be turned off and one that's off will be turned on, " +
+ "other devices of the same type will be set to the same state as their master device. " +
+ "If no master is designated then the majority of devices of the same type will be used " +
+ "to determine whether to turn on or off the devices.") {
+
+ if (switch1 || masterSwitch) {
+ input "masterSwitch", "enum", title: "Master switch", options: switch1.collect{[(it.id): it.displayName]}, required: false
+ }
+ if (lock || masterLock) {
+ input "masterLock", "enum", title: "Master lock", options: lock.collect{[(it.id): it.displayName]}, required: false
+ }
+ if (garageDoor || masterDoor) {
+ input "masterDoor", "enum", title: "Master door", options: garageDoor.collect{[(it.id): it.displayName]}, required: false
+ }
+ }
+ section([mobileOnly:true]) {
+ label title: "Assign a name", required: false
+ mode title: "Set for specific mode(s)", required: false
+ }
+ }
+ }
+
+ def installed() {
+ log.debug "Installed with settings: ${settings}"
+
+ initialize()
+ }
+
+ def updated() {
+ log.debug "Updated with settings: ${settings}"
+
+ unsubscribe()
+ initialize()
+ }
+
+ def initialize() {
+ subscribe tag, "nfcTouch", touchHandler
+ subscribe app, touchHandler
+ }
+
+ private currentStatus(devices, master, attribute) {
+ log.trace "currentStatus($devices, $master, $attribute)"
+ def result = null
+ if (master) {
+ result = devices.find{it.id == master}?.currentValue(attribute)
+ }
+ else {
+ def map = [:]
+ devices.each {
+ def value = it.currentValue(attribute)
+ map[value] = (map[value] ?: 0) + 1
+ log.trace "$it.displayName: $value"
+ }
+ log.trace map
+ result = map.collect{it}.sort{it.value}[-1].key
+ }
+ log.debug "$attribute = $result"
+ result
+ }
+
+ def touchHandler(evt) {
+ log.trace "touchHandler($evt.descriptionText)"
+ if (switch1) {
+ def status = currentStatus(switch1, masterSwitch, "switch")
+ switch1.each {
+ if (status == "on") {
+ it.off()
+ }
+ else {
+ it.on()
+ }
+ }
+ }
+
+ if (lock) {
+ def status = currentStatus(lock, masterLock, "lock")
+ lock.each {
+ if (status == "locked") {
+ lock.unlock()
+ }
+ else {
+ lock.lock()
+ }
+ }
+ }
+
+ if (garageDoor) {
+ def status = currentStatus(garageDoor, masterDoor, "status")
+ garageDoor.each {
+ if (status == "open") {
+ it.close()
+ }
+ else {
+ it.open()
+ }
+ }
+ }
+ }
}
-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!")
- }
- }
-}
+@Field def app1 = new App1(this)
+@Field def app2 = new App2(this)
+app1.installed()
+app2.installed()
-installed()
-EventHandler()