Commit #9: More classes + Extractor with Rahmadi's editions + Fixing some bugs
[smartthings-infrastructure.git] / Extractor / App2 / App2.groovy
1 /**
2  *  NFC Tag Toggle
3  *
4  *  Copyright 2014 SmartThings
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7  *  in compliance with the License. You may obtain a copy of the License at:
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13  *  for the specific language governing permissions and limitations under the License.
14  *
15  */
16  
17 definition(
18     name: "NFC Tag Toggle",
19     namespace: "smartthings",
20     author: "SmartThings",
21     description: "Allows toggling of a switch, lock, or garage door based on an NFC Tag touch event",
22     category: "SmartThings Internal",
23     iconUrl: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor.png",
24     iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png",
25     iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Developers/nfc-tag-executor@2x.png")
26
27
28 preferences {
29     page(name: "pageOne", title: "Device selection", uninstall: true, nextPage: "pageTwo") {
30         section("Select an NFC tag") {
31             input "tag", "capability.touchSensor", title: "NFC Tag"
32         }
33         section("Select devices to control") {
34             input "switch1", "capability.switch", title: "Light or switch", required: false, multiple: true
35             input "lock", "capability.lock", title: "Lock", required: false, multiple: true
36             input "garageDoor", "capability.doorControl", title: "Garage door controller", required: false, multiple: true
37         }
38     }
39     
40     page(name: "pageTwo", title: "Master devices", install: true, uninstall: true)
41 }
42
43 def pageTwo() {
44         dynamicPage(name: "pageTwo") {
45         section("If set, the state of these devices will be toggled each time the tag is touched, " + 
46                 "e.g. a light that's on will be turned off and one that's off will be turned on, " +
47                 "other devices of the same type will be set to the same state as their master device. " +
48                 "If no master is designated then the majority of devices of the same type will be used " +
49                 "to determine whether to turn on or off the devices.") {
50             
51             if (switch1 || masterSwitch) {
52                 input "masterSwitch", "enum", title: "Master switch", options: switch1.collect{[(it.id): it.displayName]}, required: false
53             }
54             if (lock || masterLock) {
55                 input "masterLock", "enum", title: "Master lock", options: lock.collect{[(it.id): it.displayName]}, required: false
56             }
57             if (garageDoor || masterDoor) {
58                 input "masterDoor", "enum", title: "Master door", options: garageDoor.collect{[(it.id): it.displayName]}, required: false
59             }            
60                 }
61                 section([mobileOnly:true]) {
62                         label title: "Assign a name", required: false
63                         mode title: "Set for specific mode(s)", required: false
64                 }        
65     }
66 }
67
68 def installed() {
69         log.debug "Installed with settings: ${settings}"
70
71         initialize()
72 }
73
74 def updated() {
75         log.debug "Updated with settings: ${settings}"
76
77         unsubscribe()
78         initialize()
79 }
80
81 def initialize() {
82         subscribe tag, "nfcTouch", touchHandler
83     subscribe app, touchHandler
84 }
85
86 private currentStatus(devices, master, attribute) {
87         log.trace "currentStatus($devices, $master, $attribute)"
88         def result = null
89         if (master) {
90         result = devices.find{it.id == master}?.currentValue(attribute)
91     }
92     else {
93         def map = [:]
94         devices.each {
95                 def value = it.currentValue(attribute)
96             map[value] = (map[value] ?: 0) + 1
97             log.trace "$it.displayName: $value"
98         }
99         log.trace map
100         result = map.collect{it}.sort{it.value}[-1].key
101     }
102     log.debug "$attribute = $result"
103     result
104 }
105
106 def touchHandler(evt) {
107         log.trace "touchHandler($evt.descriptionText)"
108     if (switch1) {
109         def status = currentStatus(switch1, masterSwitch, "switch")
110         switch1.each {
111             if (status == "on") {
112                 it.off()
113             }
114             else {
115                 it.on()
116             }
117         }
118     }
119     
120     if (lock) {
121         def status = currentStatus(lock, masterLock, "lock")
122         lock.each {
123             if (status == "locked") {
124                 lock.unlock()
125             }
126             else {
127                 lock.lock()
128             }
129         }
130     }
131     
132     if (garageDoor) {
133         def status = currentStatus(garageDoor, masterDoor, "status")
134         garageDoor.each {
135                 if (status == "open") {
136                 it.close()
137             }
138             else {
139                 it.open()
140             }
141         }
142     }
143 }