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