Update thermostat-mode-director.groovy
[smartapps.git] / official / nobody-home.groovy
1 /**
2  *  Nobody Home
3  *
4  *  Author: brian@bevey.org
5  *  Date: 12/19/14
6  *
7  *  Monitors a set of presence detectors and triggers a mode change when everyone has left.
8  *  When everyone has left, sets mode to a new defined mode.
9  *  When at least one person returns home, set the mode back to a new defined mode.
10  *  When someone is home - or upon entering the home, their mode may change dependent on sunrise / sunset.
11  */
12
13 definition(
14   name: "Nobody Home",
15   namespace: "imbrianj",
16   author: "brian@bevey.org",
17   description: "When everyone leaves, change mode.  If at least one person home, switch mode based on sun position.",
18   category: "Mode Magic",
19   iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
20   iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png"
21 )
22
23 preferences {
24   section("When all of these people leave home") {
25     input "people", "capability.presenceSensor", multiple: true
26   }
27
28   section("Change to this mode to...") {
29     input "newAwayMode",    "mode", title: "Everyone is away"
30     input "newSunsetMode",  "mode", title: "At least one person home and nightfall"
31     input "newSunriseMode", "mode", title: "At least one person home and sunrise"
32   }
33
34   section("Away threshold (defaults to 10 min)") {
35     input "awayThreshold", "decimal", title: "Number of minutes", required: false
36   }
37
38   section("Notifications") {
39     input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
40   }
41 }
42
43 def installed() {
44   init()
45 }
46
47 def updated() {
48   unsubscribe()
49   init()
50 }
51
52 def init() {
53   subscribe(people,   "presence", presence)
54   subscribe(location, "sunrise",  setSunrise)
55   subscribe(location, "sunset",   setSunset)
56
57   state.sunMode = location.mode
58 }
59
60 def setSunrise(evt) {
61   changeSunMode(newSunriseMode)
62 }
63
64 def setSunset(evt) {
65   changeSunMode(newSunsetMode)
66 }
67
68 def changeSunMode(newMode) {
69   state.sunMode = newMode
70
71   if(everyoneIsAway() && (location.mode == newAwayMode)) {
72     log.debug("Mode is away, not evaluating")
73   }
74
75   else if(location.mode != newMode) {
76     def message = "${app.label} changed your mode to '${newMode}'"
77     send(message)
78     setLocationMode(newMode)
79   }
80
81   else {
82     log.debug("Mode is the same, not evaluating")
83   }
84 }
85
86 def presence(evt) {
87   if(evt.value == "not present") {
88     log.debug("Checking if everyone is away")
89
90     if(everyoneIsAway()) {
91       log.info("Starting ${newAwayMode} sequence")
92       def delay = (awayThreshold != null && awayThreshold != "") ? awayThreshold * 60 : 10 * 60
93       runIn(delay, "setAway")
94     }
95   }
96
97   else {
98     if(location.mode != state.sunMode) {
99       log.debug("Checking if anyone is home")
100
101       if(anyoneIsHome()) {
102         log.info("Starting ${state.sunMode} sequence")
103
104         changeSunMode(state.sunMode)
105       }
106     }
107
108     else {
109       log.debug("Mode is the same, not evaluating")
110     }
111   }
112 }
113
114 def setAway() {
115   if(everyoneIsAway()) {
116     if(location.mode != newAwayMode) {
117       def message = "${app.label} changed your mode to '${newAwayMode}' because everyone left home"
118       log.info(message)
119       send(message)
120       setLocationMode(newAwayMode)
121     }
122
123     else {
124       log.debug("Mode is the same, not evaluating")
125     }
126   }
127
128   else {
129     log.info("Somebody returned home before we set to '${newAwayMode}'")
130   }
131 }
132
133 private everyoneIsAway() {
134   def result = true
135
136   if(people.findAll { it?.currentPresence == "present" }) {
137     result = false
138   }
139
140   log.debug("everyoneIsAway: ${result}")
141
142   return result
143 }
144
145 private anyoneIsHome() {
146   def result = false
147
148   if(people.findAll { it?.currentPresence == "present" }) {
149     result = true
150   }
151
152   log.debug("anyoneIsHome: ${result}")
153
154   return result
155 }
156
157 private send(msg) {
158   if(sendPushMessage != "No") {
159     log.debug("Sending push message")
160     sendPush(msg)
161   }
162
163   log.debug(msg)
164 }