Nobody Home + Sunrise / Sunset


(Im Brian) #1

I updated nobody_home to support sunrise and sunset times to trigger mode changes. I think @dawz2 wanted something like this.


(Jam Dawz) #2

Looks promising!

So, is this how it works?

If a list of people all leave, the mode is set to X. If any one of them return and it is after sunrise, but before sunset, the mode is set to Y. If any one of them return and it is after sunset, the mode is set to Z.

If this works, it is one of the apps I’ve been needing!! Excellent!


(Im Brian) #3

That’s how it’s supposed to work. There may be some bugs - let me know if you have issue.


(Jam Dawz) #4

Unfortunately, it didn’t work.

I had it set to change to mode “Away” when everyone is away, to mode “Night” when at least one person home and nightfall and to mode “Home” when at least one person home and sunrise.

The mode was set to “Away” when my wife returned home this afternoon at 1:30. The app changed to mode to “Night”.


(Im Brian) #5

Thanks for the update - I’ll look into this tonight and try and get it working for you. Thanks for being the guinea pig.


(Im Brian) #6

Tested out and I think I’ve got it now. If you see any issue or have any feature requests, just let me know.


(Jam Dawz) #7

Hey, I’m just glad you’re willing to help the slow kid! New version installed. Will follow up with results.


(Jam Dawz) #8

24 hours later and the app is operating perfectly! Again, THANK YOU for the work you put into this app!


(Im Brian) #9

Good to hear - just let me know if you run into trouble. Truth be told, I did it selfishly - I need some of this functionality, too!


(Jam Dawz) #10

@ImBrian
I don’t suppose you could help me with another? I want to be able to switch modes with the touch of a momentary push button in the app. I have the virtual button setup and I tried to modify an app to change modes when the momentary switch was pushed. I’m stuck!


(Im Brian) #11

Which mode would it switch to? You can already quickly switch to any given mode in the side menu, what would make this easier?


(Jam Dawz) #12

Trying to make things easier on my wife by placing a button right on the app home screen! I think I’ve got it figured out tho.


(Avery) #13

Hey there - this might be a silly question, but could I do this with your app:

If it’s sunset and nobody is home, turn on a light; if someone is home, do nothing
If it’s after sunset and everybody leaves, turn on a light; if it is before sunset, do nothing
If someone returns home, turn off that light
If it’s sunrise, turn off that light

Basically, it would have a light come on at sunset or if everyone leaves the house after dark, but turn off when someone comes home or at sunrise.

Thanks!


(Im Brian) #14

@amglasser - The app is meant to be do a simple task that can be leveraged by other apps. I’m trying to follow the Unix mantra:

The Unix philosophy emphasizes building short, simple, clear, modular, and extendable code that can be easily maintained and repurposed by developers other than its creators

SmartThings has provided that “extendable” portion by way of modes. You can install existing apps to do most of what you want - having them installed under specific modes.


(Tim Slagle) #15

First of all BIG thanks to @imbrian for providing the base of the code. I am just learning Groovy so im not a pro yet, and my code may be a little dirty. Please don’t castrate me. :slight_smile:

@amglasser - I took it upon myself to modify ImBrians code for myself to include the option to have it change for away and home mode and both of those modes have sunrise and sunset modes. So this allows you to leave the house during the day and not turn on any lights but change the thermostat. But when i leave at night certain lights turn on and the thermostat changes. This also applies for the present modes. I use the “Make it so” app to make these changes when the different modes change.

Also, @imbrian. If you want me to take this down for whatever reason let me know.

Before using this please rememebr that i am not familiar enough with Groovy to guarantee my work. If something isn’t working i can try and take a look at it. But as of now this code comes as-is.

Here is my code:

preferences {
  section("When all of these people leave home") {
    input "people", "capability.presenceSensor", multiple: true
  }

  section("Change to this mode to...") {
    input "newSunsetModeAway",    "mode", title: "Everyone is away and Night"
    input "newSunriseModeAway",    "mode", title: "Everyone is away and Day"
    input "newSunsetMode",  "mode", title: "At least one person home and Night"
    input "newSunriseMode", "mode", title: "At least one person home and Day"
  }

  section("False alarm threshold (defaults to 10 min)") {
    input "falseAlarmThreshold", "decimal", title: "Number of minutes", required: false
  }

  section("Zip code (for sunrise/sunset)") {
    input "zip", "decimal", required: false
  }

  section("Notifications") {
    input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
  }
}

def installed() {
  init()
}

def updated() {
  unsubscribe()
  init()
}

def init() {
  subscribe(people, "presence", presence)

  checkSun();
}

def checkSun() {
  def zip            = settings.zip as String
  def locale         = getWeatherFeature("geolookup", zip)
  def timezone       = TimeZone.getTimeZone(locale.location.tz_long)
  def weather        = getWeatherFeature("astronomy", zip)

  def sunriseCompare = (weather.moon_phase.sunrise.hour      + weather.moon_phase.sunrise.minute).toInteger()
  def sunsetCompare  = (weather.moon_phase.sunset.hour       + weather.moon_phase.sunset.minute).toInteger()
  def currentCompare = (weather.moon_phase.current_time.hour + weather.moon_phase.current_time.minute).toInteger()

  def sunrise        = weather.moon_phase.sunrise.hour       + ":" + weather.moon_phase.sunrise.minute
  def sunset         = weather.moon_phase.sunset.hour        + ":" + weather.moon_phase.sunset.minute
  def current        = weather.moon_phase.current_time.hour  + ":" + weather.moon_phase.current_time.minute

  if(sunriseCompare > currentCompare ||
     sunsetCompare  < currentCompare) {
    state.sunMode = newSunsetMode
  }

  else {
    state.sunMode = newSunriseMode
  }

  log.info("Sunset: ${sunset}")
  log.info("Sunrise: ${sunrise}")
  log.info("Current: ${current}")
  log.info("sunMode: ${state.sunMode}")

  schedule(timeToday(sunrise, timezone), setSunrise)
  schedule(timeToday(sunset,  timezone), setSunset)
  schedule(timeTodayAfter(new Date(), "01:00", timezone), checkSun)
}

def setSunrise() {
  changeSunMode(newSunriseMode);
}

def setSunset() {
  changeSunMode(newSunsetMode);
}

def changeSunMode(newMode) {
  state.sunMode = newMode

  if(everyoneIsAway() && (location.mode == newSunsetModeAway)) {
    log.debug("Home is Empty  Setting New Away Mode")
    def delay = (falseAlarmThreshold != null && falseAlarmThreshold != "") ? falseAlarmThreshold * 60 : 10 * 60 
    runIn(delay, "setAway")
  }

  if(everyoneIsAway() && (location.mode == newSunriseModeAway)) {
    log.debug("Home is Empty  Setting New Away Mode")
    def delay = (falseAlarmThreshold != null && falseAlarmThreshold != "") ? falseAlarmThreshold * 60 : 10 * 60 
    runIn(delay, "setAway")
  }
  
  if(location.mode != newMode) {
    def message = "${app.label} changed your mode to '${newMode}'"
    log.debug("Setting New Home Mode")
    send(message)
    setLocationMode(newMode)
  }

  else {
    log.debug("Mode is the same, not evaluating")
  }
}

def presence(evt) {
  if(evt.value == "not present") {
    log.debug("Checking if everyone is away")

    if(everyoneIsAway()) {
      log.info("Starting away mode sequence")
      def delay = (falseAlarmThreshold != null && falseAlarmThreshold != "") ? falseAlarmThreshold * 60 : 10 * 60 
      runIn(delay, "setAway")
    }
  }

  else {
    if(location.mode != state.sunMode) {
      log.debug("Checking if anyone is home")

      if(anyoneIsHome()) {
        log.info("Starting ${state.sunMode} sequence")

        changeSunMode(state.sunMode)
      }
    }

    else {
      log.debug("Mode is the same, not evaluating")
    }
  }
}

def setAway() {
  if(everyoneIsAway()) {
    if(state.sunMode == newSunriseMode) {
      def message = "SmartThings changed your mode to '${newSunriseModeAway}' because everyone left home"
      log.info(message)
      send(message)
      setLocationMode(newSunriseModeAway)
    }
    
    else if(state.sunMode == newSunsetMode) {
      def message = "SmartThings changed your mode to '${newSunsetModeAway}' because everyone left home"
      log.info(message)
      send(message)
      setLocationMode(newSunsetModeAway)
    }
    
    else {
      log.debug("Mode is the same, not evaluating")
    }
  }

  else {
    log.info("Somebody returned home before we set to '${newAwayMode}'")
  }
}

private everyoneIsAway() {
  def result = true

  if(people.findAll { it?.currentPresence == "present" }) {
    result = false
  }

  log.debug("everyoneIsAway: ${result}")

  return result
}

private anyoneIsHome() {
  def result = false

  if(people.findAll { it?.currentPresence == "present" }) {
    result = true
  }

  log.debug("anyoneIsHome: ${result}")

  return result
}

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

  log.debug(msg)
}

(Im Brian) #16

@tslagle13 - looks good! Where did you get the source for my version of nobody_home? It looks like you have a (slightly) older version that checks the weather once a day to determine sunrise and sunset times. This works totally fine - I have a slightly updated version that calculates these times based on location without needing to do that query. It’s of no substantive difference aside from being kind to wunderground and not wasting the once-a-day API requests.

Current version here - I’ve been using it, but that doesn’t mean there aren’t any bugs:


(Jam Dawz) #17

@ImBrian
Been experiencing issues with this app since Saturday. Isn’t recognizing sunrise at all. Is this an app issue or has SmartThings gone wonky again?!


(Im Brian) #18

I haven’t experienced issues with this, but have heard several reports of issues. I may chalk this up to getSunriseAndSunset() choking (or my lack of understanding of it).

You can try an older version that just grabs sunset/sunrise info from the weather API polled once a day:

Let me know if this works out for you.


(Jam Dawz) #19

Thank you, I’ll give it a go. I’ve been using your code for awhile and it was working fine until this weekend! I follow-up with results.


(Jam Dawz) #20

The changes worked like a charm! Back in business!