You will need to create two hub variables and a virtual switch before you install the app. I display these 3 things on my thermostat dashboard, flip the switch to off when you change the filter.
/*
* Thermostat Filter Change Reminder
*/
definition(name: "Thermostat Filter Change Reminder",
namespace: "hubitat",
author: "dagrider",
description: "Filter change reminder",
category: "",
iconUrl: "",
iconX2Url: "")
preferences {
section("<h2>Settings</h2>") {
input "theThermostat", "capability.thermostat", title: "Choose thermostat"
input "fanRunMaxHrs", "number", title: "Hours to run before filter change"
input "HVMaxRunHrs", "capability.actuator", title: "Hub Variable for max run hours"
input "HVRunHrs", "capability.actuator", title: "Hub Variable for current run hours"
input "filterChangeSwitch", "capability.switch", title: "Choose filter change switch (turn off after filter changed, to reset run hours)"
//input "smsNumber", "phone", title: "Phone number to send SMS message when filter needs to be changed", required: false
input "thePlayer", "capability.musicPlayer", title: "Choose music players to announce", multiple: true, required: false
input "volume", "number", title: "Volume", description: "0-100", required: false, defaultValue: "50"
input "theSpeakers", "capability.speechSynthesis", title: "Choose speakers to announce", multiple: true, required: false
input "notification", "capability.notification", title: "Send notification to these Notification Devices:", multiple: true, required: false
//input "resetFanRunHrs", "bool", title: "Has filter been changed? (ON=Yes, OFF=No)"
}
section("<h2>Status</h2>") {
paragraph "Fan run time (hours): ${state.fanRunHrs}"
paragraph "Does filter need to be changed? ${state.filterChange}"
}
section ("<h2>Logging</h2>") {
input name: "debugLogEnable", type: "bool", title: "Enable debug logging", defaultValue: true
}
}
def installed() {
logDebug("Installed with settings: ${settings}")
initValues()
initialize()
}
def updated() {
logDebug("Updated with settings: ${settings}")
unsubscribe()
initialize()
}
def initialize() {
subscribe(theThermostat, "thermostatOperatingState", thermostatHandler)
subscribe(filterChangeSwitch, "switch.off", switchHandler)
subscribe(HVMaxRunHrs, "variable", maxRunHrsHandler)
updateMaxRunHrsHV(settings.fanRunMaxHrs)
}
def resetValues() {
sendEvent(name: "reset values", value: "reset values", descriptionText: "reset values")
setFanRunTimeHR(0)
setFanRunTimeMS(0)
setFilterChange("No")
//app.updateSetting("resetFanRunHrs", [value: "false", type: "bool"])
}
def initValues() {
sendEvent(name: "init values", value: "init values", descriptionText: "init values")
setFanRunTimeHR(0)
setFanRunTimeMS(0)
setFanOnTime(0)
setFanOffTime(0)
setFilterChange("No")
}
def maxRunHrsHandler(evt) {
logDebug("Max run hrs handler evt: $evt, variable: $HVMaxRunHrs.currentVariable")
app.updateSetting("fanRunMaxHrs", [value: HVMaxRunHrs.currentVariable, type: "number"])
}
def switchHandler(evt) {
sendEvent(name: "switch off", value: "${filterChangeSwitch.displayName}", descriptionText: "Filter change switch off (filter was changed)")
resetValues()
}
def thermostatHandler(evt) {
logDebug("thermostatHandler event value ${evt.value}")
sendEvent(name: "thermostatOperatingState", value: "event ${evt.value}", descriptionText: "thermostatOperatingState event")
if (evt.value == "idle") {
if (state.fanOffTime == 0 && state.fanOnTime != 0) {
setFanOffTime(now())
def elapsed = state.fanOffTime - state.fanOnTime
setFanRunTimeMS(state.fanRunMS + elapsed)
setFanOnTime(0)
if (state.fanRunMS >= settings.fanRunMaxHrs * 3600000) {
setFilterChange("Yes")
def msg = "A/C Filter needs to be changed"
filterChangeSwitch.on()
//if (smsNumber) sendSMS(smsNumber, msg)
if (thePlayer) thePlayer.playTextAndRestore(msg, volume)
if (theSpeakers) theSpeakers.speak(msg)
if (notification) notification.deviceNotification(msg)
} else {
setFilterChange("No")
}
setFanRunTimeHR(Math.round(state.fanRunMS / 3600000 * 100) / 100)
}
} else {
if (state.fanOnTime == 0) {
setFanOnTime(now())
setFanOffTime(0)
}
}
}
private updateMaxRunHrsHV(val) {
//app.updateSetting("resetFanRunHrs", [value: "false", type: "bool"]) fanRunMaxHrs
logDebug("updateMaxRunHrsHV to $val")
HVMaxRunHrs.setVariable(val)
}
private updateRunHrsHV(val) {
logDebug("updateRunHrsHV to $val")
HVRunHrs.setVariable(val)
}
private setFanOnTime(val) {
state.fanOnTime = val
logDebug("Fan on time: $state.fanOnTime")
sendEvent(name: "Fan on time", value: "${state.fanOnTime}", descriptionText: "Fan on time")
}
private setFanOffTime(val) {
state.fanOffTime = val
logDebug("Fan off time: $state.fanOffTime")
sendEvent(name: "Fan off time", value: "${state.fanOffTime}", descriptionText: "Fan off time")
}
private setFanRunTimeMS(val) {
state.fanRunMS = val
logDebug("Fan run time (MS): $state.fanRunMS")
sendEvent(name: "Fan run time (MS)", value: "${state.fanRunMS}", descriptionText: "Fan run time (MS)")
}
private setFanRunTimeHR(val) {
state.fanRunHrs = val
updateRunHrsHV(val)
logDebug("Fan run time (HR): $state.fanRunHrs")
sendEvent(name: "Fan run time (HR)", value: "${state.fanRunHrs}", descriptionText: "Fan run time (HR)")
}
private setFilterChange(val) {
state.filterChange = val
logDebug("Filter change? $state.filterChange")
sendEvent(name: "Filter change?", value: "${state.filterChange}", descriptionText: "Is filter change required?")
}
private logDebug(msg) {
if (debugLogEnable) log.debug msg
}