-////////////////
-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.
}
}