//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 "<beacon-control> Installed with settings: ${settings}"
+ initialize()
+ }
+
+ def updated() {
+ log.debug "<beacon-control> Updated with settings: ${settings}"
+ unsubscribe()
+ initialize()
+ }
+
+ def initialize() {
+ subscribe(beacons, "presence", beaconHandler)
+ }
+
+ // Event handlers
+ def beaconHandler(evt) {
+ log.debug "<beacon-control> 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 "<beacon-control> data: $data - phones: " + phones*.deviceNetworkId
+
+ def beaconName = getBeaconName(evt)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> beaconName: $beaconName"
+
+ def phoneName = getPhoneName(data)
+ // removed logging of device names. can be added back for debugging
+ //log.debug "<beacon-control> 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 "<beacon-control> 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 "<beacon-control> executing: $arrivalPhrase"
+ executePhrase(arrivalPhrase)
+ msg += " ${prefix('executed')} $arrivalPhrase."
+ }
+ if (arrivalOnSwitches) {
+ log.debug "<beacon-control> turning on: $arrivalOnSwitches"
+ arrivalOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(arrivalOnSwitches)} on."
+ }
+ if (arrivalOffSwitches) {
+ log.debug "<beacon-control> turning off: $arrivalOffSwitches"
+ arrivalOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(arrivalOffSwitches)} off."
+ }
+ if (arrivalLocks) {
+ log.debug "<beacon-control> unlocking: $arrivalLocks"
+ arrivalLocks.unlock()
+ msg += " ${prefix('unlocked')} ${list(arrivalLocks)}."
+ }
+ msg
+ }
+
+ private departActions(msg) {
+ if (departPhrase || departOnSwitches || departOffSwitches || departLocks) msg += ", so"
+
+ if (departPhrase) {
+ log.debug "<beacon-control> executing: $departPhrase"
+ executePhrase(departPhrase)
+ msg += " ${prefix('executed')} $departPhrase."
+ }
+ if (departOnSwitches) {
+ log.debug "<beacon-control> turning on: $departOnSwitches"
+ departOnSwitches.on()
+ msg += " ${prefix('turned')} ${list(departOnSwitches)} on."
+ }
+ if (departOffSwitches) {
+ log.debug "<beacon-control> turning off: $departOffSwitches"
+ departOffSwitches.off()
+ msg += " ${prefix('turned')} ${list(departOffSwitches)} off."
+ }
+ if (departLocks) {
+ log.debug "<beacon-control> 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 "<beacon-control> 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 "<beacon-control> 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 "<beacon-control> 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 "<beacon-control> 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
+ }
+}