Update ha-smart-thermostat-control.yaml
manual adjustments are out
This commit is contained in:
parent
284e428e0c
commit
fc3a572171
1 changed files with 32 additions and 156 deletions
|
|
@ -2,11 +2,9 @@ blueprint:
|
||||||
name: "Smart Thermostat Controller"
|
name: "Smart Thermostat Controller"
|
||||||
author: Andreas Gammelgaard Damsbo
|
author: Andreas Gammelgaard Damsbo
|
||||||
description: |
|
description: |
|
||||||
Advanced thermostat automation with window/door sensors, presence detection, time schedules, and holiday calendar integration.
|
Smart thermostat automation based on window/door sensors, outside temperature (winter mode), time schedules, and holiday calendar integration.
|
||||||
|
|
||||||
SETUP REQUIRED:
|
* **Day Temperature is now controlled by a separate Input Number Helper.**
|
||||||
1. Create an input_boolean helper (Settings > Devices & Services > Helpers > Toggle) for manual override tracking
|
|
||||||
2. Create a timer helper (Settings > Devices & Services > Helpers > Timer) for override duration
|
|
||||||
domain: automation
|
domain: automation
|
||||||
source_url: https://gdamsbo.dk/forgejo/andreas/ha-smart-thermostat-control/raw/branch/main/ha-smart-thermostat-control.yaml
|
source_url: https://gdamsbo.dk/forgejo/andreas/ha-smart-thermostat-control/raw/branch/main/ha-smart-thermostat-control.yaml
|
||||||
input:
|
input:
|
||||||
|
|
@ -18,33 +16,6 @@ blueprint:
|
||||||
domain:
|
domain:
|
||||||
- climate
|
- climate
|
||||||
multiple: true
|
multiple: true
|
||||||
manual_override_helper:
|
|
||||||
name: Manual Override Helper
|
|
||||||
description: Select an input_boolean helper to track manual temperature overrides. Create one in Settings > Devices & Services > Helpers.
|
|
||||||
selector:
|
|
||||||
entity:
|
|
||||||
domain:
|
|
||||||
- input_boolean
|
|
||||||
multiple: false
|
|
||||||
override_timer:
|
|
||||||
name: Override Timer
|
|
||||||
description: Select a timer helper to manage override duration. Create one in Settings > Devices & Services > Helpers > Timer.
|
|
||||||
selector:
|
|
||||||
entity:
|
|
||||||
domain:
|
|
||||||
- timer
|
|
||||||
multiple: false
|
|
||||||
override_duration:
|
|
||||||
name: Manual Override Duration
|
|
||||||
description: 'How long manual temperature changes should override the schedule. This sets the timer duration. (Default = 120 minutes)'
|
|
||||||
default: 120
|
|
||||||
selector:
|
|
||||||
number:
|
|
||||||
mode: box
|
|
||||||
min: 30.0
|
|
||||||
max: 480.0
|
|
||||||
unit_of_measurement: minutes
|
|
||||||
step: 30.0
|
|
||||||
window_sensor:
|
window_sensor:
|
||||||
name: Window / Door Sensor Group
|
name: Window / Door Sensor Group
|
||||||
description: Select your grouped or single window / door sensor.
|
description: Select your grouped or single window / door sensor.
|
||||||
|
|
@ -102,16 +73,14 @@ blueprint:
|
||||||
domain:
|
domain:
|
||||||
- schedule
|
- schedule
|
||||||
multiple: false
|
multiple: false
|
||||||
day_temp:
|
day_temp_helper:
|
||||||
name: Day Time Temperature Target
|
name: Day Time Temperature Input Number
|
||||||
default: 21
|
description: Select an input_number helper that stores the desired Day Time temperature. (Create one in Settings > Devices & Services > Helpers).
|
||||||
selector:
|
selector:
|
||||||
number:
|
entity:
|
||||||
step: 0.5
|
domain:
|
||||||
min: 10.0
|
- input_number
|
||||||
max: 30.0
|
multiple: false
|
||||||
unit_of_measurement: °C or °F
|
|
||||||
mode: slider
|
|
||||||
night_temp:
|
night_temp:
|
||||||
name: Night Time Temperature Target
|
name: Night Time Temperature Target
|
||||||
default: 18
|
default: 18
|
||||||
|
|
@ -175,17 +144,8 @@ trigger:
|
||||||
entity_id: !input schedule_helper
|
entity_id: !input schedule_helper
|
||||||
id: schedule_change
|
id: schedule_change
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: !input thermostat
|
entity_id: !input day_temp_helper # Trigger when the input number changes
|
||||||
attribute: temperature
|
id: day_temp_change
|
||||||
id: manual_adjustment
|
|
||||||
- platform: state
|
|
||||||
entity_id: !input manual_override_helper
|
|
||||||
to: 'off'
|
|
||||||
id: override_expired
|
|
||||||
- platform: state
|
|
||||||
entity_id: !input override_timer
|
|
||||||
to: 'idle'
|
|
||||||
id: timer_finished
|
|
||||||
- platform: calendar
|
- platform: calendar
|
||||||
event: end
|
event: end
|
||||||
entity_id: !input away_calendar
|
entity_id: !input away_calendar
|
||||||
|
|
@ -205,86 +165,23 @@ trigger:
|
||||||
variables:
|
variables:
|
||||||
thermostat_entities: !input thermostat
|
thermostat_entities: !input thermostat
|
||||||
triggered_thermostat: "{{ trigger.entity_id | default('none') }}"
|
triggered_thermostat: "{{ trigger.entity_id | default('none') }}"
|
||||||
# Access temperature safely:
|
|
||||||
# 1. Get the 'to_state', defaulting to a simple object/dict if missing.
|
# Entity ID variables for safe templating in action conditions
|
||||||
# 2. Get the 'attributes' from that object, defaulting to a dict if missing.
|
|
||||||
# 3. Get the 'temperature' from the attributes, defaulting to 0, then convert to float.
|
|
||||||
new_temperature: >
|
|
||||||
{{ trigger.to_state.attributes.temperature | default(0) | float(0)
|
|
||||||
if trigger.to_state is defined and trigger.to_state.attributes is defined
|
|
||||||
else 0 }}
|
|
||||||
old_temperature: >
|
|
||||||
{{ trigger.from_state.attributes.temperature | default(0) | float(0)
|
|
||||||
if trigger.from_state is defined and trigger.from_state.attributes is defined
|
|
||||||
else 0 }}
|
|
||||||
override_helper: !input manual_override_helper
|
|
||||||
override_duration_id: !input override_duration
|
|
||||||
day_temp_input: !input day_temp
|
|
||||||
night_temp_input: !input night_temp
|
|
||||||
away_temp_input: !input away_temp
|
|
||||||
schedule_helper_id: !input schedule_helper
|
schedule_helper_id: !input schedule_helper
|
||||||
away_calendar_id: !input away_calendar
|
away_calendar_id: !input away_calendar
|
||||||
|
|
||||||
|
# --- REVISED VARIABLE: Get state value from helper ---
|
||||||
|
day_temp_input: "{{ states(!input day_temp_helper) | float(21) }}"
|
||||||
|
# --- END REVISED VARIABLE ---
|
||||||
|
|
||||||
|
night_temp_input: !input night_temp
|
||||||
|
away_temp_input: !input away_temp
|
||||||
|
|
||||||
condition: []
|
condition: []
|
||||||
|
|
||||||
action:
|
action:
|
||||||
- choose:
|
- choose:
|
||||||
# Priority 0: Manual Adjustment - Detect and enable override
|
# Priority 1: Windows/Doors Open - Turn OFF heating
|
||||||
- conditions:
|
|
||||||
- condition: trigger
|
|
||||||
id: manual_adjustment
|
|
||||||
# Only if temperature actually changed
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ (new_temperature - old_temperature) | abs > 0.1 }}"
|
|
||||||
# Only if the new temp is different from current schedule targets
|
|
||||||
- condition: template
|
|
||||||
value_template: >
|
|
||||||
{% if is_state(away_calendar_id, 'on') %}
|
|
||||||
{{ (new_temperature - away_temp_input) | abs > 0.1 }}
|
|
||||||
{% elif is_state(schedule_helper_id, 'on') %}
|
|
||||||
{{ (new_temperature - day_temp_input) | abs > 0.1 }}
|
|
||||||
{% else %}
|
|
||||||
{{ (new_temperature - night_temp_input) | abs > 0.1 }}
|
|
||||||
{% endif %}
|
|
||||||
sequence:
|
|
||||||
- service: logbook.log
|
|
||||||
data:
|
|
||||||
name: Smart Thermostat
|
|
||||||
message: 'Manual Override: {{ triggered_thermostat }} changed to {{ new_temperature }}°, syncing others'
|
|
||||||
# Sync temperature to all other thermostats
|
|
||||||
- repeat:
|
|
||||||
for_each: "{{ thermostat_entities | reject('eq', triggered_thermostat) | list }}"
|
|
||||||
sequence:
|
|
||||||
- service: climate.set_temperature
|
|
||||||
target:
|
|
||||||
entity_id: "{{ repeat.item }}"
|
|
||||||
data:
|
|
||||||
temperature: "{{ new_temperature }}"
|
|
||||||
# Enable manual override mode
|
|
||||||
- service: input_boolean.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: !input manual_override_helper
|
|
||||||
# Start timer
|
|
||||||
- service: timer.start
|
|
||||||
target:
|
|
||||||
entity_id: !input override_timer
|
|
||||||
data:
|
|
||||||
duration: "{{ (override_duration_id * 60) | int }}"
|
|
||||||
|
|
||||||
# Priority 0b: Timer Finished - Disable override and resume schedule
|
|
||||||
- conditions:
|
|
||||||
- condition: trigger
|
|
||||||
id: timer_finished
|
|
||||||
sequence:
|
|
||||||
- service: input_boolean.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: !input manual_override_helper
|
|
||||||
- service: logbook.log
|
|
||||||
data:
|
|
||||||
name: Smart Thermostat
|
|
||||||
message: 'Manual Override: Timer expired, resuming schedule'
|
|
||||||
|
|
||||||
# Priority 1: Windows/Doors Open - Turn OFF heating (overrides manual)
|
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: !input window_sensor
|
entity_id: !input window_sensor
|
||||||
|
|
@ -294,18 +191,12 @@ action:
|
||||||
- service: climate.turn_off
|
- service: climate.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: !input thermostat
|
entity_id: !input thermostat
|
||||||
- service: input_boolean.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: !input manual_override_helper
|
|
||||||
- service: timer.cancel
|
|
||||||
target:
|
|
||||||
entity_id: !input override_timer
|
|
||||||
- service: logbook.log
|
- service: logbook.log
|
||||||
data:
|
data:
|
||||||
name: Smart Thermostat
|
name: Smart Thermostat
|
||||||
message: 'Heating OFF: Window or door is open'
|
message: 'Heating OFF: Window or door is open'
|
||||||
|
|
||||||
# Priority 2: Too Warm Outside - Turn OFF heating (overrides manual)
|
# Priority 2: Too Warm Outside - Turn OFF heating
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: numeric_state
|
- condition: numeric_state
|
||||||
entity_id: !input outdoor
|
entity_id: !input outdoor
|
||||||
|
|
@ -314,29 +205,12 @@ action:
|
||||||
- service: climate.turn_off
|
- service: climate.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: !input thermostat
|
entity_id: !input thermostat
|
||||||
- service: input_boolean.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: !input manual_override_helper
|
|
||||||
- service: timer.cancel
|
|
||||||
target:
|
|
||||||
entity_id: !input override_timer
|
|
||||||
- service: logbook.log
|
- service: logbook.log
|
||||||
data:
|
data:
|
||||||
name: Smart Thermostat
|
name: Smart Thermostat
|
||||||
message: 'Heating OFF: Outside temperature above threshold'
|
message: 'Heating OFF: Outside temperature above threshold'
|
||||||
|
|
||||||
# Priority 3: Manual Override Active - Do nothing, keep manual temperature
|
# Priority 3: Away/Holiday Mode - Set to away temperature
|
||||||
- conditions:
|
|
||||||
- condition: state
|
|
||||||
entity_id: !input manual_override_helper
|
|
||||||
state: 'on'
|
|
||||||
sequence:
|
|
||||||
- service: logbook.log
|
|
||||||
data:
|
|
||||||
name: Smart Thermostat
|
|
||||||
message: 'Manual override active - maintaining user-set temperature'
|
|
||||||
|
|
||||||
# Priority 4: Away/Holiday Mode - Set to away temperature
|
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: !input away_calendar
|
entity_id: !input away_calendar
|
||||||
|
|
@ -360,7 +234,7 @@ action:
|
||||||
name: Smart Thermostat
|
name: Smart Thermostat
|
||||||
message: 'Away Mode: Heating set to away temperature'
|
message: 'Away Mode: Heating set to away temperature'
|
||||||
|
|
||||||
# Priority 5: Schedule Day Time - Set to day temperature
|
# Priority 4: Schedule Day Time - Set to day temperature
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: !input schedule_helper
|
entity_id: !input schedule_helper
|
||||||
|
|
@ -380,14 +254,16 @@ action:
|
||||||
target:
|
target:
|
||||||
entity_id: !input thermostat
|
entity_id: !input thermostat
|
||||||
data:
|
data:
|
||||||
temperature: !input day_temp
|
# --- REVISED ACTION: Use the variable which holds the helper state ---
|
||||||
|
temperature: "{{ day_temp_input }}"
|
||||||
|
# --- END REVISED ACTION ---
|
||||||
hvac_mode: heat
|
hvac_mode: heat
|
||||||
- service: logbook.log
|
- service: logbook.log
|
||||||
data:
|
data:
|
||||||
name: Smart Thermostat
|
name: Smart Thermostat
|
||||||
message: 'Day Mode: Heating set to day temperature'
|
message: 'Day Mode: Heating set to dynamic day temperature'
|
||||||
|
|
||||||
# Priority 6: Schedule Night Time - Set to night temperature
|
# Priority 5: Schedule Night Time - Set to night temperature
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: !input schedule_helper
|
entity_id: !input schedule_helper
|
||||||
|
|
@ -424,5 +300,5 @@ action:
|
||||||
name: Smart Thermostat
|
name: Smart Thermostat
|
||||||
message: 'Heating OFF: No active heating conditions met'
|
message: 'Heating OFF: No active heating conditions met'
|
||||||
|
|
||||||
mode: single
|
mode: restart
|
||||||
max_exceeded: silent
|
max_exceeded: silent
|
||||||
Loading…
Add table
Reference in a new issue