Update blueprints/automations/bzo_climate.yaml

Edit presence detection.
This commit is contained in:
2025-07-30 12:05:46 +03:00
parent adcec21a5c
commit e82bc55d63

View File

@@ -1,331 +1,347 @@
blueprint: blueprint:
name: BZO's Smart Climate Controller name: BZO's Smart Climate Controller
description: > description: >
Automatically control a climate device based on indoor/outdoor temperatures, Automatically control a climate device based on indoor/outdoor temperatures,
using one command per update. Sends HVAC mode, temperature, and fan settings 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, 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. presence, schedule, optional override, optional away mode, logging level, and optional window detection.
domain: automation domain: automation
input: input:
climate_entity: climate_entity:
name: Climate Device name: Climate Device
description: 'Selet the unit or units that will be controled.' description: 'Selet the unit or units that will be controled.'
selector: selector:
entity: entity:
domain: climate domain: climate
room_temp_sensor: room_temp_sensor:
name: Room Temperature Sensor name: Room Temperature Sensor
description: 'Sensor or group of sensors used to calculate thermostat values.' description: 'Sensor or group of sensors used to calculate thermostat values.'
selector: selector:
entity: entity:
domain: sensor domain: sensor
device_class: temperature device_class: temperature
outdoor_temp_sensor: outdoor_temp_sensor:
name: Outdoor Temperature Sensor name: Outdoor Temperature Sensor
description: 'Used to determine HVAC mode ( cool or heat ).' description: 'Used to determine HVAC mode ( cool or heat ).'
selector: selector:
entity: entity:
domain: sensor domain: sensor
device_class: temperature device_class: temperature
presence_entity: presence_entity:
name: Presence Sensor or Group name: Presence Sensor or Group
description: 'Used to tun off the units if house is empty.' description: 'Used to tun off the units if house is empty.'
selector: selector:
entity: entity:
domain: person domain: person
schedule_entity: schedule_entity:
name: Schedule Helper name: Schedule Helper
description: 'Schedule for the unit to run.' description: 'Schedule for the unit to run.'
selector: selector:
entity: entity:
domain: schedule domain: schedule
override_switch: override_switch:
name: (Optional) Manual Override Switch name: (Optional) Manual Override Switch
description: 'Override presence and schedule and turn on the unit.' description: 'Override presence and schedule and turn on the unit.'
default: '' default: ''
selector: selector:
entity: entity:
domain: input_boolean domain: input_boolean
away_mode_helper: away_mode_helper:
name: (Optional) Away Mode Helper (turns off A/C) name: (Optional) Away Mode Helper (turns off A/C)
default: '' default: ''
selector: selector:
entity: entity:
domain: input_boolean domain: input_boolean
window_sensor: window_sensor:
name: (Optional) Window Sensor name: (Optional) Window Sensor
default: '' default: ''
selector: selector:
entity: entity:
domain: binary_sensor domain: binary_sensor
delta_fan_low: delta_fan_low:
name: Temperature Delta for Mid Fan name: Temperature Delta for Mid Fan
default: 2 default: 2
selector: selector:
number: number:
min: 1 min: 1
max: 5 max: 5
step: 0.5 step: 0.5
unit_of_measurement: °C unit_of_measurement: °C
delta_fan_high: delta_fan_high:
name: Temperature Delta for High Fan name: Temperature Delta for High Fan
default: 3 default: 3
selector: selector:
number: number:
min: 2 min: 2
max: 10 max: 10
step: 0.5 step: 0.5
unit_of_measurement: °C unit_of_measurement: °C
external_temp_threshold: external_temp_threshold:
name: External Temperature Heat/Cool Switch Threshold name: External Temperature Heat/Cool Switch Threshold
default: 18 default: 18
selector: selector:
number: number:
min: -10 min: -10
max: 35 max: 35
step: 1 step: 1
unit_of_measurement: °C unit_of_measurement: °C
target_temp_helper: target_temp_helper:
name: Target Temperature Helper name: Target Temperature Helper
description: ' description: '
Control your comfort temperature via automations or the UI, you can Control your comfort temperature via automations or the UI, you can
specify an *[input_number](https://www.home-assistant.io/integrations/input_number/)* specify an *[input_number](https://www.home-assistant.io/integrations/input_number/)*
entity here. entity here.
Create your helper [here](https://my.home-assistant.io/redirect/helpers/). ' Create your helper [here](https://my.home-assistant.io/redirect/helpers/). '
selector: selector:
entity: entity:
domain: input_number domain: input_number
temp_adjust_threshold: temp_adjust_threshold:
name: Temperature Delta Adjustment Threshold name: Temperature Delta Adjustment Threshold
description: 'The Delta value, representing the difference between the desired and actual temperature, will adjust the thermostat.' description: 'The Delta value, representing the difference between the desired and actual temperature, will adjust the thermostat.'
default: 4 default: 4
selector: selector:
number: number:
min: 0 min: 0
max: 10 max: 10
step: 0.5 step: 0.5
unit_of_measurement: °C unit_of_measurement: °C
temp_adjust_amount: temp_adjust_amount:
name: Temperature Adjustment 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.' description: 'How many degrees to add or subtract if the difference between the desired temp and actual temp is higher than Delta.'
default: 1 default: 1
selector: selector:
number: number:
min: 0 min: 0
max: 5 max: 5
step: 0.5 step: 0.5
unit_of_measurement: °C unit_of_measurement: °C
fan_mode_profile: fan_mode_profile:
name: Fan Mode Profile name: Fan Mode Profile
description: 'Fan mode: Standard for Auto, High, mid, low and numerif for Auto, 1, 2, etc.' description: 'Fan mode: Standard for Auto, High, mid, low and numerif for Auto, 1, 2, etc.'
default: standard default: standard
selector: selector:
select: select:
options: options:
- standard - standard
- numeric - numeric
log_level: log_level:
name: Logging Level name: Logging Level
default: info default: info
selector: selector:
select: select:
options: options:
- info - info
- debug - debug
mode: restart mode: restart
max_exceeded: silent max_exceeded: silent
trigger_variables: trigger_variables:
override_switch: !input override_switch override_switch: !input override_switch
trigger: trigger:
- platform: time_pattern - platform: time_pattern
minutes: "/5" minutes: "/5"
- platform: state - platform: state
entity_id: !input schedule_entity entity_id: !input schedule_entity
to: "on" to: "on"
- platform: state - platform: state
entity_id: !input target_temp_helper entity_id: !input target_temp_helper
condition: condition:
- condition: template - condition: template
value_template: > value_template: >
{{ override_switch == '' or is_state( override_switch, 'off') }} {{ override_switch == '' or is_state( override_switch, 'off') }}
- condition: state - condition: state
entity_id: !input schedule_entity entity_id: !input schedule_entity
state: "on" state: "on"
- condition: state - condition: state
entity_id: !input presence_entity entity_id: !input presence_entity
state: "home" state: "home"
# - condition: template # - condition: template
# value_template: > # value_template: >
# {% set window = window_sensor %} # {% set window = window_sensor %}
# {{ window == '' or is_state(window, 'off') }} # {{ window == '' or is_state(window, 'off') }}
action: action:
- variables: - variables:
climate: !input climate_entity climate: !input climate_entity
room_sensor: !input room_temp_sensor room_sensor: !input room_temp_sensor
outside_sensor: !input outdoor_temp_sensor outside_sensor: !input outdoor_temp_sensor
target_temp_entity: !input target_temp_helper target_temp_entity: !input target_temp_helper
fan_profile: !input fan_mode_profile fan_profile: !input fan_mode_profile
away: !input away_mode_helper away: !input away_mode_helper
adjust_threshold: !input temp_adjust_threshold adjust_threshold: !input temp_adjust_threshold
adjust_amount: !input temp_adjust_amount adjust_amount: !input temp_adjust_amount
delta_low: !input delta_fan_low delta_low: !input delta_fan_low
delta_high: !input delta_fan_high delta_high: !input delta_fan_high
threshold: !input external_temp_threshold threshold: !input external_temp_threshold
override_switch: !input override_switch override_switch: !input override_switch
presence_entity: !input presence_entity
room_temp: > room_temp: >
{% set r = states(room_sensor) %} {% set r = states(room_sensor) %}
{{ r | float(0) if r not in ['unknown', 'unavailable'] else 0 }} {{ r | float(0) if r not in ['unknown', 'unavailable'] else 0 }}
outside_temp: > outside_temp: >
{% set o = states(outside_sensor) %} {% set o = states(outside_sensor) %}
{{ o | float(999) if o not in ['unknown', 'unavailable'] else 999 }} {{ o | float(999) if o not in ['unknown', 'unavailable'] else 999 }}
desired_temp: > desired_temp: >
{% set t = states(target_temp_entity) %} {% set t = states(target_temp_entity) %}
{{ t | float(22) if t not in ['unknown', 'unavailable'] else 22 }} {{ t | float(22) if t not in ['unknown', 'unavailable'] else 22 }}
adjusted_temp: > adjusted_temp: >
{% set delta = (room_temp - desired_temp) | abs %} {% set delta = (room_temp - desired_temp) | abs %}
{% if delta >= adjust_threshold %} {% if delta >= adjust_threshold %}
{% if room_temp > desired_temp %} {% if room_temp > desired_temp %}
{{ desired_temp - adjust_amount }} {{ desired_temp - adjust_amount }}
{% else %}
{{ desired_temp + adjust_amount }}
{% endif %}
{% else %} {% else %}
{{ desired_temp + adjust_amount }} {{ desired_temp }}
{% endif %} {% endif %}
{% else %}
{{ desired_temp }}
{% endif %}
hvac_mode: > hvac_mode: >
{% if outside_temp < threshold %} heat {% if outside_temp < threshold %} heat
{% elif outside_temp < 999 %} cool {% 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 %} auto {% endif %}
{% else %}
{% if delta | abs >= delta_high %} "5"
{% elif delta | abs >= delta_low %} "3"
{% else %} "1" {% endif %}
{% endif %}
- choose: delta: "{{ room_temp - desired_temp }}"
- 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
- choose: fan_mode: >
- conditions: {% if fan_profile == 'standard' %}
- condition: template {% if delta | abs >= delta_high %} high
value_template: > {% elif delta | abs >= delta_low %} mid
{{ away != '' and is_state(away, 'on') }} {% else %} auto {% endif %}
sequence: {% else %}
- service: climate.turn_off {% if delta | abs >= delta_high %} "5"
target: {% elif delta | abs >= delta_low %} "3"
entity_id: !input climate_entity {% else %} "1" {% endif %}
- service: logbook.log {% endif %}
data:
name: "Smart Climate"
message: "A/C turned off due to Away Mode"
entity_id: !input climate_entity
- condition: template - choose:
value_template: > - conditions:
{{ away == '' or is_state(away, 'off') }} - 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
- choose: - choose:
- conditions: - conditions:
- condition: template - condition: template
value_template: "{{ log_level == 'debug' }}" value_template: >
sequence: {{ is_state(presence_entity, 'not_home') }}
- service: logbook.log sequence:
data: - service: climate.turn_off
name: "Smart Climate" target:
message: > entity_id: !input climate_entity
External temp = {{ outside_temp }}°C, Threshold = {{ threshold }}°C → Mode = {{ hvac_mode }} - service: logbook.log
entity_id: !input climate_entity data:
name: "Smart Climate"
message: "A/C turned off because no one is home"
entity_id: !input climate_entity
- service: logbook.log - choose:
data: - conditions:
name: "Smart Climate DEBUG" - condition: template
message: > value_template: >
Current state = {{ states(climate) }}, HVAC = {{ state_attr(climate, 'hvac_modes') or 'unknown' }}, {{ away != '' and is_state(away, 'on') }}
Temp = {{ state_attr(climate, 'temperature') }}, Fan = {{ state_attr(climate, 'fan_mode') or 'unknown' }}; sequence:
Target: HVAC = {{ hvac_mode }}, Temp = {{ adjusted_temp }}, Fan = {{ fan_mode }} - service: climate.turn_off
entity_id: !input climate_entity target:
- conditions: entity_id: !input climate_entity
- condition: template - service: logbook.log
value_template: "{{ log_level == 'info' }}" data:
sequence: name: "Smart Climate"
- service: logbook.log message: "A/C turned off due to Away Mode"
data: entity_id: !input climate_entity
name: "Smart Climate"
message: "Automation triggered (log level: info)"
entity_id: !input climate_entity
- condition: or - condition: template
conditions: value_template: >
- condition: template {{ away == '' or is_state(away, 'off') }}
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 - choose:
target: - conditions:
entity_id: !input climate_entity - condition: template
data: value_template: "{{ log_level == 'debug' }}"
temperature: "{{ adjusted_temp | float }}" sequence:
hvac_mode: "{{ hvac_mode }}" - service: logbook.log
fan_mode: "{{ fan_mode }}" data:
name: "Smart Climate"
message: >
External temp = {{ outside_temp }}°C, Threshold = {{ threshold }}°C → Mode = {{ hvac_mode }}
entity_id: !input climate_entity
- service: logbook.log - service: logbook.log
data: data:
name: "Smart Climate" name: "Smart Climate DEBUG"
message: > message: >
Sent command: HVAC = {{ hvac_mode }}, Temp = {{ adjusted_temp }}°C, Fan = {{ fan_mode }} Current state = {{ states(climate) }}, HVAC = {{ state_attr(climate, 'hvac_modes') or 'unknown' }},
entity_id: !input climate_entity 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
- delay: - condition: or
minutes: 1 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 }}"
fan_mode: "{{ fan_mode }}"
- 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
- delay:
minutes: 1