Commit #9: extension to the infrastructure with more devices + minor changes in extra...
[smartthings-infrastructure.git] / Extractor / App2 / App2.groovy
index 0af812f9857b68db42e85c4e1d3f7933bfc9a110..ce2ea22d24d346b9ac174d1683c781338bb8ba9a 100644 (file)
-/////
+////////////////
 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
- */
- )
+    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")
+
+
 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
+    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
+        }
     }
-       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
-       }
+
+    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.") {
 
-def installed()
-{
-       log.debug "Installed with settings: ${settings}"
-       log.debug "Current mode = ${location.mode}"
-       subscribe(app, appTouch)
+            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
+               }
+    }
 }
 
+def installed() {
+       log.debug "Installed with settings: ${settings}"
+
+       initialize()
+}
 
-def updated()
-{
+def updated() {
        log.debug "Updated with settings: ${settings}"
-       log.debug "Current mode = ${location.mode}"
+
        unsubscribe()
-       subscribe(app, appTouch)
+       initialize()
+}
+
+def initialize() {
+       subscribe tag, "nfcTouch", touchHandler
+    subscribe app, touchHandler
+}
+
+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"
+        }
+        log.trace map
+        result = map.collect{it}.sort{it.value}[-1].key
+    }
+    log.debug "$attribute = $result"
+    result
 }
 
-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 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()
+            }
+        }
+    }
+
+    if (garageDoor) {
+        def status = currentStatus(garageDoor, masterDoor, "status")
+       garageDoor.each {
+               if (status == "open") {
+               it.close()
+            }
+            else {
+               it.open()
+            }
+        }
+    }
 }