mirror of
https://github.com/CCOSTAN/Home-AssistantConfig.git
synced 2026-07-06 06:02:22 -07:00
779 lines
28 KiB
YAML
779 lines
28 KiB
YAML
######################################################################
|
||
# @CCOSTAN - Follow Me on X
|
||
# For more info visit https://www.vcloudinfo.com/click-here
|
||
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
|
||
# -------------------------------------------------------------------
|
||
# Climate Control - Seasonal HVAC automations and sensors.
|
||
# Thermostat helpers for upstairs/downstairs comfort.
|
||
# -------------------------------------------------------------------
|
||
# Related Issue: 1571, 273
|
||
# Notes: Filter due alerts use a 350h runtime threshold, 9-month hard limit, 3-day snooze, and Filter Changed push actions.
|
||
# Notes: Condenser line cleanout uses a single 360-day reminder for both HVAC systems.
|
||
# Notes: The snooze notification pattern is also covered at https://youtu.be/y47KSflS1aw.
|
||
# Video: https://youtu.be/nScl2JxYSB8
|
||
######################################################################
|
||
# Contact: @CCOSTAN | Entity reference details below
|
||
# Entity reference and attribute summaries:
|
||
#
|
||
# Entity ID: climate.downstairs
|
||
# Supported hvac_modes: heat, cool, heat_cool, off
|
||
# Supported fan_modes: on, off
|
||
# Supported preset_modes: none, eco
|
||
# Supported temperature range: 50°F (min_temp) – 90°F (max_temp)
|
||
#
|
||
# Current state (example):
|
||
# current_temperature: 77
|
||
# temperature: 83
|
||
# target_temp_high: null
|
||
# target_temp_low: null
|
||
# current_humidity: 58
|
||
# fan_mode: off
|
||
# hvac_action: idle
|
||
# preset_mode: none
|
||
# Supported features: 411
|
||
# --------------------------------------------------------------
|
||
# Entity ID: climate.upstairs
|
||
# Supported hvac_modes: off, heat, cool, heat_cool
|
||
# Supported temperature range: 50°F (min_temp) – 90°F (max_temp)
|
||
#
|
||
# Current state (example):
|
||
# current_temperature: 76
|
||
# temperature: 78
|
||
# target_temp_high: null
|
||
# target_temp_low: null
|
||
# friendly_name: Upstairs
|
||
# Supported features: 387
|
||
|
||
######################################################################
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Template helpers – compressor status flags and numeric runtime helpers
|
||
# ---------------------------------------------------------------------------
|
||
template:
|
||
- binary_sensor:
|
||
- name: "Downstairs AC is Cooling"
|
||
unique_id: downstairs_ac_cooling
|
||
state: >
|
||
{% set action = state_attr('climate.downstairs', 'hvac_action') %}
|
||
{% set current = state_attr('climate.downstairs', 'current_temperature') | float(none) %}
|
||
{% set target = state_attr('climate.downstairs', 'temperature') | float(none) %}
|
||
{{
|
||
action == 'cooling'
|
||
or (
|
||
action is none
|
||
and is_state('climate.downstairs', 'cool')
|
||
and current is not none
|
||
and target is not none
|
||
and current > target
|
||
)
|
||
}}
|
||
- name: "Upstairs AC is Cooling"
|
||
unique_id: upstairs_ac_cooling
|
||
state: >
|
||
{% set action = state_attr('climate.upstairs', 'hvac_action') %}
|
||
{% set current = state_attr('climate.upstairs', 'current_temperature') | float(none) %}
|
||
{% set target = state_attr('climate.upstairs', 'temperature') | float(none) %}
|
||
{{
|
||
action == 'cooling'
|
||
or (
|
||
action is none
|
||
and is_state('climate.upstairs', 'cool')
|
||
and current is not none
|
||
and target is not none
|
||
and current > target
|
||
)
|
||
}}
|
||
|
||
sensor:
|
||
- name: "Downstairs AC Cooling Numeric"
|
||
unique_id: downstairs_ac_cooling_numeric
|
||
state: "{{ 1 if is_state('binary_sensor.downstairs_ac_is_cooling', 'on') else 0 }}"
|
||
- name: "Upstairs AC Cooling Numeric"
|
||
unique_id: upstairs_ac_cooling_numeric
|
||
state: "{{ 1 if is_state('binary_sensor.upstairs_ac_is_cooling', 'on') else 0 }}"
|
||
|
||
input_datetime:
|
||
downstairs_last_filter_change:
|
||
name: Downstairs Last Filter Change
|
||
has_date: true
|
||
has_time: true
|
||
downstairs_filter_snooze_until:
|
||
name: Downstairs Filter Snooze Until
|
||
has_date: true
|
||
has_time: true
|
||
upstairs_last_filter_change:
|
||
name: Upstairs Last Filter Change
|
||
has_date: true
|
||
has_time: true
|
||
upstairs_filter_snooze_until:
|
||
name: Upstairs Filter Snooze Until
|
||
has_date: true
|
||
has_time: true
|
||
hvac_condenser_lines_last_cleaned:
|
||
name: HVAC Condenser Lines Last Cleaned
|
||
has_date: true
|
||
has_time: false
|
||
initial: "2026-06-28"
|
||
hvac_condenser_lines_cleaning_snooze_until:
|
||
name: HVAC Condenser Lines Cleaning Snooze Until
|
||
has_date: true
|
||
has_time: true
|
||
initial: "2026-06-28 00:00:00"
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Integration sensors tally runtime based on compressor state
|
||
# ---------------------------------------------------------------------------
|
||
sensor:
|
||
- 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
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Utility‑meters that act like odometers (reset when you swap the filter)
|
||
# ---------------------------------------------------------------------------
|
||
utility_meter:
|
||
downstairs_ac_runtime_since_last_filter_change:
|
||
source: sensor.downstairs_ac_runtime_raw
|
||
upstairs_ac_runtime_since_last_filter_change:
|
||
source: sensor.upstairs_ac_runtime_raw
|
||
|
||
script:
|
||
reset_downstairs_filter:
|
||
alias: Reset Downstairs Filter
|
||
mode: queued
|
||
sequence:
|
||
- service: input_datetime.set_datetime
|
||
data:
|
||
entity_id: input_datetime.downstairs_last_filter_change
|
||
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
|
||
- service: input_datetime.set_datetime
|
||
data:
|
||
entity_id: input_datetime.downstairs_filter_snooze_until
|
||
datetime: "{{ (now() - timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') }}"
|
||
- service: utility_meter.reset
|
||
target:
|
||
entity_id: sensor.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: input_datetime.set_datetime
|
||
data:
|
||
entity_id: input_datetime.upstairs_filter_snooze_until
|
||
datetime: "{{ (now() - timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') }}"
|
||
- service: utility_meter.reset
|
||
target:
|
||
entity_id: sensor.upstairs_ac_runtime_since_last_filter_change
|
||
|
||
reset_hvac_condenser_lines_cleaned:
|
||
alias: Reset HVAC Condenser Lines Cleaned
|
||
mode: queued
|
||
sequence:
|
||
- service: input_datetime.set_datetime
|
||
data:
|
||
entity_id: input_datetime.hvac_condenser_lines_last_cleaned
|
||
date: "{{ now().strftime('%Y-%m-%d') }}"
|
||
- service: input_datetime.set_datetime
|
||
data:
|
||
entity_id: input_datetime.hvac_condenser_lines_cleaning_snooze_until
|
||
datetime: "{{ (now() - timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') }}"
|
||
|
||
set_downstairs_target_temp_based_on_conditions:
|
||
alias: Set Downstairs Target Temperature Based on Conditions
|
||
mode: single
|
||
sequence:
|
||
- choose:
|
||
- conditions:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'not_home'
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Downstairs HVAC set to ECO (family not_home)."
|
||
- service: climate.set_preset_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
preset_mode: 'eco'
|
||
- conditions:
|
||
- condition: and
|
||
conditions:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'home'
|
||
- condition: template
|
||
value_template: >-
|
||
{{ states('sensor.pirateweather_temperature') in ['unknown','unavailable','none',''] }}
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Outside temp unavailable; allowing downstairs cool mode (defaulting to 80F)."
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
hvac_mode: cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 80
|
||
|
||
- conditions:
|
||
- condition: and
|
||
conditions:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'home'
|
||
- condition: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
below: 78
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Downstairs target set to 78F (family home, outside temp <78F)."
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
hvac_mode: cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 78
|
||
- conditions:
|
||
- condition: and
|
||
conditions:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'home'
|
||
- condition: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
above: 92
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Downstairs target set to 78F (family home, temp >92F)."
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
hvac_mode: cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 78
|
||
- conditions:
|
||
- condition: and
|
||
conditions:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'home'
|
||
- condition: template
|
||
value_template: "{{ states('sensor.pirateweather_temperature')|float(-999) >= 78 }}"
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Downstairs target set to 80F (family home)."
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
hvac_mode: cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 80
|
||
|
||
set_downstairs_daytime_target:
|
||
alias: Set Downstairs Daytime Target
|
||
mode: single
|
||
sequence:
|
||
- service: script.set_downstairs_target_temp_based_on_conditions
|
||
|
||
set_downstairs_hvac_cool:
|
||
alias: Set Downstairs HVAC Cool
|
||
mode: single
|
||
sequence:
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
hvac_mode: cool
|
||
|
||
set_upstairs_cool_82:
|
||
alias: Set Upstairs Cool 82
|
||
mode: single
|
||
sequence:
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.upstairs
|
||
hvac_mode: cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.upstairs
|
||
temperature: 82
|
||
|
||
##############################################################################
|
||
### AUTOMATIONS - Thermostat schedules, guardrails, and presence/weather logic
|
||
### Some shutoff automations are also in the ALARM.yaml package when windows/doors are left open.
|
||
### There are also some automations in the POWERWALL.yaml package when the grid is down.
|
||
##############################################################################
|
||
automation:
|
||
- alias: Notify Climate Filter Change Due
|
||
description: Notify when HVAC filter runtime exceeds 350h or age reaches 9 months
|
||
trigger:
|
||
- platform: numeric_state
|
||
entity_id: sensor.downstairs_ac_runtime_since_last_filter_change
|
||
above: 350
|
||
id: downstairs_runtime
|
||
- platform: time
|
||
at: "09:00:00"
|
||
id: downstairs_daily
|
||
- platform: numeric_state
|
||
entity_id: sensor.upstairs_ac_runtime_since_last_filter_change
|
||
above: 350
|
||
id: upstairs_runtime
|
||
- platform: time
|
||
at: "09:10:00"
|
||
id: upstairs_daily
|
||
variables:
|
||
location: "{{ 'upstairs' if trigger.id.startswith('upstairs') else 'downstairs' }}"
|
||
location_title: "{{ 'Upstairs' if location == 'upstairs' else 'Downstairs' }}"
|
||
runtime_sensor: "sensor.{{ location }}_ac_runtime_since_last_filter_change"
|
||
last_filter_entity: "input_datetime.{{ location }}_last_filter_change"
|
||
snooze_entity: "input_datetime.{{ location }}_filter_snooze_until"
|
||
runtime_hours: "{{ states(runtime_sensor) | float(0) }}"
|
||
last_filter_ts: "{{ as_timestamp(states(last_filter_entity), 0) }}"
|
||
filter_age_days: "{{ ((as_timestamp(now()) - (last_filter_ts | float(0))) / 86400) | round(0) }}"
|
||
due_reason: >-
|
||
{% set runtime_due = runtime_hours | float(0) > 350 %}
|
||
{% set age_due = (last_filter_ts | float(0)) == 0 or (filter_age_days | int(0)) >= 274 %}
|
||
{% if runtime_due and age_due %}
|
||
Runtime has exceeded 350h and the filter is {{ filter_age_days }} days old.
|
||
{% elif runtime_due %}
|
||
Runtime has exceeded 350h.
|
||
{% else %}
|
||
Filter age has reached the 9-month hard limit ({{ filter_age_days }} days).
|
||
{% endif %}
|
||
condition:
|
||
- condition: template
|
||
value_template: >-
|
||
{{
|
||
(runtime_hours | float(0) > 350)
|
||
or (last_filter_ts | float(0)) == 0
|
||
or (filter_age_days | int(0)) >= 274
|
||
}}
|
||
- condition: template
|
||
value_template: >-
|
||
{% set snooze_until = as_timestamp(states(snooze_entity), 0) %}
|
||
{{ snooze_until <= as_timestamp(now()) }}
|
||
action:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "MAINTENANCE"
|
||
message: >-
|
||
{{ location_title }} AC filter due. {{ due_reason }} Runtime is {{ runtime_hours | round(1) }}h.
|
||
- service: script.notify_engine_two_button
|
||
data:
|
||
title: "Home Maintenance Reminder"
|
||
value1: "It's time to change your {{ location_title }} AC filter."
|
||
value2: >
|
||
{{ due_reason }} Runtime is {{ runtime_hours | round(1) }}h.
|
||
title1: "Snooze 3d"
|
||
action1: "{{ 'SNOOZE_UPSTAIRS_FILTER_3D' if location == 'upstairs' else 'SNOOZE_DOWNSTAIRS_FILTER_3D' }}"
|
||
icon1: "sfsymbols:clock"
|
||
title2: "Filter Changed"
|
||
action2: "{{ 'RESET_UPSTAIRS_FILTER' if location == 'upstairs' else 'RESET_DOWNSTAIRS_FILTER' }}"
|
||
icon2: "sfsymbols:checkmark.circle"
|
||
who: "carlo"
|
||
group: "maintenance"
|
||
level: "active"
|
||
|
||
- alias: Climate Filter Reminder Actions
|
||
id: 6d7056d0-90ce-4c4f-b8b1-fd32a7e58311
|
||
mode: queued
|
||
trigger:
|
||
- platform: event
|
||
event_type: mobile_app_notification_action
|
||
event_data:
|
||
action: SNOOZE_DOWNSTAIRS_FILTER_3D
|
||
id: downstairs_snooze
|
||
- platform: event
|
||
event_type: mobile_app_notification_action
|
||
event_data:
|
||
action: SNOOZE_UPSTAIRS_FILTER_3D
|
||
id: upstairs_snooze
|
||
- platform: event
|
||
event_type: mobile_app_notification_action
|
||
event_data:
|
||
action: RESET_DOWNSTAIRS_FILTER
|
||
id: downstairs_reset
|
||
- platform: event
|
||
event_type: mobile_app_notification_action
|
||
event_data:
|
||
action: RESET_UPSTAIRS_FILTER
|
||
id: upstairs_reset
|
||
variables:
|
||
location: "{{ 'upstairs' if trigger.id.startswith('upstairs') else 'downstairs' }}"
|
||
location_title: "{{ 'Upstairs' if location == 'upstairs' else 'Downstairs' }}"
|
||
snooze_entity: "input_datetime.{{ location }}_filter_snooze_until"
|
||
reset_script: "script.reset_{{ location }}_filter"
|
||
action:
|
||
- choose:
|
||
- conditions: "{{ trigger.id.endswith('_snooze') }}"
|
||
sequence:
|
||
- variables:
|
||
snooze_until: "{{ (now() + timedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S') }}"
|
||
- service: input_datetime.set_datetime
|
||
target:
|
||
entity_id: "{{ snooze_entity }}"
|
||
data:
|
||
datetime: "{{ snooze_until }}"
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "MAINTENANCE"
|
||
message: "{{ location_title }} AC filter reminder snoozed until {{ snooze_until }}."
|
||
- conditions: "{{ trigger.id.endswith('_reset') }}"
|
||
sequence:
|
||
- service: "{{ reset_script }}"
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "MAINTENANCE"
|
||
message: "{{ location_title }} AC filter reset from notification action."
|
||
|
||
- alias: Notify HVAC Condenser Lines Cleaning Due
|
||
id: 4dafac96-3163-4d63-847a-76727005f75b
|
||
description: Notify every 360 days when the outdoor condenser lines should be cleaned
|
||
trigger:
|
||
- platform: time
|
||
at: "09:20:00"
|
||
variables:
|
||
cleaned: "{{ states('input_datetime.hvac_condenser_lines_last_cleaned') }}"
|
||
cleaned_ts: >-
|
||
{% if cleaned in ['unknown', 'unavailable', 'none', ''] %}
|
||
0
|
||
{% else %}
|
||
{{ as_timestamp(strptime(cleaned, '%Y-%m-%d'), 0) }}
|
||
{% endif %}
|
||
days_since_cleaned: "{{ ((as_timestamp(now()) - (cleaned_ts | float(0))) / 86400) | round(0) }}"
|
||
condition:
|
||
- condition: template
|
||
value_template: "{{ (cleaned_ts | float(0)) == 0 or (days_since_cleaned | int(0)) >= 360 }}"
|
||
- condition: template
|
||
value_template: >-
|
||
{% set snooze_until = as_timestamp(states('input_datetime.hvac_condenser_lines_cleaning_snooze_until'), 0) %}
|
||
{{ snooze_until <= as_timestamp(now()) }}
|
||
action:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "MAINTENANCE"
|
||
message: "HVAC condenser lines cleanout due; last cleaned {{ days_since_cleaned }} days ago."
|
||
- service: script.notify_engine_two_button
|
||
data:
|
||
title: "Home Maintenance Reminder"
|
||
value1: "Clean the HVAC condenser lines."
|
||
value2: "360-day cleanout is due; last cleaned {{ days_since_cleaned }} days ago."
|
||
title1: "Snooze 3d"
|
||
action1: "SNOOZE_HVAC_CONDENSER_LINES_3D"
|
||
icon1: "sfsymbols:clock"
|
||
title2: "Cleaned"
|
||
action2: "RESET_HVAC_CONDENSER_LINES_CLEANED"
|
||
icon2: "sfsymbols:checkmark.circle"
|
||
who: "carlo"
|
||
group: "maintenance"
|
||
level: "active"
|
||
|
||
- alias: Climate Condenser Lines Reminder Actions
|
||
id: dfe89869-4bd3-47f6-bf0d-612bf7ee949f
|
||
mode: queued
|
||
trigger:
|
||
- platform: event
|
||
event_type: mobile_app_notification_action
|
||
event_data:
|
||
action: SNOOZE_HVAC_CONDENSER_LINES_3D
|
||
id: snooze
|
||
- platform: event
|
||
event_type: mobile_app_notification_action
|
||
event_data:
|
||
action: RESET_HVAC_CONDENSER_LINES_CLEANED
|
||
id: reset
|
||
action:
|
||
- choose:
|
||
- conditions: "{{ trigger.id == 'snooze' }}"
|
||
sequence:
|
||
- variables:
|
||
snooze_until: "{{ (now() + timedelta(days=3)).strftime('%Y-%m-%d %H:%M:%S') }}"
|
||
- service: input_datetime.set_datetime
|
||
target:
|
||
entity_id: input_datetime.hvac_condenser_lines_cleaning_snooze_until
|
||
data:
|
||
datetime: "{{ snooze_until }}"
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "MAINTENANCE"
|
||
message: "HVAC condenser lines cleanout reminder snoozed until {{ snooze_until }}."
|
||
- conditions: "{{ trigger.id == 'reset' }}"
|
||
sequence:
|
||
- service: script.reset_hvac_condenser_lines_cleaned
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "MAINTENANCE"
|
||
message: "HVAC condenser lines cleanout reset from notification action."
|
||
|
||
- alias: 'AC Status Announcement'
|
||
id: 7812fdaf-a3f8-498b-8f07-28e977e528fe
|
||
trigger:
|
||
- platform: state
|
||
entity_id:
|
||
- climate.downstairs
|
||
- climate.upstairs
|
||
from: 'off'
|
||
- platform: state
|
||
entity_id:
|
||
- climate.downstairs
|
||
- climate.upstairs
|
||
to: 'off'
|
||
action:
|
||
- service: script.speech_engine
|
||
data:
|
||
NestStatus: "The {{ trigger.entity_id.split('.')[1].split('_')[0]}} {{ trigger.entity_id.split('.')[1].split('_')[1]}} has now been turned on for {{(trigger.to_state.state)}}."
|
||
call_window_check: 1
|
||
|
||
- alias: Prevent Upstairs Nest Below 76
|
||
id: 7812fdaf-a3f8-498b-8f07-28e977e528ff
|
||
trigger:
|
||
- platform: numeric_state
|
||
entity_id: climate.upstairs
|
||
attribute: temperature
|
||
below: 76
|
||
condition:
|
||
- condition: template
|
||
value_template: "{{ is_state('binary_sensor.powerwall_grid_status', 'on') }}"
|
||
action:
|
||
- delay: "00:03:00"
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.upstairs
|
||
temperature: 78
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Upstairs target temp corrected to 78F (guardrail)."
|
||
|
||
- alias: Set Downstairs Bedtime Target When Both in Bed
|
||
id: set_downstairs_nest_77_both_in_bed
|
||
trigger:
|
||
- platform: state
|
||
entity_id: group.bed
|
||
to: 'on'
|
||
condition:
|
||
- condition: and
|
||
conditions:
|
||
- condition: state
|
||
entity_id: binary_sensor.sleepnumber_carlo_carlo_is_in_bed
|
||
state: 'on'
|
||
- condition: state
|
||
entity_id: binary_sensor.sleepnumber_carlo_stacey_is_in_bed
|
||
state: 'on'
|
||
- condition: state
|
||
entity_id: binary_sensor.powerwall_grid_status
|
||
state: 'on'
|
||
- condition: state
|
||
entity_id: sun.sun
|
||
state: 'below_horizon'
|
||
action:
|
||
- choose:
|
||
- conditions:
|
||
- condition: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
above: 80
|
||
sequence:
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 77
|
||
- conditions:
|
||
- condition: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
above: 75
|
||
below: 80
|
||
sequence:
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 79
|
||
|
||
- alias: 'Set Downstairs Thermostat Daytime Target'
|
||
id: set_downstairs_thermostat_daytime_target
|
||
mode: single
|
||
trigger:
|
||
- platform: state
|
||
entity_id: sun.sun
|
||
to: 'above_horizon'
|
||
- platform: time
|
||
at: "08:00:00"
|
||
- platform: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
above: 92
|
||
condition:
|
||
- condition: and
|
||
conditions:
|
||
- condition: state
|
||
entity_id: sun.sun
|
||
state: 'above_horizon'
|
||
- condition: state
|
||
entity_id: input_boolean.guest_mode
|
||
state: 'off'
|
||
- condition: state
|
||
entity_id: binary_sensor.powerwall_grid_status
|
||
state: 'on'
|
||
action:
|
||
- service: script.set_downstairs_daytime_target
|
||
|
||
# Set thermostats to eco mode when everyone is away
|
||
- alias: 'Set Thermostats to Eco When Away'
|
||
id: 1e2d3c4b-eco-thermostat-away
|
||
mode: single
|
||
trigger:
|
||
- platform: state
|
||
entity_id: group.family
|
||
to: 'not_home'
|
||
condition:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'not_home'
|
||
- condition: state
|
||
entity_id: input_boolean.guest_mode
|
||
state: 'off'
|
||
action:
|
||
- service: climate.set_preset_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
preset_mode: 'eco'
|
||
- choose:
|
||
- conditions:
|
||
- condition: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
below: 75
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Skipping downstairs cool mode (outside temp <75F)."
|
||
default:
|
||
- service: script.set_downstairs_hvac_cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.upstairs
|
||
temperature: 83
|
||
|
||
# Automation: Set Thermostats Back to Cool Mode
|
||
- alias: 'Set Thermostats to Cool When Home'
|
||
id: 1e2d3c4b-cool-thermostat-home
|
||
mode: single
|
||
trigger:
|
||
- platform: state
|
||
entity_id: group.family
|
||
to: 'home'
|
||
condition:
|
||
- condition: or
|
||
conditions:
|
||
- condition: state
|
||
entity_id: group.family
|
||
state: 'home'
|
||
- condition: template
|
||
value_template: "{{ is_state('input_boolean.guest_mode', 'off') }}"
|
||
- condition: state
|
||
entity_id: binary_sensor.powerwall_grid_status
|
||
state: 'on'
|
||
action:
|
||
- service: climate.set_preset_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
preset_mode: 'none'
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.upstairs
|
||
hvac_mode: cool
|
||
- service: script.set_downstairs_target_temp_based_on_conditions
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.upstairs
|
||
temperature: 82
|
||
|
||
- alias: 'Reset Upstairs to 82 Each Night'
|
||
id: reset_upstairs_thermostat_nightly_82
|
||
mode: single
|
||
trigger:
|
||
- platform: time
|
||
at: "03:00:00"
|
||
condition:
|
||
- condition: template
|
||
value_template: "{{ states('binary_sensor.powerwall_grid_status') == 'on' }}"
|
||
action:
|
||
- service: script.set_upstairs_cool_82
|
||
|
||
- alias: 'Humidity Control'
|
||
id: AC_Humidity_Control
|
||
mode: single
|
||
trigger:
|
||
- platform: numeric_state
|
||
entity_id: sensor.downstairs_humidity
|
||
above: 60
|
||
- platform: time
|
||
at: "02:00:00"
|
||
condition:
|
||
- condition: time
|
||
after: "01:00:00"
|
||
before: "08:00:00"
|
||
- condition: numeric_state
|
||
entity_id: sensor.downstairs_humidity
|
||
above: 60
|
||
- condition: template #Only needed in the winter months
|
||
value_template: "{{ now().month in [10, 11, 12, 1, 2, 3] }}"
|
||
- condition: template # Only run if AC is idle (prevents fighting other automations)
|
||
value_template: "{{ state_attr('climate.downstairs', 'hvac_action') == 'idle' }}"
|
||
- condition: template # Never run if the grid is down and running on powerwall.
|
||
value_template: "{{ states('binary_sensor.powerwall_grid_status')|lower == 'on' }}"
|
||
action:
|
||
- choose:
|
||
- conditions:
|
||
- condition: numeric_state
|
||
entity_id: sensor.pirateweather_temperature
|
||
below: 75
|
||
sequence:
|
||
- service: script.send_to_logbook
|
||
data:
|
||
topic: "CLIMATE"
|
||
message: "Skipping downstairs cool mode (outside temp <75F)."
|
||
default:
|
||
- service: climate.set_preset_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
preset_mode: 'none'
|
||
- service: climate.set_hvac_mode
|
||
data:
|
||
entity_id: climate.downstairs
|
||
hvac_mode: cool
|
||
- service: climate.set_temperature
|
||
data:
|
||
entity_id: climate.downstairs
|
||
temperature: 77
|
||
- delay: "00:20:00"
|
||
- service: script.set_downstairs_target_temp_based_on_conditions
|
||
- delay: "02:00:00" # stops it from being triggered again too soon.
|