Commit #5
[smartthings-infrastructure.git] / main.groovy
index 11d617cccb5fb74257498f1b6177c45baba2a8c0..2e249bd4c0d6c64d10f650e9b3455795e653d410 100644 (file)
@@ -3,76 +3,71 @@
 import groovy.transform.Field
 
 //Importing Classes
-import ContactSensor.contacting
-import ContactSensor.contacts
-import Lock.locking
-import Lock.locks
-import Switch.switching
-import Switch.switches
-import Event.Event
+import ContactSensor.Contacting
+import ContactSensor.Contacts
+import Lock.Locking
+import Lock.Locks
+import Switch.Switching
+import Switch.Switches
 import Logger.Logger
-import Location.locationVar
+import Location.LocationVar
 import Location.Phrase
-import appTouch.Touch
+import appTouch.Touched
+import Event.Event
 
 //GlobalVariables
+//Create a global variable for send event
+@Field def sendEvent = {eventDataMap -> eventHandler(eventDataMap)}
 //create a location object to change the variable inside the class
-@Field def location = new locationVar()
+@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:[]]
+//Global object for touch
+@Field def app = new Touched(sendEvent, 0)
 //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 variable for Functions in Subscribe method
+@Field def functionList = []
+//Create a global variable for Objects in Subscribe method
+@Field def objectList = []
+//Create a global variable for Events in Subscribe method
+@Field def eventList = []
 //Create a global list for function schedulers
-@Field def ListofTimersFunc = []
+@Field def timersFuncList = []
 //Create a global list for timer schedulers
-@Field def ListofTimers = []
-
+@Field def timersList = []
+//Create a global list for events
+@Field def evt = []
 
 
-//ExtractedObjects
+//extractedObjects
+//Global Object for class switch!
+@Field def switchesoff = new Switching(sendEvent, 1)
+//Global Object for class switch!
+@Field def switcheson = new Switching(sendEvent, 1)
 //Global Object for class lock!
-@Field def lock1 = new locking(1)
-//Global Object for class contactSensor!
-@Field def contact = new contacting(1)
-//Global variable for number!
-@Field def minutesLater = 1
+@Field def lock1 = new Locking(sendEvent, 1)
+//Global variable for mode!
+@Field def newMode = "away"
 //Global variable for number!
-@Field def secondsLater = 10
-//Global variable for recipients!
-@Field def recipients = ['AJ']
-//Global variable for phone number!
-@Field def phoneNumber = 9495379373
+@Field def waitfor = 10
 //Global Object for functions in subscribe method!
 @Field def installed = this.&installed
 //Global Object for functions in subscribe method!
 @Field def updated = this.&updated
 //Global Object for functions in subscribe method!
-@Field def initialize = this.&initialize
-//Global Object for functions in subscribe method!
-@Field def lockDoor = this.&lockDoor
-//Global Object for functions in subscribe method!
-@Field def unlockDoor = this.&unlockDoor
-//Global Object for functions in subscribe method!
-@Field def doorHandler = this.&doorHandler
+@Field def appTouch = this.&appTouch
 
 //Methods
 /////////////////////////////////////////////////////////////////////
-def definition(LinkedHashMap LHM) {
+def definition(LinkedHashMap metaData) {
        println("IGNORE -- JUST SOME DEFINITION")
 }
 
 /////////////////////////////////////////////////////////////////////
-def preferences(Closure Input) {
+def preferences(Closure metaData) {
        println("IGNORE -- JUST SOME DEFINITION")
 }
 /////////////////////////////////////////////////////////////////////
@@ -81,321 +76,165 @@ def setLocationMode(String mode) {
 }
 
 /////////////////////////////////////////////////////////////////////
-////subscribe(app, func)
-def subscribe(Object Obj, Closure Input) {
-       EventList.add("Touched")
-       FunctionList.add(Input)
-}
-////subscribe(obj, string, func)
-def subscribe(Object Obj, String S, Closure Input) {
-       ObjectList.add(Obj)
-       EventList.add(S)
-       FunctionList.add(Input)
-}
-////subscribe(obj, string, func, hashmap)
-def subscribe(Object Obj, String S, Closure Input, LinkedHashMap LHM) {
-       ObjectList.add(Obj)     
-       EventList.add(S)
-       FunctionList.add(Input)
-}
-/////////////////////////////////////////////////////////////////////
-def EventHandler() {
-       while(true) {
-               List evt = []
-               print "Waiting for an event...\n"
-               def EVENT = System.in.newReader().readLine()
-               SepLine = EVENT.split()
-               for (int i = 0; i < EventList.size(); i++) {
-                       if (EventList[i] == SepLine[0]) {
-                               println("The following effect: \n")
-                               evt.add(new Event())
-                               switch(SepLine[0]) { 
-                                       case "Touched":
-                                               ObjectList[i].touched = 1
-                                               evt[-1].value = "Touched"
-                                               evt[-1].linkText = "touched by user"
-                                               evt[-1].name = "TouchSensor"
-                                               evt[-1].descriptionText = "Touching"
-                                               break
-                                       case "lock":
-                                               if (SepLine[1] == "0") {
-                                                       ObjectList[i][0].lock()
-                                                       evt[-1].deviceId = 0
-                                                       evt[-1].value = "locked"
-                                                       evt[-1].linkText = "lock0"
-                                                       evt[-1].displayName = "lock0"
-                                                       evt[-1].name = "lock"
-                                                       evt[-1].descriptionText = "locking"
-                                               } else if (SepLine[1] == "1") {
-                                                       ObjectList[i][1].lock()
-                                                       evt[-1].deviceId = 1
-                                                       evt[-1].value = "locked"
-                                                       evt[-1].linkText = "lock1"
-                                                       evt[-1].displayName = "lock1"
-                                                       evt[-1].name = "lock"
-                                                       evt[-1].descriptionText = "locking"
-                                               } else if (SepLine[1] == "2") {
-                                                       ObjectList[i][2].lock()
-                                                       evt[-1].deviceId = 2
-                                                       evt[-1].value = "locked"
-                                                       evt[-1].linkText = "lock2"
-                                                       evt[-1].displayName = "lock2"
-                                                       evt[-1].name = "lock"
-                                                       evt[-1].descriptionText = "locking"
-                                               }
-                                               break
-                                       case "unlock":
-                                               if (SepLine[1] == "0") {
-                                                       ObjectList[i][0].unlock()
-                                                       evt[-1].deviceId = 0
-                                                       evt[-1].value = "unlocked"
-                                                       evt[-1].linkText = "lock0"
-                                                       evt[-1].displayName = "lock0"
-                                                       evt[-1].name = "lock"
-                                                       evt[-1].descriptionText = "unlocking"   
-                                               } else if (SepLine[1] == "1") {
-                                                       ObjectList[i][1].unlock()
-                                                       evt[-1].deviceId = 0
-                                                       evt[-1].value = "unlocked"
-                                                       evt[-1].linkText = "lock1"
-                                                       evt[-1].displayName = "lock1"
-                                                       evt[-1].name = "lock"
-                                                       evt[-1].descriptionText = "unlocking"
-                                               } else if (SepLine[1] == "2") {
-                                                       ObjectList[i][2].unlock()
-                                                       evt[-1].deviceId = 2
-                                                       evt[-1].value = "unlocked"
-                                                       evt[-1].linkText = "lock2"
-                                                       evt[-1].displayName = "lock2"
-                                                       evt[-1].name = "lock"
-                                                       evt[-1].descriptionText = "unlocking"
-                                               }
-                                               break
-                                       case "contact.open":
-                                               if (SepLine[1] == "0") {
-                                                       ObjectList[i][0].contactLatestValue = ObjectList[i].currentContact
-                                                       ObjectList[i][0].currentContact = "open"
-                                                       evt[-1].deviceId = 0
-                                                       evt[-1].value = "contact.open"
-                                                       evt[-1].linkText = "contact0"
-                                                       evt[-1].displayName = "contact0"
-                                                       evt[-1].name = "ContactSensor"
-                                                       evt[-1].descriptionText = "opening"     
-                                               } else if (SepLine[1] == "1") {
-                                                       ObjectList[i][1].contactLatestValue = ObjectList[i].currentContact
-                                                       ObjectList[i][1].currentContact = "open"
-                                                       evt[-1].deviceId = 1
-                                                       evt[-1].value = "contact.open"
-                                                       evt[-1].linkText = "contact1"
-                                                       evt[-1].displayName = "contact1"
-                                                       evt[-1].name = "ContactSensor"
-                                                       evt[-1].descriptionText = "opening"
-                                               } else if (SepLine[1] == "2") {
-                                                       ObjectList[i][2].contactLatestValue = ObjectList[i].currentContact
-                                                       ObjectList[i][2].currentContact = "open"
-                                                       evt[-1].deviceId = 2
-                                                       evt[-1].value = "contact.open"
-                                                       evt[-1].linkText = "contact2"
-                                                       evt[-1].displayName = "contact2"
-                                                       evt[-1].name = "ContactSensor"
-                                                       evt[-1].descriptionText = "opening"
-                                               }
-                                               break
-                                       case "contact.closed":
-                                               if (SepLine[1] == "0") {
-                                                       ObjectList[i][0].contactLatestValue = ObjectList[i].currentContact
-                                                       ObjectList[i][0].currentContact = "closed"
-                                                       evt[-1].deviceId = 0
-                                                       evt[-1].value = "contact.closed"
-                                                       evt[-1].linkText = "contact0"
-                                                       evt[-1].displayName = "contact0"
-                                                       evt[-1].name = "ContactSensor"
-                                                       evt[-1].descriptionText = "closing"
-                                               } else if (SepLine[1] == "1") {
-                                                       ObjectList[i][1].contactLatestValue = ObjectList[i].currentContact
-                                                       ObjectList[i][1].currentContact = "closed"
-                                                       evt[-1].deviceId = 1
-                                                       evt[-1].value = "contact.closed"
-                                                       evt[-1].linkText = "contact1"
-                                                       evt[-1].displayName = "contact1"
-                                                       evt[-1].name = "ContactSensor"
-                                                       evt[-1].descriptionText = "closing"
-                                               } else if (SepLine[1] == "2") {
-                                                       ObjectList[i][2].contactLatestValue = ObjectList[i].currentContact
-                                                       ObjectList[i][2].currentContact = "closed"
-                                                       evt[-1].deviceId = 2
-                                                       evt[-1].value = "contact.closed"
-                                                       evt[-1].linkText = "contact2"
-                                                       evt[-1].displayName = "contact2"
-                                                       evt[-1].name = "ContactSensor"
-                                                       evt[-1].descriptionText = "closing"
-                                               }
-                                               break
-                                       default:
-                                               break
-                               }
-                               FunctionList[i](evt[-1])
-                       }
-               }
-       }
+////subscribe(obj, func)
+def subscribe(Object obj, Closure FunctionToCall) {
+       objectList.add(obj)
+       eventList.add("Touched")
+       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 Input) {
-       ListofTimersFunc.add(Input)
-       ListofTimers.add(new Timer())
-       def task = ListofTimers[-1].runAfter(1000*seconds, Input)
+def runIn(int seconds, Closure functionToCall) {
+       timersFuncList.add(functionToCall)
+       timersList.add(new Timer())
+       def task = timersList[-1].runAfter(1000*seconds, functionToCall)
 }
 /////////////////////////////////////////////////////////////////////
 ////unschedule(func)
-def unschedule(Closure Input) {
-       for (int i = 0;i < ListofTimersFunc.size();i++) {
-               if (ListofTimersFunc[i] == Input) {
-                       ListofTimers[i].cancel()
+def unschedule(Closure functionToUnschedule) {
+       for (int i = 0;i < timersFuncList.size();i++) {
+               if (timersFuncList[i] == functionToUnschedule) {
+                       timersList[i].cancel()
                }
        }
 }
 /////////////////////////////////////////////////////////////////////
 ////sendNotificationToContacts(text, recipients)
-def sendNotificationToContacts(String S, List recipients) {
+def sendNotificationToContacts(String text, 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())
+               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 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 < eventList.size();i++) {
+               if (eventList[i] == value) {
+                       evt.add(new Event())
+                       evt[-1].value = value
+                       evt[-1].name = name
+                       evt[-1].deviceId = deviceId
+                       evt[-1].descriptionText = descriptionText
+                       evt[-1].displayed = displayed
+                       evt[-1].linkText = linkText
+                       evt[-1].displayName = linkText
+                       evt[-1].isStateChange = isStateChange
+                       evt[-1].unit = unit
+                       evt[-1].data = data
+                       functionList[i](evt[-1])
+               }
+       }
 }
 
-///////////////////////////////////////////
+/**
+ *  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: "Enhanced Auto Lock Door",
-    namespace: "Lock Auto Super Enhanced",
-    author: "Arnaud",
-    description: "Automatically locks a specific door after X minutes when closed  and unlocks it when open after X seconds.",
-    category: "Safety & Security",
-    iconUrl: "http://www.gharexpert.com/mid/4142010105208.jpg",
-    iconX2Url: "http://www.gharexpert.com/mid/4142010105208.jpg"
-)
-
-preferences{
-    section("Select the door lock:") {
-        input "lock1", "capability.lock", required: true, multiple: true
-    }
-    section("Select the door contact sensor:") {
-        input "contact", "capability.contactSensor", required: true
-    }   
-    section("Automatically lock the door when closed...") {
-        input "minutesLater", "number", title: "Delay (in minutes):", required: true
-    }
-    section("Automatically unlock the door when open...") {
-        input "secondsLater", "number", title: "Delay (in seconds):", required: true
-    }
-    section( "Notifications" ) {
-        input("recipients", "contact", title: "Send notifications to", required: false) {
-            input "phoneNumber", "phone", title: "Warn with text message (optional)", description: "Phone Number", required: false
-        }
+    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 installed()
+{
+       log.debug "Installed with settings: ${settings}"
+       log.debug "Current mode = ${location.mode}"
+       subscribe(app, appTouch)
 }
 
-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 updated()
+{
+       log.debug "Updated with settings: ${settings}"
+       log.debug "Current mode = ${location.mode}"
+       unsubscribe()
+       subscribe(app, appTouch)
 }
 
-def doorHandler(evt){
-    log.debug evt.value
-    log.debug contact.latestValue("contact")
-    if ((contact.latestValue("contact") == "open") && (evt.value == "locked")) { // If the door is open and a person locks the door then...  
-        //def delay = (secondsLater) // runIn uses seconds
-       log.debug "1"
-        runIn( secondsLater, unlockDoor )   // ...schedule (in minutes) to unlock...  We don't want the door to be closed while the lock is engaged. 
-    }
-    else if ((contact.latestValue("contact") == "open") && (evt.value == "unlocked")) { // If the door is open and a person unlocks it then...
-       log.debug "2"        
-       unschedule( unlockDoor ) // ...we don't need to unlock it later.
-    }
-    else if ((contact.latestValue("contact") == "closed") && (evt.value == "locked")) { // If the door is closed and a person manually locks it then...
-       log.debug "3"
-        unschedule( lockDoor ) // ...we don't need to lock it later.
-    }   
-    else if ((contact.latestValue("contact") == "closed") && (evt.value == "unlocked")) { // If the door is closed and a person unlocks it then...
-       log.debug "4"
-       //def delay = (minutesLater * 60) // runIn uses seconds
-        runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
-    }
-    else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "open")) { // If a person opens an unlocked door...
-       log.debug "5"
-        unschedule( lockDoor ) // ...we don't need to lock it later.
-    }
-    else if ((lock1.latestValue("lock") == "unlocked") && (evt.value == "closed")) { // If a person closes an unlocked door...
-        //def delay = (minutesLater * 60) // runIn uses seconds
-       log.debug "6"
-        runIn( (minutesLater * 60), lockDoor ) // ...schedule (in minutes) to lock.
-    }
-    else { //Opening or Closing door when locked (in case you have a handle lock)
-        log.debug "Unlocking the door."
-        lock1.unlock()
-        if(location.contactBookEnabled) {
-            if ( recipients ) {
-                log.debug ( "Sending Push Notification..." ) 
-                sendNotificationToContacts( "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!", recipients)
-            }
-        }
-        if ( phoneNumber ) {
-            log.debug("Sending text message...")
-            sendSms( phoneNumber, "${lock1} unlocked after ${contact} was opened or closed when ${lock1} was locked!")
-        }
-    }
+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)
 }
 
 installed()
-EventHandler()