[RELEASE] 5-2 Day Programmable Thermostat Scheduler (Weekday, Weekend) with Remote Temperature Sensor for each Schedule

climatecontrol
temperature
thermostat
smartapp_hvac
project_secondhome

(www.rboyapps.com - Make your home your butler!) #1

This code below is for a basic 5-2 Day Programmable Thermostat (Weekday and Weekend) with 4 programmable timers for each day.

The Advanced version of this app includes using a Remote Temperature Sensor (e.g. different room) to control the thermostat.
NOTE: Please note if you're using an external temperature sensor with the SmartApp, it will set the thermostat to 90F for heating and 50F for cooling until the external sensor temperature indicates that the desired temperature has been achieved after which they will be reversed to turn it off. This is normal behavior.

The Advanced version of this app is available on the RBoy server at http://smartthings.rboyapps.com. Refer to our Facebook page to get access to the server.

If you like the App consider supporting our development efforts. Visit our Facebook page to updates on new apps and to get Access to all our Premium Apps Server. http://www.facebook.com/RBoySTApps

On a separate thread I've also written an app for a 7-day Unlimited customizable thermostat.

BASIC 5-2 DAY PROGRAMMABLE THERMOSTAT SCHEDULER (without Remote Temperature Sensor)

/* **DISCLAIMER**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * Without limitation of the foregoing, Contributors/Regents expressly does not warrant that:
 * 1. the software will meet your requirements or expectations;
 * 2. the software or the software content will be free of bugs, errors, viruses or other defects;
 * 3. any results, output, or data provided through or generated by the software will be accurate, up-to-date, complete or reliable;
 * 4. the software will be compatible with third party software;
 * 5. any errors in the software will be corrected.
 * The user assumes all responsibility for selecting the software and for the results obtained from the use of the software. The user shall bear the entire risk as to the quality and the performance of the software.
 */ 
 
/**
 *  5-2 Day Thermostat
 *
 * Base code from mwoodengr@hotmail.com, bugfixed and enhanced by RBoy
 * Changes Copyright RBoy, redistribution of any changes or modified code is not allowed without permission
 * Version 2.1.0
 * 2015-10-3 - Fixed an issue with selecting multiple thermostats and for recent platform changes
 * 2015-5-17 - Added ability to select mutiple thermostats simultaneously
 * 2015-2-11 - Fixed issue with fan mode
 *
 */
definition(
		name: "5-2 Day Thermostat",
		namespace: "rboy",
		author: "RBoy",
		description: "Weekday and Weekend Thermostat",
    	category: "Green Living",
    	iconUrl: "https://s3.amazonaws.com/smartapp-icons/GreenLiving/Cat-GreenLiving.png",
    	iconX2Url: "https://s3.amazonaws.com/smartapp-icons/GreenLiving/Cat-GreenLiving@2x.png",
    	iconX3Url: "https://s3.amazonaws.com/smartapp-icons/GreenLiving/Cat-GreenLiving@3x.png")

preferences {
	section("Choose thermostat (s)") {
		input "thermostats", "capability.thermostat", required: true, multiple:true
	}

    section("Switch HVAC mode (auto to cool/heat) based on the outside temperature (optional)") {
		input "temperatureSensor", "capability.temperatureMeasurement", required: false
		input "temperatureH", "number", title: "Switch to heating temperature", required: false, description: "Temperature below which switch to heat mode"
		input "temperatureC", "number", title: "Switch to cooling temperature", required: false, description: "Temperature above which switch to cool mode"
	}

	section("Monday to Friday Schedule") {
		input "time1", "time", title: "Wake Time", required: true
		input "tempSetpoint1", "number", title: "Wake Heat Temp", required: true
		input "tempSetpointA", "number", title: "Wake Cool Temp", required: true
		input "time2", "time", title: "Leave Time", required: true
		input "tempSetpoint2", "number", title: "Leave Heat Temp", required: true
		input "tempSetpointB", "number", title: "Leave Cool Temp", required: true
		input "time3", "time", title: "Return Time", required: true
		input "tempSetpoint3", "number", title: "Return Heat Temp", required: true
		input "tempSetpointC", "number", title: "Return Cool Temp", required: true
		input "time4", "time", title: "Sleep Time", required: true
		input "tempSetpoint4", "number", title: "Sleep Heat Temp", required: true
		input "tempSetpointD", "number", title: "Sleep Cool Temp", required: true
	}
	section("Saturday and Sunday Schedule") {
		input "time11", "time", title: "Wake Time", required: true
		input "tempSetpoint11", "number", title: "Wake Heat Temp", required: true
		input "tempSetpointAA", "number", title: "Wake Cool Temp", required: true
		input "time21", "time", title: "Leave Time", required: true
		input "tempSetpoint21", "number", title: "Leave Heat Temp", required: true
		input "tempSetpointBB", "number", title: "Leave Cool Temp", required: true
		input "time31", "time", title: "Return Time", required: true
		input "tempSetpoint31", "number", title: "Return Heat Temp", required: true
		input "tempSetpointCC", "number", title: "Return Cool Temp", required: true
		input "time41", "time", title: "Sleep Time", required: true
		input "tempSetpoint41", "number", title: "Sleep Heat Temp", required: true
		input "tempSetpointDD", "number", title: "Sleep Cool Temp", required: true
	}
}

def installed()
{
	subscribeToEvents()
}

def updated()
{
    unsubscribe()
	subscribeToEvents()
}

def subscribeToEvents() {
	subscribe(temperatureSensor, "temperature", temperatureHandler)
    subscribe(location, modeChangeHandler)

    initialize()
}

// Handle mode changes, reinitialize the current temperature and timers after a mode change, this is to workaround the issue of the last timer firing while in a non running mode, resume operations when supported modes are set
def modeChangeHandler(evt) {
	log.debug "Reinitializing thermostats on mode change notification, new mode $evt.value"
	//sendNotificationEvent("$thermostats Reinitializing on mode change notification, new mode $evt.value")
    initialize()
}

// This section sets the HVAC mode based outside temperature. HVAC fan mode is set to "auto".
def temperatureHandler(evt) {
	log.debug "Heat mode switch temperature $temperatureH, cool mode switch temperature $temperatureC"
    
	if (temperatureH == null || temperatureC == null) { // We are in Auto mode or user doesn't want us to switch modes
		return
	}
	
    thermostats.each { thermostat ->
        def extTemp = temperatureSensor.currentTemperature
        log.debug "External temperature is: $extTemp"
        def thermostatState = thermostat.currentThermostatMode
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "HVAC current mode $thermostatState"
        log.debug "HVAC Fan current mode $thermostatFan"
        if (extTemp < temperatureH) {
            if (thermostatState == "cool") {
                def hvacmode = "heat"
                thermostat.setThermostatMode(hvacmode)
                log.debug "HVAC mode set to $hvacmode"
            }
        }
        else if (extTemp > temperatureC) {
            if (thermostatState == "heat") {
                def hvacmode = "cool"
                thermostat.setThermostatMode(hvacmode)
                log.debug "HVAC mode set to $hvacmode"
            }
        }

        if (thermostatFan != "fanAuto") {
            thermostat.setThermostatFanMode("auto")
            log.debug "HVAC fan mode set to auto"
        }
    }
}

// This section determines which day it is.
def initialize() {
	log.trace "Initialized with $settings"

	unschedule()
	def calendar = Calendar.getInstance()
	calendar.setTimeZone(location.timeZone)
	def today = calendar.get(Calendar.DAY_OF_WEEK)
   	def timeNow = now()
	def midnightToday = timeToday("2000-01-01T23:59:59.999-0000", location.timeZone)
   	log.debug("Current time is ${(new Date(timeNow)).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
	log.debug("Midnight today is ${midnightToday.format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
   	log.trace("Weekday schedule1 ${timeToday(time1, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekday schedule2 ${timeToday(time2, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekday schedule3 ${timeToday(time3, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekday schedule4 ${timeToday(time4, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekend schedule1 ${timeToday(time11, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekend schedule2 ${timeToday(time21, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekend schedule3 ${timeToday(time31, location.timeZone).format("HH:mm z", location.timeZone)}")
   	log.trace("Weekend schedule4 ${timeToday(time41, location.timeZone).format("HH:mm z", location.timeZone)}")

	// This section is where the time/temperature schedule is set
	switch (today) {
		case Calendar.MONDAY:
		case Calendar.TUESDAY:
		case Calendar.WEDNESDAY:
		case Calendar.THURSDAY:
        	if (timeNow >= timeToday(time1, location.timeZone).time && timeNow < timeToday(time2, location.timeZone).time) { // Are we between 1st time and 2nd time
        		changeTemp1()
            	schedule(timeToday(time2, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time2, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time2, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
        	}
        	else if (timeNow >= timeToday(time2, location.timeZone).time && timeNow < timeToday(time3, location.timeZone).time) { // Are we between 2nd time and 3rd time
            	changeTemp2()
				schedule(timeToday(time3, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time3, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time3, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time3, location.timeZone).time && timeNow < timeToday(time4, location.timeZone).time) { // Are we between 3rd time and 4th time
            	changeTemp3()
				schedule(timeToday(time4, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time4, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time4, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time4, location.timeZone).time && timeNow < midnightToday.time) { // Are we between 4th time and midnight, schedule next day
            	changeTemp4()
				schedule(timeToday(time1, location.timeZone) + 1, initialize)
                log.info("$thermostats Scheduled next adjustment for ${(timeToday(time1, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${(timeToday(time1, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= (midnightToday - 1).time && timeNow < timeToday(time1, location.timeZone).time) { // Are we between midnight yesterday and 1st time, schedule today
            	changeTemp4()
				schedule(timeToday(time1, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time1, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time1, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
			break
			
		case Calendar.FRIDAY:
        	if (timeNow >= timeToday(time1, location.timeZone).time && timeNow < timeToday(time2, location.timeZone).time) { // Are we between 1st time and 2nd time
        		changeTemp1()
            	schedule(timeToday(time2, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time2, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time2, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
        	}
        	else if (timeNow >= timeToday(time2, location.timeZone).time && timeNow < timeToday(time3, location.timeZone).time) { // Are we between 2nd time and 3rd time
            	changeTemp2()
				schedule(timeToday(time3, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time3, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time3, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time3, location.timeZone).time && timeNow < timeToday(time4, location.timeZone).time) { // Are we between 3rd time and 4th time
            	changeTemp3()
				schedule(timeToday(time4, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time4, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time4, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time4, location.timeZone).time && timeNow < midnightToday.time) { // Are we between 4th time Friday and midnight, we schedule Saturday
            	changeTemp4()
				schedule(timeToday(time11, location.timeZone) + 1, initialize)
                log.info("$thermostats Scheduled next adjustment for ${(timeToday(time11, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${(timeToday(time11, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= (midnightToday - 1).time && timeNow < timeToday(time11, location.timeZone).time) { // Are we between midnight Friday and 1st time on Saturday, we schedule Saturday
            	changeTemp4()
				schedule(timeToday(time11, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time11, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time11, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
			break

		case Calendar.SATURDAY:
            if (timeNow >= timeToday(time11, location.timeZone).time && timeNow < timeToday(time21, location.timeZone).time) { // Are we between 1st time and 2nd time
        		changeTemp11()
            	schedule(timeToday(time21, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time21, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time21, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
        	}
        	else if (timeNow >= timeToday(time21, location.timeZone).time && timeNow < timeToday(time31, location.timeZone).time) { // Are we between 2nd time and 3rd time
            	changeTemp21()
				schedule(timeToday(time31, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time31, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time31, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time31, location.timeZone).time && timeNow < timeToday(time41, location.timeZone).time) { // Are we between 3rd time and 4th time
            	changeTemp31()
				schedule(timeToday(time41, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time41, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time41, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time41, location.timeZone).time && timeNow < midnightToday.time) { // Are we between 4th time and midnight, schedule the next day
            	changeTemp41()
				schedule(timeToday(time11, location.timeZone) + 1, initialize)
                log.info("$thermostats Scheduled next adjustment for ${(timeToday(time11, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${(timeToday(time11, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= (midnightToday - 1).time && timeNow < timeToday(time11, location.timeZone).time) { // Are we between midnight yesterday and 1st time, schedule today
            	changeTemp41()
				schedule(timeToday(time11, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time11, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time11, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
			break
            
		case Calendar.SUNDAY:
            if (timeNow >= timeToday(time11, location.timeZone).time && timeNow < timeToday(time21, location.timeZone).time) { // Are we between 1st time and 2nd time
        		changeTemp11()
            	schedule(timeToday(time21, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time21, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time21, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
        	}
        	else if (timeNow >= timeToday(time21, location.timeZone).time && timeNow < timeToday(time31, location.timeZone).time) { // Are we between 2nd time and 3rd time
            	changeTemp21()
				schedule(timeToday(time31, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time31, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time31, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time31, location.timeZone).time && timeNow < timeToday(time41, location.timeZone).time) { // Are we between 3rd time and 4th time
            	changeTemp31()
				schedule(timeToday(time41, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time41, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time41, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= timeToday(time41, location.timeZone).time && timeNow < midnightToday.time) { // Are we between 4th time Sunday and midnight, we schedule Monday
            	changeTemp41()
				schedule(timeToday(time1, location.timeZone) + 1, initialize)
                log.info("$thermostats Scheduled next adjustment for ${(timeToday(time1, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${(timeToday(time1, location.timeZone) + 1).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
            else if (timeNow >= (midnightToday - 1).time && timeNow < timeToday(time1, location.timeZone).time) { // Are we between midnight Sunday and 1st time on Monday, we schedule Monday
            	changeTemp41()
				schedule(timeToday(time1, location.timeZone), initialize)
                log.info("$thermostats Scheduled next adjustment for ${timeToday(time1, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
                //sendNotificationEvent("$thermostats Scheduled next adjustment for ${timeToday(time1, location.timeZone).format("EEE MMM dd yyyy HH:mm z", location.timeZone)}")
            }
			break
	}
}

// This section is where the thermostat temperature settings are set. 
def changeTemp1() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint1)
            thermostat.setCoolingSetpoint(tempSetpointA)
            log.info "Set $thermostat Heat $tempSetpoint1°, Cool $tempSetpointA°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint1)
            log.info "Set $thermostat Heat $tempSetpoint1°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointA)
            log.info "Set $thermostat Cool $tempSetpointA°"
        }
    }
}

def changeTemp2() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint2)
            thermostat.setCoolingSetpoint(tempSetpointB)
            log.info "Set $thermostat Heat $tempSetpoint2°, Cool $tempSetpointB°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint2)
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointB)
        }
    }
}

def changeTemp3() {
    thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint3)
            thermostat.setCoolingSetpoint(tempSetpointC)
            log.info "Set $thermostat Heat $tempSetpoint3°, Cool $tempSetpointC°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint3)
            log.info "Set $thermostat Heat $tempSetpoint3°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointC)
            log.info "Set $thermostat Cool $tempSetpointC°"
        }
    }
}

def changeTemp4() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint4)
            thermostat.setCoolingSetpoint(tempSetpointD)
            log.info "Set $thermostat Heat $tempSetpoint4°, Cool $tempSetpointD°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint4)
            log.info "Set $thermostat Heat $tempSetpoint4°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointD)
            log.info "Set $thermostat Cool $tempSetpointD°"
        }
    }
}

def changeTemp11() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint11)
            thermostat.setCoolingSetpoint(tempSetpointAA)
            log.info "Set $thermostat Heat $tempSetpoint11°, Cool $tempSetpointAA°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint11)
            log.info "Set $thermostat Heat $tempSetpoint11°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointAA)
            log.info "Set $thermostat Cool $tempSetpointAA°"
        }
    }
}

def changeTemp21() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint21)
            thermostat.setCoolingSetpoint(tempSetpointBB)
            log.info "Set $thermostat Heat $tempSetpoint21°, Cool $tempSetpointBB°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint21)
            log.info "Set $thermostat Heat $tempSetpoint21°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointBB)
            log.info "Set $thermostat Cool $tempSetpointBB°"
        }
    }
}

def changeTemp31() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint31)
            thermostat.setCoolingSetpoint(tempSetpointCC)
            log.info "Set $thermostat Heat $tempSetpoint31°, Cool $tempSetpointCC°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint31)
            log.info "Set $thermostat Heat $tempSetpoint31°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointCC)
            log.info "Set $thermostat Cool $tempSetpointCC°"
        }
    }
}

def changeTemp41() {
	thermostats.each { thermostat ->
        def thermostatState = thermostat.currentThermostatMode
        log.debug "Thermostat mode = $thermostatState"
        def thermostatFan = thermostat.currentThermostatFanMode
        log.debug "Thermostat fan = $thermostatFan"
        if (thermostatState == "auto") {
            thermostat.setHeatingSetpoint(tempSetpoint41)
            thermostat.setCoolingSetpoint(tempSetpointDD)
            log.info "Set $thermostat Heat $tempSetpoint41°, Cool $tempSetpointDD°"
        }
        else if (thermostatState == "heat") {
            thermostat.setHeatingSetpoint(tempSetpoint41)
            log.info "Set $thermostat Heat $tempSetpoint41°"
        }
        else {
            thermostat.setCoolingSetpoint(tempSetpointDD)
            log.info "Set $thermostat Cool $tempSetpointDD°"
        }
    }
}

CT-100 Schedule
Honeywell YTH8320ZW1007 Thermostat Programming Through Hub
Thermostat Scheduler App?
New to SmartThings looking for help: Thermostat plus multiple sensors?
[RELEASE] Unlimited customizable thermostat
Smart App to turn on/off AC?
[RELEASE] Ultimate Mode Based Thermostat - Control Multiple Thermostats Temperature / Remote Temperature Sensors when Changing Modes
[RELEASE] Enhanced Z-Wave Plus Thermostat (CT30/CT50/CT80/CT100/CT101/CT110/ZTS110/ZTS500/GoControl/Honeywell/Universal) Device Handler with Battery, Humidity, Clock Set, Alarm, Swing/Temp, Deadband Configuration and Updated User Interface
[RELEASE] Stelpro releases the first Z-Wave Plus Line-Voltage thermostat: the STZW402+ Stelpro Ki Thermostat
CT-100 Schedule
Thermostat/HVAC control off an external temperature sensor
Thermostat that can use external temperature sensor?
[RELEASE] Ultimate Mode Based Thermostat - Control Multiple Thermostats Temperature / Remote Temperature Sensors when Changing Modes
Remote sensor routine or thermostat control
The new virtual thermostat app for window units etc
Integration of z-Wave /danfoss thermostatw
Schedule not working
[RELEASE] Unlimited customizable thermostat
[RELEASE] Ultimate Mode Based Thermostat - Control Multiple Thermostats Temperature / Remote Temperature Sensors when Changing Modes
(Chrisb) #2

Cool... Thanks for sharing. I'm definitely going to take a look at this. I just re-programmed by Honeywell and thought I should be able to do it with SmartThings, but didn't, at the time, think there was a program option for it.

Question: Does this set the programming on the Themostat? That is...will this push the programming to device so that it will run independent of SmartThings? I guess I don't want to see a situation where ST hiccups and doesn't turn off/on one of the programming modes.

Relates Question: If the answer to the above is no, do I need to shut off all programming on the thermostat itself or will ST and the internal programming be potentially battling each other?


(www.rboyapps.com - Make your home your butler!) #3

This is just a generic smart app designed to work wtih any thermostat so it only programs the "current" temperature and sets up timers on the ST platform to change the thermostat temperature at the user entered times. So yes it runs on the ST platform.
And no it doesn't disable any other programs or schedules so you have setup so you will need to take of any conflicts.
E.g. I have set this program to use when in Home and night mode only and ensured nothing else is changing the temperature on the thermostat in those modes.


(www.rboyapps.com - Make your home your butler!) #4

Just fixed a bug when crossing over midnight causing the scheduler to skip a day at times.


(www.rboyapps.com - Make your home your butler!) #5

Wiredly there's a bug in the platform, after schedule the apps needs to call unschedule() before scheduling the next schedule or it stops working after 2-3 schedules.


(Joepnj) #6

I installed this SmartApp and tried programming for one of my thermostats. When I hit "done" I get "an unexpected error occurred" and nothing is saved. Could this be because I have not yet deleted other temperature changes tied to modes?

I would hate to delete all my existing temperature changes and find out this SmartApp still doesn't work...

Thanks


(www.rboyapps.com - Make your home your butler!) #7

No, just take the latest code, I just updated it. Maybe you got some old code. It's working because I'm running it right now. You don't need to change anything. I have other temperature apps also connected and no issues at all. I think it just may be a bug.

If you can, in your IDE open the Live Debugger and if you get the error, let me know what line it shows up in.


(Joepnj) #8

Code detail says it was updated 11/13/14 (today). I re-published, logged out of ST. Logged back in, entered some time and temperature data. Hit "done"... same error...

I don't see the live debugger in IDE... where can I find it?

Thanks


(www.rboyapps.com - Make your home your butler!) #9

Can you help me with data you've entered. Also did you enter the external temperature ? Did you enter all temperatures for weekday and weekend?

When you open the IDE to the left of the Documentation link is a link called Live Logging (the URL is https://graph.api.smartthings.com/ide/logs)

I think you may need to enable it once in your settings? (am not sure).

But once in the live logging, then update the app and all the debug messages should show up there with the error and location.

I'm current using this on 2 thermostats, but I'm not using the external temperature option.


(www.rboyapps.com - Make your home your butler!) #10

and yes it was updated multiple times today, I just updated it about 15 minutes ago. Try taking the latest code right now if you haven't.


(Joepnj) #11

OK... logs updated so quickly it took me a couple of tries to get the data before it scrolled off the screen...

‎9‎:‎23‎:‎07‎ ‎PM: error java.text.ParseException: Unparseable date: "2014-11-13Tnull" @ line 135

BTW, I am not using the external temperature option either.


(www.rboyapps.com - Make your home your butler!) #12

It looks like your time input was wrong or your system isn’t setup right. It isn’t able to get the date from your system.

Try this, delete the app all together from your list of my smart apps. Then create a new apps and copy the paste the code and start over. It may be an installation issue, someone from the ST team told me that the date used by ST is when the app was first installed, possibly in this case it didn’t register a date due to some bug. Try clean over.


(www.rboyapps.com - Make your home your butler!) #13

Check your input specifially, see this line:
"2014-11-13Tnull"

Usualy it's a DateTTime, in your case the time is null, so it's not taking the inputs properly, possible Time2 (leave time)


(Joepnj) #14

I was not completing the leave and return fields... thought they were optional... my bad...

After entering times and temps for all fields, the app installed and seems to be working.

Sorry for all the trouble... Thanks for your patience and assistance.

Glad you took the time to develop this app. I ran out of patience waiting for ST to release the "Comfort" module that is supposed to enhance Thermostat control. Now I hear it has been delayed until after the new year,


(www.rboyapps.com - Make your home your butler!) #15

Be glad to be of help, I just put a new app to change the thermostat based on motion in the room.

This is good feedback let me see if I can make it mandatory to include all times.


(www.rboyapps.com - Make your home your butler!) #16

Done.

I know ST's slow, I understand they need to focus on the platform and it's performance and stability and if they can do just that I'd be okay.

I don't mind making apps for the community I just wish that ST had a better support on the community forum. There are just a few folks who seems to be from ST and I don't hear from them much / get much support on issues to help us get these apps out of the doors.


(Joepnj) #17

I hear you... and agree. Gets pretty frustrating sometimes...


(www.rboyapps.com - Make your home your butler!) #18

Fixed an issue with external temp sensor, now added independent cooling and heating switching temperatures for external temp sensor to avoid oscillation


(www.rboyapps.com - Make your home your butler!) #19

Added support to detect mode changes so that the latest temp is reset when an active mode is set (e.g. returning from away to home and thermostat is only set to run while in home mode, it will reset the temp to the current scheduled temp when the mode changes to home)


#20

Can you tell me where I can get the most up to date code for the 5-2 Programmable Thermostat Scheduler you created?