Sunrise/Sunset magic?

Thanks @geko. I was aware of this and looked but didn’t find attributes related to sunset/rise. That’s what made me think that ‘location’ in this context may not be the ‘location’ class. The documentation for the subscription method defines the first argument as a device or group of devices - thus was born the idea of a virtual device called ‘location’ with attributes including sunrise and sunset… Just normal newb challenges, I suppose.

I know there have been a number of questions around this, so I thought I’d try to clear it up a bit. We’ll try to get the documentation updated as well.

The location object you use is in fact your location class for this installation of the SmartApp. You don’t see sunrise/sunset attributes, because those are actually events that we send out as a platform.

There are two different sets of events that get sent out. First off are the sunrise and sunset events. These happen at the minute when it is sunrise or sunset at your specific latitude and longitude. Use these when you need something to happen right at those times. For example, you might want to turn on your yard lights when it is sunset, and off again when it is sunrise. The value for these events is always just true so the use is just to trigger some action based on the sun.

The other types of events are sunriseTime and sunsetTime. The value for these is the time when the next sunrise or sunset is going to happen. How it works behind the scenes is whenever it is sunrise, we (the platform) then look for tomorrow’s sunrise time and if it is different, which typically is every day, we send out a new sunriseTime event. And of course the same for sunset. This is in the format 2014-11-20T13:17:00.000Z which is 7:17 AM CST. The value is in UTC time. Typically you would use these events if you need an offset, like you want your lights to turn on 30 minutes before sunset and off 30 minutes after sunrise. That is what the Sunrise/Sunset app does that as @AaronZON noticed, if you want an example of how to use the offsets.

If you ever want to see your sunrise, sunset, sunriseTime, or sunsetTime events, you can look them up in the Web IDE by going to: My Locations > [Location Name] > events > from location

If you have any questions, let me know!


@matthewnohr - Super! This is very helpful. Much appreciated.

Are you the author of Sunrise/Sunset? The author is listed in the code as ‘SmartThings’. I used some of the code from this in a SmartApp in an app I did for a dusk-to-dawn light implementation and I found either an error or something I don’t fully understand (probably the later). I can take this up with you off-line or start a new thread.

I’ve done some work on that app, yes. If you found an error, please do let me know.

@matthewnohr - debugging an app that depends on firing of that is kinda…tough. Any way to simulate a sunrise / sunset in the IDE?

What is wrong with my simple code below?
I have a null pointer exception on the first line I try to subscribe for the sunrise event (subscribe(location, “sunrise”, sunriseHandler))

Here it is:

name: “Curtains Control”,
namespace: “iker.pryszo”,
author: “Iker Pryszo”,
description: “Allows a virtual switch to control the curtains and provides an option to open and close automatically the curtains for sunrise and sunset”,
category: “Convenience”,
iconUrl: “”,
iconX2Url: “”,
iconX3Url: “”)

preferences {
section(“Select the switch that controls the curtains”) {
input “mySwitch”, “capability.switch”, multiple: false
section(“Open and Close automatically for sunrise and sunset ?”) {
input “autoMode”, “bool”, title: “Auto Mode”, defaultValue: true

def installed() {
log.debug "Installed with settings: ${settings}"

def updated() {
log.debug "Updated with settings: ${settings}"

def initialize() {
subscribe(mySwitch, “switch”, switchHandler)
subscribe(location, “sunrise”, sunriseHandler)
subscribe(location, “sunset”, SunsetHandler)

def switchHandler(evt) {
log.trace "The event is: $evt.value: $evt"
if (evt.value == ‘on’) {
log.trace “Open Curtains”
} else {
if (evt.value == ‘off’) {
log.trace “Close Curtains”

def sunriseHandler(evt) { "Executing sunrise handler"
if (autoMode) { "Open Curtain Automatically"

def sunsetHandler(evt) { "Executing sunset handler"
if (autoMode) { "Close Curtain"

Thanks a lot!

You’ve got a typo here. should be sunsetHandler (first s is small, not cap).

Not sure why/how this created the error you saw but correcting the typo made your code work for me.

1 Like

That was it! Thanks.
I was confused by the exception and looked in the wrong place…

I tested it tonight and the Sunset event worked correctly!
I’ll finish my automatic curtains project and then post it for everybody.

Is there a way to ask the location if it is currently after sunrise or sunset?

1 Like

@Tony_Gutierrez, this method from one of my apps shows how you might do what you asked:

def initialSunPosition() {  
	//Determine if sun is down at time of initializtion and run sunsetHandler() if so
    //Light meter is not evaluated initially, light level first evaluated at first luminance event
    log.debug "initialSunPosition()"
	def s = getSunriseAndSunset(zipCode: zipCode, sunriseOffset: sunriseOffset, sunsetOffset: sunsetOffset)
	def now = new Date()
    def riseTime = s.sunrise
	def setTime = s.sunset
	state.ambient = "light"  //initialize to "light"
    state.sunPosition = "up" //initialize to "up"
    if(setTime.before(now) || riseTime.after(now)) {   //before midnight/after sunset or after midnight/before sunset "Sun is already down, run sunsetHandler"
	scheduleSunEvents()													//setting initial rise/set 
    schedule(timeToday("12:13",location.timeZone),scheduleSunEvents) 	//subsequent evaluation of rise/set times
    																	//at 12:13PM every day

The getSunriseAndSunset() method is documented in the docs.

Hope this helps. If not, post a follow up. . .

That is useful, but I was more curious if there was a native “get” method in the Location class that would return the current night/day status. If so we could easily avoid a lot of use of state vars, apps wouldn’t have to run for a full day before being on time, etc.

Ill implement the chunk you sent for now. Thanks!

Understood. I agree this would be handy but it doesn’t exist (see posts earlier in this thread for some discussion on this. . . I pretty much asked the same question as you). IMO, the code to do this in the SmartApp is not so bad, however.

(And @Tony_Gutierrez…).

I have a ‘hack’ idea bouncing around my head…

Create a new virtual Device (ideally with a new Capability, but we can’t add capabilities yet) whose purpose is to be a global data storage object.

We can be more tailored and create one just with one attribute: sunState [up, down] and a simple daily SmartApp (or polling within the Device?) can keep this Attribute current.


Nope. Not crazy… attribute: sunState [morning, day, evening, night] :wink:

Thanks, …

What are the definitions of the other two values? A user-preference on the Device Instance with an offset post-sunrise and pre-sunset? This seems like a reasonable way of using the availability functionality of Devices.

(Aside?: I made a feature request a long, long, time ago that SmartThings support multiple-concurrent Modes; which would be a less structured but infinitely simpler and flexible handling of this and much, much more… i.e.,

  • Modes are currently used for such things as period of day (morning, day, evening, night);
  • OR used for state of occupancy (away, home, vacation, sickday)
  • OR arbitrary usages
  • BUT cannot have more than one concurrent value (vacation & night, home & morning).

Since different SmartApps use the location Mode in app specific contexts, having only one at a time is rather crippling. A burglar alarm SmartApp is concerned about occupancy status; a lighting SmartApp is concerned about the period of the day.).

Sigh. :disappointed: ).

Can we hope that once there is an official method of adding Capabilities, then data / state storage Capabilities may be found acceptable on a case by case basis, if they help work around the limitations of single concurrent Mode, and generally no other available global attributes?

…CP / Terry.

That should work too…if you do not want a dedicated attribute…

Real life scenario:

Week day:

  1. Get up between 4:30 - 5:00 AM Weekdays. (Morning)
  2. Leave for work at 5:45 AM (pre sunrise)
  3. Wife leaves for work 7:00 - 7:30 AM (may be pre or post sunrise).
  4. Based on presence… House in away mode.
  5. Wife comes home between 4:00 - 5:00 PM (May or may not be sunset). Home is in Home mode.
  6. I come back home around 4:00 - 5:00 PM (Again may or may not be sunset). Need different behavior for evening.
  7. And then of course Good Night.

So, Finally comes down to Modes…Back to square one. :wink: And of course totally agree about multiple concurrent modes. And of course there is weekends, vacation, WFH… and of course @tslagle13’s mode… At times my head spins like crazy…

1 Like

im going to leave this here:

Four options (though more than one could be implemented for different purposes):

  1. Allow multiple concurrent active Modes. Advantage: Simple concept, but … Problem: Too unstructured; user or system may end up with incompatible concurrent modes active (i.e, Mode == day & night).

  2. Add strongly defined additional mode-like state holders, like “Alarm Mode”, “Occupancy Count”, etc… Advantage: Keeps things organized, simple, and contained. Problem: Hard to expand.

  3. Add a new Location scoped (near global) state variable: “locationState.*”, which functions like SmartApp.state.*, except writable / readable by any SmartApp or external process. Problem: security risk and clutter.

  4. Add a generic new Capability “Data Store” and instantiate Virtual Devices for related states that can be securely shared among SmartApps and authorized externals. Advantage: Arbitrary flexibility and security. Problem: Clutter (and, right now, instantiating Virtual Devices is hard.).

  5. Add well defined distinct Capabilities for each new global dataset (e.g., “capability.namedTimePeriod”).

I’m ambivalent: Not sure which of #4 and #5 is better, but that’s what I’m leaning towards: Good security and good balance of structure and flexibility.

Important Question: to @matthewnohr or designate: Isn’t there currently a security risk for Mode, because ANY SmartApp has read and write access to location.currentMode??

…CP / Terry.

@tgauchat @tslagle13

Trying to grasp it all…after 13 hrs at work (with occasional STing). :wink: and time to bug ST about today’s update as what’s in there for average users…