Latest modification: March 3 2022
By: Johan F.
Home Assistant is Open Source software that runs on various devices, for instance Raspberry Pi, and acts as a central server for smart home devices and/or self build modules to make automatizations in the home. It has an active community and a large library of integrations with products on the market. Home Assistant is a non-cloud system, which means there is not necessarily a dependance on external cloud services and an internet connection.
Website Home Assistant: home-assistant.io
With the use of Home Assistant I created a multi zone smart thermostat, which I was able to customize to my personal situation. Against low costs, about $50, and all wired to limit the EMF radiation in the home. In this document I will describe my configuration.
Screenshots of my dashboard:
Here is a tab with variables:
A tab with history:
And on my phone:
![](/home-assistant-heating-configuration/images/screenshot%20android.jpeg)
Table of contents
My appartement consists of a living room, a bedroom and a kitchen.
|
A schematic view of the floor plan with the relevant rooms |
A 3D view of the floorplan, the door between living room and bedroom can be closed off (made with https://roomstyler.com/3dplanner) |
The appartement has a boiler (Intergas kompakt hre 24/18) for central heating which can use a on-off control and OpenTherm.
Intergas hre 24/18 |
Home Assistant (The main platform on which everything is running)
Installation instructions for Home Assistant can be found on the Getting Started page of the Home Assistant website.
Download location Home-Assistant OS for Pi Zero W, used in this configuration, is not listed on the website but is available at: https://github.com/home-assistant/operating-system/releases for pi Zero W choose: hassos_rpi0-w-x.xx.img.xz.
Note: Since the release of HA OS 7.0 the Pi Zero isn't supported anymore. See this Github Pull request. The 6.6 version is still available for download. However it is uncertain how long the Home Assistant latest core will be running on this version 6. For running a future proof hardware configuration, the RPi3 or above seems to be a better choice.
Arduino IDE (for uploading Arduino sketches to the arduino mcu)
Home assistant integrations for the thermostat
Several integrations are used. The most important is the Generic Thermostat integration, designed to act as a on-off thermostat with a switch:
Bedroom
Plastic container with a hole cut out with a 5 meter USB extension cable to the server.
In this container.
Store: Aliexpress
An arduino sketch is flashed to the arduino nano. The output of this sketch will be sent to serial via USB. As an alternative to coding a sketch for a USB connected arduino(like) device, Firmata, can also be considered. With firmata it is easy to create a YAML file to add sensors and actuators and have them outputted to Home Assistant.
This setup uses a USB serial connection, which is suitable, as this is a small appartement, with just two rooms. For larger house there are other wired alternatives, see the Wired alternatives section.
Arduino sketch used:
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/*
The setup function. We only start the sensors here
*/
void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
sensors.setResolution(12);
}
/*
Main function, get and show the temperature
*/
void loop(void)
{
int numberOfDevices = sensors.getDeviceCount();
if (numberOfDevices > 0) {
sensors.requestTemperatures();
}
float t = sensors.getTempCByIndex(0);
Serial.println(t);
delay(30000);
}
Living room
Server with sensors:
Case: Aliexpress
PIR case (only used as case and fitted in 5V PIR): Aliexpress
Contains:
Store: Aliexpress
Note: DHT11/22 sensors don't work with pi0 and Home Assistant (driver not provided), if desired use an Arduino with DHT sensor and connect to Home Assistant.
Store: Aliexpress
There are two set screws on this module, one is for measure distance and one for sensitivity (how long the signal is high)
Store: Aliexpress
Connnected together:
In casing:
The casing is too small to fit al the parts, so the USB hub is connected outside the casing.
Note about the pi0
The pi Zero W is the Raspberry with the least powerful specifications. However, it does run well for a year now, as I only use it for nothing else than the thermostat function. The larger Raspberry pi boards have headers, the GPIO pins, soldered to to them. For Pi0 you can choose to buy a headerless of with header. I prefer the one already soldered, as it is only a couple of bucks more.
Download location Home-Assistant OS for pi0 at: https://github.com/home-assistant/operating-system/releases for pi Zero W choose: hassos_rpi0-w-x.xx.img.xz.
Note: Since the release of HA OS 7.0 the Pi Zero isn't supported anymore. See this Github Pull request. The 6.6 version is still available for download. However it is uncertain how long the Home Assistant latest core will be running on this version 6. For running a future proof hardware configuration, the RPi3 or above seems to be a better choice.
Thermostatic radiator valves
Both rooms have one radiator, each is equipped with an eqiva-N thermostatic radiator valve (TRV). These are only used to open and close the radiators at the beginning and end of the day. They are programmed to setpoint 12° C when the desired heating for the room is off and to 25° C when the desired heating is on.
Limitations
The limitation of using these TRVs is that they aren't being set from within Home Assistant, as I chose a TRV without connectivity. Therefore it is important to keep in mind that there is a risk that they aren't synced to the times set in Home Assistant, as their program needs to be set separately.
Another limitation is that when the set temperature of the bedroom during the day is set higher than the current room temperature, the boiler will start heating but no heat will arrive at the room, as the radiator is closed. Of course it is possible to open the valve manually.
The eqiva-N thermostatic radiator valve (TRV) |
Radiator valve before:
The Herz valve knob - old situation |
There were no thermostatic valves on my radiator (just a turn knob), to get it working with the Eqiva TRV I had to put in a new insert, part #1639091 for Herz radiator valves:
The Herz valve with the old insert removed with a drained system |
The Herz 1639091 insert to make the valve a thermostatic valve |
An extra adapter was necessary to fit the eqiva-N TRV as it doesn't fit the Herz system with the adapters provided on in the package.
|
IMI adapter for Herz part no. 15071304 |
Doorsprings
A doorspring was put on both rooms door, so that they will be kept closed as much as possible to avoid heat loss.
Doorspring for door closing |
I moved to a new apartment and had to install everything in the new situation. I made different choices for this new home, everything is still wired though. A ESPHome hub in the living room and bedroom. Both hubs are connected via Ethernet cables to the network.
Also different is the use of heating actuators instead of the Eqiva TRVs. Inspired by this topic on the Openhab forum. These heating actuators are now synced to Home Assistant, which was not the case with the Eqiva TRVs. Also added window open/close sensors.
Heating actuator, usually applied in underfloor heating, now applied in the new design |
Below is a schematic overview of this new situation. I am planning on updating this document with the automations used in the new situation.
April 2020:
Replaced the server Raspberry Pi zero with a Asus Chromebox second hand for €40. Flashed HaOS to a an SSD drive via USB with a USB to SATA connector and plugged this in the Chromebox.
Created the following helpers via configuration > helpers within Home Assistant
Type | Name: | |
---|---|---|
Someone home? | input_boolean (toggle) | input_boolean.presence |
Go to bed time | input_datetime.bedtime | |
Evening time | input_datetime.eveningtime | |
Wake up time | input_datetime.wakuptime | |
Set temperature living room night | input_text.livingroom_settemp_night | |
Set temperature living room day | input_text.livingroom_settemp_day | |
Current set temperature living room according to program | input_number.current_settemp_livingroom | |
Countdown timer | timer | timer.countdown |
Second to last movement recorded | input_datetime.movement_one_before_last | |
Last movement recorded | input_datetime.movement_last | |
Current set temperature living room according to program | input_number.current_settemp_bedroom | |
Hours and minutes for a manual change in set temperature before reverting to program | input_datetime.duration_manual_temperature_change | |
Heating toggle switch for bedroom (used in generic thermostat as heating switch) | input_boolean.switch_thermostat_bedroom | |
Heating toggle switch for Living room (used in generic thermostat as heating switch) | input_boolean.switch_thermost_livingroom | |
Set temperature living room night | input_text.bedroom_settemp_night | |
Set temperature living room day | input_text.bedroom_settemp_day |
To easily change settings to which I would like them, I make use of input variables. I made a tab in Lovelace to edit this variables.
Most of them speak for themselves. The someone home switch is turned on depending on presence detection. When the set temperature of the thermostat is changed manually, it will revert back to the initial set temperature according to program after the set Duration manual change value. The countdown shows the amount of time left until revert to initial set temperature.
As it is one of the design wishes to have an all wired system to limit the amount of EMF radiation, bluetooth and wifi aren't used and turned off.
This is done by adding to boot/config.txt
dtoverlay=disable-wifi
dtoverlay=disable-bt
You can enter the config.txt file on Windows by reading out your SD card or USB drive on your computer and opening the boot partition. On Mac it is possible to mount the boot drive and read it out, see instructions here.
Only covering the relevant part of the configuration for the smart heating system.
Note (february 20, 2020): From Home Assistant version 2022.6 the support of GPIO reading and output, will be deprecated. Background on this can be read in Architectural Decision Record 0019. As an alternative for GPIO support a HACS integration is available, ha-rpi_gpio. Other alternatives is using other connected microcontrollers and use the GPIO on those devices.
To detect 1-wire temperature sensors on the Raspberry pi first add to your config.txt:
dtoverlay=w1-gpio,gpiopin=4
You can enter the config.txt file on Windows by reading out your SD card or USB drivee on your computer and opening the boot partition. On Mac it is possible to mount the boot drive and read it out, see instructions here.
After this, add the 1-wire integration via Settings / Integrations / Add integration
Restart Home Assistant and if configuration went well, a temperature sensor is detected and a name is assigned to it, similar to sensor.28_011937d1c3d1_temperature
.
More on configuring 1-wire sensors on the Home Assistant documentation: 1-wire integration.
My DS18B20 sensors (onewire) need a correction to match the right temperature value. With the use of template platform a correction is applied to the onewire sensors.
It is actually best to calibrate a temperature sensor, based on a one or two point reference value (like water/ice), but I didn't bother. For my home, it is important that I can set certain thresholds. Whether these are very accurate isn't really important. I just set temperatures that I experience as a pleasant temperature.
See below:
sensor:
- platform: template
sensors:
ds18b20_woonkamer_correctie:
value_template: "{{ states('sensor.28_00000913d350_temperature')|float - 1.2}}"
friendly_name: 'Woonkamer temp'
unit_of_measurement: degrees
Added to configuration.yaml
switch:
- platform: rpi_gpio
ports:
5: Relay
More info on Home Assistant website: rpi_gpio integration
Connected to gpio pin 26
binary_sensor:
- platform: rpi_gpio
invert_logic: false
ports:
26: Motion sensor
More info on Home Assistant website: rpi_gpio integration
After connecting set do desired behavior with the two set screws on the PIR module.
First the sketch from the Hardware section was put on the Arduino nano, see the hardware section.
- platform: serial
serial_port: /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A1083GTG-if00-port0
On the Home Assistant documentation for Arduino integration it is described that serial_port: /dev/ttyUSB1
an be used. However, I noticed that on restarts the assignment of ttyUSB# can differ and therefore the readout of the Arduino can fail after restart. To make sure this doesn't happen the serial by-id is used. Which can be found in Supervisor - System - Click on the three dots in the Host block - Hardware
See below GIF:
This integration adds the thermostat function and when configured makes available the thermostat function in Lovelace.
Home Assistant documentation: Generic thermostat
Choices for configuration variables:
target_temp
I chose target temps within configuration.yaml lower than I actually want, cause with a sudden a reboot of the system I don't want the heating to turn on. I use automations to override the temperature to set these to desired temperatures. After a restart the target_temp
is reverted back to the last setting before the reboot. See Automations further on.min_cycle_duration
Set so that pump and gas furnace of boiler don't have to turn on and off that often. Set to 3 minutes for bedroom and 1 minute for living room. The living room has a larger radiator and 1 minute turned out as a good value. For the bedroom 3 minutes as the there is a smaller radiator.heater
I use two generic_thermostat
instances with separate heater switches, because Generic thermostat isn't able to work with multiple zones (described here) when one heater switch is on both rooms (they will contradict). For each room I used a Helper, input_boolean
switch. Trough an automation I made sure these helpers are controlling the relay switch, which controls the on-off signal to the boiler, see automations.Part in Configuration.yaml
climate:
- platform: generic_thermostat
name: Livingroom
heater: input_boolean.switch_thermost_livingroom
target_sensor: sensor.ds18b20_woonkamer_correctie
min_temp: 12
max_temp: 22
ac_mode: false
min_cycle_duration:
minutes: 1
target_temp: 18.0
cold_tolerance: 0
hot_tolerance: 0
initial_hvac_mode: "heat"
away_temp: 16
precision: 0.1
- platform: generic_thermostat
name: Bedroom
heater: input_boolean.switch_thermostat_bedroom
target_sensor: sensor.serial_sensor
min_temp: 10
max_temp: 22
ac_mode: false
min_cycle_duration:
minutes: 3
target_temp: 12.0
cold_tolerance: 0
hot_tolerance: 0
initial_hvac_mode: "heat"
away_temp: 16
precision: 0.1
I use Telegram for notifications. Currently I am using two notifications:
Translation: "Last week there were 21 hours of heating"
Translation: "Bedroom thermostat turned off bc of too slow heating up, window open?"
Home Assistant documentation: Telegram polling
telegram_bot:
- platform: polling
api_key: secret
allowed_chat_ids:
- secret
notify:
- platform: telegram
name: Telegramnotifier
chat_id: secret
Using the trend platform it is checked if the temperature will rise enough while heating. If not, it can be assumed that a window is open or some other error is happening and the heating is turned off. See automations.
The min_gradient
value, which is the temperature rising per second, for each room is set based on trial and error.
- platform: trend
sensors:
temp_falling_slaapkamer:
entity_id: sensor.serial_sensor
sample_duration: 150
max_samples: 3
min_gradient: 0.0003
invert: false
friendly_name: DeltaT slaapk voldoende
temp_falling_woonkamer:
entity_id: sensor.ds18b20_woonkamer_correctie
sample_duration: 150
max_samples: 3
min_gradient: 0.0005
invert: false
friendly_name: DeltaT woonk voldoende
sensor:
- platform: time_date
display_options:
- 'time'
- 'date'
- 'date_time'
- platform: template
sensors:
deltat_slaapkamer:
value_template: "{{state_attr('binary_sensor.temp_falling', 'gradient')|float * 1000}}"
friendly_name: 'Slaapkamer temp gradient'
unit_of_measurement: 'graden'
deltat_slaapkamer_grens:
value_template: "{{state_attr('binary_sensor.temp_falling', 'min_gradient')|float * 1000}}"
friendly_name: 'Slaapkamer min gradient'
unit_of_measurement: 'graden'
deltat_woonkamer:
value_template: "{{state_attr('binary_sensor.temp_falling_woonkamer', 'gradient')|float * 1000}}"
friendly_name: 'Woonkamer temp gradient'
unit_of_measurement: 'graden'
deltat_woonkamer_grens:
value_template: "{{state_attr('binary_sensor.temp_falling_woonkamer', 'min_gradient')|float * 1000}}"
friendly_name: 'Woonkamer min gradient'
unit_of_measurement: 'graden'
heating_state:
value_template: "{{state_attr('climate.woonkamer', 'hvac_action')}}"
friendly_name: 'thermostaat state'
Two automations per room, one for setting the desired set-temperature at bedtime and one at wake-up time. Also a helper input_number.current_settemp_bedroom
is set with the current-set temperature. This is needed for restoring the set temperatures after restart of the system and after a manual change.
Uses below variables (screenshot from Lovelace dashboard)
I came across the HACS plugin Scheduler card, which provides a lot of features that would come in hand for the desired configuration. I am testing it out right now and it is quite feature rich and suitable for setting schedules. However, as it isn't a native integration within Home Assistant, it is possible that compatibility with Home Assistant will be lost in the future because of updates on Home Assistant. Therefore I chose to go with setting my own automations which are more reliable for the future.
Bedroom set temperature after bedtime
- id: '1587807892892'
alias: Bedroom to settemperature at night
description: ''
trigger:
- at: input_datetime.bedtime
platform: time
condition: []
action:
- data_template:
entity_id: climate.slaapkamer
temperature: '{{ states.input_text.bedroom_settemp_night.state }}'
service: climate.set_temperature
- service: input_number.set_value
data:
value: '{{ states.input_text.bedroom_settemp_night.state }}'
entity_id: input_number.current_settemp_bedroom
mode: single
Living room to set temperature on wake up time
- id: '1589611935632'
alias: Livingroom set temperature at waking time
description: ''
trigger:
- at: input_datetime.wakuptime
platform: time
condition: []
action:
- data_template:
entity_id: climate.woonkamer
temperature: '{{ states.input_text.livingroom_settemp_day.state }}'
service: climate.set_temperature
- service: input_number.set_value
data:
value: '{{ states.input_text.livingroom_settemp_day.state }}'
entity_id: input_number.current_settemp_livingroom
mode: single
Bedroom to set temperature on wake up time
- id: '1587807715263'
alias: Bedroom to settempature on wake up time
description: ''
trigger:
- at: input_datetime.wakuptime
platform: time
condition: []
action:
- data_template:
entity_id: climate.slaapkamer
temperature: '{{ states.input_text.bedroom_settemp_day.state }}'
service: climate.set_temperature
- service: input_number.set_value
data:
value: '{{ states.input_text.bedroom_settemp_day.state }}'
entity_id: input_number.current_settemp_bedroom
mode: single
Living room set temperature after bedtime
- id: '1587310221936'
alias: Livingroom to set temperature at night
description: ''
trigger:
- at: input_datetime.bedtime
platform: time
condition: []
action:
- data_template:
entity_id: climate.woonkamer
temperature: '{{ states.input_text.livingroom_settemp_night.state }}'
service: climate.set_temperature
- service: input_number.set_value
data:
value: '{{ states.input_text.livingroom_settemp_night.state }}'
entity_id: input_number.current_settemp_livingroom
mode: single
As there are two zones in this situation, living room and bedroom, two thermostat instances are needed.
The generic thermostat integration is equipped to work only with one temperature sensor. You can run two instances of the generic thermostat integration. However when the heater option is set to the same switch, then when one thermostat is turned on, the other will automatically turn on too (bc they use the same switch, generic thermostat is programmed like that). This sometimes can lead to situations in which the thermostat of a room will turn on while cold air is flowing in because of a open window.
Therefore a couple of input_booleans are created and are set as heater switch. Via an automation the relay switch will be turned on if one of these input_booleans are turned on.
Also the someone status input_boolean.iemandthuis
is taken into account
- id: '1587373774458'
alias: Turn on thermostat when Someone home is set to on
description: ''
trigger:
- entity_id: input_boolean.iemandthuis
platform: state
to: 'on'
condition: []
action:
- data: {}
entity_id: climate.woonkamer
service: climate.turn_on
- data: {}
entity_id: climate.slaapkamer
service: climate.turn_on
And a seperate for turning off when the state for Someone home is off.
- id: '1608318174333'
alias: presenceheid uit
description: ''
trigger:
- platform: state
entity_id: input_boolean.iemandthuis
to: 'off'
condition: []
action:
- service: climate.turn_off
data: {}
entity_id: climate.slaapkamer
- service: climate.turn_off
data: {}
entity_id: climate.woonkamer
mode: single
- id: '1606337912735'
alias: Living room thermostaat on
description: ''
trigger:
- platform: template
value_template: '{{state_attr(''climate.woonkamer'', ''temperature'') > state_attr(''climate.woonkamer'',
''current_temperature'')}}'
- platform: template
value_template: '{{ (states.sensor.time.last_changed - states.input_boolean.iemandthuis.last_changed).total_seconds()
> 5 }}
'
- platform: time_pattern
minutes: '3'
condition:
- condition: template
value_template: '{{state_attr(''climate.woonkamer'', ''temperature'') > state_attr(''climate.woonkamer'',
''current_temperature'')}}'
- condition: state
entity_id: input_boolean.iemandthuis
state: 'on'
- condition: state
entity_id: climate.woonkamer
state: 'off'
action:
- service: climate.turn_on
data: {}
entity_id: climate.woonkamer
mode: single
max: 10
- id: '1606839006446'
alias: Woonkamer thermostaat uit
description: ''
trigger:
- platform: template
value_template: '{{state_attr(''climate.woonkamer'', ''temperature'') < state_attr(''climate.woonkamer'',
''current_temperature'')}}'
- platform: time_pattern
minutes: '2'
condition:
- condition: state
entity_id: climate.woonkamer
state: 'on'
- condition: template
value_template: '{{state_attr(''climate.woonkamer'', ''temperature'') < state_attr(''climate.woonkamer'',
''current_temperature'')}}'
action:
- service: climate.turn_off
data: {}
entity_id: climate.woonkamer
mode: restart
max: 10
- id: '1606338268883'
alias: 'Bedroom thermostaat on / off '
description: ''
trigger:
- platform: template
value_template: '{{state_attr(''climate.slaapkamer'', ''temperature'') > state_attr(''climate.slaapkamer'',
''current_temperature'')}}'
- platform: time_pattern
minutes: '3'
- platform: template
value_template: '
{{ (states.sensor.time.last_changed - states.input_boolean.iemandthuis.last_changed).total_seconds()
> 5 }}
'
condition:
- condition: template
value_template: '{{state_attr(''climate.slaapkamer'', ''temperature'') > state_attr(''climate.slaapkamer'',
''current_temperature'')}}'
- condition: state
entity_id: input_boolean.iemandthuis
state: 'on'
action:
- service: climate.turn_on
data: {}
entity_id: climate.slaapkamer
- wait_for_trigger:
- platform: template
value_template: '{{state_attr(''climate.slaapkamer'', ''temperature'') < state_attr(''climate.slaapkamer'',
''current_temperature'')}}'
- service: climate.turn_off
data: {}
entity_id: climate.slaapkamer
mode: restart
As a room is asking for a heat, the corresponding input_boolean switch is turned by the thermostat. This automations takes care of turning on the relay switch sending the heating signal to the heater.
- id: '1608298248187'
alias: Enabling heating switch to boiler based when room heat switch turns on
description: ''
trigger:
- platform: state
entity_id: input_boolean.switch_thermostat_bedroom
to: 'on'
- platform: state
entity_id: input_boolean.switch_thermost_livingroom
to: 'on'
condition: []
action:
- service: switch.turn_on
data: {}
entity_id: switch.relay
mode: single
{% raw %}
The opposite of the previous automation. When there is no heating demand by the thermostats, both input_booleans for bedroom and livingroom are off and the relay switch to the heater will go off.
{% raw %}
- id: '1608298257006'
alias: Helper schakelaars UIT klimaat
description: ''
trigger:
- platform: time_pattern
seconds: '5'
- platform: state
entity_id: input_boolean.switch_thermostat_bedroom
to: 'off'
- platform: state
entity_id: input_boolean.switch_thermost_livingroom
to: 'off'
condition:
- condition: state
entity_id: input_boolean.switch_thermostat_bedroom
state: 'off'
- condition: state
entity_id: input_boolean.switch_thermost_livingroom
state: 'off'
action:
- service: switch.turn_off
data: {}
entity_id: switch.relay
mode: single
- id: '1608318082068'
alias: presenceheid aan
description: ''
trigger:
- platform: state
entity_id: input_boolean.iemandthuis
to: 'on'
condition: []
action:
- service: climate.turn_on
data: {}
entity_id: climate.slaapkamer
- service: climate.turn_on
data: {}
entity_id: climate.woonkamer
mode: single
- id: '1608318195860'
alias: presenceheid uit
description: ''
trigger:
- platform: state
entity_id: input_boolean.iemandthuis
to: 'off'
condition: []
action:
- service: climate.turn_off
data: {}
entity_id: climate.slaapkamer
- service: climate.turn_off
data: {}
entity_id: climate.woonkamer
mode: single
Presence detection is done with both the mobile phone GPS location and a PIR movement sensor in the living room. If the mobile phone was the only source for presence detection this would have been used, but since there is a PIR as well, the away modus of Generic thermostat integration isn't used in this configuration, instead of this a helper switch input (Someone home?).
I used a PIR sensor next to the smartphone, because there are some disadvantages in using smartphones only for presence detection. There are scenarios like when the battery is down or the phone is on flight mode, in which the system will think someone is home. Also it is less suitable when having guests if the smartphone is used as only presence detection source.
The configuration is set so, that when the phone device_tracker.pra_lx1
changes location from away to home or home to away the helper switch input_boolean.iemandthuis
is toggled. So only on state change, not on current state. Next to that, the rule is followed that if two movements aren't being detected within the last half hour, the ‘someone home status' input_boolean.iemandthuis
is set to off.
In the evening the presence detection by the PIR motion detector should be different. It is assumed that if two times a motion is detected within half an hour during evening time
and bedtime
, that someone will be home during the entire night.
As it was noticed that the PIR used in very few occasions can have a false motion detection, the number of two motion detections was chosen.
This configuration set up is based on a one person household, so only one smartphone with the home assistant app running.
Triggers | Between hours | set ‘someone home status' to |
---|---|---|
Two times a motion detected within 30 minutes period ‘someone home status' is off | waking up and evening | on |
An half an hour with one or less motion detected while ‘someone home status' is on | waking up and evening | off |
Two times a motion detected within 30 minutes period while ‘someone home status' is off | evening and bedtime | on |
Smartphone location state change to away | always | off |
Smartphone location state change to home | always | on |
The following automations were set to achieve this.
Creation of input_datetime fields
Two input_datetime fields have been created for the purpose of presence detection: input_datetime.movement_last
and input_datetime.movement_one_before_last
. On a motion detection one is to date/time of the last movement detected and on the next detected motion this value is passed to the other.
This is used, bc it is desired that a minimum of two movements need to be detected in the last 30 minutes to keep the status of some one home, input_boolean.iemandthuis
, to ‘on'.
Setting the movement input_datetime fields on motion detection
- id: '1606672315270'
alias: Movementsensor last
description: ''
trigger:
- platform: state
entity_id: binary_sensor.motion_sensor
to: 'on'
condition: []
action:
- service: input_datetime.set_datetime
data:
datetime: '{{states(''input_datetime.movement_last'')}}'
entity_id: input_datetime.movement_one_before_last
- service: input_datetime.set_datetime
data:
datetime: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
entity_id: input_datetime.movement_last
mode: single
Turning of if not more than 1 movement detected during day
Timespan: between wake-up time and evening time
Description: Turn off the Someone home status input_boolean.iemandthuis
when not more than 1 movement.
- id: '1587319961411'
alias: Gedrag bewegingssensor woonkamer tussen wakuptime en eveningtime (overdag)
description: ''
trigger:
- platform: template
value_template: '{{ (states.sensor.time.last_changed - states.input_datetime.movement_one_before_last.last_changed).total_seconds()
> 1800 }}
'
- platform: state
entity_id: person.johan
to: not_home
condition:
- condition: state
entity_id: input_boolean.iemandthuis
state: 'on'
- before: input_datetime.eveningtime
condition: time
after: input_datetime.wakuptime
action:
- data: {}
entity_id: input_boolean.iemandthuis
service: input_boolean.turn_off
mode: single
Needed for the someone home status to turn on immediately when entering the living room in the morning, otherwise first two motions need to be detected, which can take a while.
- id: '1606905142912'
alias: Reset 1 na laatste beweging 31 min voor wakuptime
description: ''
trigger:
- platform: time_pattern
seconds: '30'
condition:
- condition: template
value_template: '{/% set current_time = now().hour * 60 + now().minute %}
{/% set wakuptime_hour, wakuptime_minute, wakuptime_second = states(''input_datetime.wakuptime'').split('':'')
%}
{/% set wakuptime_time = wakuptime_hour | int * 60 + wakuptime_minute | int %}
{{ current_time == wakuptime_time - 32 }}'
action:
- service: input_datetime.set_datetime
data:
datetime: '{{now().strftime(''%Y-%m-%d %H:%M:%S'')}}'
entity_id: input_datetime.movement_one_before_last
mode: restart
- id: '1587319960331'
alias: Turn on someone home status
description: ''
trigger:
- entity_id: device_tracker.pra_lx1
platform: state
to: home
- entity_id: binary_sensor.motion_sensor
platform: state
to: 'on'
condition:
- condition: state
entity_id: input_boolean.iemandthuis
state: 'off'
action:
- data: {}
entity_id: input_boolean.iemandthuis
service: input_boolean.turn_on
mode: single
- id: '1587404974211'
alias: presenceheid detectie eveningtime tot wakuptime
description: ''
trigger:
- platform: template
value_template: '{{ (states.sensor.time.last_changed - states.input_datetime.movement_one_before_last.last_changed).total_seconds()
== 300 }}'
condition:
- condition: state
entity_id: input_boolean.iemandthuis
state: 'off'
- before: input_datetime.wakuptime
condition: time
after: input_datetime.eveningtime
- condition: template
value_template: '{{ (states.sensor.time.last_changed - states.input_datetime.movement_one_before_last.last_changed).total_seconds()
< 300 }}'
action:
- data: {}
entity_id: input_boolean.iemandthuis
service: input_boolean.turn_on
mode: single
If home status was on during night it should turn of at waking time in case I wake up later than usual or leave house earlier.
- id: '1608290218329'
alias: Bij wakuptime presenceheid uit
description: ''
trigger:
- platform: time
at: input_datetime.wakuptime
condition: []
action:
- service: input_boolean.turn_off
data: {}
entity_id: input_boolean.iemandthuis
mode: single
- id: '1587319961411'
alias: Behaviour of motion sensor living room between wakeup time and evening time
description: ''
trigger:
- platform: template
value_template: '{{ (states.sensor.time.last_changed - states.input_datetime.movement_one_before_last.last_changed).total_seconds()
> 1800 }}
'
- platform: state
entity_id: person.johan
to: not_home
condition:
- condition: state
entity_id: input_boolean.iemandthuis
state: 'on'
- before: input_datetime.bedtime
condition: time
after: input_datetime.wakuptime
action:
- data: {}
entity_id: input_boolean.iemandthuis
service: input_boolean.turn_off
mode: single
- id: '1606221709908'
alias: Smartphone thuiskomen / weggaan
description: ''
trigger:
- platform: state
entity_id: person.johan
to: not_home
condition: []
action:
- service: input_boolean.turn_off
data: {}
entity_id: input_boolean.iemandthuis
- wait_for_trigger:
- platform: state
entity_id: person.johan
to: home
- service: input_boolean.turn_on
data: {}
entity_id: input_boolean.iemandthuis
mode: restart
- id: '1587373899805'
alias: Thermostaat uit bij niemand thuis
description: ''
trigger:
- entity_id: input_boolean.iemandthuis
platform: state
to: 'off'
condition: []
action:
- data: {}
entity_id: climate.woonkamer
service: climate.turn_off
- data: {}
entity_id: climate.slaapkamer
service: climate.turn_off
Automation:
- id: '1588717917351'
alias: 5 minuten verwarmen als schakelaar aan
description: ''
trigger:
- entity_id: input_boolean.30_min_verwarmen_schakelaar
platform: state
to: 'on'
condition: []
action:
- data: {}
entity_id: switch.relay
service: switch.turn_on
- timeout: 00:05
wait_template: ''
- data: {}
entity_id: switch.relay
service: switch.turn_off
- service: input_boolean.turn_off
data: {}
entity_id: input_boolean.30_min_verwarmen_schakelaar
mode: single
When there isn't anyone present in the house and the outside temperature is far below zero, the temperature in house can reach very low temperatures. This can cause heating pipes to freeze and break, which will leak when the water melts again and can cause flooding. With this automation the thermostat wil turn on, when the temperature in the bedroom reaches a value below 5 degrees..
Automation:
alias: Beveiliging vriezen
description: ''
trigger:
- platform: time_pattern
minutes: '5'
condition:
- condition: numeric_state
entity_id: climate.slaapkamer
attribute: current_temperature
below: '5'
action:
- service: climate.set_temperature
data:
temperature: 5
entity_id: climate.slaapkamer
- service: input_boolean.turn_on
data: {}
entity_id: input_boolean.iemandthuis
- service: climate.set_temperature
data:
temperature: 5
entity_id: climate.woonkamer
- service: climate.turn_on
data: {}
entity_id: climate.slaapkamer
- wait_template: ''
timeout: '300'
- service: climate.turn_off
data: {}
entity_id: climate.slaapkamer
- service: input_boolean.turn_off
data: {}
entity_id: input_boolean.iemandthuis
mode: single
There are no window sensors, but this is based on the temperature rise during heating. If the temperature doesn't rise quickly enough, it is assumed that a window is open and thermostat function will turn off.
Uses the Trend sensor to make the binary_sensor.temp_falling
After 300 seconds of heating without reaching the threshold of de trend sensor, the thermostat is turned off and sends a Telegram notification:
Translation: "Bedroom thermostat turned off bc of too slow heating up, window open?"
Automations:
For the bedroom:
- id: '1588799650928'
alias: Relay beveiging raam open
description: ''
trigger:
- platform: time_pattern
minutes: '5'
condition:
- condition: state
entity_id: binary_sensor.temp_falling
state: 'off'
- condition: template
value_template: '{{state_attr(''climate.slaapkamer'', ''temperature'') | float
> state_attr(''climate.slaapkamer'', ''current_temperature'')}}'
- condition: state
entity_id: switch.relay
state: 'on'
- condition: template
value_template: '{{ (states.sensor.time.last_changed - states.switch.relay.last_changed).total_seconds()
> 310 }}'
action:
- service: telegram_bot.send_message
data:
message: Slaapkamer thermostaat uitgeschakeld ivm te langzame opwarming, raam
open?
target: [chat-number]
- data: {}
entity_id: climate.slaapkamer
service: climate.turn_off
- delay: 00:45:00
- service: climate.turn_on
data: {}
entity_id: climate.slaapkamer
mode: single
And for the living room:
- id: '1601215001454'
alias: Relay beveiging raam open (woonkamer)
description: ''
trigger:
- platform: template
value_template: '{{ (states.sensor.time.last_changed - states.switch.relay.last_changed).total_seconds()
> 400 }}'
condition:
- condition: state
entity_id: automation.slaapkamer_overgang_off_on_set_schakelaar
state: 'on'
action:
- data: {}
entity_id: climate.woonkamer
service: climate.turn_off
- delay: 00:59:00
- service: climate.turn_on
data: {}
entity_id: climate.woonkamer
mode: single
According to input_datetime.duration_manual_temperature_change
value a timer is started after which the set temperature will revert back to set temperature according to program.
Uses the Timer integration
- id: '1604920070266'
alias: Countdown bij manual wijziging
description: ''
trigger:
- platform: state
entity_id: climate.slaapkamer
attribute: temperature
- platform: state
entity_id: climate.woonkamer
attribute: temperature
condition: []
action:
- service: timer.start
data:
duration: '{{ states.input_datetime.duration_manual_temperature_change.state }}'
entity_id: timer.countdown
- delay: '{{ states.input_datetime.duration_manual_temperature_change.state }}'
- service: climate.set_temperature
data:
temperature: '{{ states.input_number.current_settemp_bedroom.state }}'
entity_id: climate.slaapkamer
- service: climate.set_temperature
data:
temperature: '{{ states.input_number.current_settemp_livingroom.state }}'
entity_id: climate.woonkamer
mode: restart
- id: '1604938488226'
alias: Notificatie aantal uren verwarmen in week
description: ''
trigger:
- platform: time
at: '18:00'
condition:
- condition: time
weekday:
- sun
action:
- service: telegram_bot.send_message
data:
message: De afgelopen week is er {{ states.sensor.aantal_minuten_verwarmen_laatste_7_dagen.state
| int}} uren verwarmd.
mode: single
It occasionally happens that there is no signal of the DS18B20 temperature sensor or that by mistake the USB cable gets unplugged. The displayed temperature then can get below set temperature and will trigger heating while not really desired. To avoid this an automation is set to turn off.
- id: '1606221459609'
alias: Beveiliging uitvallen temp sensor
description: ''
trigger:
- platform: numeric_state
entity_id: climate.slaapkamer
attribute: current_temperature
below: '10'
- platform: numeric_state
entity_id: sensor.ds18b20_woonkamer_correctie
below: '10'
condition: []
action:
- service: climate.turn_off
data: {}
entity_id: climate.slaapkamer
- service: climate.turn_off
data: {}
entity_id: climate.woonkamer
mode: single
When using zone heating in your house, consider adding a bypass valve to your central heating plan. A bypass valve will let through water when the pressure in the system gets too high. This avoid damage to the boiler pump because of pumping while all the radiators are closed you can open a small radiator manually or add a bypass valve. I just keep a radiator in my shower always opened.
Some possible improvements for this design to implement later on:
Easiest way is to post a message in this topic on the Home Assistant community forum.
Reasons to choose for a wired configuration instead of wireless are:
The above described configuration uses a USB cable connection to an arduino to my bedroom. This is convenient as it both powers and readouts the arduino. For other, larger houses with multiple temperature sensors and zones this will not be an option, as it's not suitable for long distances.
The Olimex-poe-iso, ESP32 device with Ethernet connection |
Power over Ethernet (PoE)
Power over Ethernet can be very convenient in a wired configuration. PoE devices are providing both power and a data connection through one cable. This dismisses the need for adding power to the device by an extra power source. PoE is not available on all Ethernet connections, a PoE router or switch is needed.
Home Assistant community forum
I used these webpages for inspiration:
A tutorial: Siytek - the ultimate home-assistant DIY guide for multiple zone heating
A nice project by Davide Perini which also uses a PIR motion detector and has a 3D printed case and a LCD screen: github.com/sblantipodi/smart_thermostat
Other links to similar:
Hacking a Eqiva EQ-3 thermostatic radiator valve.
An interesting idea: using Omron D6T thermal sensors as room presence detection
Opentherm module by Ihor Melnyk
MQTT PoE radiator valves on the Home Assistant community forum
For underfloor heating systems a wired solution is "off the shelve system" is the Homematic underfloor heating system.
Scheduler plugin for HACS, the add-on library for add-ons not in the official add-on store.
An interesting idea is to use heating actuators on the radiator controlled by relays. These actuators are actually designed for floor heating manifolds. This topic on the Openhab forum discusses this option.
Below a photo from that topic.
Another project: Orientation on measuring and controlling in the vegetable garden using sensors