Skip to content

Instantly share code, notes, and snippets.

@imbrianj
Last active August 29, 2015 14:20
Show Gist options
  • Save imbrianj/9cae536d0468fe2bcbb1 to your computer and use it in GitHub Desktop.
Save imbrianj/9cae536d0468fe2bcbb1 to your computer and use it in GitHub Desktop.
Smarter Thermostat
/**
* Smarter Thermostat
*
* Copyright 2015 Brian J.
*
* 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 Window Check",
namespace: "imbrianj",
author: "brian@bevey.org",
description: "If your heating or cooling system come on, it gives you notice if there are any windows or doors left open, preventing the system from working optimally.",
category: "Green Living",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png"
)
preferences {
section("Things to check?") {
input "sensors", "capability.contactSensor", multiple: true
}
section("Thermostats to monitor") {
input "thermostats", "capability.thermostat", multiple: true
}
section("Notifications") {
input "sendPushMessage", "enum", title: "Send a push notification?", metadata: [values: ["Yes", "No"]], required: false
input "phone", "phone", title: "Send a Text Message?", required: false
}
section("Turn thermostat to AWAY automatically?") {
input "turnOffTherm", "enum", metadata: [values: ["Yes", "No"]], required: false
}
section("Delay to wait before turning thermostat off (defaults to 1 minute)") {
input "turnOffDelay", "decimal", title: "Number of minutes", required: false
}
}
def installed() {
subscribe(thermostats, "presence", modeEventFired)
subscribe(thermostats, "thermostatMode", thermoChange)
subscribe(sensors, "contact", windowChange)
}
def updated() {
unsubscribe()
subscribe(thermostats, "presence", modeEventFired)
subscribe(thermostats, "thermostatMode", thermoChange)
subscribe(sensors, "contact", windowChange)
}
def modeEventFired(evt) {
if(evt.value == "present") {
windowChange(evt)
}
}
def thermoChange(evt) {
if(evt.value == "heat" ||
evt.value == "cool") {
def open = sensors.findAll { it?.latestValue("contact") == "open" }
if(open) {
def plural = open.size() > 1 ? "are" : "is"
send("${open.join(', ')} ${plural} still open and the thermostat just came on.")
thermoShutOffTrigger()
}
else {
log.info("Thermostat came on and nothing is open.");
}
}
}
def windowChange(evt) {
def heating = thermostats.findAll { it?.latestValue("thermostatMode") == "heat" }
def cooling = thermostats.findAll { it?.latestValue("thermostatMode") == "cool" }
def open = sensors.findAll { it?.latestValue("contact") == "open" }
if(open.size()) {
if(heating || cooling) {
def tempDirection = heating ? "heating" : "cooling"
def plural = open.size() > 1 ? "were" : "was"
send("${open.join(', ')} ${plural} opened and the thermostat is still ${tempDirection}.")
}
thermoShutOffTrigger()
}
else {
log.info("Mark thermostats as Home")
thermostats?.home()
}
}
def thermoShutOffTrigger() {
if(turnOffTherm == "Yes") {
log.info("Starting timer to turn off thermostat")
def delay = (turnOffDelay != null && turnOffDelay != "") ? turnOffDelay * 60 : 60
state.turnOffTime = now()
runIn(delay, "thermoShutOff")
}
}
def thermoShutOff() {
def open = sensors.findAll { it?.latestValue("contact") == "open" }
def tempDirection = heating ? "heating" : "cooling"
def plural = open.size() > 1 ? "are" : "is"
log.info("Checking if we need to turn thermostats off")
if(open.size()) {
def heating = thermostats.findAll { it?.latestValue("thermostatMode") == "heat" }
def cooling = thermostats.findAll { it?.latestValue("thermostatMode") == "cool" }
if((heating) || (cooling)) {
send("Thermostats set to away: ${open.join(', ')} ${plural} open and thermostats ${tempDirection}.")
log.info("Windows still open, turning thermostats off")
}
thermostats?.away()
}
else {
log.info("Looks like everything is shut now - no need to turn off thermostats")
}
}
private send(msg) {
if(sendPushMessage != "No") {
log.debug("Sending push message")
sendPush(msg)
}
if(phone) {
log.debug("Sending text message")
sendSms(phone, msg)
}
log.debug(msg)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment