Here in the UK we recently had a large hike in utility costs and we’re looking at up to another 80% increase in the next month.
(src: What is the energy price cap and how high will bills go? - BBC News)
So for those of us (myself included) that have a “dumb” boiler, I thought I’d share a recent simple project that made my boiler more efficient in it’s consumption by minimising the time it’s running when not needed.
In my home, my boiler has an interface that allows a simple 3times a day on/off schedule that can be programmed for each day of the week. We can set it to 24/7 hot water, off or scheduled.
I can “boost” the heater by hitting the Advance button that starts the boiler heating before entering a scheduled time and it would go off as per the schedule.
This is inefficient for us as we rarely need hot water at the same time each day. Usually we just need 20-30mins for a shower and often forget to switch it off after or in worst cases, on all night.
Prep:
To create this setup the same way we have, you need the following
- Google Calendar integration watching a scheduling calendar. (Useful if you work a shift pattern).
- 1x SwitchBot Smart Switch Button Pusher like this: Amazon link
- (Optional) NFC tags for convenience
If you don’t have a Switchbot hub (I don’t) then you can still use it without. You need:
- Bluetooth integration (available > 2022.8)
- A Bluetooth dongle + extension cable if your Bluetooth signal isn’t strong enough to reach your boiler’s location.
Hardware Installation:
With Bluetooth integration configured, As soon as you enable the battery on the Switchbot, your HA will detect it and request you name it and give it a password. The password seems arbitrary, but just remember what you set for the device as you may need it in the future (re-install?)
For my setup, I removed all of the on/off schedules from the boiler interface, but left it on “Timed”. This is so the Advance button still triggers it to start/stop heating water + radiators.
I did a quick test of the Switchbot in my hand with a button card in Lovelace to make sure it was working ok, then I tested the positioning to make sure it would work ok. Which was handy as it needed to be closer to the button than I expected.
Then alcohol wipe and final placement of the Switchbot.
Configuration:
The way I configured this in my system is to have a single Toggle/Boolean that will trigger the script for toggling the SwitchBot. Everything else works around this one Toggle element and it also allows you to manually override any automations.
-
Create the on/off Toggle
In Helpers, create your toggle as “Water Heating” (input_boolean.water_heating) -
Prep Calendar to be used as a trigger method
If your Google Calendar uses the "older"method of monitoring events, update your google_calendars.yaml with the search term. e.g.
- cal_id: [email protected]
entities:
- device_id: my_haschedule
ignore_availability: true
name: HA Schedule
- device_id: heating
name: heating
search: "#heating"
- Create the Actuation script
In Scripts, create the action that will activate the Switchbot
alias: Boiler Toggle
sequence:
- type: toggle
device_id: th1s157h3un1qu31df0rmysw1tchb07
entity_id: switch.the_name_of_my_switchbot
domain: switch
mode: single
icon: mdi:water-boiler
- Create some action scripts
Now some sample scripts that we can use to preset to boost the boiler for n minutes when requested.
NOTE: Google calendars update every 15 minutes, so this is why we use the internal HA timer rather than letting the calendar manage these short heating scripts.
20 Minute Boost:
(Edit Note: Updated so that re-triggering the script will stop the heating if you don’t want the full 20min)
alias: Boiler Trigger 20 Mins
sequence:
- if:
- condition: state
entity_id: input_boolean.water_heating
state: "off"
then:
- service: input_boolean.turn_on
data: {}
target:
entity_id: input_boolean.water_heating
- delay:
hours: 0
minutes: 20
seconds: 0
milliseconds: 0
- if:
- condition: state
entity_id: input_boolean.water_heating
state: "on"
then:
- service: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.water_heating
mode: restart
icon: mdi:water-boiler
Sleeping:
Trigger as you go to bed so that it’s hot in the morning (assuming you sleep 8hrs)
alias: Boiler Trigger 8hrs
sequence:
- service: google.create_event
data:
summary: Heating
description: "#heating"
start_date_time: >-
{{ (as_timestamp(now()) + (7.5*3600))| timestamp_custom('%Y-%m-%d
%H:%M:%S', True) }}
end_date_time: >-
{{ (as_timestamp(now()) + (8*3600))| timestamp_custom('%Y-%m-%d
%H:%M:%S', True) }}
target:
entity_id: calendar.my_haschedulecalendar
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
mode: single
icon: mdi:water-boiler
- Last of all, the 2 automations that do all the work
The first automation monitors the Toggle and actuates the Switchbot:
alias: Hot Water Boiler Actions
description: ""
trigger:
- platform: state
entity_id:
- input_boolean.water_heating
to: "on"
id: sensor-on
- platform: state
entity_id:
- input_boolean.water_heating
to: "off"
id: sensor-off
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: sensor-on
sequence:
- service: script.boiler_toggle
data: {}
- conditions:
- condition: trigger
id: sensor-off
sequence:
- service: script.boiler_toggle
data: {}
default: []
mode: single
The second automation watches your calendar and turns the Toggle switch off/on accordingly
alias: Calendar Scheduled - Heating
description: ""
trigger:
- platform: state
entity_id:
- calendar.heating
to: "on"
id: event-start
- platform: state
entity_id:
- calendar.heating
to: "off"
id: event-end
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: event-start
sequence:
- service: input_boolean.turn_on
data: {}
target:
entity_id: input_boolean.water_heating
- conditions:
- condition: trigger
id: event-end
sequence:
- service: input_boolean.turn_off
data: {}
target:
entity_id: input_boolean.water_heating
default: []
mode: single
Display and Control
The way I view these scripts in my dashboard is with mushroom template cards
Heating off:
Heating manually:
Heating when triggered by a “boost” button:
Heating when scheduled:
Sample Lovelace card code:
square: false
columns: 1
type: grid
cards:
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: >-
{% if states('input_boolean.water_heating')=='on' %}
Heating from
{{(as_timestamp(states.input_boolean.water_heating.last_changed) |
timestamp_custom('%H:%M'))}}
{% else %}
Heating OFF
{% endif %}
icon: |-
{% set showstate = states('input_boolean.water_heating') %}
{% if showstate == 'on' %}
mdi:water-boiler
{% else %}
mdi:water-boiler-off
{% endif %}
layout: vertical
entity: input_boolean.water_heating
multiline_secondary: true
tap_action:
action: toggle
hold_action:
action: more-info
double_tap_action:
action: none
icon_color: |-
{% if states('input_boolean.water_heating')=='on' %}
yellow
{% else %}
blue
{% endif %}
fill_container: false
secondary: ''
- type: custom:mushroom-template-card
primary: Cal 30
secondary: ''
icon: |-
{% set showstate =states('script.boiler_trigger_30_mins_cal') %}
{% if showstate == 'on' %}
mdi:water-boiler
{% else %}
mdi:water-boiler-off
{% endif %}
layout: vertical
entity: script.boiler_trigger_30_mins
multiline_secondary: true
tap_action:
action: call-service
service: script.boiler_trigger_30_mins_cal
data: {}
target: {}
hold_action:
action: none
double_tap_action:
action: none
icon_color: |-
{% if states('script.boiler_trigger_30_mins_cal')=='on' %}
yellow
{% else %}
grey
{% endif %}
fill_container: false
- type: custom:mushroom-template-card
primary: >-
{% if states('calendar.heating')=='on' %}
{{as_timestamp(state_attr('calendar.heating','start_time')) |
timestamp_custom('%H:%M')}} -
{{as_timestamp(state_attr('calendar.heating','end_time')) |
timestamp_custom('%H:%M')}}
{% endif %}
secondary: >-
{% if is_state('calendar.heating','off') and
(state_attr('calendar.heating', 'start_time') is not none) %}
{{as_timestamp(state_attr('calendar.heating','start_time')) |
timestamp_custom('%H:%M')}} -
{{as_timestamp(state_attr('calendar.heating','end_time')) |
timestamp_custom('%H:%M')}}
{% elif is_state('calendar.heating','off') and
(state_attr('calendar.heating', 'start_time') == none) %}
No Schedule
{% else %}
{% endif %}
icon: |-
{% if states('calendar.heating')=='on' %}
mdi:timer-check
{% else %}
mdi:timer-outline
{% endif %}
layout: vertical
entity: calendar.heating
multiline_secondary: true
tap_action:
action: more-info
hold_action:
action: more-info
double_tap_action:
action: none
icon_color: |-
{% if states('calendar.heating')=='on' %}
yellow
{% else %}
grey
{% endif %}
fill_container: false
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: 10min
secondary: ''
icon: |-
{% set showstate =states('script.boiler_trigger_10_mins') %}
{% if showstate == 'on' %}
mdi:water-boiler
{% else %}
mdi:water-boiler-off
{% endif %}
layout: vertical
entity: script.boiler_trigger_10_mins
multiline_secondary: true
tap_action:
action: call-service
service: script.boiler_trigger_10_mins
data: {}
target: {}
hold_action:
action: none
double_tap_action:
action: none
icon_color: |-
{% if states('script.boiler_trigger_10_mins')=='on' %}
yellow
{% else %}
grey
{% endif %}
fill_container: false
- type: custom:mushroom-template-card
primary: 20min
secondary: ''
icon: |-
{% set showstate =states('script.boiler_trigger_20_mins') %}
{% if showstate == 'on' %}
mdi:water-boiler
{% else %}
mdi:water-boiler-off
{% endif %}
layout: vertical
entity: script.boiler_trigger_20_mins
multiline_secondary: true
tap_action:
action: call-service
service: script.boiler_trigger_20_mins
data: {}
target: {}
hold_action:
action: none
double_tap_action:
action: none
icon_color: |-
{% if states('script.boiler_trigger_20_mins')=='on' %}
yellow
{% else %}
grey
{% endif %}
fill_container: false
- type: custom:mushroom-template-card
primary: 30min
secondary: ''
icon: |-
{% set showstate =states('script.boiler_trigger_30_mins') %}
{% if showstate == 'on' %}
mdi:water-boiler
{% else %}
mdi:water-boiler-off
{% endif %}
layout: vertical
entity: script.boiler_trigger_30_mins
multiline_secondary: true
tap_action:
action: call-service
service: script.boiler_trigger_30_mins
data: {}
target: {}
hold_action:
action: none
double_tap_action:
action: none
icon_color: |-
{% if states('script.boiler_trigger_30_mins')=='on' %}
yellow
{% else %}
grey
{% endif %}
fill_container: false
- type: custom:mushroom-template-card
primary: +8h
secondary: ''
icon: |-
{% set showstate =states('script.boiler_trigger_8hrs') %}
{% if showstate == 'on' %}
mdi:sleep
{% else %}
mdi:sleep
{% endif %}
layout: vertical
entity: script.boiler_trigger_8hrs
multiline_secondary: true
tap_action:
action: call-service
service: script.boiler_trigger_8hrs
data: {}
target: {}
hold_action:
action: none
double_tap_action:
action: none
icon_color: |-
{% if states('script.boiler_trigger_8hrs')=='on' %}
yellow
{% else %}
grey
{% endif %}
fill_container: false
Summary:
It’s early days, but so far it’s working well. No unnecessary heating of the water when it’s not needed which also includes electrical consumption running the boiler pumps and internals.
Being able to schedule by calendar will be great if you work a pattern of regular or irregular hours.
Or even go on leave so you can plan in advance when to start getting your home warm for your return.
If it’s a second/rental home that’s unoccupied, If you have other sensors inside, if it gets too cold then you could have an automation to heat the home to prevent damp and/or monitor live weather to set up automations to prevent ice from splitting pipes.
Lots of automation ideas that can be applied to a once dumb appliance