@ -1,14 +1,20 @@
# --------------------------------------------------
# AC Filter‑ change runtime tracker
# --------------------------------------------------
input_datetime:
input_datetime:
downstairs_last_filter_change:
downstairs_last_filter_change:
name : Downstairs Last Filter Change
name : Downstairs Last Filter Change
has_date : true
has_date : true
has_time : true
has_time : true
upstairs_last_filter_change:
upstairs_last_filter_change:
name : Upstairs Last Filter Change
name : Upstairs Last Filter Change
has_date : true
has_date : true
has_time : true
has_time : true
# ---------------------------------------------------------------------------
# Binary sensors – true when the thermostat reports the compressor is running
# ---------------------------------------------------------------------------
binary_sensor:
binary_sensor:
- platform : template
- platform : template
sensors:
sensors:
@ -16,71 +22,106 @@ binary_sensor:
friendly_name : "Downstairs AC is Cooling"
friendly_name : "Downstairs AC is Cooling"
value_template : >
value_template : >
{{ state_attr('climate.downstairs', 'hvac_action') == 'cooling' }}
{{ state_attr('climate.downstairs', 'hvac_action') == 'cooling' }}
upstairs_ac_cooling:
upstairs_ac_cooling:
friendly_name : "Upstairs AC is Cooling"
friendly_name : "Upstairs AC is Cooling"
value_template : >
value_template : >
{{ state_attr('climate.upstairs', 'hvac_action') == 'cooling' }}
{{ state_attr('climate.upstairs', 'hvac_action') == 'cooling' }}
sensor:
sensor:
- platform : history_stats
- platform : template
name : Downstairs AC Runtime Since Last Filter Change
sensors:
entity_id : binary_sensor.downstairs_ac_cooling
downstairs_ac_cooling_numeric:
state : 'on'
friendly_name : "Downstairs AC Cooling Numeric"
type : time
value_template : "{{ 1 if is_state('binary_sensor.downstairs_ac_cooling', 'on') else 0 }}"
start : "{{ states('input_datetime.downstairs_last_filter_change') }}"
upstairs_ac_cooling_numeric:
end : "{{ now() }}"
friendly_name : "Upstairs AC Cooling Numeric "
value_template : "{{ 1 if is_state('binary_sensor.upstairs_ac_cooling', 'on') else 0 }}"
- platform : integration
name : Downstairs AC Runtime Raw
source : sensor.downstairs_ac_cooling_numeric
unit_time : h
method : left
round : 2
- platform : integration
name : Upstairs AC Runtime Raw
source : sensor.upstairs_ac_cooling_numeric
unit_time : h
method : left
round : 2
- platform : history_stats
# ---------------------------------------------------------------------------
name : Upstairs AC Runtime Since Last Filter Change
# Utility‑ meters that act like odometers (reset when you swap the filter)
entity_id : binary_sensor.upstairs_ac_cooling
# ---------------------------------------------------------------------------
state : 'on'
utility_meter:
type : time
downstairs_ac_runtime_since_last_filter_change:
start : "{{ states('input_datetime.upstairs_last_filter_change') }}"
source : sensor.downstairs_ac_runtime_raw
end : "{{ now() }}"
cycle : none # never auto‑ reset
upstairs_ac_runtime_since_last_filter_change:
source : sensor.upstairs_ac_runtime_raw
cycle : none
script:
script:
reset_filter_change_date:
reset_downstairs_filter:
alias : Reset Downstairs Filter Change Date
alias : Reset Downstairs Filter
mode : queued
sequence:
sequence:
- service : input_datetime.set_datetime
- service : input_datetime.set_datetime
data:
data:
entity_id : input_datetime.downstairs_last_filter_change
entity_id : input_datetime.downstairs_last_filter_change
datetime : "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
datetime : "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
- service : utility_meter.reset
target:
entity_id : utility_meter.downstairs_ac_runtime_since_last_filter_change
reset_upstairs_filter:
alias : Reset Upstairs Filter
mode : queued
sequence:
- service : input_datetime.set_datetime
data:
entity_id : input_datetime.upstairs_last_filter_change
datetime : "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
- service : utility_meter.reset
target:
entity_id : utility_meter.upstairs_ac_runtime_since_last_filter_change
automation:
automation:
- alias : Notify Downstairs Filter Change Due
- alias : Notify Downstairs Filter Change Due
description : "Notify when AC runtime exceeds threshold since last filter change"
description : Notify when downstairs runtime exceeds threshold since last filter change
trigger:
trigger:
- platform : numeric_state
- platform : numeric_state
entity_id : sensor.downstairs_ac_runtime_since_last_filter_change
entity_id : sensor.downstairs_ac_runtime_since_last_filter_change
above : 800
above : 800 # hours
action:
action:
- service : script.notify_engine
- service : script.notify_engine # <-- keep your existing notify helper
data:
data:
title : "Home Maintenance Reminder"
title : "Home Maintenance Reminder"
value1 : "It's time to change your Downstairs AC filter."
value1 : "It's time to change your Downstairs AC filter."
value2 : "Runtime has exceeded 800 hours. Last changed {{ ((now() - states.input_datetime.downstairs_last_filter_change.last_changed).total_seconds() / 86400) | round(0) }} days ago."
value2 : >
Runtime has exceeded 800 h. Last changed {{ ((now() - states.input_datetime.downstairs_last_filter_change.last_changed).total_seconds() / 86400) | round(0) }} days ago.
who : "Carlo"
who : "Carlo"
group : "maintenance"
group : "maintenance"
level : "active"
level : "active"
- alias : Notify Upstairs Filter Change Due
- alias : Notify Upstairs Filter Change Due
description : "Notify when AC runtime exceeds threshold since last filter change"
description : Notify when upstairs runtime exceeds threshold since last filter change
trigger:
trigger:
- platform : numeric_state
- platform : numeric_state
entity_id : sensor.upstairs_ac_runtime_since_last_filter_change
entity_id : sensor.upstairs_ac_runtime_since_last_filter_change
above : 450
above : 450 # hours
action:
action:
- service : script.notify_engine
- service : script.notify_engine
data:
data:
title : "Home Maintenance Reminder"
title : "Home Maintenance Reminder"
value1 : "It's time to change your Upstairs AC filter."
value1 : "It's time to change your Upstairs AC filter."
value2 : "Runtime has exceeded 450 hours. Last changed {{ ((now() - states.input_datetime.upstairs_last_filter_change.last_changed).total_seconds() / 86400) | round(0) }} days ago."
value2 : >
Runtime has exceeded 450 h. Last changed {{ ((now() - states.input_datetime.upstairs_last_filter_change.last_changed).total_seconds() / 86400) | round(0) }} days ago.
who : "Carlo"
who : "Carlo"
group : "maintenance"
group : "maintenance"
- alias : 'Prevent Upstairs Nest Below 76'
- alias : Prevent Upstairs Nest Below 76
id : 7812fdaf-a3f8-498b-8f07-28e977e528ff
id : 7812fdaf-a3f8-498b-8f07-28e977e528ff
trigger:
trigger:
- platform : numeric_state
- platform : numeric_state
@ -88,8 +129,7 @@ automation:
attribute : temperature
attribute : temperature
below : 76
below : 76
action:
action:
- delay:
- delay : "00:03:00"
minutes : 3
- service : climate.set_temperature
- service : climate.set_temperature
data:
data:
entity_id : climate.upstairs
entity_id : climate.upstairs