Update gentle-wake-up.groovy
[smartapps.git] / official / bright-when-dark-and-or-bright-after-sunset.groovy
1 definition(
2     name: "Bright When Dark And/Or Bright After Sunset",
3     namespace: "Arno",
4     author: "Arnaud",
5     description: "Turn ON light(s) and/or dimmer(s) when there's movement and the room is dark with illuminance threshold and/or between sunset and sunrise. Then turn OFF after X minute(s) when the brightness of the room is above the illuminance threshold or turn OFF after X minute(s) when there is no movement.",
6     category: "Convenience",
7     iconUrl: "http://neiloseman.com/wp-content/uploads/2013/08/stockvault-bulb128619.jpg",
8     iconX2Url: "http://neiloseman.com/wp-content/uploads/2013/08/stockvault-bulb128619.jpg"
9 )
10
11 preferences
12 {
13         page(name: "timeIntervalInput", title: "Only during a certain time...")
14         {
15                 section
16                 {
17                         input "starting", "time", title: "Starting", required: false
18                         input "ending", "time", title: "Ending", required: false
19                 }
20         }
21         
22         page(name: "configurations")
23         page(name: "options")
24
25         
26 }
27
28 def configurations()
29 {
30         dynamicPage(name: "configurations", title: "Configurations...", uninstall: true, nextPage: "options")
31         {
32                 section(title: "Turn ON lights on movement when...")
33                 {
34                         input "dark", "bool", title: "It is dark?", required: true
35             input "sun", "bool", title: "Between sunset and surise?", required: true
36                         }
37                 section(title: "More options...", hidden: hideOptionsSection(), hideable: true)
38                 {
39                         def timeLabel = timeIntervalLabel()
40                         href "timeIntervalInput", title: "Only during a certain time:", description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : null
41                         input "days", "enum", title: "Only on certain days of the week:", multiple: true, required: false, options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
42                         input "modes", "mode", title: "Only when mode is:", multiple: true, required: false
43                         }
44                 section ("Assign a name")
45                 {
46                         label title: "Assign a name", required: false
47                         }
48                 }
49 }
50
51 def options()
52 {
53         if (dark == true && sun == true)
54         {
55                 dynamicPage(name: "options", title: "Lights will turn ON on movement when it is dark and between sunset and sunrise...", install: true, uninstall: true)
56                 {
57                         section("Control these light(s)...")
58                         {
59                                 input "lights", "capability.switch", title: "Light(s)?", multiple: true, required: false
60                         }    
61                 section("Control these dimmer(s)...")
62                         { 
63                         input "dimmers", "capability.switchLevel", title: "Dimmer(s)?", multiple: true, required:false
64                         input "level", "number", title: "How bright?", required:false, description: "0% to 100%"
65                                 }
66                         section("Turning ON when it's dark and there's movement...")
67                         {
68                                 input "motionSensor", "capability.motionSensor", title: "Where?", multiple: true, required: true
69                                 } 
70                         section("And then OFF when it's light or there's been no movement for...")
71                         {
72                                 input "delayMinutes", "number", title: "Minutes?", required: false
73                                 }
74                         section("Using this light sensor...")
75                         {
76                                 input "lightSensor", "capability.illuminanceMeasurement",title: "Light Sensor?", multiple: false, required: true
77                         input "luxLevel", "number", title: "Illuminance threshold? (default 50 lux)",defaultValue: "50", required: false
78                                 }
79                         section ("And between sunset and sunrise...")
80                         {
81                                 input "sunriseOffsetValue", "text", title: "Sunrise offset", required: false, description: "00:00"
82                                 input "sunriseOffsetDir", "enum", title: "Before or After", required: false, metadata: [values: ["Before","After"]]
83                         input "sunsetOffsetValue", "text", title: "Sunset offset", required: false, description: "00:00"
84                                 input "sunsetOffsetDir", "enum", title: "Before or After", required: false, metadata: [values: ["Before","After"]]
85                                 }
86                         section ("Zip code (optional, defaults to location coordinates when location services are enabled)...")
87                         {
88                                 input "zipCodeText", "text", title: "Zip Code?", required: false, description: "Local Zip Code"
89                                 }
90                         }
91                 }
92         else if (dark == true && sun == false)
93         {
94         dynamicPage(name: "options", title: "Lights will turn ON on movement when it is dark...", install: true, uninstall: true)
95                 {
96                         section("Control these light(s)...")
97                         {
98                                 input "lights", "capability.switch", title: "Light(s)?", multiple: true, required: false
99                         }    
100                 section("Control these dimmer(s)...")
101                         { 
102                         input "dimmers", "capability.switchLevel", title: "Dimmer(s)?", multiple: true, required:false
103                         input "level", "number", title: "How bright?", required:false, description: "0% to 100%"
104                                 }
105                         section("Turning ON when it's dark and there's movement...")
106                         {
107                                 input "motionSensor", "capability.motionSensor", title: "Where?", multiple: true, required: true
108                                 } 
109                         section("And then OFF when it's light or there's been no movement for...")
110                         {
111                                 input "delayMinutes", "number", title: "Minutes?", required: false
112                                 }
113                         section("Using this light sensor...")
114                         {
115                                 input "lightSensor", "capability.illuminanceMeasurement",title: "Light Sensor?", multiple: false, required: true
116                         input "luxLevel", "number", title: "Illuminance threshold? (default 50 lux)",defaultValue: "50", required: false
117                                 }
118                         }
119                 }
120     else if (sun == true && dark == false)
121         {
122         dynamicPage(name: "options", title: "Lights will turn ON on movement between sunset and sunrise...", install: true, uninstall: true)
123                 {
124                         section("Control these light(s)...")
125                         {
126                                 input "lights", "capability.switch", title: "Light(s)?", multiple: true, required: false
127                         }    
128                 section("Control these dimmer(s)...")
129                         { 
130                         input "dimmers", "capability.switchLevel", title: "Dimmer(s)?", multiple: true, required:false
131                         input "level", "number", title: "How bright?", required:false, description: "0% to 100%"
132                                 }
133                         section("Turning ON there's movement...")
134                         {
135                                 input "motionSensor", "capability.motionSensor", title: "Where?", multiple: true, required: true
136                                 } 
137                         section("And then OFF there's been no movement for...")
138                         {
139                                 input "delayMinutes", "number", title: "Minutes?", required: false
140                                 }
141                         section ("Between sunset and sunrise...")
142                         {
143                                 input "sunriseOffsetValue", "text", title: "Sunrise offset", required: false, description: "00:00"
144                                 input "sunriseOffsetDir", "enum", title: "Before or After", required: false, metadata: [values: ["Before","After"]]
145                         input "sunsetOffsetValue", "text", title: "Sunset offset", required: false, description: "00:00"
146                                 input "sunsetOffsetDir", "enum", title: "Before or After", required: false, metadata: [values: ["Before","After"]]
147                                 }
148                         section ("Zip code (optional, defaults to location coordinates when location services are enabled)...")
149                         {
150                                 input "zipCodeText", "text", title: "Zip Code?", required: false, description: "Local Zip Code"
151                                 }
152                         }
153                 }
154         else
155         {
156         dynamicPage(name: "options", title: "Lights will turn ON on movement...", install: true, uninstall: true)
157                 {
158                         section("Control these light(s)...")
159                         {
160                                 input "lights", "capability.switch", title: "Light(s)?", multiple: true, required: false
161                         }    
162                 section("Control these dimmer(s)...")
163                         { 
164                         input "dimmers", "capability.switchLevel", title: "Dimmer(s)?", multiple: true, required:false
165                         input "level", "number", title: "How bright?", required:false, description: "0% to 100%"
166                                 }
167                         section("Turning ON when there's movement...")
168                         {
169                                 input "motionSensor", "capability.motionSensor", title: "Where?", multiple: true, required: true
170                                 } 
171                         section("And then OFF when there's been no movement for...")
172                         {
173                                 input "delayMinutes", "number", title: "Minutes?", required: false
174                                 }
175                         }
176         }
177 }
178
179 def installed()
180 {
181         log.debug "Installed with settings: ${settings}."
182         initialize()
183 }
184
185 def updated()
186 {
187         log.debug "Updated with settings: ${settings}."
188         unsubscribe()
189         unschedule()
190         initialize()
191 }
192
193 def initialize()
194 {
195         subscribe(motionSensor, "motion", motionHandler)
196     if (lights != null && lights != "" && dimmers != null && dimmers != "")
197         {
198         log.debug "$lights subscribing..."
199         subscribe(lights, "switch", lightsHandler)
200         log.debug "$dimmers subscribing..."
201         subscribe(dimmers, "switch", dimmersHandler)
202         if (dark == true && lightSensor != null && lightSensor != "")
203                 {
204                 log.debug "$lights and $dimmers will turn ON when movement detected and when it is dark..."
205                         subscribe(lightSensor, "illuminance", illuminanceHandler, [filterEvents: false])
206                         }
207                 if (sun == true)
208                 {
209                 log.debug "$lights and $dimmers will turn ON when movement detected between sunset and sunrise..."
210                         astroCheck()
211                 subscribe(location, "position", locationPositionChange)
212             subscribe(location, "sunriseTime", sunriseSunsetTimeHandler)
213             subscribe(location, "sunsetTime", sunriseSunsetTimeHandler)
214                         }
215         else if (dark != true && sun != true)
216             {
217             log.debug "$lights and $dimmers will turn ON when movement detected..."
218             }
219         }
220     else if (lights != null && lights != "")
221         {
222         log.debug "$lights subscribing..."
223         subscribe(lights, "switch", lightsHandler)
224         if (dark == true && lightSensor != null && lightSensor != "")
225                 {
226                 log.debug "$lights will turn ON when movement detected and when it is dark..."
227                         subscribe(lightSensor, "illuminance", illuminanceHandler, [filterEvents: false])
228                         }
229                 if (sun == true)
230                 {
231                 log.debug "$lights will turn ON when movement detected between sunset and sunrise..."
232                         astroCheck()
233                 subscribe(location, "position", locationPositionChange)
234             subscribe(location, "sunriseTime", sunriseSunsetTimeHandler)
235             subscribe(location, "sunsetTime", sunriseSunsetTimeHandler)
236                         }
237         else if (dark != true && sun != true)
238             {
239             log.debug "$lights will turn ON when movement detected..."
240             }
241         }
242         else if (dimmers != null && dimmers != "")
243         {
244         log.debug "$dimmers subscribing..."
245         subscribe(dimmers, "switch", dimmersHandler)
246         if (dark == true && lightSensor != null && lightSensor != "")
247                 {
248                 log.debug "$dimmers will turn ON when movement detected and when it is dark..."
249                         subscribe(lightSensor, "illuminance", illuminanceHandler, [filterEvents: false])
250                         }
251                 if (sun == true)
252                 {
253                 log.debug "$dimmers will turn ON when movement detected between sunset and sunrise..."
254                         astroCheck()
255                 subscribe(location, "position", locationPositionChange)
256             subscribe(location, "sunriseTime", sunriseSunsetTimeHandler)
257             subscribe(location, "sunsetTime", sunriseSunsetTimeHandler)
258                         }
259         else if (dark != true && sun != true)
260             {
261             log.debug "$dimmers will turn ON when movement detected..."
262             }
263         }
264         log.debug "Determinating lights and dimmers current value..."
265         if (lights != null && lights != "")
266                 {
267             if (lights.currentValue("switch").toString().contains("on"))
268                 {
269                 state.lightsState = "on"
270                 log.debug "Lights $state.lightsState."
271                 }
272             else if (lights.currentValue("switch").toString().contains("off"))
273                 {
274                 state.lightsState = "off"
275                 log.debug "Lights $state.lightsState."
276                 }
277             else
278                 {
279                 log.debug "ERROR!"
280                 }
281                         }
282                 if (dimmers != null && dimmers != "")
283                 {
284             if (dimmers.currentValue("switch").toString().contains("on"))
285                 {
286                 state.dimmersState = "on"
287                 log.debug "Dimmers $state.dimmersState."
288                 }
289             else if (dimmers.currentValue("switch").toString().contains("off"))
290                 {
291                 state.dimmersState = "off"
292                 log.debug "Dimmers $state.dimmersState."
293                 }
294             else
295                 {
296                 log.debug "ERROR!"
297                 }
298                         }
299 }
300             
301 def locationPositionChange(evt)
302 {
303         log.trace "locationChange()"
304         astroCheck()
305 }
306
307 def sunriseSunsetTimeHandler(evt)
308 {
309         state.lastSunriseSunsetEvent = now()
310         log.debug "SmartNightlight.sunriseSunsetTimeHandler($app.id)"
311         astroCheck()
312 }
313
314 def motionHandler(evt)
315 {
316         log.debug "$evt.name: $evt.value"
317         if (evt.value == "active")
318         {
319         unschedule(turnOffLights)
320         unschedule(turnOffDimmers)
321         if (dark == true && sun == true)
322                 {
323             if (darkOk == true && sunOk == true)
324                 {
325                 log.debug "Lights and Dimmers will turn ON because $motionSensor detected motion and $lightSensor was dark or because $motionSensor detected motion between sunset and sunrise..."
326                 if (lights != null && lights != "")
327                     {
328                     log.debug "Lights: $lights will turn ON..."
329                     turnOnLights()
330                     }
331                 if (dimmers != null && dimmers != "")
332                     {
333                     log.debug "Dimmers: $dimmers will turn ON..."
334                     turnOnDimmers()
335                     }
336                                 }
337                         else if (darkOk == true && sunOk != true)
338                 {
339                 log.debug "Lights and Dimmers will turn ON because $motionSensor detected motion and $lightSensor was dark..."
340                 if (lights != null && lights != "")
341                     {
342                     log.debug "Lights: $lights will turn ON..."
343                     turnOnLights()
344                     }
345                 if (dimmers != null && dimmers != "")
346                     {
347                     log.debug "Dimmers: $dimmers will turn ON..."
348                     turnOnDimmers()
349                     }
350                                 }
351                         else if (darkOk != true && sunOk == true)
352                 {
353                 log.debug "Lights and dimmers will turn ON because $motionSensor detected motion between sunset and sunrise..."
354                 if (lights != null && lights != "")
355                     {
356                     log.debug "Lights: $lights will turn ON..."
357                     turnOnLights()
358                     }
359                 if (dimmers != null && dimmers != "")
360                     {
361                     log.debug "Dimmers: $dimmers will turn ON..."
362                     turnOnDimmers()
363                     }
364                                 }
365                         else
366                 {
367                                 log.debug "Lights and dimmers will not turn ON because $lightSensor is too bright or because time not between sunset and surise."
368                 }
369                         }
370                 else if (dark == true && sun != true)
371                 {
372             if (darkOk == true)
373                 {
374                 log.debug "Lights and dimmers will turn ON because $motionSensor detected motion and $lightSensor was dark..."
375                 if (lights != null && lights != "")
376                     {
377                     log.debug "Lights: $lights will turn ON..."
378                     turnOnLights()
379                     }
380                 if (dimmers != null && dimmers != "")
381                     {
382                     log.debug "Dimmers: $dimmers will turn ON..."
383                     turnOnDimmers()
384                     }
385                                 }
386                         else
387                 {
388                                 log.debug "Lights and dimmers will not turn ON because $lightSensor is too bright."
389                 }
390                 }
391                 else if (dark != true && sun == true)
392                 {
393             if (sunOk == true)
394                 {
395                 log.debug "Lights and dimmers will turn ON because $motionSensor detected motion between sunset and sunrise..."
396                 if (lights != null && lights != "")
397                     {
398                     log.debug "Lights: $lights will turn ON..."
399                     turnOnLights()
400                     }
401                 if (dimmers != null && dimmers != "")
402                     {
403                     log.debug "Dimmers: $dimmers will turn ON..."
404                     turnOnDimmers()
405                     }
406                                 }
407                         else
408                 {
409                                 log.debug "Lights and dimmers will not turn ON because time not between sunset and surise."
410                 }
411                 }
412                 else if (dark != true && sun != true)
413                 {
414             log.debug "Lights and dimmers will turn ON because $motionSensor detected motion..."
415             if (lights != null && lights != "")
416                                 {
417                                 log.debug "Lights: $lights will turn ON..."
418                                 turnOnLights()
419                                 }
420                         if (dimmers != null && dimmers != "")
421                 {
422                                 log.debug "Dimmers: $dimmers will turn ON..."
423                                 turnOnDimmers()
424                                 }
425                 }
426                 }
427         else if (evt.value == "inactive")
428         {
429         unschedule(turnOffLights)
430         unschedule(turnOffDimmers)
431                 if (state.lightsState != "off" || state.dimmersState != "off")
432                 {
433             log.debug "Lights and/or dimmers are not OFF."
434                         if (delayMinutes)
435                 {
436                 def delay = delayMinutes * 60
437                 if (dark == true && sun == true)
438                     {
439                     log.debug "Lights and dimmers will turn OFF in $delayMinutes minute(s) after turning ON when dark or between sunset and sunrise..."
440                     if (lights != null && lights != "")
441                         {
442                         log.debug "Lights: $lights will turn OFF in $delayMinutes minute(s)..."
443                         runIn(delay, turnOffLights)
444                         }
445                      if (dimmers != null && dimmers != "")
446                         {
447                         log.debug "Dimmers: $dimmers will turn OFF in $delayMinutes minute(s)..."
448                         runIn(delay, turnOffDimmers)
449                         }
450                     }
451                 else if (dark == true && sun != true)
452                     {
453                     log.debug "Lights and dimmers will turn OFF in $delayMinutes minute(s) after turning ON when dark..."
454                     if (lights != null && lights != "")
455                         {
456                         log.debug "Lights: $lights will turn OFF in $delayMinutes minute(s)..."
457                         runIn(delay, turnOffLights)
458                         }
459                      if (dimmers != null && dimmers != "")
460                         {
461                         log.debug "Dimmers: $dimmers will turn OFF in $delayMinutes minute(s)..."
462                         runIn(delay, turnOffDimmers)
463                         }
464                     }
465                 else if (dark != true && sun == true)
466                     {
467                     log.debug "Lights and dimmers will turn OFF in $delayMinutes minute(s) between sunset and sunrise..."
468                     if (lights != null && lights != "")
469                         {
470                         log.debug "Lights: $lights will turn OFF in $delayMinutes minute(s)..."
471                         runIn(delay, turnOffLights)
472                         }
473                      if (dimmers != null && dimmers != "")
474                         {
475                         log.debug "Dimmers: $dimmers will turn OFF in $delayMinutes minute(s)..."
476                         runIn(delay, turnOffDimmers)
477                         }
478                     }
479                 else if (dark != true && sun != true)
480                     {
481                     log.debug "Lights and dimmers will turn OFF in $delayMinutes minute(s)..."
482                     if (lights != null && lights != "")
483                         {
484                         log.debug "Lights: $lights will turn OFF in $delayMinutes minute(s)..."
485                         runIn(delay, turnOffLights)
486                         }
487                     if (dimmers != null && dimmers != "")
488                         {
489                         log.debug "Dimmers: $dimmers will turn OFF in $delayMinutes minute(s)..."
490                         runIn(delay, turnOffDimmers)
491                         }
492                     }
493                 }
494                         else
495                         {
496                         log.debug "Lights and dimmers will stay ON because no turn OFF delay was set..."
497                                 }
498             }
499                 else if (state.lightsState == "off" && state.dimmersState == "off")
500                 {
501                 log.debug "Lights and dimmers are already OFF and will not turn OFF in $delayMinutes minute(s)."
502                         }
503                 }
504 }
505
506 def lightsHandler(evt)
507 {
508         log.debug "Lights Handler $evt.name: $evt.value"
509     if (evt.value == "on")
510         {
511         log.debug "Lights: $lights now ON."
512         unschedule(turnOffLights)
513         state.lightsState = "on"
514         }
515         else if (evt.value == "off")
516         {
517         log.debug "Lights: $lights now OFF."
518         unschedule(turnOffLights)
519         state.lightsState = "off"
520         }
521 }
522
523 def dimmersHandler(evt)
524 {
525         log.debug "Dimmer Handler $evt.name: $evt.value"
526     if (evt.value == "on")
527         {
528         log.debug "Dimmers: $dimmers now ON."
529         unschedule(turnOffDimmers)
530         state.dimmersState = "on"
531         }
532         else if (evt.value == "off")
533         {
534         log.debug "Dimmers: $dimmers now OFF."
535         unschedule(turnOffDimmers)
536         state.dimmersState = "off"
537         }
538 }
539
540 def illuminanceHandler(evt)
541 {
542         log.debug "$evt.name: $evt.value, lastStatus lights: $state.lightsState, lastStatus dimmers: $state.dimmersState, motionStopTime: $state.motionStopTime"
543         unschedule(turnOffLights)
544     unschedule(turnOffDimmers)
545     if (evt.integerValue > 999)
546         {
547         log.debug "Lights and dimmers will turn OFF because illuminance is superior to 999 lux..."
548         if (lights != null && lights != "")
549                         {
550                         log.debug "Lights: $lights will turn OFF..."
551                         turnOffLights()
552                         }
553                 if (dimmers != null && dimmers != "")
554                         {
555                         log.debug "Dimmers: $dimmers will turn OFF..."
556                         turnOffDimmers()
557                         }
558                 }
559         else if (evt.integerValue > ((luxLevel != null && luxLevel != "") ? luxLevel : 50))
560                 {
561                 log.debug "Lights and dimmers will turn OFF because illuminance is superior to $luxLevel lux..."
562         if (lights != null && lights != "")
563                         {
564                         log.debug "Lights: $lights will turn OFF..."
565                         turnOffLights()
566                         }
567                 if (dimmers != null && dimmers != "")
568                         {
569                         log.debug "Dimmers: $dimmers will turn OFF..."
570                         turnOffDimmers()
571                         }
572                 }
573 }
574
575 def turnOnLights()
576 {
577         if (allOk)
578         {
579         if (state.lightsState != "on")
580             {
581             log.debug "Turning ON lights: $lights..."
582             lights?.on()
583             state.lightsState = "on"
584             }
585         else
586             {
587             log.debug "Lights: $lights already ON."
588             }
589                 }
590         else
591         {
592         log.debug "Time, days of the week or mode out of range! $lights will not turn ON."
593         }
594 }
595
596 def turnOnDimmers()
597 {
598         if (allOk)
599         {
600         if (state.dimmersState != "on")
601             {
602             log.debug "Turning ON dimmers: $dimmers..."
603             settings.dimmers?.setLevel(level)
604             state.dimmersState = "on"
605             }
606         else
607             {
608             log.debug "Dimmers: $dimmers already ON."
609             }
610                 }
611         else
612         {
613         log.debug "Time, days of the week or mode out of range! $dimmers will not turn ON."
614         }
615 }
616
617
618 def turnOffLights()
619 {
620         if (allOk)
621         {
622         if (state.lightsState != "off")
623             {
624             log.debug "Turning OFF lights: $lights..."
625             lights?.off()
626             state.lightsState = "on"
627             }
628         else
629             {
630             log.debug "Lights: $lights already OFF."
631             }
632                 }
633         else
634         {
635         log.debug "Time, day of the week or mode out of range! $lights will not turn OFF."
636         }
637 }
638
639 def turnOffDimmers()
640 {
641         if (allOk)
642         {
643         if (state.dimmersState != "off")
644             {
645             log.debug "Turning OFF dimmers: $dimmers..."
646             dimmers?.off()
647             state.dimmersState = "off"
648             }
649         else
650             {
651             log.debug "Dimmers: $dimmers already OFF."
652             }
653                 }
654         else
655         {
656         log.debug "Time, day of the week or mode out of range! $dimmers will not turn OFF."
657         }
658 }
659
660 def astroCheck()
661 {
662         def s = getSunriseAndSunset(zipCode: zipCodeText, sunriseOffset: sunriseOffset, sunsetOffset: sunsetOffset)
663         state.riseTime = s.sunrise.time
664         state.setTime = s.sunset.time
665         log.debug "Sunrise: ${new Date(state.riseTime)}($state.riseTime), Sunset: ${new Date(state.setTime)}($state.setTime)"
666 }
667
668 private getDarkOk()
669 {
670         def result
671         if (dark == true && lightSensor != null && lightSensor != "")
672         {
673                 result = lightSensor.currentIlluminance < ((luxLevel != null && luxLevel != "") ? luxLevel : 50)
674                 }
675         log.trace "darkOk = $result"
676         result
677 }
678
679 private getSunOk()
680 {
681         def result
682         if (sun == true)
683         {
684                 def t = now()
685                 result = t < state.riseTime || t > state.setTime
686                 }
687         log.trace "sunOk = $result"
688         result
689 }
690
691 private getSunriseOffset()
692 {
693         sunriseOffsetValue ? (sunriseOffsetDir == "Before" ? "-$sunriseOffsetValue" : sunriseOffsetValue) : null
694 }
695
696 private getSunsetOffset()
697 {
698         sunsetOffsetValue ? (sunsetOffsetDir == "Before" ? "-$sunsetOffsetValue" : sunsetOffsetValue) : null
699 }
700
701 private getAllOk()
702 {
703         return true//modeOk //&& daysOk && timeOk
704 }
705
706 private getModeOk()
707 {
708         def result = !modes || modes.contains(location.mode)
709         log.trace "modeOk = $result"
710         result
711 }
712
713 private getDaysOk()
714 {
715         def result = true
716         if (days)
717         {
718                 def df = new java.text.SimpleDateFormat("EEEE")
719                 if (location.timeZone)
720                 {
721                         df.setTimeZone(location.timeZone)
722                         }
723                 else
724                 {
725                         df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
726                         }
727                 def day = df.format(new Date())
728                 result = days.contains(day)
729                 }
730         log.trace "daysOk = $result"
731         result
732 }
733
734 private getTimeOk()
735 {
736         def result = true
737         if (starting && ending)
738         {
739                 def currTime = now()
740                 def start = timeToday(starting).time
741                 def stop = timeToday(ending).time
742                 result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
743                 }
744         log.trace "timeOk = $result"
745         result
746 }
747
748 private hhmm(time, fmt = "h:mm a")
749 {
750         def t = timeToday(time, location.timeZone)
751         def f = new java.text.SimpleDateFormat(fmt)
752         f.setTimeZone(location.timeZone ?: timeZone(time))
753         f.format(t)
754 }
755
756 private hideOptionsSection()
757 {
758         (starting || ending || days || modes) ? false : true
759 }
760
761 private timeIntervalLabel()
762 {
763         (starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : ""
764 }