Commit #9: extension to the infrastructure with more devices + minor changes in extra...
[smartthings-infrastructure.git] / Extractor / App2 / App2.groovy
1 ////////////////
2 definition(
3     name: "NFC Tag Toggle",
4     namespace: "smartthings",
5     author: "SmartThings",
6     description: "Allows toggling of a switch, lock, or garage door based on an NFC Tag touch event",
7     category: "SmartThings Internal",
8     iconUrl: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor.png",
9     iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png",
10     iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png")
11
12
13 preferences {
14     page(name: "pageOne", title: "Device selection", uninstall: true, nextPage: "pageTwo") {
15         section("Select an NFC tag") {
16             input "tag", "capability.touchSensor", title: "NFC Tag"
17         }
18         section("Select devices to control") {
19             input "switch1", "capability.switch", title: "Light or switch", required: false, multiple: true
20             input "lock", "capability.lock", title: "Lock", required: false, multiple: true
21             input "garageDoor", "capability.doorControl", title: "Garage door controller", required: false, multiple: true
22         }
23     }
24
25     page(name: "pageTwo", title: "Master devices", install: true, uninstall: true)
26 }
27
28 def pageTwo() {
29         dynamicPage(name: "pageTwo") {
30         section("If set, the state of these devices will be toggled each time the tag is touched, " +
31                 "e.g. a light that's on will be turned off and one that's off will be turned on, " +
32                 "other devices of the same type will be set to the same state as their master device. " +
33                 "If no master is designated then the majority of devices of the same type will be used " +
34                 "to determine whether to turn on or off the devices.") {
35
36             if (switch1 || masterSwitch) {
37                 input "masterSwitch", "enum", title: "Master switch", options: switch1.collect{[(it.id): it.displayName]}, required: false
38             }
39             if (lock || masterLock) {
40                 input "masterLock", "enum", title: "Master lock", options: lock.collect{[(it.id): it.displayName]}, required: false
41             }
42             if (garageDoor || masterDoor) {
43                 input "masterDoor", "enum", title: "Master door", options: garageDoor.collect{[(it.id): it.displayName]}, required: false
44             }
45                 }
46                 section([mobileOnly:true]) {
47                         label title: "Assign a name", required: false
48                         mode title: "Set for specific mode(s)", required: false
49                 }
50     }
51 }
52
53 def installed() {
54         log.debug "Installed with settings: ${settings}"
55
56         initialize()
57 }
58
59 def updated() {
60         log.debug "Updated with settings: ${settings}"
61
62         unsubscribe()
63         initialize()
64 }
65
66 def initialize() {
67         subscribe tag, "nfcTouch", touchHandler
68     subscribe app, touchHandler
69 }
70
71 private currentStatus(devices, master, attribute) {
72         log.trace "currentStatus($devices, $master, $attribute)"
73         def result = null
74         if (master) {
75         result = devices.find{it.id == master}?.currentValue(attribute)
76     }
77     else {
78         def map = [:]
79         devices.each {
80                 def value = it.currentValue(attribute)
81             map[value] = (map[value] ?: 0) + 1
82             log.trace "$it.displayName: $value"
83         }
84         log.trace map
85         result = map.collect{it}.sort{it.value}[-1].key
86     }
87     log.debug "$attribute = $result"
88     result
89 }
90
91 def touchHandler(evt) {
92         log.trace "touchHandler($evt.descriptionText)"
93     if (switch1) {
94         def status = currentStatus(switch1, masterSwitch, "switch")
95         switch1.each {
96             if (status == "on") {
97                 it.off()
98             }
99             else {
100                 it.on()
101             }
102         }
103     }
104
105     if (lock) {
106         def status = currentStatus(lock, masterLock, "lock")
107         lock.each {
108             if (status == "locked") {
109                 lock.unlock()
110             }
111             else {
112                 lock.lock()
113             }
114         }
115     }
116
117     if (garageDoor) {
118         def status = currentStatus(garageDoor, masterDoor, "status")
119         garageDoor.each {
120                 if (status == "open") {
121                 it.close()
122             }
123             else {
124                 it.open()
125             }
126         }
127     }
128 }