Hello.
Is it possible to solve this problem, using a generic thermostat?
It is necessary to control the temperature in the house, 2 floors. There is no physical thermostat, but there are controlled relays that regulate heating by floors separately.
I would like to make a separate night and day temperature, with the possibility of changing it from the hass interface.
At the moment, he sees the decision “out of the house”, turn it on at night. But the thermostat does not save the night temperature if you change it.
Create 2 input_numbers that you can modify and keep persistent in lovelace.
# In configuration.yaml
input_number:
temperature_day:
name: House Temp Daytime
min: 10
max: 30
step: 0.5
temperature_night:
name: House Temp Nighttime
min: 10
max: 30
step: 0.5
By not specifying ‘initial’, these values will remember their last value across reboots. Keep in mind, you’ll have to set the initial value your first time (they probably start at ‘min’)
Your 2 options for type are ‘slider’ or ‘box’. Slider if you want to just drag a little slider around to modify, box requires you to type a value. Whatever you prefer.
You could also create an input_datetime if you want to also be able to control when day/night is from lovelace as well.
# In configuration.yaml
input_datetime:
temp_time_transition:
has_date: false
has_time: true
You would pick the time of day you want it to switch from daytime/nightime.
Also, create the time sensor.
This is useful for many things, and necessary for this example. At a minimum, we need the one with ‘time’.
# With all of your other sensors
sensor:
- platform: time_date
display_options:
- 'time'
To make life easier, we’ll create a template sensor that combines time of day and those 2 input numbers. The output of this sensor is the target temperature based on time of day. With this template sensor, we don’t have to do all of the crazy template comparison everywhere else.
sensor:
- platform: template
sensors:
climate_target_temp:
unit_of_measurement: '°C'
# Tell it to track these sensors
entity_id:
# This one tells it to evaluate every minute.
- sensor.time
# Otherwise, if one of these changes, also re-evaluate the state.
- input_number.temperature_day
- input_number.temperature_night
- input_datetime.temp_time_transition
# If it's before specified time, it's morning temp. Otherwise, it's night.
# Time comparison is kind of annoying. Add today's date to the input_datetime
# so we can compare if it's > or < that time.
value_template: >
{% set d = now().strftime("%Y-%m-%d ") %}
{% set t = d + strptime(states("temp_time_transition"), "%H:%M:%S") | as_timestamp %}
{% if now().timestamp() < t %}
{{ states('input_number.temperature_day') }}
{% else %}
{{ states('input_number.temperature_night') }}
So now, we just need an automation to handle the 2 temp sensors and turning on/off the pumps.
There are many different ways to do it. You could wait for state changes of the temp sensors and make decisions based on that. Or you could just check periodically. Each has its own advantages/disadvantages. You could also have upstairs and downstairs be its own automation. For simplicity, we’ll do single floor.
- alias: "First Floor Climate Control"
trigger:
# Any time one of these temperature's change, reevaluate
- platform: state
entity_id: sensor.1st_floor_temp
condition:
# But only do something if this is true.
# The temp is higher than target AND switch is on.
# OR
# The temp is lower than target AND switch is off.
condition: or
# On and Higher
- condition: and
- condition: state
entity_id: switch.1st_floor_pump
state: 'on'
- condition: template
value_template: "{{ trigger.to_state.state | float > states('climate_target_temp') | float }}"
# Off and Lower
- condition: and
- condition: state
entity_id: switch.1st_floor_pump
state: 'off'
- condition: template
value_template: "{{ trigger.to_state.state | float < states('climate_target_temp') | float }}"
action:
- service_template: switch.turn_"{{ 'on' if (trigger.to_state.state | float < states('climate_target_temp') | float) else 'off' }}"
entity_id: switch.1st_floor_pump
Yeah, the ‘condition’ syntax is kind of wonky. I feel like I have to type ‘condition’ and ‘conditions’ way too many times. This should be better…
- alias: "First Floor Climate Control"
trigger:
# Any time one of these temperature's change, reevaluate
- platform: state
entity_id: sensor.1st_floor_temp
condition:
# But only do something if this is true.
# The temp is higher than target AND switch is on.
# OR
# The temp is lower than target AND switch is off.
condition: or
conditions:
# On and Higher
- condition: and
conditions:
- condition: state
entity_id: switch.1st_floor_pump
state: 'on'
- condition: template
value_template: "{{ trigger.to_state.state | float > states('climate_target_temp') | float }}"
# Off and Lower
- condition: and
conditions:
- condition: state
entity_id: switch.1st_floor_pump
state: 'off'
- condition: template
value_template: "{{ trigger.to_state.state | float < states('climate_target_temp') | float }}"
action:
- service_template: switch.turn_"{{ 'on' if (trigger.to_state.state | float < states('climate_target_temp') | float) else 'off' }}"
entity_id: switch.1st_floor_pump
I feel a little stupid.
The automation section is now being tested. But when checking the main config - I get an error:
Invalid config for [sensor.template]: invalid template (TemplateSyntaxError: Unexpected end of template. Jinja was looking for the following tags:
'endif'. The innermost block that needs to be closed is 'if'.) for dictionary value @ data['sensors']['climate_target_temp']['value_template'].
Got '{% set d = now().strftime("%Y-%m-%d ") %} {% set t = d + strptime(states("temp_time_transition"), "%H:%M:%S") |
as_timestamp %} {% if now().timestamp() < t %}\n {{ states(\'input_number.temperature_day\') }}\n{% else %}\n {{ states(\'input_number.temperature_night\') }}\n'. (See ?, line ?).
It seems like I need to seriously read the manuals.
No no, it’s super hard when just using someone else’s code to try to debug it. Especially when learning and don’t fully understand wtf it does already lol.
Few things:
- I have the action wrong in the automation. Quotes need to go around the whole thing. It’s possible this isn’t actually wrong, but I think it is. Not sure if the checker would complain…
action:
- service_template: "switch.turn_{{ 'on' if (trigger.to_state.state | float < states('climate_target_temp') | float) else 'off' }}"
entity_id: switch.1st_floor_pump
- The template sensor syntax is wrong.
value_template: >
{% set d = now().strftime("%Y-%m-%d ") %}
{% set t = d + strptime(states("temp_time_transition"), "%H:%M:%S") | as_timestamp %}
{% if now().timestamp() < t %}
{{ states('input_number.temperature_day') }}
{% else %}
{{ states('input_number.temperature_night') }}
{% endif %}
This one the checker did give a helpful error for.
“Jinja was looking for the following tags: ‘endif’. The innermost block that needs to be closed is ‘if’.)”
Sure enough, I forgot the {% endif %}.
This is just learning jinja2 syntax, which will come with usage. If blocks must look like this:
{% if %}
...
...
...
{% endif %}