Update thermostat-mode-director.groovy
[smartapps.git] / official / color-coordinator.groovy
1 /**
2  *      Color Coordinator 
3  *  Version 1.1.1 - 11/9/16
4  *  By Michael Struck
5  *
6  *  1.0.0 - Initial release
7  *  1.1.0 - Fixed issue where master can be part of slaves. This causes a loop that impacts SmartThings. 
8  *  1.1.1 - Fix NPE being thrown for slave/master inputs being empty.
9  *
10  *
11  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
12  *  in compliance with the License. You may obtain a copy of the License at:
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
17  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
18  *  for the specific language governing permissions and limitations under the License.
19  *
20  */
21 definition(
22         name: "Color Coordinator",
23         namespace: "MichaelStruck",
24         author: "Michael Struck",
25         description: "Ties multiple colored lights to one specific light's settings",
26         category: "Convenience",
27         iconUrl: "https://raw.githubusercontent.com/MichaelStruck/SmartThings/master/Other-SmartApps/ColorCoordinator/CC.png",
28         iconX2Url: "https://raw.githubusercontent.com/MichaelStruck/SmartThings/master/Other-SmartApps/ColorCoordinator/CC@2x.png"
29 )
30
31 preferences {
32         page name: "mainPage"
33 }
34
35 def mainPage() {
36         dynamicPage(name: "mainPage", title: "", install: true, uninstall: false) {
37                 def masterInList = slaves?.id?.find{it==master?.id}
38         if (masterInList) {
39                 section ("**WARNING**"){
40                 paragraph "You have included the Master Light in the Slave Group. This will cause a loop in execution. Please remove this device from the Slave Group.", image: "https://raw.githubusercontent.com/MichaelStruck/SmartThingsPublic/master/img/caution.png"
41             }
42         }
43         section("Master Light") {
44                         input "master", "capability.colorControl", title: "Colored Light", required: true
45                 }
46                 section("Lights that follow the master settings") {
47                         input "slaves", "capability.colorControl", title: "Colored Lights",  multiple: true, required: true, submitOnChange: true
48                 }
49         section([mobileOnly:true], "Options") {
50                         input "randomYes", "bool",title: "When Master Turned On, Randomize Color", defaultValue: false
51                         href "pageAbout", title: "About ${textAppName()}", description: "Tap to get application version, license and instructions"
52         }
53         }
54 }
55
56 page(name: "pageAbout", title: "About ${textAppName()}", uninstall: true) {
57         section {
58         paragraph "${textVersion()}\n${textCopyright()}\n\n${textLicense()}\n"
59         }
60         section("Instructions") {
61                 paragraph textHelp()
62         }
63     section("Tap button below to remove application"){
64     }
65 }
66
67 def installed() {   
68         init() 
69 }
70
71 def updated(){
72         unsubscribe()
73     init()
74 }
75
76 def init() {
77         subscribe(master, "switch", onOffHandler)
78         subscribe(master, "level", colorHandler)
79     subscribe(master, "hue", colorHandler)
80     subscribe(master, "saturation", colorHandler)
81     subscribe(master, "colorTemperature", tempHandler)
82 }
83 //-----------------------------------
84 def onOffHandler(evt){
85         if (slaves && master) {
86                 if (!slaves?.id.find{it==master?.id}){
87                 if (master?.currentValue("switch") == "on"){
88                     if (randomYes) getRandomColorMaster()
89                                 else slaves?.on()
90                 }
91                 else {
92                     slaves?.off()  
93                 }
94                 }
95         }
96 }
97
98 def colorHandler(evt) {
99         if (slaves && master) {
100                 if (!slaves?.id?.find{it==master?.id} && master?.currentValue("switch") == "on"){
101                         log.debug "Changing Slave units H,S,L"
102                 def dimLevel = master?.currentValue("level")
103                 def hueLevel = master?.currentValue("hue")
104                 def saturationLevel = master.currentValue("saturation")
105                         def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer]
106                 slaves?.setColor(newValue)
107                 try {
108                         log.debug "Changing Slave color temp"
109                         def tempLevel = master?.currentValue("colorTemperature")
110                         slaves?.setColorTemperature(tempLevel)
111                 }
112                         catch (e){
113                         log.debug "Color temp for master --"
114                 }
115                 }
116         }
117 }
118
119 def getRandomColorMaster(){
120     def hueLevel = Math.floor(Math.random() *1000)
121     def saturationLevel = Math.floor(Math.random() * 100)
122     def dimLevel = master?.currentValue("level")
123         def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer]
124     log.debug hueLevel
125     log.debug saturationLevel
126     master.setColor(newValue)
127     slaves?.setColor(newValue)   
128 }
129
130 def tempHandler(evt){
131         if (slaves && master) {
132             if (!slaves?.id?.find{it==master?.id} && master?.currentValue("switch") == "on"){
133                 if (evt.value != "--") {
134                     log.debug "Changing Slave color temp based on Master change"
135                     def tempLevel = master.currentValue("colorTemperature")
136                     slaves?.setColorTemperature(tempLevel)
137                 }
138                 }
139         }
140 }
141
142 //Version/Copyright/Information/Help
143
144 private def textAppName() {
145         def text = "Color Coordinator"
146 }       
147
148 private def textVersion() {
149     def text = "Version 1.1.1 (12/13/2016)"
150 }
151
152 private def textCopyright() {
153     def text = "Copyright © 2016 Michael Struck"
154 }
155
156 private def textLicense() {
157     def text =
158                 "Licensed under the Apache License, Version 2.0 (the 'License'); "+
159                 "you may not use this file except in compliance with the License. "+
160                 "You may obtain a copy of the License at"+
161                 "\n\n"+
162                 "    http://www.apache.org/licenses/LICENSE-2.0"+
163                 "\n\n"+
164                 "Unless required by applicable law or agreed to in writing, software "+
165                 "distributed under the License is distributed on an 'AS IS' BASIS, "+
166                 "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. "+
167                 "See the License for the specific language governing permissions and "+
168                 "limitations under the License."
169 }
170
171 private def textHelp() {
172         def text =
173         "This application will allow you to control the settings of multiple colored lights with one control. " +
174         "Simply choose a master control light, and then choose the lights that will follow the settings of the master, "+
175         "including on/off conditions, hue, saturation, level and color temperature. Also includes a random color feature."
176 }