Update step-notifier.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         section("Master Light") {
37                 input "master", "capability.colorControl", title: "Colored Light", required: true
38         }
39         section("Lights that follow the master settings") {
40                 input "slaves", "capability.colorControl", title: "Colored Lights",  multiple: true, required: true, submitOnChange: true
41         }
42         section([mobileOnly:true], "Options") {
43                 input "randomYes", "bool",title: "When Master Turned On, Randomize Color", defaultValue: false
44                 href "pageAbout", title: "About ${textAppName()}", description: "Tap to get application version, license and instructions"
45         }
46         
47         dynamicPage(name: "mainPage", title: "", install: true, uninstall: false) {
48         def masterInList = slaves?.id?.find{it==master?.id}
49         if (masterInList) {
50                 section ("**WARNING**"){
51                         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"
52                 }
53         }
54         
55         page(name: "pageAbout", title: "About ${textAppName()}", uninstall: true) {
56                         section {
57                                 paragraph "${textVersion()}\n${textCopyright()}\n\n${textLicense()}\n"
58                         }
59                         section("Instructions") {
60                                 paragraph textHelp()
61                         }
62                         section("Tap button below to remove application"){
63                         }
64                 }
65                 
66         }
67 }
68
69 def installed() {   
70         init() 
71 }
72
73 def updated(){
74         unsubscribe()
75     init()
76 }
77
78 def init() {
79     subscribe(master, "switch", onOffHandler)
80     subscribe(master, "level", colorHandler)
81     subscribe(master, "hue", colorHandler)
82     subscribe(master, "saturation", colorHandler)
83     subscribe(master, "colorTemperature", tempHandler)
84 }
85 //-----------------------------------
86 def onOffHandler(evt){
87         if (slaves && master) {
88                 if (!slaves?.id.find{it==master?.id}){
89                 if (master?.currentValue("switch") == "on"){
90                     if (randomYes) getRandomColorMaster()
91                                 else slaves?.on()
92                 }
93                 else {
94                     slaves?.off()  
95                 }
96                 }
97         }
98 }
99
100 def colorHandler(evt) {
101         if (slaves && master) {
102                 if (!slaves?.id?.find{it==master?.id} && master?.currentValue("switch") == "on"){
103                         log.debug "Changing Slave units H,S,L"
104                 def dimLevel = master?.currentValue("level")
105                 def hueLevel = master?.currentValue("hue")
106                 def saturationLevel = master.currentValue("saturation")
107                         def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer]
108                 slaves?.setColor(newValue)
109                 try {
110                         log.debug "Changing Slave color temp"
111                         def tempLevel = master?.currentValue("colorTemperature")
112                         slaves?.setColorTemperature(tempLevel)
113                 }
114                         catch (e){
115                         log.debug "Color temp for master --"
116                 }
117                 }
118         }
119 }
120
121 def getRandomColorMaster(){
122     def hueLevel = Math.floor(Math.random() *1000)
123     def saturationLevel = Math.floor(Math.random() * 100)
124     def dimLevel = master?.currentValue("level")
125         def newValue = [hue: hueLevel, saturation: saturationLevel, level: dimLevel as Integer]
126     log.debug hueLevel
127     log.debug saturationLevel
128     master.setColor(newValue)
129     slaves?.setColor(newValue)   
130 }
131
132 def tempHandler(evt){
133         if (slaves && master) {
134             if (!slaves?.id?.find{it==master?.id} && master?.currentValue("switch") == "on"){
135                 if (evt.value != "--") {
136                     log.debug "Changing Slave color temp based on Master change"
137                     def tempLevel = master.currentValue("colorTemperature")
138                     slaves?.setColorTemperature(tempLevel)
139                 }
140                 }
141         }
142 }
143
144 //Version/Copyright/Information/Help
145
146 private def textAppName() {
147         def text = "Color Coordinator"
148 }       
149
150 private def textVersion() {
151     def text = "Version 1.1.1 (12/13/2016)"
152 }
153
154 private def textCopyright() {
155     def text = "Copyright © 2016 Michael Struck"
156 }
157
158 private def textLicense() {
159     def text =
160                 "Licensed under the Apache License, Version 2.0 (the 'License'); "+
161                 "you may not use this file except in compliance with the License. "+
162                 "You may obtain a copy of the License at"+
163                 "\n\n"+
164                 "    http://www.apache.org/licenses/LICENSE-2.0"+
165                 "\n\n"+
166                 "Unless required by applicable law or agreed to in writing, software "+
167                 "distributed under the License is distributed on an 'AS IS' BASIS, "+
168                 "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. "+
169                 "See the License for the specific language governing permissions and "+
170                 "limitations under the License."
171 }
172
173 private def textHelp() {
174         def text =
175         "This application will allow you to control the settings of multiple colored lights with one control. " +
176         "Simply choose a master control light, and then choose the lights that will follow the settings of the master, "+
177         "including on/off conditions, hue, saturation, level and color temperature. Also includes a random color feature."
178 }