Just time for sunrise and sunset

Hello,
I have been scratching my head over this for the last couple of days! Quite new to working with Groovy and rather used to VBS!

My SmartApp is designed to increase the brightness of a Wemo bulb, and then decrease it again upon a contact open/closed… however I only want it to run between sunset and sunrise the following day.

The below code was sent to me by a colleague of mine, however I think its a little broken and needs some work. Whilst it works after sunset, I don’t think it will work after midnight!

What I think it needs to get is just the time of sunrise and sunset, not the full date. However I have yet to find how to do it!

Thanks!

def isItDarkOut() {

	def sunRiseStr = (location.currentValue("sunriseTime"))
    def sunSetStr = (location.currentValue("sunsetTime"))

    Date sunRise = new Date().parse("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", sunRiseStr).plus(0)
    Date sunSet = new Date().parse("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", sunSetStr).plus(-1)

    Date now = new Date()
	
	log.info "**************************************"
	log.info "BWO: Sunrise $sunRise"
	log.info "BWO: **Sunset $sunSet"
	log.info "BWO: **Now $now"
	log.info "BWO: **Night time only?: $boolDark"

    if((now < sunRise) && (now > sunSet)){ 
		log.info "BWO: Night time"
        return true
		}
	else if (boolDark == "No") {
		log.info "BWO: Its daytime, but settings say let it happen anyway"
		return true
		}
    else{
		
		log.info "BWO: Day time"
		return false
		}
}

There are several SmartApps that do something similar that are worth studying.

Basically the strategy is to check if the current time is within whatever window you’re interested in, before executing.

private getTimeOk() {
    	def result = true
    	if (starting && ending) {
    		def currTime = now()
    		def start = timeToday(starting, location?.timeZone).time
    		def stop = timeToday(ending, location?.timeZone).time
    		result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
    	}
    	log.trace "timeOk = $result"
    	result
    }

So if starting is the time of sunset and ending is the time of sunrise, it would return true if the current time is within that window.

Note: I haven’t tested this specific case with sunrise or sunset, so you may need to play around with it a bit.

If you search the SmartThingsPublic GitHub repo for “getTimeOk” you’ll see a bunch of similar code to do this task:

1 Like

I finally figured this out, took some time… quite simple in the end.

Yes, you could do some math to figure it out (which I have seen others do…), but I figured out that a simple third “else” was an easier way. This will also give you the bonus to detect if its night (Evening), or night (morning) as well as day…

//Is it night or day?
def sunRiseSet = getSunriseAndSunset()
def currentTime = new Date(now())
def sunriseTime = sunRiseSet.sunrise 
def sunsetTime = sunRiseSet.sunset 

log.debug("Motion Control: Sunrise: $sunriseTime") 
log.debug("Motion Control: Sunset: $sunsetTime") 
		
if(currentTime.time > sunriseTime.time && currentTime.time < sunsetTime.time){
	log.debug ("Motion Control: Day time")
	TimeofDay = "day"
	}
else if(currentTime.time > sunriseTime.time && currentTime.time > sunsetTime.time){
	log.debug ("Motion Control: Night time (evening)")
	TimeofDay = "night"
	}
else if(currentTime.time < sunriseTime.time && currentTime.time < sunsetTime.time){
 	log.debug ("Motion Control: Night time (morning)")
	TimeofDay = "night"
	}