Update blueprints/automations/bzo_climate.yaml
latest version
This commit is contained in:
@@ -1,361 +1,643 @@
|
||||
blueprint:
|
||||
name: BZO's Smart Climate Controller
|
||||
description: >
|
||||
Automatically control a climate device based on indoor/outdoor temperatures,
|
||||
using one command per update. Sends HVAC mode, temperature, and fan settings
|
||||
only if different from current state. Supports external temp threshold for heat/cool switching,
|
||||
presence, schedule, optional override, optional away mode, logging level, and optional window detection.
|
||||
domain: automation
|
||||
input:
|
||||
climate_entity:
|
||||
name: Climate Device
|
||||
description: 'Selet the unit or units that will be controled.'
|
||||
selector:
|
||||
entity:
|
||||
domain: climate
|
||||
blueprint:
|
||||
name: BZO's Smart A/C Temperature Control
|
||||
description: Comprehensive A/C control with automatic temperature management, presence detection, scheduling, and safety features
|
||||
domain: automation
|
||||
input:
|
||||
thermostat_section:
|
||||
name: Climate Unit & Sensors
|
||||
icon: mdi:thermostat
|
||||
input:
|
||||
# Core Devices
|
||||
ac_unit:
|
||||
name: A/C Unit
|
||||
description: The climate entity for your A/C unit
|
||||
selector:
|
||||
entity:
|
||||
domain: climate
|
||||
|
||||
room_temp_sensor:
|
||||
name: Room Temperature Sensor
|
||||
description: 'Sensor or group of sensors used to calculate thermostat values.'
|
||||
selector:
|
||||
entity:
|
||||
domain: sensor
|
||||
device_class: temperature
|
||||
fan_mode_profile:
|
||||
name: Fan Mode Profile
|
||||
description: 'Fan mode: Standard for Auto, High, mid, low and numerif for Auto, 1, 2, etc.'
|
||||
default: standard
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- standard
|
||||
- numeric
|
||||
|
||||
outdoor_temp_sensor:
|
||||
name: Outdoor Temperature Sensor
|
||||
description: 'Used to determine HVAC mode ( cool or heat ).'
|
||||
selector:
|
||||
entity:
|
||||
domain: sensor
|
||||
device_class: temperature
|
||||
|
||||
presence_entity:
|
||||
name: ( Optional ) Presence Sensor or Group
|
||||
description: 'Used to tun off the units if house is empty.'
|
||||
default: ''
|
||||
selector:
|
||||
entity:
|
||||
domain: person
|
||||
|
||||
schedule_entity:
|
||||
name: Schedule Helper
|
||||
description: 'Schedule for the unit to run.'
|
||||
selector:
|
||||
entity:
|
||||
domain: schedule
|
||||
|
||||
override_switch:
|
||||
name: (Optional) Manual Override Switch
|
||||
description: 'Override presence and schedule and turn on the unit.'
|
||||
default: ''
|
||||
selector:
|
||||
entity:
|
||||
domain: input_boolean
|
||||
|
||||
away_mode_helper:
|
||||
name: (Optional) Away Mode Helper (turns off A/C)
|
||||
default: ''
|
||||
selector:
|
||||
entity:
|
||||
domain: input_boolean
|
||||
|
||||
window_sensor:
|
||||
name: (Optional) Window Sensor
|
||||
default: ''
|
||||
selector:
|
||||
entity:
|
||||
domain: binary_sensor
|
||||
|
||||
delta_fan_low:
|
||||
name: Temperature Delta for Mid Fan
|
||||
default: 2
|
||||
selector:
|
||||
number:
|
||||
min: 1
|
||||
max: 5
|
||||
step: 0.5
|
||||
unit_of_measurement: °C
|
||||
|
||||
delta_fan_high:
|
||||
name: Temperature Delta for High Fan
|
||||
default: 3
|
||||
selector:
|
||||
number:
|
||||
min: 2
|
||||
max: 10
|
||||
step: 0.5
|
||||
unit_of_measurement: °C
|
||||
|
||||
external_temp_threshold:
|
||||
name: External Temperature Heat/Cool Switch Threshold
|
||||
default: 18
|
||||
selector:
|
||||
number:
|
||||
min: -10
|
||||
max: 35
|
||||
step: 1
|
||||
unit_of_measurement: °C
|
||||
|
||||
target_temp_helper:
|
||||
name: Target Temperature Helper
|
||||
description: '
|
||||
Control your comfort temperature via automations or the UI, you can
|
||||
specify an *[input_number](https://www.home-assistant.io/integrations/input_number/)*
|
||||
entity here.
|
||||
|
||||
|
||||
Create your helper [here](https://my.home-assistant.io/redirect/helpers/). '
|
||||
selector:
|
||||
entity:
|
||||
domain: input_number
|
||||
|
||||
temp_adjust_threshold:
|
||||
name: Temperature Delta Adjustment Threshold
|
||||
description: 'The Delta value, representing the difference between the desired and actual temperature, will adjust the thermostat.'
|
||||
default: 4
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 10
|
||||
step: 0.5
|
||||
unit_of_measurement: °C
|
||||
|
||||
temp_adjust_amount:
|
||||
name: Temperature Adjustment Amount
|
||||
description: 'How many degrees to add or subtract if the difference between the desired temp and actual temp is higher than Delta.'
|
||||
default: 1
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 5
|
||||
step: 0.5
|
||||
unit_of_measurement: °C
|
||||
|
||||
fan_mode_profile:
|
||||
name: Fan Mode Profile
|
||||
description: 'Fan mode: Standard for Auto, High, mid, low and numerif for Auto, 1, 2, etc.'
|
||||
default: standard
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- standard
|
||||
- numeric
|
||||
|
||||
log_level:
|
||||
name: Logging Level
|
||||
default: info
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- info
|
||||
- debug
|
||||
|
||||
mode: restart
|
||||
max_exceeded: silent
|
||||
trigger_variables:
|
||||
override_switch: !input override_switch
|
||||
|
||||
trigger:
|
||||
- platform: time_pattern
|
||||
minutes: "/5"
|
||||
- platform: state
|
||||
entity_id: !input schedule_entity
|
||||
to: "on"
|
||||
- platform: state
|
||||
entity_id: !input target_temp_helper
|
||||
|
||||
condition:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ override_switch == '' or is_state( override_switch, 'off') }}
|
||||
- condition: state
|
||||
entity_id: !input schedule_entity
|
||||
state: "on"
|
||||
# - condition: state
|
||||
# entity_id: !input presence_entity
|
||||
# state: "home"
|
||||
# - condition: template
|
||||
# value_template: >
|
||||
# {% set window = window_sensor %}
|
||||
# {{ window == '' or is_state(window, 'off') }}
|
||||
|
||||
action:
|
||||
- variables:
|
||||
climate: !input climate_entity
|
||||
room_sensor: !input room_temp_sensor
|
||||
outside_sensor: !input outdoor_temp_sensor
|
||||
target_temp_entity: !input target_temp_helper
|
||||
fan_profile: !input fan_mode_profile
|
||||
away: !input away_mode_helper
|
||||
adjust_threshold: !input temp_adjust_threshold
|
||||
adjust_amount: !input temp_adjust_amount
|
||||
delta_low: !input delta_fan_low
|
||||
delta_high: !input delta_fan_high
|
||||
threshold: !input external_temp_threshold
|
||||
override_switch: !input override_switch
|
||||
presence: !input presence_entity
|
||||
log_level: !input log_level
|
||||
schedule_entity: !input schedule_entity
|
||||
|
||||
room_temp: >
|
||||
{% set r = states(room_sensor) %}
|
||||
{{ r | float(0) if r not in ['unknown', 'unavailable'] else 0 }}
|
||||
|
||||
outside_temp: >
|
||||
{% set o = states(outside_sensor) %}
|
||||
{{ o | float(999) if o not in ['unknown', 'unavailable'] else 999 }}
|
||||
|
||||
desired_temp: >
|
||||
{% set t = states(target_temp_entity) %}
|
||||
{{ t | float(22) if t not in ['unknown', 'unavailable'] else 22 }}
|
||||
|
||||
adjusted_temp: >
|
||||
{% set delta = (room_temp - desired_temp) | abs %}
|
||||
{% if delta >= adjust_threshold %}
|
||||
{% if room_temp > desired_temp %}
|
||||
{{ desired_temp - adjust_amount }}
|
||||
{% else %}
|
||||
{{ desired_temp + adjust_amount }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ desired_temp }}
|
||||
{% endif %}
|
||||
|
||||
hvac_mode: >
|
||||
{% if outside_temp < threshold %} heat
|
||||
{% elif outside_temp < 999 %} cool
|
||||
{% else %} auto {% endif %}
|
||||
|
||||
delta: "{{ room_temp - desired_temp }}"
|
||||
|
||||
fan_mode: >
|
||||
{% if fan_profile == 'standard' %}
|
||||
{% if delta | abs >= delta_high %} high
|
||||
{% elif delta | abs >= delta_low %} mid
|
||||
{% else %} auto {% endif %}
|
||||
{% else %}
|
||||
{% if delta | abs >= delta_high %} "5"
|
||||
{% elif delta | abs >= delta_low %} "3"
|
||||
{% else %} "1" {% endif %}
|
||||
{% endif %}
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: !input schedule_entity
|
||||
state: "off"
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input climate_entity
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off because schedule is OFF"
|
||||
entity_id: !input climate_entity
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ schedule_entity != 'off' }}
|
||||
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ presence != '' and is_state(presence, 'not_home') }}
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input climate_entity
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off due to absence (not_home)"
|
||||
entity_id: !input climate_entity
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ presence == '' or is_state(presence, 'home') }}
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ away != '' and is_state(away, 'on') }}
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input climate_entity
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off due to Away Mode"
|
||||
entity_id: !input climate_entity
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ away == '' or is_state(away, 'off') }}
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ log_level == 'debug' }}"
|
||||
sequence:
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: >
|
||||
External temp = {{ outside_temp }}°C, Threshold = {{ threshold }}°C → Mode = {{ hvac_mode }}
|
||||
entity_id: !input climate_entity
|
||||
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate DEBUG"
|
||||
message: >
|
||||
Current state = {{ states(climate) }}, HVAC = {{ state_attr(climate, 'hvac_modes') or 'unknown' }},
|
||||
Temp = {{ state_attr(climate, 'temperature') }}, Fan = {{ state_attr(climate, 'fan_mode') or 'unknown' }};
|
||||
Target: HVAC = {{ hvac_mode }}, Temp = {{ adjusted_temp }}, Fan = {{ fan_mode }}
|
||||
entity_id: !input climate_entity
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ log_level == 'info' }}"
|
||||
sequence:
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "Automation triggered (log level: info)"
|
||||
entity_id: !input climate_entity
|
||||
|
||||
- condition: or
|
||||
conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ states(climate) in ['off', 'unavailable', 'unknown'] }}
|
||||
- condition: template
|
||||
value_template: >
|
||||
{% set state = states(climate) %}
|
||||
{% set fan = (state_attr(climate, 'fan_mode') or 'unknown') | string %}
|
||||
{% set temp = state_attr(climate, 'temperature') | float(999) %}
|
||||
{{ state != hvac_mode or fan != fan_mode or (temp | round(1)) != (adjusted_temp | round(1)) }}
|
||||
|
||||
- service: climate.set_temperature
|
||||
target:
|
||||
entity_id: !input climate_entity
|
||||
data:
|
||||
temperature: "{{ adjusted_temp | float }}"
|
||||
hvac_mode: "{{ hvac_mode }}"
|
||||
room_temperature_sensor:
|
||||
name: Room Temperature Sensor
|
||||
description: Dedicated room temperature sensor
|
||||
selector:
|
||||
entity:
|
||||
domain: sensor
|
||||
#device_class: temperature
|
||||
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input climate_entity
|
||||
data:
|
||||
fan_mode: "{{ fan_mode }}"
|
||||
external_temperature_sensor:
|
||||
name: External Temperature Sensor
|
||||
description: External temperature sensor for heat/cool mode selection
|
||||
selector:
|
||||
entity:
|
||||
domain: sensor
|
||||
device_class: temperature
|
||||
helper_section:
|
||||
name: Helper section
|
||||
icon: mdi:sun-clock
|
||||
collapsed: true
|
||||
input:
|
||||
# Helpers
|
||||
desired_temperature_helper:
|
||||
name: Desired Temperature Helper
|
||||
description: Input number helper to store desired temperature
|
||||
selector:
|
||||
entity:
|
||||
domain: input_number
|
||||
|
||||
schedule_helper:
|
||||
name: Schedule Helper
|
||||
description: Schedule helper for time-based control
|
||||
selector:
|
||||
entity:
|
||||
domain: schedule
|
||||
|
||||
override_helper:
|
||||
name: Override Helper
|
||||
description: Boolean helper to override automatic control
|
||||
selector:
|
||||
entity:
|
||||
domain: input_boolean
|
||||
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: >
|
||||
Sent command: HVAC = {{ hvac_mode }}, Temp = {{ adjusted_temp }}°C, Fan = {{ fan_mode }}
|
||||
entity_id: !input climate_entity
|
||||
away_mode_helper:
|
||||
name: (Optional) Away Mode Helper (turns off A/C)
|
||||
default: ''
|
||||
selector:
|
||||
entity:
|
||||
domain: input_boolean
|
||||
|
||||
- delay:
|
||||
minutes: 1
|
||||
temp_control_waiting_helper:
|
||||
name: temp_control_waiting Helper
|
||||
selector:
|
||||
entity:
|
||||
domain: input_boolean
|
||||
|
||||
temp_control_last_check_helper:
|
||||
name: temp_control_last_check Helper
|
||||
selector:
|
||||
entity:
|
||||
domain: input_datetime
|
||||
|
||||
presence_section:
|
||||
name: Presence and Detection section
|
||||
icon: mdi:sun-clock
|
||||
collapsed: true
|
||||
input:
|
||||
window_detection_entity:
|
||||
name: Window Detection Entity
|
||||
description: Entity that detects if windows are open (binary_sensor) - Optional
|
||||
default: ""
|
||||
selector:
|
||||
entity:
|
||||
domain: binary_sensor
|
||||
|
||||
# Presence Detection
|
||||
presence_entity:
|
||||
name: Presence Entity
|
||||
description: Entity that tracks if someone is home - Optional
|
||||
default: ""
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- person
|
||||
- group
|
||||
|
||||
# Timing Configuration
|
||||
home_duration:
|
||||
name: Home Duration
|
||||
description: Minutes to wait after arriving home before turning on A/C
|
||||
default: 5
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 60
|
||||
unit_of_measurement: minutes
|
||||
|
||||
away_duration:
|
||||
name: Away Duration
|
||||
description: Minutes to wait after leaving home before turning off A/C
|
||||
default: 15
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 120
|
||||
unit_of_measurement: minutes
|
||||
|
||||
window_reaction_time:
|
||||
name: Window Reaction Time
|
||||
description: Minutes to wait after window detection before taking action
|
||||
default: 2
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 30
|
||||
unit_of_measurement: minutes
|
||||
|
||||
# off_duration_check:
|
||||
# name: Off Duration Check
|
||||
# description: Minutes to keep A/C off when desired temperature is reached
|
||||
# default: 10
|
||||
# selector:
|
||||
# number:
|
||||
# min: 5
|
||||
# max: 60
|
||||
# unit_of_measurement: minutes
|
||||
|
||||
no_action_duration:
|
||||
name: No Action Duration
|
||||
description: Minutes of no actions after A/C was turned off
|
||||
default: 5
|
||||
selector:
|
||||
number:
|
||||
min: 1
|
||||
max: 30
|
||||
unit_of_measurement: minutes
|
||||
|
||||
# restart_check_duration:
|
||||
# name: Restart Check Duration
|
||||
# description: Minutes to wait before checking if A/C should restart
|
||||
# default: 15
|
||||
# selector:
|
||||
# number:
|
||||
# min: 5
|
||||
# max: 60
|
||||
# unit_of_measurement: minutes
|
||||
|
||||
# Temperature Configuration
|
||||
temp_delta_low:
|
||||
name: Temperature Delta for Med Intensity
|
||||
description: Temperature difference to trigger low fan intensity
|
||||
default: 2.0
|
||||
selector:
|
||||
number:
|
||||
min: 0.5
|
||||
max: 5.0
|
||||
step: 0.5
|
||||
unit_of_measurement: "°C"
|
||||
|
||||
temp_delta_high:
|
||||
name: Temperature Delta for High Intensity
|
||||
description: Temperature difference to trigger high fan intensity
|
||||
default: 3.0
|
||||
selector:
|
||||
number:
|
||||
min: 1.0
|
||||
max: 10.0
|
||||
step: 0.5
|
||||
unit_of_measurement: "°C"
|
||||
|
||||
calibration_offset:
|
||||
name: Calibration Offset
|
||||
description: Temperature offset for A/C unit calibration
|
||||
default: 0.0
|
||||
selector:
|
||||
number:
|
||||
min: -5.0
|
||||
max: 5.0
|
||||
step: 0.1
|
||||
unit_of_measurement: "°C"
|
||||
|
||||
cool_heat_threshold:
|
||||
name: Cool/Heat Threshold
|
||||
description: External temperature threshold to switch between cooling and heating
|
||||
default: 20.0
|
||||
selector:
|
||||
number:
|
||||
min: 10.0
|
||||
max: 30.0
|
||||
step: 0.5
|
||||
unit_of_measurement: "°C"
|
||||
|
||||
debug_mode:
|
||||
name: Debug Mode
|
||||
description: 'Set Debug mode to show values for variables.'
|
||||
default: standard
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- standard
|
||||
- debug
|
||||
variables:
|
||||
climate_dev: !input ac_unit
|
||||
room_temperature_sensor: !input room_temperature_sensor
|
||||
desired_temperature_helper: !input desired_temperature_helper
|
||||
external_temperature_sensor: !input external_temperature_sensor
|
||||
presence_entity: !input presence_entity
|
||||
schedule_helper: !input schedule_helper
|
||||
override_helper: !input override_helper
|
||||
window_detection_entity: !input window_detection_entity
|
||||
calibration_offset: !input calibration_offset
|
||||
cool_heat_threshold: !input cool_heat_threshold
|
||||
temp_delta_high: !input temp_delta_high
|
||||
temp_delta_low: !input temp_delta_low
|
||||
fan_profile: !input fan_mode_profile
|
||||
away: !input away_mode_helper
|
||||
temp_control_last_check: !input temp_control_last_check_helper
|
||||
temp_control_waiting: !input temp_control_waiting_helper
|
||||
no_action_duration_var: !input no_action_duration
|
||||
debug: !input debug_mode
|
||||
|
||||
no_action_duration_sec: "{{ no_action_duration_var*60 }}"
|
||||
ac_off: "{{ is_state(climate_dev, 'off') }}"
|
||||
room_temp: "{{ states(room_temperature_sensor) | float(0) }}"
|
||||
desired_temp: "{{ states(desired_temperature_helper) | float(20) }}"
|
||||
external_temp: "{{ states(external_temperature_sensor) | float(20) }}"
|
||||
temp_delta: "{{ (room_temp - desired_temp) | abs }}"
|
||||
is_home: "{{ presence_entity == '' or is_state(presence_entity, 'home') }}"
|
||||
is_scheduled: "{{ is_state(schedule_helper, 'on') }}"
|
||||
is_override: "{{ is_state(override_helper, 'on') }}"
|
||||
is_window_open: "{{ window_detection_entity != '' and is_state(window_detection_entity, 'on') }}"
|
||||
|
||||
should_cool: "{{ external_temp > cool_heat_threshold }}"
|
||||
should_heat: "{{ external_temp <= cool_heat_threshold }}"
|
||||
should_be_off: >-
|
||||
{% if should_cool %}
|
||||
{% if room_temp < (desired_temp - temp_delta_high) %}
|
||||
true
|
||||
{% else %}
|
||||
false
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if room_temp > (desired_temp + temp_delta_high) %}
|
||||
true
|
||||
{% else %}
|
||||
false
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
hvac_mode: >-
|
||||
{% if should_cool %} "cool"
|
||||
{% else %} "heat"
|
||||
{% endif %}
|
||||
calibrated_temp: >-
|
||||
{% if should_cool %}
|
||||
{% if room_temp > desired_temp %} {{ desired_temp - calibration_offset }}
|
||||
{% elif room_temp <= desired_temp %} {{ desired_temp }} {% endif %}
|
||||
{% else %}
|
||||
{% if room_temp > desired_temp %} {{ desired_temp }}
|
||||
{% elif room_temp <= desired_temp %} {{ desired_temp + calibration_offset }} {% endif %}
|
||||
{% endif %}
|
||||
climate_fan_mode: >-
|
||||
{% if fan_profile == 'standard' %}
|
||||
{% if ( temp_delta | abs ) >= temp_delta_high %} high
|
||||
{% elif ( temp_delta | abs ) >= temp_delta_low %} mid
|
||||
{% else %} auto {% endif %}
|
||||
{% else %}
|
||||
{% if ( temp_delta | abs ) >= temp_delta_high %} 5
|
||||
{% elif ( temp_delta | abs ) >= temp_delta_low %} 3
|
||||
{% else %} auto {% endif %}
|
||||
{% endif %}
|
||||
ac_fan_mode: "{{ state_attr(climate_dev, 'fan_mode') }}"
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: !input desired_temperature_helper
|
||||
id: desire_temp_change
|
||||
# - platform: state
|
||||
# entity_id: !input room_temperature_sensor
|
||||
# id: temp_change
|
||||
- platform: state
|
||||
entity_id: !input schedule_helper
|
||||
id: schedule_change
|
||||
- platform: state
|
||||
entity_id: !input override_helper
|
||||
id: override_change
|
||||
# - platform: state
|
||||
# entity_id: !input external_temperature_sensor
|
||||
# id: external_temp_change
|
||||
- platform: state
|
||||
entity_id: !input away_mode_helper
|
||||
id: state
|
||||
- platform: state
|
||||
entity_id: !input temp_control_waiting_helper
|
||||
to: "off"
|
||||
id: temp_control_waiting_off
|
||||
#Time-based trigger to handle optional entities
|
||||
- platform: time_pattern
|
||||
minutes: "/5"
|
||||
id: periodic_check
|
||||
|
||||
condition: []
|
||||
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ not ac_off or ac_off}}"
|
||||
- condition: template
|
||||
value_template: "{{ debug == 'debug'}}"
|
||||
sequence:
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: ' Room_temp = {{ room_temp }}°C, Desired_temp = {{ desired_temp }}°C
|
||||
|
||||
Calculated = {{ calibrated_temp }}°C → Cool = {{ should_cool }}
|
||||
|
||||
Fan_mode = {{ climate_fan_mode }}, AC_off = {{ ac_off }}
|
||||
|
||||
AC_mode = {{ states(climate_dev) }}
|
||||
|
||||
Temp_delta = {{ temp_delta }}, Is_Home = {{ is_home }}
|
||||
|
||||
date= {{ states(temp_control_last_check) | as_datetime }}, seconds: {{ (now().timestamp() - states(temp_control_last_check) | as_datetime | as_timestamp) }}
|
||||
|
||||
time_no_action: {{ no_action_duration_sec }}
|
||||
|
||||
'
|
||||
entity_id: !input ac_unit
|
||||
- choose:
|
||||
# AWAY mode - turn off A/C if on, otherwise stop
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{ away != '' and is_state(away, 'on') }}
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: not
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input ac_unit
|
||||
state: "off"
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off due to Away Mode"
|
||||
entity_id: !input ac_unit
|
||||
default:
|
||||
- stop: "Away mode active but A/C already off"
|
||||
- stop: "Away mode active"
|
||||
|
||||
# Window open - turn off A/C
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ is_window_open }}"
|
||||
- "{{ not ac_off }}"
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off due to Window detected open"
|
||||
entity_id: !input ac_unit
|
||||
- stop: "Window detected open"
|
||||
|
||||
# Not home - turn off A/C
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ not is_home }}"
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: not
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input ac_unit
|
||||
state: "off"
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off due Nobody Home"
|
||||
entity_id: !input ac_unit
|
||||
default:
|
||||
- stop: "Nobody Home active but A/C already off"
|
||||
- stop: "Nobody Home mode active"
|
||||
|
||||
# Not scheduled - turn off A/C
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ not is_scheduled }}"
|
||||
- "{{ not is_override }}"
|
||||
#- "{{ not ac_off }}"
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: not
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input ac_unit
|
||||
state: "off"
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: "Smart Climate"
|
||||
message: "A/C turned off due Outside schedule"
|
||||
entity_id: !input ac_unit
|
||||
default:
|
||||
- stop: "Outside schedule active but A/C already off"
|
||||
- stop: "Outside schedule mode active"
|
||||
|
||||
# Currently waiting - check if 10 minutes have passed
|
||||
- conditions:
|
||||
- condition: state
|
||||
entity_id: !input temp_control_waiting_helper
|
||||
state: 'on'
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ (now().timestamp() - states(temp_control_last_check) | as_datetime | as_timestamp) >= no_action_duration_sec }}
|
||||
sequence:
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ (should_cool and room_temp <= desired_temp) or
|
||||
(not should_cool and room_temp >= desired_temp) }}
|
||||
then:
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: !input temp_control_last_check_helper
|
||||
data:
|
||||
datetime: "{{ now() }}"
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ (should_cool and room_temp > desired_temp) or
|
||||
(not should_cool and room_temp < desired_temp) }}
|
||||
then:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: !input temp_control_waiting_helper
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: Temperature Control
|
||||
message: >-
|
||||
10-minute wait completed. Rechecking temperature: {{ room_temp }}° vs {{ desired_temp }}°
|
||||
|
||||
# Temperature reached target - turn off and wait
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ room_temp + 0.5 <= desired_temp }}"
|
||||
- condition: state
|
||||
entity_id: !input ac_unit
|
||||
state: 'cool'
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: !input temp_control_waiting_helper
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: !input temp_control_last_check_helper
|
||||
data:
|
||||
datetime: "{{ now() }}"
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: Temperature Control
|
||||
message: >-
|
||||
Target reached ({{ room_temp }}° vs {{ desired_temp }}° ).
|
||||
Stopping unit for 10 minutes.
|
||||
- stop: "Temperature control cycle"
|
||||
|
||||
# # Similar logic for heating mode
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ room_temp - 0.5 > desired_temp }}"
|
||||
- condition: state
|
||||
entity_id: !input ac_unit
|
||||
state: 'heat'
|
||||
sequence:
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: !input temp_control_waiting_helper
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: !input temp_control_last_check_helper
|
||||
data:
|
||||
datetime: "{{ now() }}"
|
||||
- service: logbook.log
|
||||
data:
|
||||
name: Temperature Control
|
||||
message: >-
|
||||
Target reached ({{ room_temp }}° vs {{ desired_temp }}°).
|
||||
Stopping unit for 10 minutes.
|
||||
- stop: "Temperature control cycle"
|
||||
|
||||
# Main control logic
|
||||
default:
|
||||
- choose:
|
||||
# Cooling mode
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ should_cool and (is_scheduled or is_override) }}"
|
||||
- condition: and
|
||||
conditions:
|
||||
- "{{ (room_temp + 0.5) >= desired_temp and ((climate_fan_mode != state_attr(climate_dev, 'fan_mode')
|
||||
or calibrated_temp != state_attr(climate_dev, 'temperature') or ac_off)) }}"
|
||||
- condition: state
|
||||
entity_id: !input temp_control_waiting_helper
|
||||
state: 'off'
|
||||
sequence:
|
||||
- service: climate.set_temperature
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
temperature: "{{ calibrated_temp | abs }}"
|
||||
hvac_mode: cool
|
||||
- choose:
|
||||
# High intensity
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ temp_delta >= temp_delta_high }}"
|
||||
sequence:
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
fan_mode: "{{ climate_fan_mode }}"
|
||||
# Low intensity
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ temp_delta >= temp_delta_low }}"
|
||||
sequence:
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
fan_mode: "{{ climate_fan_mode }}"
|
||||
# Auto intensity (default)
|
||||
default:
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
fan_mode: auto
|
||||
|
||||
# Heating mode
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ should_heat and (is_scheduled or is_override) }}"
|
||||
- condition: and
|
||||
conditions:
|
||||
#- states(climate_dev) != heat
|
||||
- "{{ (room_temp - 0.5) <= desired_temp and (climate_fan_mode != state_attr(climate_dev, 'fan_mode')
|
||||
or calibrated_temp != state_attr(climate_dev, 'temperature') or ac_off) }}"
|
||||
sequence:
|
||||
- service: climate.set_temperature
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
temperature: "{{ calibrated_temp }}"
|
||||
hvac_mode: heat
|
||||
- choose:
|
||||
# High intensity
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ temp_delta >= temp_delta_high }}"
|
||||
sequence:
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
fan_mode: high
|
||||
# Low intensity
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ temp_delta >= temp_delta_low }}"
|
||||
sequence:
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
fan_mode: mid
|
||||
# Auto intensity (default)
|
||||
default:
|
||||
- service: climate.set_fan_mode
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
data:
|
||||
fan_mode: auto
|
||||
|
||||
# Turn off if temperature is within acceptable range
|
||||
default:
|
||||
- condition: template
|
||||
value_template: "{{ should_be_off == true }}"
|
||||
- service: climate.turn_off
|
||||
target:
|
||||
entity_id: !input ac_unit
|
||||
|
||||
mode: queued
|
||||
max_exceeded: silent
|
||||
|
||||
Reference in New Issue
Block a user