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")
165 log.debug "checking if everyone is away and quiet at home"
166 if (residentsHaveBeenQuiet()) {
168 if (everyoneIsAway()) {
170 send("AwayFromHome>Quiet at home...")
172 runIn(delay, "takeActions")
174 log.debug "Not everyone is away, doing nothing"
176 send("AwayFromHome>Not everyone is away, doing nothing..")
181 log.debug "Things are not quiet at home, doing nothing"
183 send("AwayFromHome>Things are not quiet at home...")
187 log.debug "Still present; doing nothing"
192 log.debug ("ecobeeAwayFromHome>location.mode= $location.mode, givenClimate
\7f=${givenClimateName}, about to takeAction")
199 Integer thresholdMinutes = 2 // check that the security alarm is close in a 2-minute delay
200 Integer delay = 60 * thresholdMinutes
201 def msg, minHeatTemp, minCoolTemp
203 def scale = getTemperatureScale()
205 minHeatTemp = givenHeatTemp ?: 14 // by default, 14°C is the minimum heat temp
206 minCoolTemp = givenCoolTemp ?: 27 // by default, 27°C is the minimum cool temp
208 minHeatTemp = givenHeatTemp ?: 60 // by default, 60°F is the minimum heat temp
209 minCoolTemp = givenCoolTemp ?: 80 // by default, 80°F is the minimum cool temp
211 // Making sure everybody is away and no motion at home
213 if (everyoneIsAway() && residentsHaveBeenQuiet()) {
214 send("AwayFromHome>Nobody is at home, and it's quiet, about to take actions")
215 if (alarmSwitch?.currentContact == "open") {
216 alarmSwitch.on() // arm the alarm system
218 log.debug "alarm is not set, arm it..."
222 if ((givenClimateName != null) && (givenClimateName != "")) {
224 it.setClimate('', givenClimateName) // Set to the climateName
228 // Set heating and cooling points at ecobee
230 it.setHold('', minCoolTemp, minHeatTemp, null, null)
234 msg = "AwayFromHome>${ecobee} thermostats' settings are now lower"
235 if (detailedNotif ) {
240 locks?.lock() // lock the locks
241 msg = "AwayFromHome>Locked the locks"
242 if ((locks) && (detailedNotif)) {
247 switches?.off() // turn off the lights
248 msg = "AwayFromHome>Switched off all switches"
249 if ((switches) && (detailedNotif)) {
255 cameras?.alarmOn() // arm the cameras
256 msg = "AwayFromHome>cameras are now armed"
257 if ((cameras) && (detailedNotif)) {
262 runIn(delay, "checkAlarmSystem", [overwrite: false]) // check that the alarm system is armed
269 private checkAlarmSystem() {
270 if (alarmSwitch.currentContact == "open") {
272 send("AwayFromHome>alarm still not activated,repeat...")
274 alarmSwitch.on() // try to arm the alarm system again
280 private everyoneIsAway() {
282 for (person in people) {
283 if (person.currentPresence == "present") {
288 log.debug "everyoneIsAway: $result"
292 private getPerson(evt) {
294 evt.deviceId == it.id
299 if (sendPushMessage != "No") {
300 log.debug("sending push message")
305 log.debug("sending text message")