X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=main.groovy;h=a1474f1fcd60a238b457107787b61fcc76bf007f;hb=fea13f011a64a64558ad697eee68e3927395cccd;hp=e406b84248a0ca0013e123ccc59bf4f78b510c4e;hpb=4c11bc74dad5814ff9ba94fa21894ff0f90dc291;p=smartthings-infrastructure.git diff --git a/main.groovy b/main.groovy index e406b84..a1474f1 100644 --- a/main.groovy +++ b/main.groovy @@ -1,350 +1,1161 @@ //Infrastructure for SmartThings Application //Importing Libraries import groovy.transform.Field +import groovy.json.JsonSlurper //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 AccelerationSensor.AccelerationSensor +import AccelerationSensor.AccelerationSensors +import Battery.Battery +import Battery.Batteries +import BeaconSensor.BeaconSensor +import BeaconSensor.BeaconSensors +import CarbonMonoxideDetector.CarbonMonoxideDetector +import CarbonMonoxideDetector.CarbonMonoxideDetectors +import ColorControl.ColorControl +import ColorControl.ColorControls +import EnergyMeter.EnergyMeter +import EnergyMeter.EnergyMeters +import IlluminanceMeasurement.IlluminanceMeasurement +import IlluminanceMeasurement.IlluminanceMeasurements +import PowerMeter.PowerMeter +import PowerMeter.PowerMeters +import RelativeHumidityMeasurement.RelativeHumidityMeasurement +import RelativeHumidityMeasurement.RelativeHumidityMeasurements +import RelaySwitch.RelaySwitch +import RelaySwitch.RelaySwitches +import SleepSensor.SleepSensor +import SleepSensor.SleepSensors +import StepSensor.StepSensor +import StepSensor.StepSensors +import SwitchLevel.SwitchLevel +import SwitchLevel.SwitchLevels +import TemperatureMeasurement.TemperatureMeasurement +import TemperatureMeasurement.TemperatureMeasurements +import WaterSensor.WaterSensor +import WaterSensor.WaterSensors +import Valve.Valve +import Valve.Valves +import MobilePresence.MobilePresence +import MobilePresence.MobilePresences +import Event.Event +import AtomicState.AtomicState +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 = [] +//JPF's Verify API +import gov.nasa.jpf.vm.Verify +//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) + app2.functionList[i](event) + } + } -//ExtractedObjects -//Global Object for class switch! -@Field def switchesoff = new switching(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) + app1.functionList[i](event) + } + } +} + +//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 AtomicState! +@Field def atomicState = new AtomicState() +//Global Object for class Touch Sensor! +@Field def touchSensorObject = new NfcTouch(sendEvent, 1) //Global Object for class switch! -@Field def switcheson = new switching(1) +@Field def switchObject = new Switches(sendEvent, 1) //Global Object for class lock! -@Field def lock1 = new locking(1) -//Global variable for mode! -@Field def newMode = "away" -//Global variable for number! -@Field def waitfor = 5 -//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 appTouch = this.&appTouch +@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) +//Global Object for class acceleration sensor! +@Field def accelerationSensorObject = new AccelerationSensors(sendEvent, 1) +//Global Object for class Battery! +@Field def batteryObject = new Batteries(sendEvent, 1) +//Global Object for class beacon sensor! +@Field def beaconSensorObject = new BeaconSensors(sendEvent, 1) +//Global Object for class carbon monoxide! +@Field def carbonMonoxideDetectorObject = new CarbonMonoxideDetectors(sendEvent, 1) +//Global Object for class color control! +@Field def colorControlObject = new ColorControls(sendEvent, 1) +//Global Object for class energy meter! +@Field def energyMeterObject = new EnergyMeters(sendEvent, 1) +//Global Object for class illuminance measurement! +@Field def illuminanceMeasurementObject = new IlluminanceMeasurements(sendEvent, 1) +//Global Object for class power meter! +@Field def powerMeterObject = new PowerMeters(sendEvent, 1) +//Global Object for class humidity measurement! +@Field def humidityMeasurementObject = new RelativeHumidityMeasurements(sendEvent, 1) +//Global Object for class relay switch! +@Field def relaySwitchObject = new RelaySwitches(sendEvent, 1) +//Global Object for class sleep sensor! +@Field def sleepSensorObject = new SleepSensors(sendEvent, 1) +//Global Object for class step sensor! +@Field def stepSensorObject = new StepSensors(sendEvent, 1) +//Global Object for class switch level! +@Field def switchLevelObject = new SwitchLevels(sendEvent, 1) +//Global Object for class temperature measurement! +@Field def temperatureMeasurementObject = new TemperatureMeasurements(sendEvent, 1) +//Global Object for class water sensor! +@Field def waterSensorObject = new WaterSensors(sendEvent, 1) +//Global Object for class valves! +@Field def valveObject = new Valves(sendEvent, 1) +//Global Object for class mobile presence! +@Field def mobilePresenceObject = new MobilePresences(sendEvent, 1) -//Methods -///////////////////////////////////////////////////////////////////// -def definition(LinkedHashMap LHM) { - println("IGNORE -- JUST SOME DEFINITION") -} +//Application #1 +class App1 { + def reference + def location + def app + def atomicState -///////////////////////////////////////////////////////////////////// -def preferences(Closure Input) { - println("IGNORE -- JUST SOME DEFINITION") -} -///////////////////////////////////////////////////////////////////// -def setLocationMode(String mode) { - location.mode = mode -} + //Extracted objects for App1 + //Object for class lock! + def lock1 + //Object for class contactSensor! + def contact + //Global variable for number! + def minutesLater = 70 + //Global variable for number! + def secondsLater = 93 + //Global variable for contact! + def recipients = "AJ" + //Global variable for phone! + def phoneNumber = 9495379373 -///////////////////////////////////////////////////////////////////// -////subscribe(app, func) -def subscribe(Object Obj, Closure Input) { - ObjectList.add(Obj) - 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 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 + atomicState = obj.atomicState + lock1 = obj.lockObject + contact = obj.contactObject + //Global variable for settings! + settings = [app:app, lock1:lock1, contact:contact, minutesLater:minutesLater, secondsLater:secondsLater, recipients:recipients, phoneNumber:phoneNumber] + } + //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*0, nameOfFunction) + } else { + timersFuncList.add(nameOfFunction) + timersList.add(new SimulatedTimer()) + def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*0, nameOfFunction) + } + } + ///////////////////////////////////////////////////////////////////// + def now() { + return System.currentTimeMillis() + } + ///////////////////////////////////////////////////////////////////// + def getTemperatureScale() { + return 'F' //Celsius for now + } + + ///////////////////////////////////////////////////////////////////// + def getSunriseAndSunset(LinkedHashMap metaData) { + def sunRiseSetInfo = [sunrise:[time:1563800160000],sunset:[time:1563850740000]] + return sunRiseSetInfo + } + ///////////////////////////////////////////////////////////////////// + def httpPostJson(LinkedHashMap metaData, Closure inputData) { + inputData(metaData) + } + ///////////////////////////////////////////////////////////////////// + def runEvery15Minutes(Closure inputData) { + inputData() + } + ///////////////////////////////////////////////////////////////////// + def timeToday(String time, Object timeZone) { + def timeOfDay = new Date() + def _inputTime = time.split(':') + def inputTime = Integer.parseInt(_inputTime[0])*3600+Integer.parseInt(_inputTime[1])*60+1564191100415 + timeOfDay.time = inputTime + return timeOfDay + } + ///////////////////////////////////////////////////////////////////// + def sendNotification(String text, LinkedHashMap metaData) { + println("Sending \""+text+"\" to "+metaData.phone.toString()) + } + ///////////////////////////////////////////////////////////////////// + def canSchedule() { + return true + } -/** - * Good Night House - * - * Copyright 2014 Joseph Charette - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License - * for the specific language governing permissions and limitations under the License. - * - */ -definition( - name: "Good Night House", - namespace: "charette.joseph@gmail.com", - author: "Joseph Charette", - description: "Some on, some off with delay for bedtime, Lock The Doors", - category: "Convenience", - iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", - iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png" -/** -* Borrowed code from -* Walk Gentle Into That Good Night -* -* Author: oneaccttorulethehouse@gmail.com -* Date: 2014-02-01 - */ - ) -preferences { - section("When I touch the app turn these lights off…"){ - input "switchesoff", "capability.switch", multiple: true, required:true - } - section("When I touch the app turn these lights on…"){ - input "switcheson", "capability.switch", multiple: true, required:false - } - section("Lock theses locks...") { - input "lock1","capability.lock", multiple: true - } - section("And change to this mode...") { - input "newMode", "mode", title: "Mode?" - } - section("After so many seconds (optional)"){ - input "waitfor", "number", title: "Off after (default 120)", required: true + 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!") + } + } } } -def installed() -{ - log.debug "Installed with settings: ${settings}" - log.debug "Current mode = ${location.mode}" - subscribe(app, appTouch) -} +//Application #2 +class App2 { + def reference + def location + def app + def atomicState + + //Extracted objects for App2 + //Global variable for time! + def starting = "15:00" + //Global variable for time! + def ending = "15:00" + //Object for class beacon sensor! + def beacons + //Object for class mobile presence! + def phones + //Global variable for enum! + def arrivalPhrase = "Good Night!" + //Object for class switch! + def arrivalOnSwitches + //Object for class switch! + def arrivalOffSwitches + //Object for class lock! + def arrivalLocks + //Global variable for enum! + def departPhrase = "Good Night!" + //Object for class switch! + def departOnSwitches + //Object for class switch! + def departOffSwitches + //Object for class lock! + def departLocks + //Global variable for boolean! + def pushNotification = "0" + //Global variable for phone! + def phone = 9495379373 + //Global variable for enum! + def days = "Monday" + //Global variable for mode! + def modes = "night" + + //Extracted objects for functions for App2 + //Global Object for functions in subscribe method! + def mainPage = this.&mainPage + //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 beaconHandler = this.&beaconHandler + //Global Object for functions in subscribe method! + def arriveActions = this.&arriveActions + //Global Object for functions in subscribe method! + def departActions = this.&departActions + //Global Object for functions in subscribe method! + def prefix = this.&prefix + //Global Object for functions in subscribe method! + def listPhrases = this.&listPhrases + //Global Object for functions in subscribe method! + def executePhrase = this.&executePhrase + //Global Object for functions in subscribe method! + def getBeaconName = this.&getBeaconName + //Global Object for functions in subscribe method! + def getPhoneName = this.&getPhoneName + //Global Object for functions in subscribe method! + def hideOptionsSection = this.&hideOptionsSection + //Global Object for functions in subscribe method! + def getAllOk = this.&getAllOk + //Global Object for functions in subscribe method! + def getModeOk = this.&getModeOk + //Global Object for functions in subscribe method! + def getDaysOk = this.&getDaysOk + //Global Object for functions in subscribe method! + def getTimeOk = this.&getTimeOk + //Global Object for functions in subscribe method! + def hhmm = this.&hhmm + //Global Object for functions in subscribe method! + def timeIntervalLabel = this.&timeIntervalLabel + //Global Object for functions in subscribe method! + def list = this.&list + + App2(Object obj) { + reference = obj + location = obj.locationObject + app = obj.appObject + atomicState = obj.atomicState + beacons = obj.beaconSensorObject + phones = obj.mobilePresenceObject + arrivalOnSwitches = obj.switchObject + arrivalOffSwitches = obj.switchObject + arrivalLocks = obj.lockObject + departOnSwitches = obj.switchObject + departOffSwitches = obj.switchObject + departLocks = obj.lockObject + //Global variable for settings! + settings = [app:app, starting:starting, ending:ending, beacons:beacons, phones:phones, arrivalPhrase:arrivalPhrase, arrivalOnSwitches:arrivalOnSwitches, arrivalOffSwitches:arrivalOffSwitches, arrivalLocks:arrivalLocks, departPhrase:departPhrase, departOnSwitches:departOnSwitches, departOffSwitches:departOffSwitches, departLocks:departLocks, pushNotification:pushNotification, phone:phone, days:days, modes:modes] + } + //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() + } + } + } + + + 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()) + } + ///////////////////////////////////////////////////////////////////// + ////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*0, nameOfFunction) + } else { + timersFuncList.add(nameOfFunction) + timersList.add(new SimulatedTimer()) + def task = timersList[timersFuncList.indexOf(nameOfFunction)].runAfter(delay*0, nameOfFunction) + } + } + ///////////////////////////////////////////////////////////////////// + def now() { + return System.currentTimeMillis() + } + ///////////////////////////////////////////////////////////////////// + def getTemperatureScale() { + return 'F' //Celsius for now + } + + ///////////////////////////////////////////////////////////////////// + def getSunriseAndSunset(LinkedHashMap metaData) { + def sunRiseSetInfo = [sunrise:[time:1563800160000],sunset:[time:1563850740000]] + return sunRiseSetInfo + } + ///////////////////////////////////////////////////////////////////// + def httpPostJson(LinkedHashMap metaData, Closure inputData) { + inputData(metaData) + } + ///////////////////////////////////////////////////////////////////// + def runEvery15Minutes(Closure inputData) { + inputData() + } + ///////////////////////////////////////////////////////////////////// + def timeToday(String time, Object timeZone) { + def timeOfDay = new Date() + def _inputTime = time.split(':') + def inputTime = Integer.parseInt(_inputTime[0])*3600+Integer.parseInt(_inputTime[1])*60+1564191100415 + timeOfDay.time = inputTime + return timeOfDay + } + ///////////////////////////////////////////////////////////////////// + def sendNotification(String text, LinkedHashMap metaData) { + println("Sending \""+text+"\" to "+metaData.phone.toString()) + } + ///////////////////////////////////////////////////////////////////// + def canSchedule() { + return true + } + def mainPage() { + dynamicPage(name: "mainPage", install: true, uninstall: true) { + + section("Where do you want to watch?") { + input name: "beacons", type: "capability.beacon", title: "Select your beacon(s)", + multiple: true, required: true + } + + section("Who do you want to watch for?") { + input name: "phones", type: "device.mobilePresence", title: "Select your phone(s)", + multiple: true, required: true + } + + section("What do you want to do on arrival?") { + input name: "arrivalPhrase", type: "enum", title: "Execute a phrase", + options: listPhrases(), required: false + input "arrivalOnSwitches", "capability.switch", title: "Turn on some switches", + multiple: true, required: false + input "arrivalOffSwitches", "capability.switch", title: "Turn off some switches", + multiple: true, required: false + input "arrivalLocks", "capability.lock", title: "Unlock the door", + multiple: true, required: false + } + + section("What do you want to do on departure?") { + input name: "departPhrase", type: "enum", title: "Execute a phrase", + options: listPhrases(), required: false + input "departOnSwitches", "capability.switch", title: "Turn on some switches", + multiple: true, required: false + input "departOffSwitches", "capability.switch", title: "Turn off some switches", + multiple: true, required: false + input "departLocks", "capability.lock", title: "Lock the door", + multiple: true, required: false + } + + section("Do you want to be notified?") { + input "pushNotification", "bool", title: "Send a push notification" + input "phone", "phone", title: "Send a text message", description: "Tap to enter phone number", + required: false + } + + section { + label title: "Give your automation a name", description: "e.g. Goodnight Home, Wake Up" + } + + def timeLabel = timeIntervalLabel() + section(title: "More options", hidden: hideOptionsSection(), hideable: true) { + href "timeIntervalInput", title: "Only during a certain time", + description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : "incomplete" + + input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false, + options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] + + input "modes", "mode", title: "Only when mode is", multiple: true, required: false + } + } + } + + // Lifecycle management + def installed() { + log.debug " Installed with settings: ${settings}" + initialize() + } + + def updated() { + log.debug " Updated with settings: ${settings}" + unsubscribe() + initialize() + } + + def initialize() { + subscribe(beacons, "presence", beaconHandler) + } + + // Event handlers + def beaconHandler(evt) { + log.debug " beaconHandler: $evt" + + if (allOk) { + def data = new groovy.json.JsonSlurper().parseText(evt.data) + // removed logging of device names. can be added back for debugging + //log.debug " data: $data - phones: " + phones*.deviceNetworkId + + def beaconName = getBeaconName(evt) + // removed logging of device names. can be added back for debugging + //log.debug " beaconName: $beaconName" + + def phoneName = getPhoneName(data) + // removed logging of device names. can be added back for debugging + //log.debug " phoneName: $phoneName" + if (phoneName != null) { + def action = data.presence == "1" ? "arrived" : "left" + def msg = "$phoneName has $action ${action == 'arrived' ? 'at ' : ''}the $beaconName" + + if (action == "arrived") { + msg = arriveActions(msg) + } + else if (action == "left") { + msg = departActions(msg) + } + log.debug " msg: $msg" + + if (pushNotification || phone) { + def options = [ + method: (pushNotification && phone) ? "both" : (pushNotification ? "push" : "sms"), + phone: phone + ] + sendNotification(msg, options) + } + } + } + } + + // Helpers + private arriveActions(msg) { + if (arrivalPhrase || arrivalOnSwitches || arrivalOffSwitches || arrivalLocks) msg += ", so" + + if (arrivalPhrase) { + log.debug " executing: $arrivalPhrase" + executePhrase(arrivalPhrase) + msg += " ${prefix('executed')} $arrivalPhrase." + } + if (arrivalOnSwitches) { + log.debug " turning on: $arrivalOnSwitches" + arrivalOnSwitches.on() + msg += " ${prefix('turned')} ${list(arrivalOnSwitches)} on." + } + if (arrivalOffSwitches) { + log.debug " turning off: $arrivalOffSwitches" + arrivalOffSwitches.off() + msg += " ${prefix('turned')} ${list(arrivalOffSwitches)} off." + } + if (arrivalLocks) { + log.debug " unlocking: $arrivalLocks" + arrivalLocks.unlock() + msg += " ${prefix('unlocked')} ${list(arrivalLocks)}." + } + msg + } + + private departActions(msg) { + if (departPhrase || departOnSwitches || departOffSwitches || departLocks) msg += ", so" + + if (departPhrase) { + log.debug " executing: $departPhrase" + executePhrase(departPhrase) + msg += " ${prefix('executed')} $departPhrase." + } + if (departOnSwitches) { + log.debug " turning on: $departOnSwitches" + departOnSwitches.on() + msg += " ${prefix('turned')} ${list(departOnSwitches)} on." + } + if (departOffSwitches) { + log.debug " turning off: $departOffSwitches" + departOffSwitches.off() + msg += " ${prefix('turned')} ${list(departOffSwitches)} off." + } + if (departLocks) { + log.debug " unlocking: $departLocks" + departLocks.lock() + msg += " ${prefix('locked')} ${list(departLocks)}." + } + msg + } + + private prefix(word) { + def result + def index = settings.prefixIndex == null ? 0 : settings.prefixIndex + 1 + switch (index) { + case 0: + result = "I $word" + break + case 1: + result = "I also $word" + break + case 2: + result = "And I $word" + break + default: + result = "And $word" + break + } + + settings.prefixIndex = index + log.trace "prefix($word'): $result" + result + } + + private listPhrases() { + location.helloHome.getPhrases().label + } + + private executePhrase(phraseName) { + if (phraseName) { + location.helloHome.execute(phraseName) + log.debug " executed phrase: $phraseName" + } + } + + private getBeaconName(evt) { + def beaconName = beacons.find { b -> b.id == evt.deviceId } + return beaconName + } + + private getPhoneName(data) { + def phoneName = phones.find { phone -> + // Work around DNI bug in data + def pParts = phone.deviceNetworkId.split('\\|') + def dParts = data.dni.split('\\|') + pParts[0] == dParts[0] + } + return phoneName + } + + private hideOptionsSection() { + (starting || ending || days || modes) ? false : true + } + + private getAllOk() { + modeOk && daysOk && timeOk + } + + private getModeOk() { + def result = !modes || modes.contains(location.mode) + log.trace " modeOk = $result" + result + } + + private getDaysOk() { + def result = true + if (days) { + def df = new java.text.SimpleDateFormat("EEEE") + if (location.timeZone) { + df.setTimeZone(location.timeZone) + } + else { + df.setTimeZone(TimeZone.getTimeZone("America/New_York")) + } + def day = df.format(new Date()) + result = days.contains(day) + } + log.trace " daysOk = $result" + result + } + + private getTimeOk() { + def result = true + if (starting && ending) { + def currTime = now() + def start = timeToday(starting, location?.timeZone).time + def stop = timeToday(ending, location?.timeZone).time + result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start + } + log.trace " timeOk = $result" + result + } + + private hhmm(time, fmt = "h:mm a") { + def t = timeToday(time, location.timeZone) + def f = new java.text.SimpleDateFormat(fmt) + f.setTimeZone(location.timeZone ?: timeZone(time)) + f.format(t) + } + + private timeIntervalLabel() { + (starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : "" + } + + private list(Object names) { + return names[0] + } +} -def updated() -{ - log.debug "Updated with settings: ${settings}" - log.debug "Current mode = ${location.mode}" - unsubscribe() - subscribe(app, appTouch) +@Field def app1 +@Field def app2 +def initOrder = Verify.getBoolean() +if (initOrder) { + app1 = new App1(this) + app2 = new App2(this) +} else { + app2 = new App2(this) + app1 = new App1(this) } -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) +def installOrder = Verify.getBoolean() +if (installOrder) { + app1.installed() + app2.installed() +} else { + app2.installed() + app1.installed() } -installed() -EventHandler() +while(true) { + def eventNumber = Verify.getInt(0,4) + switch(eventNumber) { + case 0: + lockObject.setValue([name: "lock", value: "locked", deviceId: "lockID0", descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']) + break + case 1: + lockObject.setValue([name: "unlock", value: "unlocked ", deviceId: "lockID0", descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']) + break + case 2: + contactObject.setValue([name: "contact.open", value: "open", deviceId: "contactSensorID0", descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']) + break + case 3: + contactObject.setValue([name: "contact.closed", value: "closed", deviceId: "contactSensorID0", descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']) + break + case 4: + def event = Verify.getInt(0,1) + if (event == 0) { + presenceSensorObject.setValue([name: "presence", value: "present", deviceId: "presenceSensorID0", descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"1","dni":"mobile0"}']) + } else { + presenceSensorObject.setValue([name: "presence", value: "not present", deviceId: "presenceSensorID0", descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"presence":"0","dni":"mobile0"}']) + } + break + } +}