Sunset program does not trigger with "Before" offset

(MrPresident) #1

I have a smartapp that turns on a lamp at sunset. Problem is that I’ve defined a sunset offset of 02:00 hours before.
The smartapp works great in that it turns on at sunset, but does not factor in the offset. So for example, Sunset yesterday was at 4:31pm. The lamp turned on at precisely 4:31pm. however, The offset is set as 2 hours before so I would have expected the lamp to turn on at 2:31pm.

Surely I am doing something wrong in not factoring in the offset. Can someone please advise?

The code is attached. which is a hacked up version of sunrise/sunset provided in the IDE Examples.

Thanks in advance.

    name: "foyerLampSunset",
    namespace: "mlupo",
    author: "michael lupo",
    description: "Turn the foyer lamp on 1.5 hours before sunset and leave on till 11:59pm.",
    category: "Safety & Security",
    iconUrl: "",
    iconX2Url: "",
    iconX3Url: "")

preferences {
	section ("At sunset...") {
		input "sunsetMode", "mode", title: "Change mode to?", required: false
		input "foyerOutlet", "capability.switch", title: "Turn on?", required: false, multiple: true
    section ("Sunset offset (optional)...") {
		input "sunsetOffsetValue", "text", title: "HH:MM", required: false
		input "sunsetOffsetDir", "enum", title: "Before or After", required: false, options: ["Before","After"]
    //section ("How long to leave the light on for? MINUTES (ie. 90)") {
	//	input name: "minutes", title: "Minutes?", type: "number", multiple: false
    section("What time to turn the light off?") {
    	input "time1", "time", title: "When?", required: true
    section ("Zip code (optional, defaults to location coordinates)...") {
		input "zipCode", "text", required: false
	section( "Notifications" ) {
		input "sendPushMessage", "enum", title: "Send a push notification?", options: ["Yes", "No"], required: false
		input "phoneNumber", "phone", title: "Send a text message?", required: false

def installed() {

def updated() {
	//unschedule handled in astroCheck method

def initialize() {
	subscribe(location, "position", locationPositionChange)
	subscribe(location, "sunsetTime", sunriseSunsetTimeHandler)

def locationPositionChange(evt) {
	log.trace "locationChange()"

def sunriseSunsetTimeHandler(evt) {
	log.trace "sunriseSunsetTimeHandler()"

def astroCheck() {
    log.debug "sunsetOffset is: $sunsetOffset"
	def s = getSunriseAndSunset(zipCode: zipCode, sunriseOffset: sunriseOffset, sunsetOffset: sunsetOffset)
    def off = getSunriseAndSunset(zipCode: zipCode, sunriseOffset: sunriseOffset, sunsetOffset: sunsetOffset)
	def now = new Date()
	def sunsetTime = s.sunset
	log.debug "sunsetTime: $sunsetTime"
	if (state.sunsetTime != sunsetTime.time) {
		state.sunsetTime = sunsetTime.time

		if(sunsetTime.before(now)) {
		} "scheduling sunset handler for a sunset at: $sunsetTime"
		runDaily(sunsetTime, sunsetHandler)

def sunsetHandler() { "Executing sunset handler. Will turn off the outlet at 11:59pm."
	if (foyerOutlet) {

def changeMode(newMode) {
	if (newMode && location.mode != newMode) {
		if (location.modes?.find{ == newMode}) {
			send "${label} has changed the mode to '${newMode}'"
		else {
			send "${label} tried to change to undefined mode '${newMode}'"

private send(msg) {
	if ( sendPushMessage != "No" ) {
		log.debug( "sending push message" )
		sendPush( msg )

	if ( phoneNumber ) {
		log.debug( "sending text message" )
		sendSms( phoneNumber, msg )

	log.debug msg

private getLabel() {
	app.label ?: "SmartThings"

private getSunriseOffset() {
	log.debug "DEBUG: getting offset value"
	sunsetOffsetValue ? (sunsetOffsetDir == "Before" ? "-$sunsetOffsetValue" : sunsetOffsetValue) : null

def outletOff() {
    log.debug "called outletsOff() and delaying turning off the outlet till ${time1}"
    //log.debug "called outletsOff() and delaying turning off the outlet at 11:59pm"
    //schedule("00 59 23 * * ?", scheduledTurnOff)
    schedule(time1, scheduledTurnOff)

def scheduledTurnOff() {
	unschedule("scheduledTurnOff") // Temporary work-around to scheduling bug

(Eric R) #2

I see a few things that could be wrong. First, your getSunsetOffset() is actually getSunriseOffset(). Also, I don’t see that function called anywhere. I would expect the offset to happen after because you never check for the before in your code.

Also, to help with debugging, you can go to My Locations in the ide and click on smartapps. You can then see the status of the installed smartapp to see what time it is actually scheduling for.

(MrPresident) #3

Hi Eric,
Thanks for the reply. Sorry mine is so late. Busy weekend.

Anyway, I fixed the method name. But I don’t see where this method is even called (as you even stated). Even in the example sunrise/sunset app that is provided by ST, I don’t see where any either the getSunriseOffset or getSunsetOffset methods are even called. So it’s difficult to figure out what magic is going on behind the scenes…and how to apply that voodoo to my own smartapp.

Thanks for the dialog…

private getSunsetOffset() {
	sunsetOffsetValue ? (sunsetOffsetDir == "Before" ? "-$sunsetOffsetValue" : sunsetOffsetValue) : null

below is a copy of the settings that I see in the IDE. It still shows the incorrect scheduled runtime. Expected to see 2 Hours before sunset, What is see is precisely sunset.

Name Type Value
foyerOutlet capability.switch Foyer Outlet
phoneNumber phone
sendPushMessage enum Yes
sunsetMode mode ""
sunsetOffsetDir enum Before
sunsetOffsetValue 02:00

time1 time 11:59 PM EDT
zipCode 01234
Event Subscriptions
Name Handler Filter Source
position locationPositionChange true Reynolds (Location)
sunsetTime sunriseSunsetTimeHandler true Reynolds (Location)
Application State
Name Value
sunsetTime 1415654940000
Scheduled Jobs
Handler Next Run Time Prev Run Time Status Schedule
sunsetHandler 2014-11-11 4:29:00 PM EST 1969-12-31 6:59:59 PM EST WAITING 0 29 16 ? * * America/New_York
SmartApp Version foyerLampSunset
Development App True

(Eric R) #4

try adding def sunsetOffest = getSunsetOffset() before your def s = getSunriseAndSunset(zipCode: zipCode, sunriseOffset: sunriseOffset, sunsetOffset: sunsetOffset)