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