Commit #7: Events thread-based + new easier Extractor.py + our own Timer class
[smartthings-infrastructure.git] / main.groovy
index b08146d504111bc87618f29f4504da16d3595b75..d0d579664406ff6254a92e6a19b2d419b996152a 100644 (file)
@@ -14,6 +14,7 @@ import Location.LocationVar
 import Location.Phrase
 import appTouch.Touched
 import Event.Event
+import Timer.SimulatedTimer
 
 //Global eventHandler
 /////////////////////////////////////////////////////////////////////
@@ -27,87 +28,22 @@ def eventHandler(LinkedHashMap eventDataMap) {
        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])
-               }
+       for (int i = 0;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])
+                       def event = new Event(value, name, deviceId, descriptionText, displayed, linkText, linkText, isStateChange, unit, data)
+                       evt.add(event)
+                       app2.functionList[i](event)
                }
        }
 
-       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])
-                       }
+       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)
                }
-       }       
+       }
 }
 
 //GlobalVariables for both Apps
@@ -124,10 +60,10 @@ def eventHandler(LinkedHashMap eventDataMap) {
 
 //Extracted global objects for both Apps
 //Global Object for class lock!
-@Field def lockObject = new Locking(sendEvent, 1)
+@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 contactObject = new Contacting(sendEvent,1)
+//Global Object for class switch!
 @Field def switchObject = new Switching(sendEvent, 1)
 
 //Application #1
@@ -144,11 +80,13 @@ class App1 {
        //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 secondsLater = 10
+       //Global variable for contact!
+       def recipients = "AJ"
+       //Global variable for phone!
        def phoneNumber = 9495379373
+
+       //Extracted objects for functions for App1
        //Global Object for functions in subscribe method!
        def installed = this.&installed
        //Global Object for functions in subscribe method!
@@ -215,22 +153,36 @@ class App1 {
        /////////////////////////////////////////////////////////////////////
        ////runIn(time, func)
        def runIn(int seconds, Closure functionToCall) {
-               timersFuncList.add(functionToCall)
-               timersList.add(new Timer())
-               def task = timersList[-1].runAfter(1000*seconds, functionToCall)
+               if (timersFuncList.contains(functionToCall)) {
+                       timersList[timersFuncList.indexOf(functionToCall)].cancel()
+                       def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds, functionToCall)
+               } else {
+                       timersFuncList.add(functionToCall)
+                       timersList.add(new SimulatedTimer())
+                       def task = timersList[timersFuncList.indexOf(functionToCall)].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()
+                               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, List 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]) {
@@ -244,6 +196,61 @@ class App1 {
        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) {
+                       "$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, nameOfFunction)
+               } else {
+                       timersFuncList.add(nameOfFunction)
+                       timersList.add(new SimulatedTimer())
+                       def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds, nameOfFunction)
+               }
+       }
 
        def installed(){
            initialize()
@@ -340,16 +347,18 @@ class App2 {
        def app
 
        //Extracted objects for App2
-       //Object for class Switch!
+       //Object for class switch!
        def switchesoff
-       //Object for class Switch!
+       //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
+       def waitfor = 4
+
+       //Extracted objects for functions for App2
        //Global Object for functions in subscribe method!
        def installed = this.&installed
        //Global Object for functions in subscribe method!
@@ -411,22 +420,36 @@ class App2 {
        /////////////////////////////////////////////////////////////////////
        ////runIn(time, func)
        def runIn(int seconds, Closure functionToCall) {
-               timersFuncList.add(functionToCall)
-               timersList.add(new Timer())
-               def task = timersList[-1].runAfter(1000*seconds, functionToCall)
+               if (timersFuncList.contains(functionToCall)) {
+                       timersList[timersFuncList.indexOf(functionToCall)].cancel()
+                       def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds, functionToCall)
+               } else {
+                       timersFuncList.add(functionToCall)
+                       timersList.add(new SimulatedTimer())
+                       def task = timersList[timersFuncList.indexOf(functionToCall)].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()
+                               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, List 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]) {
@@ -440,6 +463,56 @@ class App2 {
        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) {
+                       "$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, nameOfFunction)
+               } else {
+                       timersFuncList.add(nameOfFunction)
+                       timersList.add(new SimulatedTimer())
+                       def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds, nameOfFunction)
+               }
+       }
 
        def installed()
        {
@@ -477,6 +550,72 @@ class App2 {
 @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: []])
 
+       // Generate a random variable
+       Random random = new Random(1131)
+       int nextRandom = 10
+       
+       // Touch events
+       new Thread() {
+               @Override
+               public void run() {
+                       while(true) {
+                               appObject.setValue([name: "Touched", value: "Touched", deviceId: 0, descriptionText: "",
+                                                  displayed: true, linkText: "", isStateChange: false, unit: "", data: []])
+                               Thread.sleep(random.nextInt(nextRandom));       
+                               
+                       }
+               }
+       }.start()
+       
+       // Lock events
+       new Thread() {
+               
+               @Override
+               public void run() {
+                       while(true) {
+                               lockObject.setValue([name: "lock", value: "locked", deviceId: 0, descriptionText: "",
+                                                  displayed: true, linkText: "", isStateChange: false, unit: "", data: []])
+                               Thread.sleep(random.nextInt(nextRandom));       
+                       }
+               }
+       }.start()
+       
+       new Thread() {
+               
+               @Override
+               public void run() {
+                       while(true) {
+                               lockObject.setValue([name: "unlock", value: "unlocked", deviceId: 0, descriptionText: "",
+                                                  displayed: true, linkText: "", isStateChange: false, unit: "", data: []])
+                               Thread.sleep(random.nextInt(nextRandom));       
+                       }
+               }
+       }.start()
+       
+       // Contact sensor events
+       new Thread() {
+               
+               @Override
+               public void run() {
+                       while(true) {
+                               contactObject.setValue([name: "contact.open", value: "open", deviceId: 0, descriptionText: "",
+                                                  displayed: true, linkText: "", isStateChange: false, unit: "", data: []])
+                               Thread.sleep(random.nextInt(nextRandom));       
+                               
+                       }
+               }
+       }.start()
+       
+       new Thread() {
+               
+               @Override
+               public void run() {
+                       while(true) {
+                               contactObject.setValue([name: "contact.closed", value: "closed", deviceId: 0, descriptionText: "",
+                                                  displayed: true, linkText: "", isStateChange: false, unit: "", data: []])
+                               Thread.sleep(random.nextInt(nextRandom));       
+                               
+                       }
+               }
+       }.start()