Simple App to put Thermostat in HOME or AWAY Mode Based on Motion Sensors


(Tuffcalc) #1

Here is a simple app that puts your thermostat in AWAY or HOME based on motion sensors and time delays.

Thanks to @copyninja for writting the iComfort app, and to @AaronZON who’s work this app is based on.

/**
 *  Put thermostat in away or home mode based on motion and time delay.
 *
 *   Written by Tuffcalc
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */

definition(
    name: "Thermostat (Away/Present on Motion)",
    namespace: "tuffcalc",
    author: "tuffcalc",
    description: "Thermostat (Away/Present on Motion)",
    category: "",
    iconUrl: "http://www.bayareaheatingandcooling.com/wp-content/uploads/2014/01/thermostat-icon-150x150.png",  
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
 


preferences {
	section("Select Motion Sensor(s) you want to use") {
        input "motions", "capability.motionSensor", title: "Motion Detector", required: true, multiple: true
	}
    section("Select Thermostat you want to use") {
        input "thermostat", "capability.thermostat", title: "Thermostat", required: false, multiple: true
	}
    
        input "DelayMinStr", "number", title: "Turn on AWAY mode after how many minutes?", required: true, 
        	defaultValue: "120"
        	
}
def installed() {
	log.debug "Installed with settings: ${settings}"

	initialize()
}

def updated() {
	log.debug "Updated with settings: ${settings}"

	unsubscribe()
	initialize()
}

def initialize() {
	log.debug "Initialize... starting app and setting mode as HOME."
   
    state.DelayMin = DelayMinStr
    state.Home=true
    thermostat?.present()

    subscribe(motions, "motion.active", handleMotionEvent)
    subscribe(motions, "motion.inactive", handleEndMotionEvent)

}


def handleMotionEvent(evt) {
	log.debug "Motion detected."

    unschedule(putAwayMode)

    if (state.Home) {
        log.debug "Thermostat already in HOME mode (do nothing)."
        }
    else {
    	   	thermostat?.present()
        	state.Home=true
        	log.debug "Putting thermostat in HOME mode."
        }
        
	}

def handleEndMotionEvent(evt) {
	log.debug "Motion stopped."

    if (state.Home) {
    	runIn((state.DelayMin*60), putAwayMode)
       }

}

def putAwayMode() {   

	log.debug "Putting thermostat in AWAY mode." 
    thermostat?.away()
    state.Home=false
}

(Tuffcalc) #2

Here is an updated version that also works with a contact sensor. Logic is as follows:

  1. If contact sensor is open, put system in AWAY mode (i.e., you have your patio door open) to save energy.
  2. If motion is detected and contact door is open, ignore and leave in away mode.
  3. If contact sensor is closed, put in home mode.
  4. If motion is sensed, put in home mode, put in away mode after X minutes when motion stops.

(Tuffcalc) #3
/**
 *  Put thermostat in away or home mode based on motion sensor and/or contact sensor
 *
 *   Written by Tuffcalc
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */

definition(
    name: "Thermostat (Away/Present on Motion or Contact)",
    namespace: "tuffcalc",
    author: "tuffcalc",
    description: "Thermostat (Away/Present on Motion or Contact)",
    category: "",
    iconUrl: "http://www.bayareaheatingandcooling.com/wp-content/uploads/2014/01/thermostat-icon-150x150.png",  
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
 


preferences {
	section("Select Motion Sensor(s) you want to use") {
        input "motions", "capability.motionSensor", title: "Motion Detector", required: false, multiple: true
	}
    section("Select Contact Sensor(s) you want to use") {
        input "contacts", "capability.contactSensor", title: "Contact Sensor", required: false, multiple: true
	}
    section("Select Thermostat you want to use") {
        input "thermostat", "capability.thermostat", title: "Thermostat", required: true, multiple: true
	}
    
        input "DelayMinStr", "number", title: "Turn on AWAY mode after how many minutes?", required: true, 
        	defaultValue: "120"
        	
}
def installed() {
	log.debug "Installed with settings: ${settings}"

	initialize()
}

def updated() {
	log.debug "Updated with settings: ${settings}"

	unsubscribe()
	initialize()
}

def initialize() {
	log.debug "Initialize..."
   
    state.DelayMin = DelayMinStr
    state.HomeMotion=true
    state.HomeContactOpen=false
    thermostat?.present()

    subscribe(motions, "motion.active", handleMotionEvent)
    subscribe(motions, "motion.inactive", handleEndMotionEvent)
	subscribe(contacts, "contact.open", ContactOpen)
    subscribe(contacts, "contact.closed", ContactClosed)

// contact closed - start
}


def ContactClosed(evt) {
	log.debug "Contact is closed."
            
    	   	thermostat?.present()
        	state.HomeContactOpen=false

        	log.debug "Putting thermostat in HOME mode because of Contact."
        
       
	}


// contact closed - end

// contact open - start
def ContactOpen(evt) {   
	
    log.debug "Door or Window is Open."
	log.debug "Putting thermostat in AWAY mode because of Contact." 
    thermostat?.away()
    state.HomeContactOpen=true
}
// contact open - end


def handleMotionEvent(evt) {
	log.debug "Motion detected."

    unschedule(putAwayMode)
    
    
    if (state.HomeContactOpen) {
        log.debug "Thermostat already in AWAY mode due to CONTACT (do nothing)."
        }
    else if (state.HomeMotion) {
        log.debug "Thermostat already in HOME mode due to MOTION (do nothing)."
        }
         else {
    	   	thermostat?.present()
        	state.HomeMotion=true
        	log.debug "Putting thermostat in HOME mode because of Motion."
        }
	}

def handleEndMotionEvent(evt) {
	log.debug "Motion stopped."
    log.debug "Start countdown timer to AWAY mode."

    if (state.HomeMotion) {
    	runIn((state.DelayMin*60), putAwayMode)
       }

}

def putAwayMode() {   

	log.debug "Putting thermostat in AWAY mode because of Motion delay." 
    thermostat?.away()
    state.HomeMotion=false
 }

(Rey Rios) #4

Anyone know how to modify this to only work from let’s say 9am to 5pm only?


(Mike) #5

I believe all of this (the app and your question about only doing it from 9to 5) can be done with the existing “Hello Home” functionality of SmartThings.

https://support.smartthings.com/hc/en-us/articles/200902220-Creatively-using-Hello-Home-phrases-and-modes


(Benson Wong) #6

Thanks! this is just what I was looking for… will see how it works out.

My Nest is in a hallway that only will sense me when I go to the bathroom basically. I have a motion sensor in my living room so this sounds ideal for me. Would also love to have the nest Temperature be based on my temperature sensor in my living room, or bed room, or average of the two. that’s for another day i suppose.


(Rey Rios) #7

@zj4x4 Thanks! I didn’t know I could do that with the Hello Home functionality. Works great!


#8

I’d like to use this with the ST modes … is there a way to do that (instead of contacts and sensors)?


(Mac Gregor Magruder) #9

This is exactly what I am looking for but when I run through the settings and click done it gives me an error “Failed to save page:Defaultpage”

Any pointers and thanks in advance for you assistance as I am new to this effort