Update to Nobody Home

I’ve had several users tell me that the “Nobody Home” app triggers events at the wrong time. I’ve checked in what I believe is a fix for these issues. If you’ve had trouble with mode changes using this app in the past, please test this out and let me know how it works for you:

@imbrian

Im having problems with my app i created from your base. If i could ask a huge favor and ask you to take a look at this code and see if you think anything is out of whack. I have implemented your latest change into my new code, so the sunset should be working. But for some reason smartthings is chanigng my mode to sunset around 9:30 in the morning when there is obviously sun out… kinda lost as what you do from here. Any help would be appreciated.

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 sunInfo = getSunriseAndSunset(zipCode: zip)
  def current = now()

  if(sunInfo.sunrise.time > current ||
     sunInfo.sunset.time  < current) {
    state.sunMode = newSunsetMode
  }

  else {
    state.sunMode = newSunriseMode
  }

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

  if(current < sunInfo.sunrise.time) {
    runIn(((sunInfo.sunrise.time - current) / 1000).toInteger(), setSunrise)
  }

  if(current < sunInfo.sunset.time) {
    runIn(((sunInfo.sunset.time - current) / 1000).toInteger(), setSunset)
  }

  schedule(timeTodayAfter(new Date(), "01:00", location.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)
}

@tslagle13 - can you provide a diff for your changes? I ran a diff locally, but I think the forum messed with some spacing and made it pretty unreadable.

Glancing through your code, I don’t see any significant changes - none that stand out that could cause issue.

You can try running the app in the IDE and see what times it prints for sunrise / sunset / current time. There’s a chance it thinks you’re in a (very) different timezone.

I’d also started putting in debug SMS messages when I was debugging, as I couldn’t monitor the IDE at all times. When a mode change occurred, it’d text me what it thought the times were so I could narrow down my search.

Awesome, thanks @imbrian! Good idea with the SMS debugging. I’ll give that a shot. I also just posted something in the General Forum about my zip and log times being way off… im thinking that is probably the culprit. Thanks a ton for the help. I’ll start with the SMS debugging and see where that goes. Funny thing is it only does this in the morning. all other events work fine.

Thanks man!