Skip to content

Instantly share code, notes, and snippets.

@WizBangCrash
Last active February 24, 2024 11:50
Show Gist options
  • Save WizBangCrash/001517d205c31b1bca81550a7b470ebc to your computer and use it in GitHub Desktop.
Save WizBangCrash/001517d205c31b1bca81550a7b470ebc to your computer and use it in GitHub Desktop.
Climate control using calendar and home presence
#
# Climate control
#
# Use a local calendar and a prescense sensor to optimise a thermostat climate control
#
# The automation uses calendar events to control the setpoint of the thermostat.
# Each calendar event summary field contains either a numeric temperature value or
# a present name as the last word in the summary field.
# The thermostat will then be set to the appropiate setpoint when the claendar events
# start and end. If no events are present then the setpoint will be the "home" preset.
#
# Calendar events can overlap as the automation will alwasy use the last start event
# and then return to the current event or 'home' at the end of the overlapping event.
#
# The presence sensor enables the thermostat to switch to the 'away' setpoint when
# the house becomes 'unoccupied', automatically saving energy.
#
# If used in conjunction with my home presence template trigger sensor here:
# https://gist.github.com/01d3599761b4c63afcdff446d63b4848.git
#
# When you are returning to your home the automation will detect you crossing the boundary of
# 'Close to Home' zone and switch to the 'home' preset. Thus warming your house up for your arrival.
# Upon entering the house and it becoming 'occupied' the thermostat will be set to the
# current active event.
#
# I've only been using this automation for a few weeks, but already see a 10% saving
# on our gas bills this winter.
#
blueprint:
name: Climate control using calendar and home presence
description: 'v1.3
Use a combination of home prescence and calendar events to set the
thermostat temperature and maintain a healthy home climate.
'
domain: automation
input:
calendar_entity_id:
name: Calendar
description: The calendar to use for scheduling
selector:
entity:
filter:
- domain:
- calendar
multiple: false
home_prescense_entity_id:
name: Home Prescense
description: The home presence sensor to use
selector:
entity:
domain:
- sensor
device_class:
- enum
multiple: false
climate_entity_id:
name: Thermostat
description: The thermostat to use
selector:
entity:
domain:
- climate
multiple: false
preset_modes:
name: Preset Modes
description: The present modes the thermostat supports
selector:
object: {}
default:
- comfort
- home
- sleep
- away
source_url: https://gist.github.com/WizBangCrash/001517d205c31b1bca81550a7b470ebc
variables:
calendar_entity_id: !input calendar_entity_id
home_prescense_entity_id: !input home_prescense_entity_id
climate_entity_id: !input climate_entity_id
preset_modes: !input preset_modes
trigger:
- alias: Calendar Start
platform: calendar
event: start
offset: 0:0:0
entity_id: !input calendar_entity_id
id: start event
- alias: Calendar End
platform: calendar
event: end
offset: 0:0:20
entity_id: !input calendar_entity_id
id: end event
- platform: state
entity_id:
- !input home_prescense_entity_id
id: Home presence changes
- platform: homeassistant
event: start
id: hassio started
condition: []
action:
- alias: Determine actions to perform
choose:
- alias: Is home unoccupied
conditions:
- condition: template
value_template: '{{ is_state(home_prescense_entity_id, "unoccupied") }}'
sequence:
- alias: Set climate preset to away
service: climate.set_preset_mode
target:
entity_id: !input climate_entity_id
data:
preset_mode: away
- alias: Has the home just become vacated
conditions:
- condition: or
conditions:
- condition: template
value_template: '{{ is_state(home_prescense_entity_id, "leaving") and state_attr(climate_entity_id,
"preset_mode") not in ["away", "sleep"] }}'
- condition: template
value_template: '{{ is_state(home_prescense_entity_id, "approaching") }}'
sequence:
- alias: Set climate preset to home
service: climate.set_preset_mode
target:
entity_id: !input climate_entity_id
data:
preset_mode: home
default:
- alias: "Only process events if house is not unoccupied"
condition: template
value_template: "{{ not is_state(home_prescense_entity_id, 'unoccupied') }}"
- alias: Retrieve the current event
service: calendar.get_events
data:
duration:
hours: 0
minutes: 1
seconds: 0
response_variable: current_events
target:
entity_id: !input calendar_entity_id
- variables:
setpoint: "{% if current_events[calendar_entity_id].events|count == 0\n or
(current_events[calendar_entity_id].events|last).summary|length == 0 %}\n
\ home\n{% else %}\n {% set setting = (current_events[calendar_entity_id].events|last).summary.lower().split()[-1]
%}\n {% if is_number(setting) or setting in preset_modes %}\n {{ setting
}}\n {% else %}\n none\n {% endif %}\n{% endif %}"
- if:
- alias: Numeric or preset value?
condition: template
value_template: '{{ is_number(setpoint) }}'
then:
- alias: Set preset
service: climate.set_preset_mode
target:
entity_id: !input climate_entity_id
data:
preset_mode: none
- alias: Set target temperature
service: climate.set_temperature
target:
entity_id: !input climate_entity_id
data:
temperature: '{{ setpoint }}'
else:
- if:
- alias: Preset is none
condition: template
value_template: '{{ setpoint == ''none'' }}'
then:
- service: system_log.write
data:
level: warning
message: Preset was set to none. Summary field is "{{ (current_events[calendar_entity_id].events|last).summary
}}"
logger: myblueprint.climate_control
- alias: Set preset
service: climate.set_preset_mode
target:
entity_id: !input climate_entity_id
data:
preset_mode: '{{ setpoint }}'
mode: queued
trace:
stored_traces: 20
max: 10
@WizBangCrash
Copy link
Author

v1.2
Stop using the calendar_entity_id as the thermostat entity! 🤦

@WizBangCrash
Copy link
Author

v1.3
Calendar events no longer processed if the house is unoccupied

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment