Commit #9: extension to the infrastructure with more devices + minor changes in extra...
[smartthings-infrastructure.git] / Extractor / App1 / App1.groovy
index b94d720c26e4d62334b42874fbf0925656a6fdd7..0d4c97e23b7b623f0b2f8fd0f4e82e5a8fd2d23f 100644 (file)
-////////////////
-definition(
-    name: "NFC Tag Toggle",
-    namespace: "smartthings",
-    author: "SmartThings",
-    description: "Allows toggling of a switch, lock, or garage door based on an NFC Tag touch event",
-    category: "SmartThings Internal",
-    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor.png",
-    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png",
-    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png")
 
+/**
+ *  Auto Lock Door
+ *
+ *  Author: Chris Sader (@csader)
+ *  Collaborators: @chrisb
+ *  Date: 2013-08-21
+ *  URL: http://www.github.com/smartthings-users/smartapp.auto-lock-door
+ *
+ * Copyright (C) 2013 Chris Sader.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions: The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
 
-preferences {
-    page(name: "pageOne", title: "Device selection", uninstall: true, nextPage: "pageTwo") {
-        section("Select an NFC tag") {
-            input "tag", "capability.touchSensor", title: "NFC Tag"
-        }
-        section("Select devices to control") {
-            input "switch1", "capability.switch", title: "Light or switch", required: false, multiple: true
-            input "lock", "capability.lock", title: "Lock", required: false, multiple: true
-            input "garageDoor", "capability.doorControl", title: "Garage door controller", required: false, multiple: true
-        }
+preferences
+{
+    section("When a door unlocks...") {
+        input "lock1", "capability.lock"
     }
-    
-    page(name: "pageTwo", title: "Master devices", install: true, uninstall: true)
-}
-
-def pageTwo() {
-       dynamicPage(name: "pageTwo") {
-       section("If set, the state of these devices will be toggled each time the tag is touched, " + 
-                "e.g. a light that's on will be turned off and one that's off will be turned on, " +
-                "other devices of the same type will be set to the same state as their master device. " +
-                "If no master is designated then the majority of devices of the same type will be used " +
-                "to determine whether to turn on or off the devices.") {
-            
-            if (switch1 || masterSwitch) {
-                input "masterSwitch", "enum", title: "Master switch", options: switch1.collect{[(it.id): it.displayName]}, required: false
-            }
-            if (lock || masterLock) {
-                input "masterLock", "enum", title: "Master lock", options: lock.collect{[(it.id): it.displayName]}, required: false
-            }
-            if (garageDoor || masterDoor) {
-                input "masterDoor", "enum", title: "Master door", options: garageDoor.collect{[(it.id): it.displayName]}, required: false
-            }            
-               }
-               section([mobileOnly:true]) {
-                       label title: "Assign a name", required: false
-                       mode title: "Set for specific mode(s)", required: false
-               }        
+    section("Lock it how many minutes later?") {
+        input "minutesLater", "number", title: "When?"
+    }
+    section("Lock it only when this door is closed") {
+        input "openSensor", "capability.contactSensor", title: "Where?"
     }
 }
 
-def installed() {
-       log.debug "Installed with settings: ${settings}"
-
-       initialize()
+def installed()
+{
+    log.debug "Auto Lock Door installed. (URL: http://www.github.com/smartthings-users/smartapp.auto-lock-door)"
+    initialize()
 }
 
-def updated() {
-       log.debug "Updated with settings: ${settings}"
-
-       unsubscribe()
-       initialize()
+def updated()
+{
+    unsubscribe()
+    unschedule()
+    log.debug "Auto Lock Door updated."
+    initialize()
 }
 
-def initialize() {
-       subscribe tag, "nfcTouch", touchHandler
-    subscribe app, touchHandler
+def initialize()
+{
+    log.debug "Settings: ${settings}"
+    subscribe(lock1, "lock", doorHandler)
+    subscribe(openSensor, "contact.closed", doorClosed)
+    subscribe(openSensor, "contact.open", doorOpen)
 }
 
-private currentStatus(devices, master, attribute) {
-       log.trace "currentStatus($devices, $master, $attribute)"
-       def result = null
-       if (master) {
-       result = devices.find{it.id == master}?.currentValue(attribute)
-    }
-    else {
-       def map = [:]
-        devices.each {
-               def value = it.currentValue(attribute)
-            map[value] = (map[value] ?: 0) + 1
-            log.trace "$it.displayName: $value"
+def lockDoor()
+{
+    log.debug "Locking Door if Closed"
+    if((openSensor.latestValue("contact") == "closed")){
+       log.debug "Door Closed"
+       lock1.lock()
+    } else {
+       if ((openSensor.latestValue("contact") == "open")) {
+        def delay = minutesLater * 60
+        log.debug "Door open will try again in $minutesLater minutes"
+        runIn( delay, lockDoor )
         }
-        log.trace map
-        result = map.collect{it}.sort{it.value}[-1].key
     }
-    log.debug "$attribute = $result"
-    result
 }
 
-def touchHandler(evt) {
-       log.trace "touchHandler($evt.descriptionText)"
-    if (switch1) {
-       def status = currentStatus(switch1, masterSwitch, "switch")
-        switch1.each {
-            if (status == "on") {
-                it.off()
-            }
-            else {
-                it.on()
-            }
-        }
-    }
-    
-    if (lock) {
-       def status = currentStatus(lock, masterLock, "lock")
-        lock.each {
-            if (status == "locked") {
-                lock.unlock()
-            }
-            else {
-                lock.lock()
-            }
-        }
+def doorOpen(evt) {
+    log.debug "Door open reset previous lock task..."
+    unschedule( lockDoor )
+    def delay = minutesLater * 60
+    runIn( delay, lockDoor )
+}
+
+def doorClosed(evt) {
+    log.debug "Door Closed"
+}
+
+def doorHandler(evt)
+{
+    log.debug "Door ${openSensor.latestValue}"
+    log.debug "Lock ${evt.name} is ${evt.value}."
+
+    if (evt.value == "locked") {                  // If the human locks the door then...
+        log.debug "Cancelling previous lock task..."
+        unschedule( lockDoor )                  // ...we don't need to lock it later.
     }
-    
-    if (garageDoor) {
-        def status = currentStatus(garageDoor, masterDoor, "status")
-       garageDoor.each {
-               if (status == "open") {
-               it.close()
-            }
-            else {
-               it.open()
-            }
-        }
+    else {                                      // If the door is unlocked then...
+        def delay = minutesLater * 60          // runIn uses seconds
+        log.debug "Re-arming lock in ${minutesLater} minutes (${delay}s)."
+        runIn( delay, lockDoor )                // ...schedule to lock in x minutes.
     }
 }