X-Git-Url: http://plrg.eecs.uci.edu/git/?p=smartthings-infrastructure.git;a=blobdiff_plain;f=main.groovy;h=d8f3667539d5a478345ea263835084017281e3a6;hp=54605116eadba871d6e24cf2164acc84236ad0e4;hb=4b10e92c8b054d930453dcb73dda257af1fefd0d;hpb=099c82f83bc2f4b8bd060d1985cf4a9fed3bc695 diff --git a/main.groovy b/main.groovy index 5460511..d8f3667 100644 --- a/main.groovy +++ b/main.groovy @@ -24,11 +24,19 @@ 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 -import gov.nasa.jpf.vm.Verify - //Global eventHandler ///////////////////////////////////////////////////////////////////// def eventHandler(LinkedHashMap eventDataMap) { @@ -65,7 +73,7 @@ def eventHandler(LinkedHashMap eventDataMap) { eventHandler(eventDataMap) } //Object for location -@Field def locationObject = new LocationVar() +@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 @@ -88,6 +96,16 @@ def eventHandler(LinkedHashMap eventDataMap) { @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) //Application #1 class App1 { @@ -96,12 +114,16 @@ class App1 { def app //Extracted objects for App1 + //Global variable for time! + def time = "15:00" //Object for class lock! - def lock1 - //Global variable for number! - def minutesLater = 1 + def lock //Object for class contactSensor! - def openSensor + def contact + //Global variable for enum! + def sendPushMessage = "Yes" + //Global variable for phone! + def phone = 9495379373 //Extracted objects for functions for App1 //Global Object for functions in subscribe method! @@ -109,24 +131,20 @@ class App1 { //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 doorOpen = this.&doorOpen + def setTimeCallback = this.&setTimeCallback //Global Object for functions in subscribe method! - def doorClosed = this.&doorClosed + def doorOpenCheck = this.&doorOpenCheck //Global Object for functions in subscribe method! - def doorHandler = this.&doorHandler + def lockMessage = this.&lockMessage App1(Object obj) { reference = obj location = obj.locationObject app = obj.appObject - lock1 = obj.lockObject - openSensor = obj.contactObject + lock = obj.lockObject + contact = obj.contactObject //Global variable for settings! - settings = [app:app, lock1:lock1, minutesLater:minutesLater, openSensor:openSensor] + settings = [app:app, time:time, lock:lock, contact:contact, sendPushMessage:sendPushMessage, phone:phone] } //Global variables for each app //Global variable for state[mode] @@ -145,6 +163,8 @@ class App1 { def timersList = [] //Create a global variable for settings def settings + //Zip code + def zipCode = 92617 //Methods ///////////////////////////////////////////////////////////////////// @@ -182,11 +202,27 @@ class App1 { def runIn(int seconds, Closure functionToCall) { if (timersFuncList.contains(functionToCall)) { timersList[timersFuncList.indexOf(functionToCall)].cancel() - def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds, functionToCall) + 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, functionToCall) + 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"() } } ///////////////////////////////////////////////////////////////////// @@ -223,6 +259,10 @@ class App1 { 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) { @@ -248,7 +288,7 @@ class App1 { timersFuncList.add(nameOfFunction) timersList.add(new SimulatedTimer()) - def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*1000) { + def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*1000*0) { "$nameOfFunction"() } } @@ -271,80 +311,72 @@ class App1 { if (timersFuncList.contains(nameOfFunction)) { timersList[timersFuncList.indexOf(nameOfFunction)].cancel() - def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds, nameOfFunction) + 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, nameOfFunction) + def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds*0, nameOfFunction) } } ///////////////////////////////////////////////////////////////////// def now() { return System.currentTimeMillis() } - - def installed() - { - log.debug "Auto Lock Door installed. (URL: http://www.github.com/smartthings-users/smartapp.auto-lock-door)" - initialize() - } - - def updated() - { - unsubscribe() - unschedule() - log.debug "Auto Lock Door updated." - initialize() - } - - def initialize() - { - log.debug "Settings: ${settings}" - subscribe(lock1, "lock", doorHandler) - subscribe(openSensor, "contact.closed", doorClosed) - subscribe(openSensor, "contact.open", doorOpen) - } - - def lockDoor() - { - log.debug "Locking Door if Closed" - if((openSensor.latestValue("contact") == "closed")){ - log.debug "Door Closed" - lock1.lock() - } else { - if ((openSensor.latestValue("contact") == "open")) { - def delay = minutesLater * 60 - log.debug "Door open will try again in $minutesLater minutes" - runIn( delay, lockDoor ) - } - } + ///////////////////////////////////////////////////////////////////// + def getTemperatureScale() { + return 'C' //Celsius for now } - def doorOpen(evt) { - log.debug "Door open reset previous lock task..." - unschedule( lockDoor ) - def delay = minutesLater * 60 - runIn( delay, lockDoor ) + ///////////////////////////////////////////////////////////////////// + def getSunriseAndSunset(LinkedHashMap metaData) { + def sunRiseSetInfo = [sunrise:[time:1563800160000],sunset:[time:1563850740000]] + return sunRiseSetInfo } + + def installed() { + schedule(time, "setTimeCallback") - def doorClosed(evt) { - log.debug "Door Closed" } - def doorHandler(evt) - { - log.debug "Door ${openSensor.latestValue}" - log.debug "Lock ${evt.name} is ${evt.value}." + def updated(settings) { + unschedule() + schedule(time, "setTimeCallback") + } - if (evt.value == "locked") { // If the human locks the door then... - log.debug "Cancelling previous lock task..." - unschedule( lockDoor ) // ...we don't need to lock it later. + 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 } - else { // If the door is unlocked then... - def delay = minutesLater * 60 // runIn uses seconds - log.debug "Re-arming lock in ${minutesLater} minutes (${delay}s)." - runIn( delay, lockDoor ) // ...schedule to lock in x minutes. + 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 + } } } @@ -365,11 +397,11 @@ class App2 { //Object for class door control! def garageDoor //Global variable for enum! - def masterSwitch = "switchID0" + def masterSwitch = "Yes" //Global variable for enum! - def masterLock = "lockID0" + def masterLock = "Yes" //Global variable for enum! - def masterDoor = "DoorControlID0" + def masterDoor = "Yes" //Extracted objects for functions for App2 //Global Object for functions in subscribe method! @@ -381,8 +413,6 @@ class App2 { //Global Object for functions in subscribe method! def initialize = this.&initialize //Global Object for functions in subscribe method! - def currentStatus = this.¤tStatus - //Global Object for functions in subscribe method! def touchHandler = this.&touchHandler App2(Object obj) { @@ -413,6 +443,8 @@ class App2 { def timersList = [] //Create a global variable for settings def settings + //Zip code + def zipCode = 92617 //Methods ///////////////////////////////////////////////////////////////////// @@ -450,11 +482,27 @@ class App2 { def runIn(int seconds, Closure functionToCall) { if (timersFuncList.contains(functionToCall)) { timersList[timersFuncList.indexOf(functionToCall)].cancel() - def task = timersList[timersFuncList.indexOf(functionToCall)].runAfter(1000*seconds, functionToCall) + 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, functionToCall) + 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"() } } ///////////////////////////////////////////////////////////////////// @@ -491,6 +539,10 @@ class App2 { 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) { @@ -511,7 +563,7 @@ class App2 { timersFuncList.add(nameOfFunction) timersList.add(new SimulatedTimer()) - def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*1000) { + def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*1000*0) { "$nameOfFunction"() } } @@ -534,22 +586,36 @@ class App2 { if (timersFuncList.contains(nameOfFunction)) { timersList[timersFuncList.indexOf(nameOfFunction)].cancel() - def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*seconds, nameOfFunction) + 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, nameOfFunction) + 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 pageTwo() { dynamicPage(name: "pageTwo") { - section("If set, the state of these devices will be toggled each time the tag is touched, " + + 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 } @@ -558,12 +624,12 @@ class App2 { } 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 - } + } } } @@ -618,7 +684,7 @@ class App2 { } } } - + if (lock) { def status = currentStatus(lock, masterLock, "lock") lock.each { @@ -630,7 +696,7 @@ class App2 { } } } - + if (garageDoor) { def status = currentStatus(garageDoor, masterDoor, "status") garageDoor.each { @@ -650,48 +716,3 @@ class App2 { app1.installed() app2.installed() -def events = [1,2,3,4,5,6,7] -def list = events.permutations() -int count = Verify.getInt(0,list.size()-1) -println "COUNT: " + count - -list[count].each { - switch(it) { - case 1: - appObject.setValue([name: "Touched", value: "Touched", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println "1" - break - case 2: - lockObject.setValue([name: "lock0", value: "locked", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println " 2" - break - case 3: - lockObject.setValue([name: "lock0", value: "unlocked", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println " 3" - break - case 4: - contactObject.setValue([name: "contact0", value: "open", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println " 4" - break - case 5: - contactObject.setValue([name: "contact0", value: "closed", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println " 5" - break - case 6: - switchObject.setValue([name: "switch0", value: "on", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println " 6" - break - case 7: - switchObject.setValue([name: "switch0", value: "off", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) - println " 7" - default: - break - } -}