3 * Copyright 2014 Yves Racine
4 * linkedIn profile: ca.linkedin.com/pub/yves-racine-m-sc-a/0/406/4b/
6 * Developer retains all right, title, copyright, and interest, including all copyright, patent rights, trade secret
7 * in the Background technology. May be subject to consulting fees under the Agreement between the Developer and the Customer.
8 * Developer grants a non exclusive perpetual license to use the Background technology in the Software developed for and delivered
9 * to Customer under this Agreement. However, the Customer shall make no commercial use of the Background technology without
10 * Developer's written consent.
12 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
13 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * Away from Home with Ecobee Thermostat
16 * Turn off the lights, turn on the security alarm, and lower the settings at ecobee when away from home
18 * Software Distribution is restricted and shall be done only with Developer's written approval.
20 * N.B. Requires MyEcobee device available at
21 * http://www.ecomatiqhomes.com/#!store/tc3yr
24 // Automatically generated. Make future change here.
26 name: "ecobeeAwayFromHome",
28 author: "Yves Racine",
29 description: "Away From Home",
31 iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee.png",
32 iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee@2x.png"
37 paragraph "ecobeeAwayFromHome, the smartapp that sets your ecobee thermostat to 'Away' or to some specific settings when all presences leave your home"
38 paragraph "Version 1.9.5"
39 paragraph "If you like this smartapp, please support the developer via PayPal and click on the Paypal link below "
40 href url: "https://www.paypal.me/ecomatiqhomes"
41 paragraph "Copyright©2014 Yves Racine"
42 href url:"http://github.com/yracine/device-type.myecobee", style:"embedded", required:false, title:"More information..."
43 description: "http://github.com/yracine/device-type.myecobee/blob/master/README.md"
45 section("When all of these people leave home") {
46 input "people", "capability.presenceSensor", multiple: true
48 section("And there is no motion at home on these sensors [optional]") {
49 input "motions", "capability.motionSensor", title: "Where?", multiple: true, required: false
51 section("Turn off these lights") {
52 input "switches", "capability.switch", title: "Switch", multiple: true, required: optional
54 section("And activate the alarm system [optional]") {
55 input "alarmSwitch", "capability.contactSensor", title: "Alarm Switch", required: false
57 section("Set the ecobee thermostat(s)") {
58 input "ecobee", "capability.thermostat", title: "Ecobee Thermostat(s)", multiple: true
60 section("Heating set Point for the thermostat [default = 60°F/14°C]") {
61 input "givenHeatTemp", "decimal", title: "Heat Temp", required: false
63 section("Cooling set Point for the thermostat [default = 80°F/27°C]") {
64 input "givenCoolTemp", "decimal", title: "Cool Temp", required: false
66 section("Or set the ecobee to this Climate Name (ex. Away)") {
67 input "givenClimateName", "text", title: "Climate Name", required: false
69 section("Lock these locks [optional]") {
70 input "locks", "capability.lock", title: "Locks?", required: false, multiple: true
72 section("Arm this(ese) camera(s) [optional]") {
73 input "cameras", "capability.imageCapture", title: "Cameras", multiple: true, required: false
75 section("Trigger these actions when home has been quiet for [default=3 minutes]") {
76 input "residentsQuietThreshold", "number", title: "Time in minutes", required: false
78 section("Notifications") {
79 input "sendPushMessage", "enum", title: "Send a push notification?", metadata: [values: ["Yes", "No"]], required: false
80 input "phone", "phone", title: "Send a Text Message?", required: false
82 section("Detailed Notifications") {
83 input "detailedNotif", "bool", title: "Detailed Notifications?", required: false
90 log.debug "Installed with settings: ${settings}"
91 log.debug "Current mode = ${location.mode}, people = ${people.collect{it.label + ': ' + it.currentPresence}}"
99 log.debug "Updated with settings: ${settings}"
100 log.debug "Current mode = ${location.mode}, people = ${people.collect{it.label + ': ' + it.currentPresence}}"
105 private initialize() {
106 subscribe(people, "presence", presence)
107 subscribe(alarmSwitch, "contact", alarmSwitchContact)
108 if (motions != null && motions != "") {
109 subscribe(motions, "motion", motionEvtHandler)
111 subscribe(app, appTouch)
115 def alarmSwitchContact(evt) {
116 log.info "alarmSwitchContact, $evt.name: $evt.value"
118 if ((alarmSwitch.currentContact == "closed") && residentsHaveBeenQuiet() && everyoneIsAway()) {
120 send("AwayFromHome>alarm system just armed, take actions")
122 log.debug "alarm is armed, nobody at home"
128 def motionEvtHandler(evt) {
129 if (evt.value == "active") {
130 state.lastIntroductionMotion = now()
131 log.debug "Motion at home..."
136 private residentsHaveBeenQuiet() {
138 def threshold = residentsQuietThreshold ?: 3 // By default, the delay is 3 minutes
139 Integer delay = threshold * 60
142 def t0 = new Date(now() - (threshold * 60 * 1000))
143 for (sensor in motions) {
144 def recentStates = sensor.statesSince("motion", t0)
145 if (recentStates.find {it.value == "active"}) {
150 log.debug "residentsHaveBeenQuiet: $result"
156 def threshold = residentsQuietThreshold ?: 3 // By default, the delay is 3 minutes
157 Integer delay = threshold * 60
159 log.debug "$evt.name: $evt.value"
160 if (evt.value == "not present") {
161 def person = getPerson(evt)
163 //send("AwayFromHome> ${person.displayName} not present at home")
164 send("AwayFromHome> person not present at home")
166 log.debug "checking if everyone is away and quiet at home"
167 if (residentsHaveBeenQuiet()) {
169 if (everyoneIsAway()) {
171 send("AwayFromHome>Quiet at home...")
173 runIn(delay, "takeActions")
175 log.debug "Not everyone is away, doing nothing"
177 send("AwayFromHome>Not everyone is away, doing nothing..")
182 log.debug "Things are not quiet at home, doing nothing"
184 send("AwayFromHome>Things are not quiet at home...")
188 log.debug "Still present; doing nothing"
193 log.debug ("ecobeeAwayFromHome>location.mode= $location.mode, givenClimate
\7f=${givenClimateName}, about to takeAction")
200 Integer thresholdMinutes = 2 // check that the security alarm is close in a 2-minute delay
201 Integer delay = 60 * thresholdMinutes
202 def msg, minHeatTemp, minCoolTemp
204 def scale = getTemperatureScale()
206 minHeatTemp = givenHeatTemp ?: 14 // by default, 14°C is the minimum heat temp
207 minCoolTemp = givenCoolTemp ?: 27 // by default, 27°C is the minimum cool temp
209 minHeatTemp = givenHeatTemp ?: 60 // by default, 60°F is the minimum heat temp
210 minCoolTemp = givenCoolTemp ?: 80 // by default, 80°F is the minimum cool temp
212 // Making sure everybody is away and no motion at home
214 if (everyoneIsAway() && residentsHaveBeenQuiet()) {
215 send("AwayFromHome>Nobody is at home, and it's quiet, about to take actions")
216 if (alarmSwitch?.currentContact == "open") {
217 alarmSwitch.on() // arm the alarm system
219 log.debug "alarm is not set, arm it..."
223 if ((givenClimateName != null) && (givenClimateName != "")) {
225 it.setClimate('', givenClimateName) // Set to the climateName
229 // Set heating and cooling points at ecobee
231 it.setHold('', minCoolTemp, minHeatTemp, null, null)
235 msg = "AwayFromHome>${ecobee} thermostats' settings are now lower"
236 if (detailedNotif ) {
241 locks?.lock() // lock the locks
242 msg = "AwayFromHome>Locked the locks"
243 if ((locks) && (detailedNotif)) {
248 switches?.off() // turn off the lights
249 msg = "AwayFromHome>Switched off all switches"
250 if ((switches) && (detailedNotif)) {
256 cameras?.alarmOn() // arm the cameras
257 msg = "AwayFromHome>cameras are now armed"
258 if ((cameras) && (detailedNotif)) {
263 runIn(delay, "checkAlarmSystem", [overwrite: false]) // check that the alarm system is armed
270 private checkAlarmSystem() {
271 if (alarmSwitch.currentContact == "open") {
273 send("AwayFromHome>alarm still not activated,repeat...")
275 alarmSwitch.on() // try to arm the alarm system again
281 private everyoneIsAway() {
283 for (person in people) {
284 if (person.currentPresence == "present") {
289 log.debug "everyoneIsAway: $result"
293 private getPerson(evt) {
295 evt.deviceId == it.id
300 if (sendPushMessage != "No") {
301 log.debug("sending push message")
306 log.debug("sending text message")